# lib_acscan.pl
# 23/09/2010 Add warnign about input
# 04/09/2010 This version is similar to lib_acscan-ok.pl, excepted does NOT use while (<CONFIG>) and $_, nor $.
# 02/09/2010 geoff mclane http://geoffair.net/mperl
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )

# options
my $abort_on_ac_config = 0; # automake requires 'AM_CONFIG_HEADER', not 'AC_CONFIG_HEADER'
# forward
sub scan_configure_ac_file($$);

my $AM_CONDITIONAL_PATTERN = "AM_CONDITIONAL\\((\\w+)";
my $AM_INIT_AUTOMAKE = "AM_INIT_AUTOMAKE\\(([^,]+),[ \t]*([^)]+)";
# AC_INIT (package, version, [bug-report], [tarname]) 
# Set the name of the package and its version
# BUT can be a FILE NAME ONLY
my $AC_INIT = "AC_INIT\\((.+)\\)";
my $AC_DEFINE = "AC_DEFINE\\((.+)\\)";
my $AC_DEFINE_UNQ = "AC_DEFINE_UNQUOTED\\((.+)\\)";

### shared with library
our ($dbg_lac01, $dbg_lac02, $dbg_lac03, $dbg_lac04, $dbg_lac05, $dbg_lac06, $dbg_lac07, $dbg_lac08,
     $dbg_lac09, $dbg_lac10, $dbg_lac11, $dbg_lac12, $dbg_lac13, $dbg_lac14, $dbg_lac15, $dbg_lac16, 
     $dbg_lac17, $dbg_lac18, $dbg_lac19, $dbg_lac20,
     $dbg_last
     );

my $ac_done_debug_flags = 0;
my $dbg_extra = 0;
my $dbg_extra2 = 0;
my $dbg_extra3 = 0;
sub set_dbg_shell_actions();
sub ac_set_dbg_extra() {
    $dbg_extra = 1; $dbg_extra2 = 1; $dbg_extra3 = 1;
    set_dbg_shell_actions();
}
my $ac_dbg_base = 'dbg_lac';
sub ac_get_dbg_val_var($) {
    my $val = shift;
    my $var = $ac_dbg_base;
    if ($val < 10) {
        $var .= "0$val";
    } else {
        $var .= "$val";
    }
    return $var;
}
sub ac_get_dbg_var($) {
    my $val = shift;
    my $var = ac_get_dbg_val_var($val);
    my $res = -1;
    # from : http://perldoc.perl.org/functions/eval.html
    if (eval "defined \$$var") {
        $res = eval "\$$var";
    }
    return $res;
}
sub ac_set_dbg_var($) {
    my $val = shift;
    my $var = ac_get_dbg_val_var($val);
    # from : http://perldoc.perl.org/functions/eval.html
    # NOT $$var++; # does not work!
    if (eval "defined \$$var") {
        eval "\$$var++";
    } else {
        #print "ERROR: \$$var does NOT exist\n";
        return 0;
    }
    return 1;
}
sub ac_get_dbg_range() {
    my ($i,$res);
    for ($i = 1; ;$i++) {
        $res = ac_get_dbg_var($i);
        last if ($res == -1);
    }
    return $i - 1;
}

sub ac_get_dbg_stg() {
    my $s = '';
    my ($i,$res,$i2);
    for ($i = 1; ;$i++) {
        $res = ac_get_dbg_var($i);
        last if ($res == -1);
        if ($i < 10) {
            $i2 = "0$i";
        } else {
            $i2 = "$i";
        }
        if ($res > 0) {
            $s .= "$i2 ";
        }
    }
    return $s;
}

# this converts a BIT to a flag value
sub ac_set_debug_flags($) {
    my $dbg = shift;
    $ac_done_debug_flags = 1;
    my $nxt = 1;
    my $flg = 0;
    my $rng = ac_get_dbg_range();
    my $pack = __PACKAGE__;
    prt("Setting [$pack] debug flags for 1 to $rng, for value [$dbg]\n") if ($dbg);
    while ($dbg && $nxt) {
        $flg++;
        if ($dbg & $nxt) {
            if ($flg < $rng) {
                ac_set_dbg_var($flg);
            } else {
                last;
            }
        }
        $dbg &= ~$nxt;
        $nxt = $nxt << 1;
    }
}

sub ac_set_all_dbg_on() {
    my ($i,$res);
    for ($i = 1; ;$i++) {
        $res = ac_set_dbg_var($i);
        last if (!$res);
    }
}

sub ac_set_all_dbg_off() {
    my ($i,$res);
    for ($i = 1; ;$i++) {
        $res = ac_clear_dbg_var($i);
        last if (!$res);
    }
}

########################################################
### DIRECTORY SCANNING ###
sub ac_do_dir_scan($$$);

sub ac_do_dir_scan($$$) {
    my ($rparams,$dir,$lv) = @_;
    my $rda = ${$rparams}{'CURR_DIR_SCAN'};
    $dir .= "\\" if !($dir =~ /(\\|\/)$/);
    $dir = path_u2d($dir);
    my ($file,$ff,$n,$d);
    my @dirs = ();
    prt("Moment, doing full directory scan of [$dir]...\n") if ($lv == 0);
    if (opendir(DIR,$dir)) {
        my @files = readdir(DIR);
        closedir(DIR);
        foreach $file (@files) {
            next if (($file eq '.')||($file eq '..'));
            $ff = $dir.$file;
            if (-d $ff) {
                push(@dirs,$ff);
                next;
            }
            #             0     1   2 3
            push(@{$rda},[$file,$ff,0,0]);
        }
    }
    if (@dirs) {
        foreach $file (@dirs) {
            ac_do_dir_scan($rparams,$file,$lv+1);
        }
    }
    if ($lv == 0) {
        $file = scalar @{$rda};
        prt("Done scan... got $file files...\n");
        ${$rparams}{'CURR_DONE_SCAN'} = 1;
        ${$rparams}{'CURR_FILE_COUNT'} = $file;
    }
}

my %ac_searches_shown = ();
sub ac_is_file_in_scan($$$$) {
    my ($rparams,$test,$fd,$ra) = @_;
    if (! ${$rparams}{'CURR_DONE_SCAN'} ) {
        my $dir = ${$rparams}{'CURR_FILE_DIR'};
        if (-d $dir) {
            ac_do_dir_scan($rparams,$dir,0);
        } else {
            prtw("WARNING: Directory SEARCH FAILED! [$dir] NOT found!\n");
            return 0;
        }
    }
    my $rda = ${$rparams}{'CURR_DIR_SCAN'};
    my $cnt = scalar @{$rda};
    my ($i,$file,$fcnt,$ff);
    $fcnt = 0;
    for ($i = 0; $i < $cnt; $i++) {
        $file = ${$rda}[$i][0];
        if ($test eq $file) {
            $ff = ${$rda}[$i][1];
            # could now check if $fd at least partially matches, but for now
            push(@{$ra},$ff);
            $fcnt++;
        }
    }
    if ($dbg_lac20 && !defined $ac_searches_shown{$test}) {
        prt("[20] Directory SEARCH for [$test], found $fcnt.\n") if ($dbg_lac20);
    }
    $ac_searches_shown{$test} = 1;
    return $fcnt;
}

sub ac_match_dir_for_c_source($$$$) {
    my ($rparams,$oky,$dir,$ra) = @_;
    if (! ${$rparams}{'CURR_DONE_SCAN'} ) {
        my $dir = ${$rparams}{'CURR_FILE_DIR'};
        if (-d $dir) {
            ac_do_dir_scan($rparams,$dir,0);
        } else {
            prtw("WARNING: Directory SEARCH FAILED! [$dir] NOT found!\n");
            return 0;
        }
    }
    my $rda = ${$rparams}{'CURR_DIR_SCAN'};
    my $cnt = scalar @{$ra};
    my ($i,$file,$fcnt,$fn,$fd,$fx);
    $fcnt = 0;
    $dir = path_u2d($dir);
    $dir .= "\\" if (!($dir =~ /\\$/));
    for ($i = 0; $i < $cnt; $i++) {
        $file = ${$rda}[$i][1];  # get FULL FILE
        ($fn,$fd,$fx) = fileparse($file,qr/\.[^.]*/);
        $fd = path_u2d($fd);
        if (($fd eq $dir) && ($fn eq $oky)) {
            if (is_c_source_extended($file)) {
                push(@{$ra},$file);
                return 1;
            }
        }
    }
    return 0;
}


#########################################################
sub show_ac_hash($) {
    my ($rparams) = @_;
    my ($key,$val,$cnt,$ky2,$val2,$len,$min,$ff,$ok,$typ,$cnt2,$msg);
    my $inf = ${$rparams}{'CURR_FILE'};
    my $rh =  ${$rparams}{'CURR_HASH'};
    my $supp_in = ${$rparams}{'SUPP_MAKE_IN'};
    my ($in_name, $in_dir) = fileparse($inf);
    $msg = "\nGot keys: ";
    foreach $key (keys %{$rh}) {
        $msg .= "$key ";
    }
    prt("$msg\n") if ($dbg_lac13);
    my $tot_cnt = 0;
    $cnt2 = 0;
    foreach $key (keys %{$rh}) {
        $val = ${$rh}{$key};
        $cnt2++;
        if ($key eq '-NEW_PROJECT_NAME-') {
            prt("\n") if ($dbg_lac13);
            prt("KEY:$cnt2: $key = [$val]\n");
        } elsif ($key eq 'H_CONF_AC_MACS') {
            $cnt = scalar keys(%{$val});
            prt("\n") if ($dbg_lac13);
            prt("KEY:$cnt2: $key with $cnt macros in hash\n");
            $tot_cnt += $cnt;
            if ($dbg_lac13) {
                $min = 0;
                foreach $ky2 (keys %{$val}) {
                    $val2 = ${$val}{$ky2};
                    $len = length($ky2);
                    $min = $len if ($len > $min);
                }
                $min = 40 if ($min > 40);
                foreach $ky2 (keys %{$val}) {
                    $val2 = ${$val}{$ky2};
                    $ky2 .= ' ' while (length($ky2) < $min);
                    prt(" $ky2 = [$val2]\n");
                }
            }
        } elsif ($key eq 'R_SUBS_NOT_FOUND') {
            $cnt = scalar keys(%{$val});
            prt("\n") if ($dbg_lac13);
            prt("KEY:$cnt2: $key with $cnt macros in hash\n");
            $tot_cnt += $cnt;
            if ($dbg_lac13) {
                $min = 0;
                foreach $ky2 (keys %{$val}) {
                    $val2 = ${$val}{$ky2};
                    $len = length($ky2);
                    $min = $len if ($len > $min);
                }
                $min = 40 if ($min > 40);
                foreach $ky2 (keys %{$val}) {
                    $val2 = ${$val}{$ky2};
                    $ky2 .= ' ' while (length($ky2) < $min);
                    prt(" $ky2 = [$val2]\n");
                }
            }
        } elsif ($key eq 'A_MAKE_INPUT_LIST') {
            prt("\n") if ($dbg_lac13);
            $cnt = scalar @{$val};
            prt("KEY:$cnt2: $key with $cnt in array...\n");
            foreach $ky2 (@{$val}) {
                $typ = ".am";
                $ff = $in_dir.$ky2.$typ;
                if ($supp_in && ( ! -f $ff ) && ( -f $in_dir.$ky2.'.in') && ($ky2 =~ /^Makefile/)) {
                    $typ = ".in";
                    $ff = $in_dir.$ky2.$typ;
                }
                if (-f $ff) {
                    $ok = "$typ ok";
                    write_to_am_list($ff,1);
                } else {
                    $ok = "NOT FOUND [$ff]";
                    write_to_am_list($ff,0);
                }
                prt( " $ky2 $ok, ");
                prt("\n") if ($dbg_lac13);
            }
            prt("\n") if ($cnt && !$dbg_lac13);
        } elsif ($key eq 'A_OTHER_INPUT_LIST') {
            $cnt = scalar @{$val};
            prt("\n") if ($dbg_lac13);
            prt("KEY:$cnt2: $key with $cnt in array...\n");
            $tot_cnt += $cnt;
            if ($dbg_lac13) {
                foreach $ky2 (@{$val}) {
                    $ff = $in_dir.$ky2;
                    if (-f $ff) {
                        $ok = "ok";
                        #write_to_am_list($ff,1);
                    } else {
                        $ok = "NOT FOUND [$ff]";
                        #write_to_am_list($ff,0);
                    }
                    prt( " $ky2 $ok\n");
                }
            }
        } elsif ($key =~ /^CURR_/) {
            # ignore current items
            # ====================
        } else {
            prtw("WARNING:$cnt2: Unhandled key [$key]!\n");
        }
    }
    if ($dbg_lac13) {
        prt("End show_ac_hash\n");
    } else {
        prt("Add command '-d 113' to view $tot_cnt items in detail.\n");
    } 
}

##########################################################
### attempt to emulate a few shell actions to set a macro
my $dbg01 = 0;
my $dbg05 = 0;
my $dbg06 = 0;
my $dbg37 = 0;
my $dbg38 = 0;
sub set_dbg_shell_actions() { $dbg01 = 1; $dbg05 = 1; $dbg06 = 1; $dbg37 = 1; $dbg38 = 1; }
# [m]/PATTERN/[g][i][m][o][s][x]
# s/PATTERN/REPLACEMENT/[e][g][i][m][o][s][x]
# tr/SEARCHLIST/REPLACMENTLIST/[c][d][s]
my $m_mods = 'gimosx';
my $s_mods = 'egimosx';
my $t_mods = 'cds';
my $add_scalars = 0;
my $add_quoted = 1;
# FLAGS
my $FG_NONE = 0;
my $FG_SCAL = 1;   # is a SCALAR entry
my $FG_QUOT = 1;  # is a QUOTED entry

# simply, does it start and end with '`' chars
sub ac_is_shell_action($) {
    my $txt = shift;
    return 1 if ($txt =~ /^`.+`$/);
    return 0;
}

# 2010-08-27: This could be split(/\s/,$line), but there is a
# problem with name="with space", that this overcomes.
# Slower. but sure the split is as desired.
# This version obeys either type of quote - single or double
sub ac_local_space_split($) {
	my ($lin) = shift;
	my $ll = length($lin);
	my $tag = '';
	my @rarr = ();
	my $inquots = 0;
    my ($p,$ch,$cq);
	for ($p = 0; $p < $ll; $p++) {
		$ch = substr($lin,$p,1);
		if ($inquots) {
			$tag .= $ch; # accumulate
			if ($ch eq $cq) {
				$inquots = 0;   # end of quotes
				push(@rarr, $tag) if (length($tag));
				$tag = '';
			}
		} else {
			if ($ch =~ /\s/) {
				push(@rarr, $tag) if (length($tag));
				$tag = '';
			} else {
				$tag .= $ch;    # accumulate
				if (($ch eq '"')||($ch eq "'")) {
					$inquots = 1;
                    $cq = $ch; # keep the quote type
				}
			}
		}
	}
	push(@rarr, $tag) if (length($tag));
	return @rarr;
}


sub grep_for_value($$) {
    my ($file,$find) = @_;
    my $res = '';
    if (open INF,"<$file") {
        my @lns = <INF>;
        close INF;
        my ($ln,$ind);
        foreach $ln (@lns) {
            $ind = index($ln,$find);
            if ($ind >= 0) {
                chomp $ln;
                $res = $ln;
                last;
            }
        }
    } else {
        prtw("WARNING: Unable to open file [$file]\n") if ($dbg38);
    }
    return $res;
}

sub ac_return_regex2($) {
    my ($rp) = @_;
    my $txt = ${$rp}{'TEXT'};
    my ($ind,$len,$i,$c,$reg,$nc,$go,$pc,$mods,$ppc,$endc,$sub,$rege1,$dn1,$rege2);
    $len = length($txt);
    $ind = 0;
    $reg = '';
    $go = 0;
    $endc = '/';
    $sub = 0;
    $rege1 = '';
    $dn1 = 0;
    $rege2 = '';
    for ($i = 0; $i < $len; $i++) {
        $c = substr($txt,$i,1);
        $nc = (($i + 1) < $len) ? substr($txt,$i+1,1) : '';
        #prt( "Check char [$c] nc = [$nc]\n" );
         if ($c eq '/') {
            $reg = $c;
            $mods = $m_mods;
            $go = 1;
         } elsif (($c eq 'm')&&($nc eq '/')) {
            $reg = "$c$nc";
            $mods = $m_mods;
            $i++;
            $go = 1;
         } elsif (($c eq 'm')&&($nc eq '|')) {
            $reg = "$c$nc";
            $mods = $m_mods;
            $endc = $nc;
            $i++;
            $go = 1;
         } elsif (($c eq 's')&&($nc eq '/')) {
            $reg = "$c$nc";
            $mods = $s_mods;
            $sub = 1;
            $i++;
            $go = 1;
         } elsif (($c eq 't')&&($nc eq 'r')) {
            if (($i + 2) < $len) {
               $nc = (($i + 2) < $len) ? substr($txt,$i+2,1) : '';
               if ($nc eq '/') {
                  $reg = "tr/";
                  $i += 2;
                  $mods = $t_mods;
                  $sub = 1;
                  $go = 1;
               }
            }
         } elsif ($c eq '$') {
            # special case of a scalar
            if ($add_scalars) {
               $reg = $c;
               $i++;
               for (; $i < $len; $i++) {
                  $ppc = $pc;
                  $pc = $c;
                  $c = substr($txt,$i,1);
                  $nc = (($i + 1) < $len) ? substr($txt,$i+1,1) : '';
                  if ($c =~ /\w/) {
                     $reg .= $c;
                  } else {
                     last;
                  }
               }
               if (length($reg) > 1) {
                  $ind += $i;
                  ${$rp}{'REGEX'} = $reg;
                  ${$rp}{'OFFSET'} = $ind;
                  ${$rp}{'FLAG'} = $FG_SCAL;
                  ${$rp}{'REG1'} = $rege1;
                  ${$rp}{'REG2'} = $rege2;
                  prt( "Returning SCALAR success [$reg] at off=[$ind]\n" ) if ($dbg06);
                  return 1;
               }
            }
         } elsif ($c eq '"') {
            if ($add_quoted) {
               # limited to '"\w+"'
               $reg = $c;
               $i++;
               for (; $i < $len; $i++) {
                  $ppc = $pc;
                  $pc = $c;
                  $c = substr($txt,$i,1);
                  $nc = (($i + 1) < $len) ? substr($txt,$i+1,1) : '';
                  if ($c =~ /\w/) {
                     $reg .= $c;
                  } elsif ($c eq '"') {
                     $reg .= $c;
                     $i++;
                     last;
                  } else {
                     $reg = '';
                     last;
                  }
               }
               if (length($reg) > 1) {
                  $ind += $i;
                  ${$rp}{'REGEX'} = $reg;
                  ${$rp}{'OFFSET'} = $ind;
                  ${$rp}{'FLAG'} = $FG_QUOT;
                  ${$rp}{'REG1'} = $rege1;
                  ${$rp}{'REG2'} = $rege2;
                  prt( "Returning QUOTED success [$reg] at off=[$ind]\n" ) if ($dbg05);
                  return 1;
               }
            }
         }
         if ($go) {
            prt( "Found GO at offset $i\n" ) if ($dbg01);
            $i++;
            $c = '/';
            for (; $i < $len; $i++) {
               $ppc = $pc;
               $pc = $c;
               $c = substr($txt,$i,1);
               $nc = (($i + 1) < $len) ? substr($txt,$i+1,1) : '';
               $reg .= $c;
               # if (($c eq '/')&&($pc ne "\\")) {
               if ( ($c eq $endc) && 
                  (($pc ne "\\") || (($pc eq "\\") && ($ppc eq "\\")) ) ) {
                  # we appear to have it...
                  if ($sub) {
                     $sub--;
                     $dn1 = 1;
                     next;    # continue for next part of tr or s/.../.../
                  }
                  $i++; # now check for MODS
                  for (; $i < $len; $i++) {
                     $c = substr($txt,$i,1);
                     last if ( !($c =~ /\w/) );
                     if ($c =~ /[$mods]/) {
                        $reg .= $c;
                     } else {
                        last;
                     }
                  }
                  $ind += $i;
                  ${$rp}{'REGEX'} = $reg;
                  ${$rp}{'OFFSET'} = $ind;
                  ${$rp}{'FLAG'} = $FG_NONE;
                  ${$rp}{'REG1'} = $rege1;
                  ${$rp}{'REG2'} = $rege2;
                  prt( "Returning success [$reg] at off=[$ind] 1 [$rege1] 2 [$rege2]\n" ) if ($dbg01);
                  return 1;
               }
               if ($dn1) {
                   $rege2 .= $c;
               } else {
                   $rege1 .= $c;
               }
            }
            last;
     }
  }
  #prt( "Returning FAILED\n" );
  return 0;
}

sub ac_return_regex($$$$) {
    my ($txt,$roff,$rreg,$rflag) = @_;   # like substr($line,$off), \$off, \$reg )
    my ($ind);
    $ind = index($txt,'=~');
    if ($ind >= 0) {
        $ind += 2;
        $txt = substr($txt,$ind);
        my %p = ();
        my $rp = \%p;
        ${$rp}{'TEXT'} = trim_all($txt);
        my ($rege1,$rege2);
        if (ac_return_regex2($rp)) {
            if (${$rp}{'FLAG'} == $FG_NONE) {
                $rege1 = ${$rp}{'REG1'};
                $rege2 = ${$rp}{'REG2'};
                ${$roff} = ${$rp}{'OFFSET'};
                ${$rreg} = ${$rp}{'REGEX'};
                ${$rflag} = ${$rp}{'FLAG'};
                return 1;
            }
        }
        #   return ac_return_regex2($txt,$roff,$rreg,$rflag);
   }
   #prt( "Returning FAILED\n" );
   return 0;
}

# cut range
# N   N'th byte, char or field, counted from 1
# N-  from N'th to end
# N-M from N'th to M'th (included)
# -M  from 1st to M'th (included)
sub get_cut_range($$) {
    my ($txt,$rrng) = @_;
    if ($txt =~ /^\d+$/) {
        # only digits
        if ($txt >= 1) {
            ${$rrng}[0] = 1;
            ${$rrng}[1] = $txt;
            return 1;
        }
    } elsif ($txt =~ /^\d+-\d*$/) {
        my @arr = split('-',$txt);
        my ($bgn,$end,$len);
        $len = scalar @arr;
        if ($len == 1) {
            $bgn = $arr[0];
            if ($bgn >= 1) {
                ${$rrng}[0] = $bgn;
                ${$rrng}[1] = -1;
                return 1;
            }
        } elsif ($len == 2) {
            $bgn = $arr[0];
            $end = $arr[1];
            if (($bgn >= 1)&&($end >= $bgn)) {
                ${$rrng}[0] = $bgn;
                ${$rrng}[1] = $end;
            }
        }
    } elsif ($txt =~ /^-/) {
        $txt = substr($txt,1);
        if ($txt =~ /^\d+$/) {
            ${$rrng}[0] = 1;
            ${$rrng}[1] = $txt;
            return 1;
        }
    }
    return 0;
}

sub ac_set_by_shell_action($$$) {
    my ($rparams,$key,$rval) = @_;
    my $val = ${$rval}; # get the shell action string
    my (@arr,$len,$act,$k,$res,$find,$file,$rng,$oval,$rlen);
    $res = '';
    $oval = $val;
    my $dir = ${$rparams}{'CURR_FILE_DIR'};
    prt("Set by shell [$key] val [${$rval}], in dir [$dir]\n") if ($dbg37);
    if ($val =~ /^`(.+)`$/) {
        $val = $1;
    }
    $oval = $val;
    @arr = ac_local_space_split($val);
    $len = scalar @arr;
    if ($dbg37) {
        prt("Got space split... $len pieces...\n");
        for ($k = 0; $k < $len; $k++) {
            $act = $arr[$k];
            prt(" [$act]\n");
        }
    }
    for ($k = 0; $k < $len; $k++) {
        $act = $arr[$k];
        if ($act eq 'grep') {
           # ok expect 'something' in file
           if (($k + 2) < $len) {
               $k++;
               $find = strip_both_quotes($arr[$k]);
               $k++;
               $file = $arr[$k];
               $file =~ s/\$\{srcdir\}/$dir/;
               $file = path_u2d($file);
               $file =~ s/\\\\/\\/g;
               prt("Act = $act, find [$find], in [$file]\n") if ($dbg37);
               $res = grep_for_value($file,$find);
               if (length($res)) {
                   prt("Result: [$res]\n") if ($dbg37);
               } else {
                   prtw("WARNING: grep_for_value: $act, find [$find], in [$file] in [$dir] FAILED!\n") if ($dbg37);
               }
           }
        } elsif ($act eq 'cut') {
            # expect - like cut -c 29-
            $k++;
            if ($k < $len) {
                $find = $arr[$k];
                $k++;
                if ($k < $len) {
                    $file = $arr[$k];
                    prt("Act = $act, type [$find], range [$file]\n") if ($dbg37);
                    $rlen = length($res);
                    if ($rlen) {
                        my (@rng); # cut range
                        if (get_cut_range($file,\@rng)) {
                            my ($bgn,$end,$dif);
                            $bgn = $rng[0];
                            $end = $rng[1];
                            prt("Got 'cut' range [$bgn] to [".(($end == -1) ? "End" : $end)."], on string [$rlen]\n") if ($dbg37);
                            if ($end == -1) {
                                if (($bgn - 1) < $rlen) {
                                    $val = substr($res,($bgn - 1));
                                } else {
                                    $val = '';
                                }
                            } else {
                                $dif = $end - $bgn + 1;
                                $bgn--;
                                $val = substr($res,$bgn,$dif);
                            }
                        }
                    }
                }
            }
        } elsif ($act eq 'sed') {
            # sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' C:\Projects\curl\/include/curl/curlver.h
            # Got space split... 4 pieces...
            # [sed] [-ne] ['s/^#define LIBCURL_VERSION "\(.*\)"/\1/p'] [C:\Projects\curl\/include/curl/curlver.h]
           if ($len == 4) {
               $find = strip_both_quotes($arr[2]);
               $file = $arr[3];
               $file = path_u2d($file);
               $file =~ s/\\\\/\\/g;
               prt("Act = $act, find [$find], in [$file]\n") if ($dbg37);
               my %p = ();
               my $rp = \%p;
               $p{'TEXT'} = $find;
               if (ac_return_regex2($rp)) {
                   if (${$rp}{'FLAG'} == $FG_NONE) {
                       #$reg = ${$rp}{'REGEX'};
                       #$off = ${$rp}{'OFFSET'};
                       my $rege1 = ${$rp}{'REG1'};
                       my @ar2 = ac_local_space_split($rege1);
                       if (scalar @ar2 >= 2) {
                           my $f1 = $ar2[0];
                           my $f2 = $ar2[1];
                           if (open INF, "<$file") {
                               while (<INF>) {
                                   if (/^$f1\s+$f2\s+(.+)$/) {
                                       $val = $1;
                                       $val = strip_both_quotes($val);
                                       last;
                                   }
                               }
                               close INF;
                           }
                       }
                   }
               }
               $k += 3;
           }
        } elsif ($act eq '|') {
            prt("Act = $act\n") if ($dbg37);
        } else {
            prt("Item NOT handled [$act]\n") if ($dbg37);
        }
    }
    if ($dbg37) {
        prt("Setting NEW value [$val]\n") if ($val ne $oval);
    }
    #exit(1);
    ${$rval} = $val;
}

# ========================================================
# split ac file macro
# 1: $MACRO\W
# 2: $(MACRO)
# 3: ${MACRO}
# Not done @MACRO@
# input:
# $val = string value to SPLIT
# $add = 0=only macro keys in array
#        1=Macro key, and other bits in array
sub ac_split_macros($$) {
    my ($val,$add) = @_;
    my $len = length($val);
    my @arr = ();
    my $tag = '';
    my ($i,$ch,$nxt,$nc,$k,$pc,$i2,$cn,$min);
    for ($i = 0; $i < $len; $i++) {
        $i2 = $i + 1;
        $ch = substr($val,$i,1);
        if ($ch eq '$') {
            # got the beginning '$' char, so get NEXT
            $cn = (($i2 < $len) ? substr($val,$i2,1) : '');
            $nxt = $ch;
            $k = $i + 1;
            $pc = '';   # NO end cahr
            $min = 3;   # has to be '$12' - a length greater than this
            if ($cn eq '{') {
                $pc = '}';  # set end '}'
                $nxt .= $cn;
                $k++;
                $min = 5;
            } elsif ($cn eq '(') {
                $pc = ')';  # set end ')'
                $nxt .= $cn;
                $k++;
                $min = 5;
            }
            for (; $k < $len; $k++) {
                $nc = substr($val,$k,1);
                if ($nc =~ /\W/) {
                    # NOT an alpha-numeric + '_', then
                    # hmmm, what to do about things like ${DEFAULT_BLOCKING-20}
                    if ($nc eq $pc) {
                        $nxt .= $nc;
                        $k++;
                    } elsif (length($pc)) {
                        $nxt = '';  # NOT HANDLED like ${DEFAULT_BLOCKING-20}
                    }
                    last;
                }
                $nxt .= $nc;
            }
            if (length($nxt) > $min) {
                push(@arr,$tag) if (length($tag) && $add);
                push(@arr,$nxt);
                $tag = '';
                $i = $k - 1;
                $ch = '';
                next;
            }
        }
        $tag .= $ch;
    }
    push(@arr,$tag) if (length($tag) && $add);
    if ($dbg_lac14) {
        $len = scalar @arr;
        prt("[14] Value [$val] split into $len pieces...\n");
        $len = 0;
        foreach $nxt (@arr) {
            $len++;
            prt(" $len: [$nxt]\n");
        }
    }
    return \@arr;
}

sub ac_add_2_ac_macros($$$) {
	my ($key,$val,$rcacm) = @_;
    #prt("[18] ac_add_2_ac_macros: KEY = [$key] VALUE = [$val]\n");
    if (defined ${$rcacm}{$key}) {
        my $cval = ${$rcacm}{$key};
        prt("[18] KEY: [$key] Replacing [$cval], with [$val]\n") if ($dbg_lac18);
    } else {
        prt("[18] KEY: [$key] Setting [$val]\n") if ($dbg_lac18);
    }
	${$rcacm}{$key} = $val;
}

sub ac_do_macro_subs($$$);

# $nval = ac_do_macro_sub($nval,$rmh);
# 13/09/2010 - Added USER supplied, and do this FIRST
# 27/09/2010 - Added GLOBAL hash, and do this LAST
sub ac_do_macro_subs($$$) {
    my ($val,$src,$rparams) = @_;
    my $ruserh = ${$rparams}{'CURR_USERS_SUBS'}; # user supplied MACRO SUBS
    my $rmh = ${$rparams}{'CURR_AC_MAC'};
    my $key = ${$rparams}{'CURR_KEY'};
    my $rch = ${$rparams}{'CURR_COMMON_SUBS'};
    my $rgh = ${$rparams}{'REF_GLOBAL_HASH'};
    if ($val =~ /^`(.+)`$/) {
        $val = $1;  # stripped outer shell  quotes
        # prt("Value before [$val]\n");
        $val = ac_do_macro_subs($val,$src,$rparams);
        # prt("Value after [$val]\n");
        ac_set_by_shell_action($rparams,$key,\$val);
    }
    if ($val =~ /\$/) {
        my $rvarr = ac_split_macros($val,0);
        my ($blk,$key2,$nval,$done,$cnt,$oline,$typ,$typ2,$msg);
        my %failed_macro = ();
        $cnt = 0;
        $oline = $val;
        foreach $blk (@{$rvarr}) {
            if ($blk =~ /\$/) {
                $done = 0;
                $key2 = '<none>';
                $typ = 0;
                $typ2 = 0;
                # 1: if a bare '$ABC'
                if ($blk =~ /^\$(\w+)$/) {
                    $key2 = $1;
                    $typ = 1;
                    if (defined ${$ruserh}{$key2}) {
                        $nval = ${$ruserh}{$key2};
                        $done = 1;
                        $typ2 = 4;
                        $cnt++;
                    } elsif (defined ${$rmh}{$key2}) {
                        $nval = ${$rmh}{$key2};
                        $done = 1;
                        $typ2 = 1;
                        $cnt++;
                    } elsif (defined ${$rch}{$key2}) {
                        $nval = ${$rch}{$key2};
                        $done = 1;
                        $typ2 = 2;
                        $cnt++;
                    } elsif (defined ${$rgh}{$key2}) {
                        $nval = ${$rgh}{$key2};
                        $done = 1;
                        $typ2 = 5;
                        $cnt++;
                    } elsif ($key eq $key2) {
                        $nval = '';
                        ac_add_2_ac_macros($key2,$nval,$rmh);
                        $done = 1;
                        $typ2 = 3;
                        $cnt++;
                    }
                    if ($done) {
                        if (length($nval)) {
                            $val =~ s/\$$key2/$nval/;
                        } else {
                            $val =~ s/\$$key2\s*//;
                        }
                    }
                # 2: if a curly '${ABC}'
                } elsif ($blk =~ /^\$\{(\w+)\}$/) {
                    $key2 = $1;
                    $typ = 2;
                    if (defined ${$ruserh}{$key2}) {
                        $nval = ${$ruserh}{$key2};
                        $done = 1;
                        $typ2 = 4;
                        $cnt++;
                    } elsif (defined ${$rmh}{$key2}) {
                        $nval = ${$rmh}{$key2};
                        $done = 1;
                        $typ2 = 1;
                        $cnt++;
                    } elsif (defined ${$rch}{$key2}) {
                        $nval = ${$rch}{$key2};
                        $done = 1;
                        $typ2 = 2;
                        $cnt++;
                    } elsif (defined ${$rgh}{$key2}) {
                        $nval = ${$rgh}{$key2};
                        $done = 1;
                        $typ2 = 5;
                        $cnt++;
                    } elsif ($key eq $key2) {
                        $nval = '';
                        ac_add_2_ac_macros($key2,$nval,$rmh);
                        $typ2 = 3;
                        $done = 1;
                        $cnt++;
                    }
                    if ($done) {
                        if (length($nval)) {
                            $val =~ s/\$\{$key2\}/$nval/;
                        } else {
                            $val =~ s/\$\{$key2\}\s*//;
                        }
                    }
                # 3: if a bracket '$(ABC)'
                } elsif ($blk =~ /^\$\((\w+)\)$/) {
                    $key2 = $1;
                    $typ = 3;
                    if (defined ${$ruserh}{$key2}) {
                        $nval = ${$ruserh}{$key2};
                        $done = 1;
                        $typ2 = 4;
                        $cnt++;
                    } elsif (defined ${$rmh}{$key2}) {
                        $nval = ${$rmh}{$key2};
                        $done = 1;
                        $typ2 = 1;
                        $cnt++;
                    } elsif (defined ${$rch}{$key2}) {
                        $nval = ${$rch}{$key2};
                        $done = 1;
                        $typ2 = 2;
                        $cnt++;
                    } elsif (defined ${$rgh}{$key2}) {
                        $nval = ${$rgh}{$key2};
                        $done = 1;
                        $typ2 = 5;
                        $cnt++;
                    } elsif ($key eq $key2) {
                        $nval = '';
                        ac_add_2_ac_macros($key2,$nval,$rmh);
                        $done = 1;
                        $typ2 = 3;
                        $cnt++;
                    }
                    if ($done) {
                        if (length($nval)) {
                            $val =~ s/\$\($key2\)/$nval/;
                        } else {
                            $val =~ s/\$\($key2\)\s*//;
                        }
                    }
                }
                # ==========================================================================================
                if ($done) {
                    prt("[17] ac macro subs:$typ:$typ2: [$key2] for [$nval]\n") if ($dbg_lac17);
                } elsif (!$done && $src) {
                    my $file = ${$rparams}{'CURR_FILE'};
                    my $lnn = ${$rparams}{'CURR_LINENUM'};
                    $msg = "[13] $lnn: Failed on MACRO [$key] = [$blk], [$typ] [$key2], in file [$file]";
                    if (!defined $failed_macro{$msg}) {
                        $failed_macro{$msg} = 1;
                        prt("$msg\n") if ($dbg_lac13);
                    }
                    $key2 = $blk if (!$typ);
                    my $rsnf = ${$rparams}{'CURR_SUBS_NOT_FOUND'};
                    if (! defined ${$rsnf}{$key2}) {
                        # keep the first instance of not found
                        ${$rsnf}{$key2} = "$lnn:$file";
                    }
                }
                # ==========================================================================================
            }
        }
    }
    return $val;
}

# =======================================================================
# based on ALL AC_MACROS are of the form
# AC_MACRO([...],....,....), could also check [ ], but that's for later..
# $cline = accumulate_ac_macro($cline,$lncnt,\$ln,\@lines);
# =======================================================================
sub accumulate_ac_macro($$$$) {
    my ($iline,$lncnt,$ri,$rlines) = @_;
    my ($i,$ch,$brcnt,$k,$k2,$lcnt,$acmac,$oline,$sqcnt,$bgnln);
    # prt("Accumulate AC MACRO until end...\n");
    $k = ${$ri};    # extract current line number, 0 based
    $bgnln = $k + 1;
    $oline = $iline;
    my $len = length($iline);
    prt("[dbg_extra3] $bgnln: Doing line [$iline], len $len\n") if ($dbg_extra3);
    # eat any initial space only
    for ($i = 0; $i < $len; $i++) {
        $ch = substr($iline,$i,1);
        last if ($ch =~ /\S/);  # stop on first non-white space
    }
    $acmac = '';    # accumulate the name of the MACRO
    for (; $i < $len; $i++) {
        $ch = substr($iline,$i,1);
        last if ($ch =~ /\W/);  # stop on non-alpha-numeric - should be '('
        $acmac .= $ch;
    }
    # could allow 'space' BEFORE '('
    # ONE DAY

    pgm_exit(1,"ERROR: mac=[$acmac] Fix eat_ac_macro to accept [$ch] following 'name'!\n") if ($ch ne '(');

    # essentially get to END of MACRO - may be mutiple lines
    $i++;   # note, BUMP past FIRST '(', and set $brcnt == 0
    $brcnt = 0;
    $sqcnt = 0;
    $lcnt = 1;
    for (; $i < $len; $i++) {
        $ch = substr($iline,$i,1);
        if ($ch eq '(') {
            if (!$sqcnt) {
                $brcnt++;
                prt("[dbg_extra2]:1:$i:$len: br=$brcnt sq=$sqcnt bumped br count\n") if ($dbg_extra2);
            } else {
                prt("[dbg_extra2]:1:$i:$len: br=$brcnt sq=$sqcnt skipped br count due sqcnt\n") if ($dbg_extra2);
            }
        } elsif ($ch eq '[') {
            $sqcnt++;
            prt("[dbg_extra2]:1:$i:$len: br=$brcnt sq=$sqcnt bumped sq count\n") if ($dbg_extra2);
        } elsif ($ch eq ']') {
            prt("[dbg_extra2]:1:$i:$len: br=$brcnt sq=$sqcnt will decrement sq count\n") if ($dbg_extra2);
            $sqcnt-- if ($sqcnt);
        } elsif ($ch eq ')') {
            if ($sqcnt) {
                $ch = '';
                prt("[dbg_extra2]:1:$i:$len: br=$brcnt sq=$sqcnt skipped br decement due sq count\n") if ($dbg_extra2);
            } else {
                if ($brcnt) {
                    $brcnt--;
                    $ch = '';
                     prt("[dbg_extra2]:1:$i:$len: br=$brcnt sq=$sqcnt decrement br count\n") if ($dbg_extra2);
                } else {
                    prt("[dbg_extra2]:1:$i:$len: br=$brcnt sq=$sqcnt EXIT0\n") if ($dbg_extra2);
                    last;
                }
            }
        }
    }

    if ($ch ne ')') {   # oops, need more lines
        $k++;
        $k2 = $k + 1;
        my $nline = '';
        prt( "\n[dbg_extra] br=$brcnt sq=$sqcnt no closed! Get next line $k, of $lncnt lines\n" ) if ($dbg_extra);
        while ($k < $lncnt) {
            #prt( "$k2:$.: need more lines...br=$brcnt, sq=$sqcnt...\n" ); # if ($dbg01);
            $nline = trim_all(${$rlines}[$k]);
            $lcnt++;
            $len = length($nline);
            prt( "[dbg_extra] br=$brcnt sq=$sqcnt line=$lcnt, len=$len [$nline]\n" ) if ($dbg_extra);
            for ($i = 0; $i < $len; $i++) {
                $ch = substr($nline,$i,1);
                if ($ch eq '(') {
                    if ($sqcnt) {
                        $ch = '';
                        prt("[dbg_extra] br=$brcnt sq=$sqcnt skipped br count due sqcnt\n") if ($dbg_extra);
                    } else {
                        $brcnt++;
                        prt("[dbg_extra] br=$brcnt sq=$sqcnt bumped br count\n") if ($dbg_extra);
                    }
                } elsif ($ch eq '[') {
                    $sqcnt++;
                    prt("[dbg_extra] br=$brcnt sq=$sqcnt bumped sq count\n") if ($dbg_extra);
                } elsif ($ch eq ']') {
                    prt("[dbg_extra] br=$brcnt sq=$sqcnt will decrement sq count\n") if ($dbg_extra);
                    $sqcnt-- if ($sqcnt);
                } elsif ($ch eq ')') {
                    if ($sqcnt) {
                        $ch = '';
                        prt("[dbg_extra] br=$brcnt sq=$sqcnt skipped br decement due sq count\n") if ($dbg_extra);
                    } else {
                        if ($brcnt) {
                            $brcnt--;
                            $ch = '';   # CLEAR this char - is NOT the end
                            prt("[dbg_extra] br=$brcnt sq=$sqcnt decrement sq count\n") if ($dbg_extra);
                        } else {
                            prt("[dbg_extra] br=$brcnt sq=$sqcnt EXIT1\n") if ($dbg_extra);
                            last;
                        }
                    }
                }
            }
            if ($ch eq ')') {
                prt("[dbg_extra] br=$brcnt sq=$sqcnt EXIT2\n") if ($dbg_extra);
                if (length($nline)) {
                    #$iline .= ' ' if ( !( ($iline =~ /\s$/) || ($nline =~ /^\s/) ) );
                    $iline .= " "; # "\n";
                    $iline .= $nline;
                    $nline = '';
                }
                last;
            }
            $k++;   # need MORE
            $k2 = $k + 1;
            if (length($nline)) {
                #$iline .= ' ' if ( !( ($iline =~ /\s$/) || ($nline =~ /^\s/) ) );
                $iline .= " "; #"\n";
                $iline .= $nline;
                $nline = '';
            }
        }
        if ($k >= $lncnt) {
            $ch = ${$ri};    # extract current line number
            prt("Started at line $ch, and now at line $k, of $lncnt, searching AC MACRO [$acmac] end...\n");
            $iline = trim_all($iline);
            if (length($iline) > 200) {
                $nline = substr($iline,0,100)."...\n".substr($iline,(length($iline) - 100));
                prt("Have accumulated [$nline]!\n");
            } else {
                prt("Have accumulated [$iline]!\n");
            }
            pgm_exit(1,"ERROR: Ran out of line in an ac macro!\n");
        }
        ${$ri} = $k;    # pass back new line number
    } else {
        prt( "[dbg_extra] Closed in current line\n" ) if ($dbg_extra);
    }

    if ($dbg_lac15 && ($oline ne $iline)) {
        prt("Accumulated from [$bgnln]\n[$oline] to line $k2\n[$iline]\n");
    }
    return $iline;
}

# $cline = accumulate_with_back($cline,$lncnt,\$ln,\@lines);
sub accumulate_with_back($$$$) {
    my ($iline,$lncnt,$rln,$rlines) = @_;
    my ($nline,$oline);
    $oline = $iline;
    $oline =~ s/\\$//;
    $oline = substr($oline,0,length($oline) - 1) while ($oline =~ /\s$/); # remove all TRAILING space
    my $ln = ${$rln};
    while ($iline =~ /\\$/) {
        $iline =~ s/\\$//;  # remove '\'
        $iline = substr($iline,0,length($iline) - 1) while ($iline =~ /\s$/); # remove all TRAILING space
        $ln++;
        if ($ln < $lncnt) {
            $nline = trim_all(${$rlines}[$ln]);
            if (length($nline)) {
                $iline .= " ";
                $iline .= $nline;
            }
        } else {
            last;
        }
    }
    ${$rln} = $ln;  # pass back potentially new line...
    if ($dbg_lac16 && ($oline ne $iline)) {
        prt("Accumulated back from\n[$oline] to line $ln\n[$iline]\n");
    }
    return $iline;
}

#ac_am_conf_line_error($filename, 
# $., "automake requires 'AM_CONFIG_HEADER', not 'AC_CONFIG_HEADER'") if $1 eq 'C';
sub ac_am_conf_line_error($$$) {
    my ($fname,$lnum,$msg) = @_;
    prt("ERROR: file $fname: line $lnum: $msg\n");
    mydie("Aborting scan ...\n");
}

sub ac_trim_all2 {
	my ($txt) = shift;
	$txt = trim_all($txt);
	if ($txt =~ /^\[.+\]$/) {
		$txt = substr($txt,1,length($txt)-2);
	}
	$txt = trim_all($txt);
	return $txt;
}

sub trim_ac_define($) {
    my ($txt) = shift;
    my $len = length($txt);
    my $ntxt = '';
    my ($i,$ch,$brcnt,$sqcnt);
    $brcnt = 0;
    $sqcnt = 0;
    for ($i = 0; $i < $len; $i++) {
        $ch = substr($txt,$i,1);
        $ntxt .= $ch;
        if ($ch eq '[') {
            $sqcnt++;
        } elsif ($ch eq ']') {
            $sqcnt-- if ($sqcnt);
        } elsif ($ch eq '(') {
            if (!$sqcnt) {
                $brcnt++;
            }
        } elsif ($ch eq ')') {
            if (!$sqcnt) {
                if ($brcnt) {
                    $brcnt--;
                } else {
                    last;
                }
            }
        }
    }
    return $ntxt;
}


# tried very HARD to use while (<CONFIGURE>) but it seems WRONG sometimes
# so do a FULL LINE READ, and CLOSE FILE
sub scan_configure_ac_file($$) {
    my ($rparams,$lev) = shift;
    ac_set_debug_flags(${$rparams}{'CURR_DEBUG_FLAG'}) if (!$ac_done_debug_flags);
    my $filename = ${$rparams}{'CURR_FILE'};
    #my $rch = ${$rparams}{'CURR_COMMON_SUBS'};
    #my $ruserh = ${$rparams}{'CURR_USERS_SUBS'};
    my ($sfilnm,$root_dir) = fileparse($filename);
    my $in_ac_output = 0;
    my $ac_output_line = '';
	my %var_hash = ();
    my $ac_prog = '';   # this is an IMPORTANT name set by AC_INIT but hopefully later by AM_INIT_AUTOMAKE
    my $ac_vers = '';
    my %make_list = ();
    my @other_input_files = ();
    my $config_header_line = '';
    my @config_fullnames = ();
    my @config_names = ();
    my @config_headers = ();
    my %cfg_defines = ();
    my %configure_cond = ();
    my ($err_msg);
    my ($ln,$lncnt,$lnn,$tline,$ff,$cline);
	my ($key,$nval,$orgkey,$orgnval,@varr,$vlen,$i,$ky,$nline,$msg);
    my $scan_flag = 0;

	if (!open(CONFIGURE, $filename)) {
		pgm_exit(1,"ERROR: can not open [$filename]: $!\n");
	}
    my @lines = <CONFIGURE>;
    close CONFIGURE;
    $lncnt = scalar @lines;
    ${$rparams}{'TOTAL_LINE_COUNT'} += $lncnt;
    prt("[01] SCAN CONFIGURE AC FILE: Reading [$filename], $lncnt lines...\n" ) if $dbg_lac01;
    my $rh = ${$rparams}{'CURR_HASH'};
    my $racmacs = ${$rparams}{'CURR_AC_MAC'};
    my $rsnf = ${$rparams}{'CURR_SUBS_NOT_FOUND'};
    my $ramil = ${$rparams}{'CURR_MAKE_INP_LIST'};
    my $supp_in = ${$rparams}{'SUPP_MAKE_IN'};

    # ============================================================
    for ($ln = 0; $ln < $lncnt; $ln++) {
		$cline = $lines[$ln];	# get current line
        chomp $cline;
        $nline = $cline;
        $lnn = $ln + 1;
		prt( "[01] $lnn: [$cline]\n" ) if ($dbg_lac01);
		# Remove comments from current line.
		$cline =~ s/\bdnl\b.*$//;
		$cline =~ s/^\#.*$//;
		$tline = trim_all($cline);
		next if (length($tline) == 0);
        if ($cline =~ /\\$/) {
            $cline = accumulate_with_back($cline,$lncnt,\$ln,\@lines);
        }
        if ($cline =~ /^\s*\w+\(.*$/) {
            $cline = accumulate_ac_macro($cline,$lncnt,\$ln,\@lines);
        }
        $lnn = $ln + 1;
        if ($cline =~ /(\$|\@)/) {
            ${$rparams}{'CURR_KEY'} = "";
            ${$rparams}{'CURR_LINENUM'} = $lnn;
            $cline = ac_do_macro_subs($cline,1,$rparams);
        }
		$tline = trim_all($cline);
		prt( "[02] $lnn: [$cline]\n" ) if ($dbg_lac02 && ($nline ne $cline));

		if ($cline =~ /^(\w+)="(\d+)"$/) {
            $key = $1;
            $nval = $2;
			prt("[03] $lnn: Num Variable $key=$nval\n") if ($dbg_lac03);
			$var_hash{$key} = $nval;
			ac_add_2_ac_macros($key, $nval, $racmacs);
		###} elsif ($cline =~ /^(\w+)="(.+)"$/) {
		###} elsif ($cline =~ /^(\w+)=(.+)$/) {
		} elsif ($cline =~ /^\s*(\w+)=(.+)$/) {
			$key  = $1;
			$nval = $2;
			$nval = substr($nval,1,length($nval)-2) if ($nval =~ /^".*"$/);
			$orgkey = $key;
			$orgnval = $nval;
			prt( "[03] $lnn: Var [$key] = [$nval], ln [$cline]\n" ) if ($dbg_lac03);
            ${$rparams}{'CURR_KEY'} = $key;
            ${$rparams}{'CURR_LINENUM'} = $lnn;
            $nval = ac_do_macro_subs($nval,1,$rparams);
            if ($dbg_lac05) {
                 if (($orgkey ne $key)||($orgnval ne $nval)) {
                     prt( "[05] Substitute [$key] = [$nval]\n" );
                 } elsif (($orgkey =~ /\$/)||($orgnval =~ /\$/)) {
                     prt( "[05] Sub FAILED [$key] = [$nval]\n" );
                 }
            }
			$var_hash{$key} = $nval;
			ac_add_2_ac_macros($key, $nval, $racmacs);
			# $conf_ac_macs{$key} = $nval;
		} elsif ($cline =~ /^\s+(\w+)=(.+)$/) {
			prt( "[12] $lnn: 1=[$1] = 2=[$2] NOT USED [$cline]\n" ) if ($dbg_lac12); # there are lots of them ...
		}
		# Skip macro definitions.  Otherwise we might be confused into
		# thinking that a macro that was only defined was actually
		# used.
        if ($cline =~ /AC_DEFUN/) {
			prt( "[07] $lnn: Got AC_DEFUN = [$cline] SKIPPING\n" ) if ($dbg_lac07);
            next;
        }

		if ($cline =~ /$AC_INIT/) {
            $nval = trim_all($1);
            # Macro: AC_INIT (package, version, [bug-report], [tarname], [url])
            # but can sometimes just be a FILE NAME
            $scan_flag |= 1;
			@varr = split(',', $nval);
			$vlen = scalar @varr;
            if ($dbg_lac07) {
    			prt( "[07] $lnn: Got AC_INIT = [$nval] $vlen items {" );
    			for ($i = 0; $i < $vlen; $i++) {
    				$nval = trim_all(strip_square_braces(trim_all($varr[$i])));
                    prt("$nval");
                    prt(", ") if (($i + 1) < $vlen);
                }
                prt("}\n");
            }
			for ($i = 0; $i < $vlen; $i++) {
				$nval = trim_all(strip_square_braces(trim_all($varr[$i])));
				if ($i == 0) {
					$nval =~ s/\s/_/g;
                    if ($nval =~ /(\\|\/)/) {
                        # looks like a FILE name
                        ($nval,$key) = fileparse($nval);
                        $nval =~ s/\./_/g;
                    }
					ac_add_2_ac_macros('PACKAGE_NAME', $nval, $racmacs);
        			prt("[07] $lnn:AC_INIT: Setting PACKAGE_NAME = [$nval]\n") if ($dbg_lac07);
                    ${$rparams}{'PROJECT_NAME'} = $nval; # overall PROJECT NAME
					$ac_prog = $nval;
				} elsif ($i == 1) {
					ac_add_2_ac_macros('PACKAGE_VERSION', $nval, $racmacs);
					ac_add_2_ac_macros('PACKAGE_STRING', ${$racmacs}{'PACKAGE_NAME'} .' ' .$nval, $racmacs );
					$ac_vers = $nval;
				} elsif ($i == 2) {
					ac_add_2_ac_macros('PACKAGE_BUGREPORT', $nval, $racmacs);
				} elsif ($i == 3) {
					ac_add_2_ac_macros('PACKAGE_TARNAME', $nval, $racmacs);
				} elsif ($i == 4) { # 08/09/2010 - added
					ac_add_2_ac_macros('PACKAGE_URL', $nval, $racmacs);
				} else {
					$err_msg = "WARNING: $i Split of AC_INIT = $nval\n";
					prtw($err_msg);
				}
			}
			next;
		} elsif ($cline =~ /$AC_DEFINE/) {
            $nval = trim_ac_define($1);
			prt( "[07] $lnn: Got AC_DEFINE = [$nval]\n" ) if ($dbg_lac07);
			@varr = split(',', $nval);
			$vlen = scalar @varr;
			if ($vlen >= 2) {
				$ky = ac_trim_all2($varr[0]);
				$nval = ac_trim_all2($varr[1]);
				ac_add_2_ac_macros( $ky, $nval, $racmacs );
			}
			next;
		} elsif ($cline =~ /$AC_DEFINE_UNQ/) {
            $nval = trim_ac_define($1);
			prt( "[07] $lnn: Got AC_DEFINE_UNQUOTED = [$nval]\n" ) if ($dbg_lac07);
			@varr = split(',', $nval);
			$vlen = scalar @varr;
			if ($vlen >= 2) {
				$ky = ac_trim_all2($varr[0]);
				$nval = ac_trim_all2($varr[1]);
				ac_add_2_ac_macros( $ky, $nval, $racmacs );
			}
			next;
		}

		# Follow includes.  This is a weirdness commonly in use at
		# Cygnus and hopefully nowhere else.
		if (($cline =~ /sinclude\((.*)\)/)||($cline =~ /\s*include\((.*)\)/)) {
            $ff = $root_dir.$1;
            if ( -f $ff ) {
                ${$rparams}{'CURR_FILE'} = $ff;
                scan_configure_ac_file($rparams,($lev + 1));
                ${$rparams}{'CURR_FILE'} = $filename;
            } else {
                prtw("WARNING:$lnn: Unable to find INCLUDE [$ff], line [$_], in [$filename]\n");
            }
		}

		if (! $in_ac_output && ($cline =~ s/AC_OUTPUT\s*\(\[?// || $cline =~ s/AC_CONFIG_FILES\s*\(\[?// ) ) {
			$in_ac_output = 1;
			$ac_output_line = $lnn;	# get LINE number
			prt( "[08] Got ac_output_line = line $ac_output_line ... [$tline]\n" ) if ($dbg_lac08);
		}

		if ($in_ac_output) {
			my $closing = 0;
			if ($cline =~ s/[\]\),].*$//) {
				$in_ac_output = 0;
				$closing = 1;
				prt( "[08] ac_out: [$tline] CLOSING\n" ) if ($dbg_lac08);
			} else {
				prt( "[08] ac_out: [$tline]\n" ) if ($dbg_lac08);
			}

			# Look at potential Makefile.am's
            @varr = split(/\s/,$cline);
			foreach $nline (@varr) {
				# Must skip empty string for Perl 4.
				next if (($nline eq "\\") || ($nline eq ''));
				my ($local,$input,@rest) = split(/:/,$nline);
                my ($inp2);
				if (! $input) {
					$input = $local;
                    $inp2 = $local;
				} else {
                    $inp2 = $input;
					$input =~ s/\.in$//;
				}
                if ($input =~ /Makefile/) {
                    $ff = $root_dir . $input . '.am';
                    if ($supp_in && ( ! -f $ff ) && ( -f $root_dir.$input.'.in') ) {
                        $ff = $root_dir.$input.'.in';
                    }
                    if (-f $ff) {
                        prt( "[01|09] Adding $input [$ff] to mk_inp_list ...\n" ) if ($dbg_lac01 || $dbg_lac09);
                        push(@{$ramil}, $input);
                        $make_list{$input} = join(':', ($local,@rest));
                    } else {
                        prt( "[01|10] M NOT LOCATED [$ff] [$input] to other_input_files ...\n" ) if ($dbg_lac01 || $dbg_lac10);
                        # We have a file that automake should cause to be
                        # rebuilt, but shouldn't generate itself.
                        push (@other_input_files, $nline);
                    }
                } else {
                    # NOT a Makefile
                    # We have a file that automake should cause to be
                    # rebuilt, but shouldn't generate itself.
                    $ff = $root_dir . $inp2;
                    if (-f $ff) {
                        prt( "[01|10] O found [$ff] [$inp2] to other_input_files ...\n" ) if ($dbg_lac01 || $dbg_lac10);
                        push (@other_input_files, $inp2);
                    } else {
                        prt( "[01|10] O NOT LOCATED [$ff] [$inp2] to other_input_files ...\n" ) if ($dbg_lac01 || $dbg_lac10);
                        push (@other_input_files, $nline);
                    }
                }
			}
		}

		# Handle configuration headers.  A config header of `[$1]'
		# means we are actually scanning AM_CONFIG_HEADER from
		# aclocal.m4.
		if (($cline =~ /A([CM])_CONFIG_HEADER\s*\((.*)\)/) && ($2 ne '[$1]')) {
            if ($abort_on_ac_config) {
    			ac_am_conf_line_error($filename, 
                    $lnn, "automake requires 'AM_CONFIG_HEADER', not 'AC_CONFIG_HEADER'") if $1 eq 'C';
            } else { # 23/09/2010 - downgrade to a NOTE
                prt("[11] NOTE: $lnn: automake requires 'AM_CONFIG_HEADER', not 'AC_CONFIG_HEADER'!\n file [$filename]\n") if ($dbg_lac11);
            }
			$config_header_line = $lnn;
			my ($one_hdr);
			foreach $one_hdr (split (' ', $2)) {
				push (@config_fullnames, $one_hdr);
				if ($one_hdr =~ /^([^:]+):(.+)$/) {
					push (@config_names, $1);
					push (@config_headers, $2);
				} else {
					push (@config_names, $one_hdr);
					push (@config_headers, $one_hdr . '.in');
				}
			}
		}

		if ($cline =~ /$AM_CONDITIONAL_PATTERN/o) {
			if ( defined $cfg_defines{$1} ) {
				# has been DEFINED in am2dsp?.cfg file
				prt( "[11] Storing configure_cond key $1 ... value=2\n" ) if ($dbg_lac11);
				$configure_cond{$1} = 2;
			} else {
				prt( "[11] Storing configure_cond key $1 ... value=1\n" ) if ($dbg_lac11);
				$configure_cond{$1} = 1;
			}
		}

		if ($cline =~ /$AM_INIT_AUTOMAKE/o) {
			$ac_prog = $1;
			$ac_vers = $2;
			prt( "[07] $lnn: Got AM_INIT_AUTOMAKE = [$ac_prog] [$ac_vers] [$tline]\n" ) if ($dbg_lac07);
            $scan_flag |= 2;
            #$ac_prog = ac_do_macro_subs($ac_prog,0,$rparams);
            #${$rparams}{'CURR_KEY'} = $ac_prog;
			#$ac_prog = ac_do_macro_subs($ac_vers,0,$rparams);
            if (defined ${$rh}{'-NEW_PROJECT_NAME-'}) {
                if (${$rh}{'-NEW_PROJECT_NAME-'} ne $ac_prog) {
                    prtw("WARNING: CHANGED DSP package from ".${$rh}{'-NEW_PROJECT_NAME-'}." to $ac_prog, DSP version = $ac_vers ...\n" );
                }
            }
            ac_add_2_ac_macros('PACKAGE_NAME', $ac_prog, $racmacs);
   			prt("[07] $lnn:AM_INIT_AUTOMAKE: Setting PACKAGE_NAME = [$ac_prog]\n") if ($dbg_lac07);
		}
    }

    if (( !($scan_flag & 1) && !($scan_flag & 2)) || (length($ac_prog)==0) || ($ac_prog =~ /^\s+$/)) {
        $msg = "\nBIG BIG WARNING: Parsing [$filename]\n";
        $msg .= " You supplied an INVALID input. It has bad (or missing) AC_INIT or AM_INIT_AUTOMAKE macros!\n";
        $msg .= " Check that you supplied a valid input file, such as 'configure.ac' or 'configure.in'!\n";
        if (($filename =~ /\.(ac)$/)||($filename =~ /\.(in)$/)) {
            $msg .= " Although it has an '$1' extension, it does NOT look like a configure[.ac|.in] file!\n";
        } else {
            $msg .= " What you supplied does NOT have a '.ac', nor '.in' extension!\n";
        }
        if ($sfilnm =~ /^configure/) {
            $msg .= " And although it starts with 'configure', it does NOT feel like a configure[.ac|.in] file!\n";
        } else {
            $msg .= " And also note it does NOT start with 'configure'!\n";
        }
        $msg .= " Simply, [$sfilnm] is not a valid file for input. Try another...\n";
        $msg .= " NOTE: You may see many other warnings, and perhaps errors after here,\n since this is a VERY BAD START ;=()\n";
        prtw("$msg\n");
    }

    $nval = ((defined ${$rparams}{'PROJECT_NAME_MASTER'}) ? ${$rparams}{'PROJECT_NAME_MASTER'} : '');
    if (length($nval) && ($nval ne $ac_prog)) {
        prt("Over-ridding current [$ac_prog], with user [$nval], as master project name\n");
        $ac_prog = $nval;
    } else {
        if (($scan_flag & 1) && !($scan_flag & 2)) {
            prtw("WARNING: Project NAME [$ac_prog] only set from AC_INIT, no AM_INIT_ATUOMAKE found!\n");
        }
    }
    if ((length($ac_prog) == 0)||($ac_prog =~ /^\s+$/)) {
        prtw("WARNING: Blank (or spacey) program name [$ac_prog]!\n".
            " Setting it to be 'temp_no_name' for now,\n".
            " but you can use '-n <name>' to set your OWN project name.\n");
        $ac_prog = 'temp_no_name';
    }

    if ( !($ac_prog =~ /^[\+\-\w]+$/) ) {
        $nval = $ac_prog; # keep original for comparison
        $ac_prog = trim_all(strip_square_braces(trim_all($ac_prog)));
        $ac_prog =~ s/\./_/g;
        $ac_prog =~ s/(\\|\/)/_/g;
        $ac_prog =~ s/\$/_/g;
        $ac_prog =~ s/\@/_/g;
        if ($ac_prog =~ /^[\+\-\w]+$/) {
            prtw("WARNING: Project name CHANGED from [$nval] TO [$ac_prog]\n");
        } else {
            $lnn = __LINE__;
            $msg = "\nBIG WARNING: Project name ";
            if ($nval eq $ac_prog) {
                $msg .= "MASSAGED but remains unchanged as [$ac_prog]\n";
            } else {
                $msg .= "CHANGED from [$nval] TO [$ac_prog]\n";
            }
            $msg .= "BUT IS STILL NOT ALL alphanumeric chars!!!\n".
                "NEED 'FIX' in lib_acscan.pl about line $lnn\n";
            prtw("$msg\n");
        }
    }

    ${$rparams}{'PROJECT_NAME'} = $ac_prog; # overall PROJECT NAME
    ${$rh}{'-NEW_PROJECT_NAME-'} = $ac_prog;
    ${$rh}{'H_CONF_AC_MACS'} = $racmacs;
    ${$rh}{'A_MAKE_INPUT_LIST'} = $ramil;
    ${$rh}{'R_SUBS_NOT_FOUND'} = $rsnf;
    ${$rh}{'A_OTHER_INPUT_LIST'} = \@other_input_files;

    prt("[01] END SCAN CONFIGURE AC FILE: [$filename] $lncnt lines.\n" ) if ($dbg_lac01);
}

1;
# eof - lib_acscan.pl
