Generated: Sun Aug 21 11:11:10 2011 from lib_amscan-new.pl 2010/09/29 104.3 KB.
#!/usr/bin/perl -w # lib_amscan.pl # Library of services for scanning Makefile.am files # 15/09/2010 - continuing to add things - like try target scan if no libs/progs # 01/09/2010 geoff mclane http://geoffair.net/mperl use strict; use warnings; use File::Basename; # to split path into ($name, $dir) = fileparse($ff); or ($nm,$dir,$ext) = fileparse( $fil, qr/\.[^.]*/ ); use Cwd; my $cwd = cwd(); my $find_bad_source = 1; my $show_dup_title = 0; my $max_of_type = 30; our ($dbg_s01, $dbg_s02, $dbg_s03, $dbg_s04, $dbg_s05, $dbg_s06, $dbg_s07, $dbg_s08, $dbg_s09, $dbg_s10, $dbg_s11, $dbg_s12, $dbg_s13, $dbg_s14, $dbg_s15, $dbg_s16, $dbg_s17, $dbg_s18, $dbg_s19, $dbg_s20, $dbg_s21, $dbg_s22 ); # CONSTANTS my $IF_PATTERN = "^if[ \t]+\([A-Za-z][A-Za-z0-9_]*\)[ \t]*\(#.*\)?\$"; my $IFD_PATTERN = "^ifdef[ \t]+\([A-Za-z][A-Za-z0-9_]*\)[ \t]*\(#.*\)?\$"; my $NIF_PATTERN = "^if[ \t]+!(.+)\$"; my $NIF_PATTERN2 = "^if!\\s+(.+)\$"; my $ELSE_PATTERN = "^else[ \t]*\(#.*\)?\$"; my $ENDIF_PATTERN = "^endif[ \t]*\(#.*\)?\$"; my $PATH_PATTERN = '(-|\\w|/|\\.)+'; my $INCLUDE_PATTERN = "^include[ \t]+((\\\$\\\(top_srcdir\\\)/${PATH_PATTERN})|(\\\$\\\(srcdir\\\)/${PATH_PATTERN})|([^/\\\$]${PATH_PATTERN}))[ \t]*(#.*)?\$"; my $INCLUDE_PATTERN2 = "^\\s*include\\s+(.+)\$"; ##################################################### ##################################################### # FOR DEBUG my $am_dbg_base = 'dbg_s'; sub am_set_dbg_base($) { $am_dbg_base = shift; } sub am_dbg_val_var($) { my $val = shift; my $var = $am_dbg_base; if ($val < 10) { $var .= "0$val"; } else { $var .= "$val"; } return $var; } sub am_get_dbg_var($) { my $val = shift; my $var = am_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 am_get_dbg_stg() { my $s = ''; my ($i,$res,$i2); for ($i = 1; ;$i++) { $res = am_get_dbg_var($i); last if ($res == -1); if ($i < 10) { $i2 = "0$i"; } else { $i2 = "$i"; } if ($res) { $s .= "$i2 "; } } return $s; } sub am_get_dbg_range() { my ($i,$res); for ($i = 1; ;$i++) { $res = am_get_dbg_var($i); last if ($res == -1); } return $i - 1; } sub am_set_dbg_var($) { my $val = shift; my $var = am_dbg_val_var($val); # from : http://perldoc.perl.org/functions/eval.html # NOT $$var++; # does not work! if (eval "defined \$$var") { eval "\$$var = 1"; } else { #print "ERROR: \$$var does NOT exist\n"; return 0; } return 1; } sub am_clear_dbg_var($) { my $val = shift; my $var = am_dbg_val_var($val); # from : http://perldoc.perl.org/functions/eval.html # NOT $$var++; # does not work! if (eval "defined \$$var") { eval "\$$var = 0"; } else { #print "ERROR: \$$var does NOT exist\n"; return 0; } return 1; } sub am_set_all_dbg_on() { my ($i,$res); for ($i = 1; ;$i++) { $res = am_set_dbg_var($i); last if (!$res); } } sub am_set_all_dbg_off() { my ($i,$res); for ($i = 1; ;$i++) { $res = am_clear_dbg_var($i); last if (!$res); } } ###################################################### ### DIRECTORY SCAN STUFF - moved to lib_acscan.pl ##################################################### ## SUBSTITUTIONS ## ============= # skip these [-@(for i in $(srcdir)/test/HTML/* ; do n...], etc sub skip_these_strings($) { my ($txt) = @_; return 1 if ($txt =~ /\bfor\s+\w+\s+in\s+/); return 1 if ($txt =~ /^-\@\(for/); return 1 if ($txt =~ /^-*\@\(if\s+\[/); return 1 if ($txt =~ /^-\@\(\$\(top/); return 1 if ($txt =~ /`.+`/); # shell quite '`' return 0; } # AM macro split # 1: $(MACRO) # 2: ${MACRO} # 3: @MACRO@ sub am_macro_split($$) { my ($txt,$add) = @_; my @arr = (); my $len = length($txt); my ($i,$tag,$ch,,$nc,$mac,$k); $tag = ''; for ($i = 0; $i < $len; $i++) { $ch = substr($txt,$i,1); if ($ch eq '$') { $k = $i + 1; if ((($k+3) < $len)&&(substr($txt,$k,1) eq '(')) { $k++; $mac = '$('; for (; $k < $len; $k++) { $nc = substr($txt,$k,1); $mac .= $nc; last if ($nc eq ')'); last if ($nc =~ /\W/); } if ($nc eq ')') { push(@arr,$tag) if (length($tag) && $add); $tag = ''; push(@arr,$mac); $ch = ''; $i = $k; } } elsif ((($k+3) < $len)&&(substr($txt,$k,1) eq '{')) { $k++; $mac = '${'; for (; $k < $len; $k++) { $nc = substr($txt,$k,1); $mac .= $nc; last if ($nc eq '}'); last if ($nc =~ /\W/); } if ($nc eq '}') { push(@arr,$tag) if (length($tag) && $add); $tag = ''; push(@arr,$mac); $ch = ''; $i = $k; } } elsif ((($k+3) < $len)&&($txt =~ /\$\w+/)) { # skip some big things seen, that are NOT missing macros # not really that size matters - if ( ($len > 100) && skip_these_strings($txt) ) { if ( skip_these_strings($txt) ) { # like skip these [-@(for i in $(srcdir)/test/HTML/* ; do n...], etc } else { prtw("[13] WARNING: Potential MACRO [$txt]($len) of form \$MAC NOT HANDLED.\n") if ($dbg_s13); } } } elsif ($ch eq '@') { $k = $i + 1; if ((($k+1) < $len) && (substr($txt,$k) =~ /^(\w+)\@/)) { $mac = '@'; for (; $k < $len; $k++) { $nc = substr($txt,$k,1); $mac .= $nc; last if ($nc eq '@'); last if ($nc =~ /\W/); } if ($nc eq '@') { push(@arr,$tag) if (length($tag) && $add); $tag = ''; push(@arr,$mac); $ch = ''; $i = $k; } } } if ($add && (($ch eq "'") || ($ch eq '"'))) { push(@arr,$tag) if (length($tag) && $add); $tag = ''; push(@arr,$ch); } else { $tag .= $ch; } } return @arr; } sub valid_for_am_test($) { my ($rparams) = @_; my @arr = qw(CURR_LINE CURR_REF_HASH CURR_LINENUM AM_FILE CURR_COMMON_SUBS CURR_COMMON_SUBS CURR_USER_SUBS CURR_SUBS_NOT_FOUND); my ($key); foreach $key (@arr) { if (!defined ${$rparams}{$key}) { my $line = __LINE__; my $file = __FILE__; pgm_exit(1,"Service 'am_test_for_substitution' call in module [$file]\n". " around line $line, with key [$key] NOT DEFINED!\n"); } } } sub show_scalar_hash($) { my ($rh) = @_; my ($cnt,$key,$val); $cnt = 0; foreach $key (keys %{$rh}) { $val = ${$rh}{$key}; $cnt++; prt(" $cnt: [$key] = [$val]\n"); } } sub show_all_subs($$) { my ($key,$rparams) = @_; my ($cnt); prt("Searching for [$key]\n"); my $rus = ${$rparams}{'CURR_USER_SUBS'}; $cnt = scalar keys(%{$rus}); prt("Got $cnt USER subs...\n"); show_scalar_hash($rus); my $rhash = ${$rparams}{'CURR_REF_HASH'}; $cnt = scalar keys(%{$rhash}); prt("Got $cnt RTHASH subs...\n"); show_scalar_hash($rhash); my $rcomsubs = ${$rparams}{'CURR_COMMON_SUBS'}; $cnt = scalar keys(%{$rcomsubs}); prt("Got $cnt COMMON subs...\n"); show_scalar_hash($rcomsubs); pgm_exit(1,"ERROR: $key should be one of those!!!!\n"); } sub key_in_cond_TRUE($$$) { my ($key,$rhash,$rval) = @_; my ($tmp); foreach $tmp (keys %{$rhash}) { if ($tmp =~ /^$key\s+.+\@_TRUE\@/) { ${$rval} = $tmp; return 1; } } return 0; } sub key_in_a_conditional($$$$) { my ($key,$rhash,$rparams,$rtmp) = @_; # 27/09/2010 - user conditionals my $rusrcond = ${$rparams}{'REF_DEF_CONDITIONS'}; my ($tmp,$cond,$val,$tf,$prev,$k1,$k2,$v2,$msg); $prev = key_in_cond_TRUE($key,$rhash,\$k2); $v2 = ($prev ? ${$rhash}{$k2} : ''); $val = ''; $tf = 'TRUE'; foreach $tmp (keys %{$rhash}) { if ($tmp =~ /^$key\s+if\s+(\w+)\@_(TRUE|FALSE)\@/) { $k1 = $1; $cond = $2; $tf = 'TRUE'; $msg = 'Assumed'; if (defined ${$rusrcond}{$k1}) { $tf = ${$rusrcond}{$k1}; $msg = 'as SET by user'; } if ($cond eq $tf) { ${$rtmp} = $tmp; $val = ${$rhash}{$tmp}; if ($prev) { if ($val ne $v2) { prt("[22] CHANGED:1: [$tmp] key [$key] cond [$cond] Was [$v2], now [$val] $tf $msg\n") if ($dbg_s22); } else { prt("[22] NOCHANGE:1: [$tmp] key [$key] cond [$cond] stays [$val] $tf $msg\n") if ($dbg_s22); } } else { prt("[22] CHANGED:2: [$tmp] key [$key] cond [$cond] Was [$v2] NOTHING, now [$val] $tf $msg\n") if ($dbg_s22); } return 1; } } } if ($prev) { prt("[22] MISSED CHANGE:3: key [$key] Was [$v2], now NOT FOUND!\n") if ($dbg_s22); } return 0; } #sub test_for_substitution($$$$) { # my ($line,$rhash,$i2,$sfil) = @_; # 09/09/2010 - also try to EXPAND @ABC@ macros # 1: $(MACRO) # 2: ${MACRO} # 3: @MACRO@ # found : 1=rhash, 2=rhash mod, 3=common, 4=User sub am_test_for_substitution($) { my ($rparams) = @_; valid_for_am_test($rparams); my $line = ${$rparams}{'CURR_LINE'}; if (($line =~ /\$/)||($line =~ /\@\w+\@/)) { my $rhash = ${$rparams}{'CURR_REF_HASH'}; my $i2 = ${$rparams}{'CURR_LINENUM'}; my $fil = ${$rparams}{'AM_FILE'}; #my $rcomsubs = ${$rparams}{'REF_COMMON_SUBS'}; my $rcomsubs = ${$rparams}{'CURR_COMMON_SUBS'}; my $rus = ${$rparams}{'CURR_USER_SUBS'}; my $rsnf = ${$rparams}{'CURR_SUBS_NOT_FOUND'}; my $rglobhash = ${$rparams}{'REF_GLOBAL_HASH'}; my $sfil = sub_root_folder($fil); my $oline = $line; # keep copy of original my @arr = am_macro_split($line,0); my ($itm,$key,$nval,$tmp,$done,$cnt,$typ,$fnd); $cnt = 0; $fnd = 0; my @subs = (); foreach $itm (@arr) { $typ = 0; if ($itm =~ /^\$\((\w+)\)$/) { $key = $1; $done = 0; $typ = 1; # is of form $(MACRO) if (defined ${$rus}{$key}) { $nval = ${$rus}{$key}; $line =~ s/\$\($key\)/$nval/; $fnd = 4; prt("[13] $i2:$typ:$fnd: Did sub of [$key] to [$nval]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } elsif (defined ${$rhash}{$key}) { $nval = ${$rhash}{$key}; $line =~ s/\$\($key\)/$nval/; $fnd = 1; prt("[13] $i2:$typ:$fnd: Did sub of [$key] to [$nval]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } else { if ( key_in_a_conditional($key,$rhash,$rparams,\$tmp) ) { #foreach $tmp (keys %{$rhash}) { # if ($tmp =~ /^$key\s+.+\@_TRUE\@/) { $nval = ${$rhash}{$tmp}; $line =~ s/\$\($key\)/$nval/; $fnd = 2; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] tmp = [$tmp]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; last; # } } } if (!$done) { # try in the common, which can be user expanded if (defined ${$rcomsubs}{$key}) { $nval = ${$rcomsubs}{$key}; $line =~ s/\$\($key\)/$nval/; $fnd = 3; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] common subs\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } if (!$done) { if (defined ${$rglobhash}{$key}) { $nval = ${$rglobhash}{$key}; $line =~ s/\$\($key\)/$nval/; $fnd = 5; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] common subs\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } } } if (!$done) { prt("[13|14] $i2:$typ: NO sub FOUND for [$itm] key [$key] file [$sfil]\n") if ($dbg_s13 || $dbg_s14); #$subs_not_found{$key} = $sfil; if (! defined ${$rsnf}{$key}) { ${$rsnf}{$key} = "$i2:$sfil"; } } } elsif ($itm =~ /^\$\{(\w+)\}$/) { $key = $1; $done = 0; $typ = 2; # is of form ${MACRO} if (defined ${$rus}{$key}) { $nval = ${$rus}{$key}; $line =~ s/\$\{$key\}/$nval/; $fnd = 4; prt("[13] $i2:$typ:$fnd: Did sub of [$key] to [$nval]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } elsif (defined ${$rhash}{$key}) { $nval = ${$rhash}{$key}; $line =~ s/\$\{$key\}/$nval/; $fnd = 1; prt("[13] $i2:$typ:$fnd: Did sub of [$key] to [$nval]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } else { if ( key_in_a_conditional($key,$rhash,$rparams,\$tmp) ) { #foreach $tmp (keys %{$rhash}) { # if ($tmp =~ /^$key\s+.+\@_TRUE\@/) { $nval = ${$rhash}{$tmp}; $line =~ s/\$\{$key\}/$nval/; $fnd = 2; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] tmp = [$tmp]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; last; # } } } if (!$done) { # try in the common, which can be user expanded if (defined ${$rcomsubs}{$key}) { $nval = ${$rcomsubs}{$key}; $line =~ s/\$\{$key\}/$nval/; $fnd = 3; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] common subs\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } if (!$done) { # try global (known) items if (defined ${$rglobhash}{$key}) { $nval = ${$rglobhash}{$key}; $line =~ s/\$\{$key\}/$nval/; $fnd = 5; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] common subs\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } } } if (!$done) { prt("[13|14] $i2:$typ: NO sub FOUND for [$itm] key [$key] file [$sfil]\n") if ($dbg_s13 || $dbg_s14); #$subs_not_found{$key} = $sfil; if (! defined ${$rsnf}{$key}) { ${$rsnf}{$key} = "$i2:$sfil"; } } } elsif ($itm =~ /^\@(\w+)\@$/) { $key = $1; $done = 0; $typ = 3; # is of the form @MACRO@ if (defined ${$rus}{$key}) { $nval = ${$rus}{$key}; $line =~ s/\@$key\@/$nval/; $fnd = 4; prt("[13] $i2:$typ:$fnd: Did sub of [$key] to [$nval]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } elsif (defined ${$rhash}{$key}) { $nval = ${$rhash}{$key}; $line =~ s/\@$key\@/$nval/; $fnd = 1; prt("[13] $i2:$typ:$fnd: Did sub of [$key] to [$nval]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } else { if ( key_in_a_conditional($key,$rhash,$rparams,\$tmp) ) { #foreach $tmp (keys %{$rhash}) { # if ($tmp =~ /^$key\s+.+\@_TRUE\@/) { $nval = ${$rhash}{$tmp}; $line =~ s/\@$key\@/$nval/; $fnd = 2; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] tmp = [$tmp]\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; last; # } } } if (!$done) { # try in the common, which can be user expanded if (defined ${$rcomsubs}{$key}) { $nval = ${$rcomsubs}{$key}; $line =~ s/\@$key\@/$nval/; $fnd = 3; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] common subs\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } if (!$done) { # try global (known) items if (defined ${$rglobhash}{$key}) { $nval = ${$rglobhash}{$key}; $line =~ s/\@$key\@/$nval/; $fnd = 5; prt("[13] $i2:$typ:$fnd: Did sub to [$nval] key [$key] common subs\n") if ($dbg_s13); push(@subs,"$i2:$typ:$fnd:$itm:$key:$nval"); $done = 1; $cnt++; } } } if (!$done) { #$subs_not_found{$key} = $sfil; prt("[13|14] $i2:$typ: NO sub FOUND for [$itm] key [$key] file [$sfil]\n") if ($dbg_s13 || $dbg_s14); if (! defined ${$rsnf}{$key}) { # keep only the FIRST instance ${$rsnf}{$key} = "$i2:$sfil"; } ##### show_all_subs($key,$rparams); } } else { prtw("WARNING: am_test_for_substitution: got a split NOT handled! [$itm]\n"); } } if ($line ne $oline) { prt("[13] $i2: Line SUB [$oline] TO [$line]\n") if ($dbg_s13); } elsif ($cnt) { $nval = "ERROR INTERNAL: $i2:$cnt: SUBSTITUTIONS FAILED! file [$sfil]\n"; $fnd = length($oline); $cnt = length($line); $nval .= "Appears SUB failed to CHANGE LINE!\n orig [$oline]$fnd\n curr [$line]$cnt\n"; $cnt = 0; foreach $itm (@subs) { $cnt++; $nval .= " $cnt: [$itm]\n"; } pgm_exit(1,"$nval\n"); } } return $line; } ######################################################## # given two scalar items, separated by '\s' or '\' # reutrn ZERO if ALL the second are IN the first. sub value_not_in_first($$) { my ($src,$rval) = @_; # $programs{$ky},$val my @arr1 = split(/[\s\|]/,$src); my $val2 = ${$rval}; my @arr2 = split(/[\s\|]/,$val2); my $cnt = scalar @arr2; my ($val1,$dcnt); if ($cnt == 1) { foreach $val1 (@arr1) { return 0 if ($val1 eq $val2); } } else { # put values in a hash, to allow delete my %vals = (); foreach $val1 (@arr2) { $vals{$val1} = 1; } $dcnt = 0; foreach $val1 (@arr1) { if (defined $vals{$val1}) { delete $vals{$val1}; $dcnt++; } } if ($dcnt) { @arr1 = keys(%vals); return 0 if (scalar @arr1 == 0); # but if there were 'some' items delete due to existance # then adjust the original $val... ${$rval} = join(' ',@arr1); } } return 1; } sub get_value_from_hash { my ($rval2,$ms,$rhash,$rparams) = @_; my ($ky2, @vals, $fnd, $val, @keys, $i); my ($itm, $cond); my $rdef_conds = ${$rparams}{'REF_DEF_CONDITIONS'}; $fnd = 0; foreach $ky2 (keys %{$rhash}) { if ($ky2 =~ /^$ms\s+/) { $val = ${$rhash}{$ky2}; if (!is_in_array($val, @vals)) { push(@vals,$val); push(@keys,$ky2); $fnd++; } } } if ($fnd == 1) { $$rval2 = $vals[0]; # just ONE to RETURN } elsif ($fnd > 1) { my $msg = "WARNING: For sub of [$ms], have [$fnd] to CHOOSE FROM!\n"; for ($i = 0; $i < $fnd; $i++) { $val = $vals[$i]; $ky2 = $keys[$i]; $msg .= " or \n" if ($i > 0); $msg .= "[$ky2={".$val.'}]'; if ($ky2 =~ /^$ms\s+if\s+(\w+)\@_(TRUE|FALSE)\@/) { $itm = $1; $cond = $2; $msg .= " [$itm]=[$cond]"; if (defined ${$rdef_conds}{$itm}) { if (${$rdef_conds}{$itm} eq $cond) { $$rval2 = $val; # RETURN selected ### prtw("CHECK: Returning [$val] for [$ms], due [$itm]=[$cond] in def_condits!\n" ); return $fnd; } } } } $msg .= " Defaulting to FIRST! CHECK ME!!"; prtw("$msg\n"); ${$rval2} = $vals[0]; # just RETURN first } return $fnd; } # did, one or more AM (or IN) files, but NO libraries, or programs # my $ref_targets = ${$rparams}{'AM_FILE_TARGETS'}; sub show_target_list($) { my ($rparams) = @_; my $ref_targets = ${$rparams}{'AM_FILE_TARGETS'}; my ($cnt,$key,$fcnt,$scnt,$val); $cnt = scalar keys(%{$ref_targets}); $fcnt = 0; prt("\[21] nGot NO libraries, or programs, checking $cnt 'targets'...\n"); foreach $key (keys %{$ref_targets}) { if ($key =~ /^\w+$/) { $fcnt++; $val = ${$ref_targets}{$key}; prt(" $fcnt: [$key] = [$val]\n"); } } prt("\nOther targets...\n"); $scnt = 0; foreach $key (keys %{$ref_targets}) { if ( !($key =~ /^\w+$/) ) { $scnt++; $val = ${$ref_targets}{$key}; prt(" $scnt: [$key] = [$val]\n"); } } prt("[21] Done $cnt targets list... got $fcnt as alphanumeric, and others $scnt...\n"); } # ======================================================================================== # process_target_list # Present assumtions # - The process starts with finding 'all', or if not 'default' targets # and assumes its contents (after expansion) are the final 'targets' desired. # results stored in %objects = $value hash. # - Each 'target' is then searched, and results found are stored in %sobjects = $value hash # - Libraries are assumed to end in '.la', else assumed a console application # - Only C and H files are stored # ========================================================================================= sub process_target_list($) { my ($rparams) = @_; # if it is an Makefile.in, then may have to look at TARGETS for libraries/programs/sources show_target_list($rparams) if ($dbg_s21); my $ref_targets = ${$rparams}{'AM_FILE_TARGETS'}; my ($cnt,$key,$fcnt,$scnt,$val,@arr,$dkey,$dval,$ky,$v,%dupes); my ($kyo,@arr2,$itm,$nv); $cnt = scalar keys(%{$ref_targets}); prt("\n[21] Seeking 'all' or 'default' in $cnt keys...\n") if ($dbg_s21); $fcnt = 0; $val = ''; $dkey = ''; $dval = ''; foreach $key (keys %{$ref_targets}) { if ($key =~ /^all$/) { $val = ${$ref_targets}{$key}; prt(" [$key] = [$val]\n") if ($dbg_s21); if ( length($val) && !($val =~ /^\s+$/) ) { $fcnt++; $dkey = $key; $dval = $val; last; } } } if (!$fcnt) { foreach $key (keys %{$ref_targets}) { if ($key =~ /^default$/) { $val = ${$ref_targets}{$key}; prt(" [$key] = [$val]\n") if ($dbg_s21); if ( length($val) && !($val =~ /^\s+$/) ) { $fcnt++; $dkey = $key; $dval = $val; last; } } } } if ( !$fcnt || (length($dval) == 0) || ($dval =~ /^\s+$/)) { prt("[21] Valid target 'all' or 'default' NOT found in $cnt keys... [$dval]\n") if ($dbg_s21); return; } @arr = split(/\s/,$dval); # split to an ARRAY %dupes = (); $dupes{$dkey} = 1; my %objects = (); my %sobjects = (); my %not_found = (); my %dupes2 = (); foreach $ky (@arr) { next if (defined $dupes{$ky}); $dupes{$ky} = 1; $v = ''; if (defined ${$ref_targets}{$ky}) { $v = ${$ref_targets}{$ky}; } else { foreach $key (keys %{$ref_targets}) { next if (defined $dupes{$key}); if ($key =~ /$ky/) { $v .= ${$ref_targets}{$key}; } } } if (length($v)) { $v =~ s/\n.*$// while ($v =~ /\n/); prt("[21] For [$dkey] : [$ky] = [$v]\n") if ($dbg_s21); #@arr2 = split(/\s/,$v); $objects{$ky} = $v; } else { if (! defined $not_found{$ky}) { $not_found{$ky} = 1; prt("[21] Not found [$ky]\n") if ($dbg_s21); } } } my %libs = (); my $islib = 0; # foreach primary object - library or program foreach $kyo (keys %objects) { $val = $objects{$kyo}; $islib = ($kyo =~ /\.la$/) ? 1 : 0; @arr = split(/\s/,$val); # if this is a program, may find a dependence on a LIBRARY # in this list... foreach $ky (@arr) { if (!$islib && ($ky =~ /\.la/)) { # a program, seems dependant on a library if (defined $libs{$kyo}) { $libs{$kyo} .= " $ky"; } else { $libs{$kyo} = $ky; } } next if (defined $dupes{$ky}); $dupes{$ky} = 1; $v = ''; if (defined ${$ref_targets}{$ky}) { $v = ${$ref_targets}{$ky}; } else { foreach $key (keys %{$ref_targets}) { next if (defined $dupes{$key}); if ($key =~ /$ky/) { $v .= ${$ref_targets}{$key}; } } } if (length($v)) { $v =~ s/\n.*$// while ($v =~ /\n/); #prt("Sub [$kyo] : [$ky] = [$v]\n"); @arr2 = split(/\s/,$v); $nv = ''; foreach $itm (@arr2) { $itm = sub_root_dir(path_u2d($itm)); $itm =~ s/^\\//; if (!defined $dupes2{$itm}) { $dupes2{$itm} = 1; $nv .= ' ' if (length($nv)); $nv .= $itm; } } if (length($nv)) { prt("[21] Red [$kyo] : [$ky] = [$nv]\n") if ($dbg_s21); $sobjects{$ky} = $nv; # if (length($nv)) } else { prt("[21] Sub [$kyo] : [$ky] = [$v] discarded as duplicates\n") if ($dbg_s21); } } else { if (! defined $not_found{$ky}) { $not_found{$ky} = 1; prt("[21] Not found [$ky]\n") if ($dbg_s21); } } } } # now to process what was collected my $rhash = ${$rparams}{'CURR_REF_HASH'}; my $rprogs = ${$rparams}{'REF_PROGRAMS'}; my $rlibs = ${$rparams}{'REF_LIBRARIES'}; my $srcs = ''; my $rlh = ${$rparams}{'REF_LIBS_HASH'}; my $rph = ${$rparams}{'REF_PROG_HASH'}; # run, just to get built LIBRARY list # foreach $key (keys %objects) { # $val = $objects{$key}; # @arr = split(/\s/,$val); # %dupes = (); # foreach $ky (@arr) { # if (defined $sobjects{$ky}) { # $v = $sobjects{$ky}; # @arr2 = split(/\s/,$v); # foreach $itm (@arr2) { # if ( is_c_source($itm) ) { # $dupes{$itm} = $key; # } # } # } # } # @arr = keys %dupes; # $scnt = scalar @arr; # if ($scnt) { # if ($key =~ /\.la$/) { # #$itm = 'LIBRARY'; # $libs{$key} = 1; # prt("Stored [$key] in libs hash, for later dependence addition.\n"); # } # } # } # now a run to create entries, and include 'libs' in programs # by adding it to a LDADD entry in the '$rhash' # For [all] : [pcretestexe] = [libpcre.la @POSIX_LIB@ pcretest.obj @ON_WINDOWS@ winshared] my $addlibs = ''; foreach $key (keys %objects) { $val = $objects{$key}; @arr = split(/\s/,$val); %dupes = (); $addlibs = ''; foreach $ky (@arr) { if (defined $sobjects{$ky}) { $v = $sobjects{$ky}; @arr2 = split(/\s/,$v); foreach $itm (@arr2) { if ( is_c_source($itm) ) { $dupes{$itm} = $key; } elsif (defined $libs{$itm}) { $addlibs .= ' ' if (length($addlibs)); $addlibs .= $itm; } } } } @arr = keys %dupes; $scnt = scalar @arr; if ($scnt) { $srcs = join(" ",@arr); if ($key =~ /\.la$/) { $itm = 'LIBRARY'; ${$rlibs}{$key} = $srcs; ${$rlh}{$key} = $rhash; # keep the original Makefile.in hash scan } else { $itm = 'PROGRAM'; ${$rprogs}{$key} = $srcs; if (defined $libs{$key}) { $addlibs = $libs{$key}; $itm .= " +lib [$addlibs]"; if (defined ${$rhash}{'LDADD'}) { ${$rhash}{'LDADD'} .= " $addlibs"; } else { ${$rhash}{'LDADD'} = $addlibs; } } ${$rph}{$key} = $rhash; # keep the original Makefile.in hash scan } prt("[21] Stored $itm key [$key], with $scnt sources [$srcs]\n") if ($dbg_s21); } else { prt("[21] Ugh! key [$key], yielded NO sources!\n") if ($dbg_s21); } } prt("[21] Done $cnt targets list...\n") if ($dbg_s21); } sub a_source_does_exist($$$) { my ($dir,$file,$rval) = @_; my ($val,$tmp); my @arr = qw( .c .cxx .cpp .cc ); foreach $val (@arr) { $tmp = $file.$val; if (-f $dir.$tmp) { ${$rval} = $tmp; return 1; } } return 0; } sub a_source_does_exist_ok($$$) { my ($dir,$file,$rval) = @_; my ($tmp); $tmp = $file.".c"; if (-f $dir.$tmp) { ${$rval} = $tmp; return 1; } $tmp = $file.".cxx"; if (-f $dir.$tmp) { ${$rval} = $tmp; return 1; } $tmp = $file.".cpp"; if (-f $dir.$tmp) { ${$rval} = $tmp; return 1; } $tmp = $file.".cc"; if (-f $dir.$tmp) { ${$rval} = $tmp; return 1; } return 0; } # extract info from ONE am file scan, # and try to do any substitutions, twice, but these should have been done already, # done at end of each process_AM_file, with the reference hash collected sub am_extract_from_hash($) { my ($rparams) = @_; my $fil = ${$rparams}{'AM_FILE'}; # store for programs and library SOURCES # under the key of the program or library name my $rprogs = ${$rparams}{'REF_PROGRAMS'}; my $rlibs = ${$rparams}{'REF_LIBRARIES'}; # the actual (messy) Makefile.am HASH my $rhash = ${$rparams}{'CURR_REF_HASH'}; # common substitutions #my $rcomsubs = ${$rparams}{'REF_COMMON_SUBS'}; my $rcomsubs = ${$rparams}{'CURR_COMMON_SUBS'}; my $rcussubs = ${$rparams}{'CURR_USER_SUBS'}; my $rglobhash = ${$rparams}{'REF_GLOBAL_HASH'}; my $rdnf = ${$rparams}{'REF_DEFS_NOT_FOUND'}; my $rsnf = ${$rparams}{'CURR_SUBS_NOT_FOUND'}; my $rexcept = ${$rparams}{'REF_SRC_EXCEPT'}; # reference to the script exit value, should thre be a problem my $rexit_val = ${$rparams}{'REF_EXIT_VALUE'}; # ***TBD*** if it is an Makefile.in, then may have to look at TARGETS for libraries/programs/sources my $ref_targets = ${$rparams}{'AM_FILE_TARGETS'}; # ================================================================================================== my ($a_nm, $a_dir) = fileparse($fil); my ($key, $val, @av); my (@skeys, @progs, @progkeys, @libs, @libkeys, @srcs, @srckeys, @psrcs); my ($ky, $vky, $ms, $val2, $ky2, $orgval, $fnd, $acnt); my ($src, $ff, $scnt, $i, $min, $len, $oky, $fcnt); my ($tot_scnt); my %dupes = (); #my %extract = (); # really interested in # noinst_LIBRARIES = libAirports.a # noinst_PROGRAMS = calc_loc # bin_PROGRAMS = fgfs something # libAirports_a_SOURCES = apt_loader.cxx apt_loader.hxx ... @skeys = sort keys(%{$rhash}); $acnt = scalar @skeys; prt( "[02] extract_from_hash: Listing $acnt keys in hash passed... file [$fil]\n" ) if ($dbg_s02); # collect PROGRAM keys @progs = (); @progkeys = (); @libs = (); @libkeys = (); @srcs = (); @srckeys = (); # NOTE: This appears redundant, since it should ALREADY HAVE BEEN DONE! # 27/09/2010 - Output a WARNING if either of these 2 additional sub are used, # since it indicates the earlier substitution MISSED a case # And note this ONLY handles the $(MACRO) case!!! # Eventually this should be REMOVED # try to do substitutions $min = 0; foreach $key (@skeys) { $val = ${$rhash}{$key}; $orgval = $val; next if (!defined $val || (length($val) == 0)); if ($val =~ /\$\((\w+)\)/) { $ms = $1; $val2 = ''; # no sub yet $fnd = 0; # none found if (defined ${$rhash}{$ms}) { $val2 = ${$rhash}{$ms}; # found in local $fnd = 3; } elsif (defined ${$rcomsubs}{$ms}) { $val2 = ${$rcomsubs}{$ms}; # found in common $fnd = 2; } elsif (defined ${$rglobhash}{$ms}) { $val2 = ${$rglobhash}{$ms}; # found in global $fnd = 1; } else { # hmmm, maybe like 'GFX_CODE if @USE_GLUT_FALSE@ = fg_os_osgviewer.cxx $(GFX_COMMON)' $fnd = get_value_from_hash(\$val2, $ms, $rhash, $rparams ); } if ($fnd > 0) { $val =~ s/\$\($ms\)/$val2/g; prtw("WARNING:1: Substitution DONE [$ms] to [$val2]. [$fnd] WHY WAS THIS NOT DONE EARLIER?\n"); } else { # ONLY ON SECOND RUN #if ( ! (defined ${$rdnf}{$ms} || defined ${$rsnf}{$ms}) ) { # prtw("[10] WARNING:1: No definition for [$ms] found in hash ...\n" ) if ($dbg_s10); # ${$rdnf}{$ms} = $fil; # ${$rsnf}{$ms} = $fil; #} #if ( ! is_in_array($ms,@subsnotfound) ) { # prtw("[10] WARNING:1: No substitution for [$ms] found in hash ...\n" ) if ($dbg_s10); # push(@subsnotfound,$ms); #} } } if ($val ne $orgval) { ${$rhash}{$key} = $val; } $len = length($key); $min = $len if ($len > $min); } # try to do substitutions, TWICE foreach $key (@skeys) { $val = ${$rhash}{$key}; next if (!defined $val || (length($val) == 0)); $orgval = $val; if ($val =~ /\$\((\w+)\)/) { $ms = $1; $val2 = ''; $fnd = 0; if (defined ${$rhash}{$ms}) { $val2 = ${$rhash}{$ms}; $fnd = 3; } elsif (defined ${$rcomsubs}{$ms}) { $val2 = ${$rcomsubs}{$ms}; # found in common $fnd = 2; } elsif (defined ${$rglobhash}{$ms}) { $val2 = ${$rglobhash}{$ms}; $fnd = 1; } else { # hmmm, maybe like 'GFX_CODE if @USE_GLUT_FALSE@ = fg_os_osgviewer.cxx $(GFX_COMMON)' foreach $ky2 (keys %{$rhash}) { if ($ky2 =~ /^$ms/) { $val2 = ${$rhash}{$ky2}; $fnd = 4; last; } } } if ($fnd > 0) { $val =~ s/\$\($ms\)/$val2/g; prtw("WARNING:2: Substitution DONE [$ms] to [$val2]. [$fnd] WHY WAS THIS NOT DONE EARLIER?\n"); } else { if ( ! (defined ${$rdnf}{$ms} || defined ${$rsnf}{$ms}) ) { prtw("[10] WARNING:1: No definition for [$ms] found in hash ...\n" ) if ($dbg_s10); ${$rdnf}{$ms} = $fil; ${$rsnf}{$ms} = $fil; } } } if ($val ne $orgval) { ${$rhash}{$key} = $val; } } my %htmp = (); ### my $max_of_type = ${$rparams}{'MAX_OF_TYPE'}; my $add_rel_sources = ${$rparams}{'ADD_REL_SOURCE'}; my $root_folder = ${$rparams}{'ROOT_FOLDER'}; my $try_harder = ${$rparams}{'TRY_HARDER'}; my $try_much_harder = ${$rparams}{'TRY_MUCH_HARDER'}; my $ignore_EXTRA_DIST = ${$rparams}{'IGNORE_EXTRA_DIST'}; foreach $key (@skeys) { $val = ${$rhash}{$key}; if (!defined $val) { delete ${$rhash}{$key}; prtw("WARNING: Deleted key [$key] from hash ref! How did this get here?\n"); next; } if ($key =~ /_PROGRAMS/) { push(@progkeys,$key); push(@progs,$val); $ms = "PROGRAMS"; } elsif (($key =~ /_LIBRARIES/)||($key =~ /_LTLIBRARIES/)) { push(@libkeys,$key); push(@libs,$val); $ms = "LIBRARIES"; } elsif (($key =~ /_SOURCES/)||($key =~ /_EXTRASOURCES/)||($key =~ /_AUXSOURCES/)) { push(@srckeys,$key); ###push(@srcs,$val); # will scan and massage the sources later $ms = "SOURCES"; } elsif ($key =~ /LDADD/) { $ms = "LDADD"; } else { $ms = "*SKIPPED*"; if (($key =~ /_/) && (($key =~ /PROGRAMS/)||($key =~ /LIBRARIES/)||($key =~ /SOURCES/))) { if (! defined ${$rexcept}{$key}) { # found bin_JAVAPROGRAMS CSHARPPROGRAMS hello_RESOURCES prtw("WARNING: *** CHECK ME *** Got [$key] val = [$val] *** CHECK ME ***\n". " SHOULD THIS ITEMS BE INCLUDED IN THE ACCUMULATION [$fil]\n"); ${$rexcept}{$key} = 1; # only output ONCE if ( !(($key =~ /JAVA/)||($key =~ /CSHARP/)||($key =~ /RESOURCES/)||($key =~ /PASCAL/)) ) { ${$rexit_val} = 1; } } } } $htmp{$ms} = [] if ( ! defined $htmp{$ms}); # list the sources, but this is JUST for DISPLAY #@av = split(/\s/,$val); # SPLIT LIST @av = split(/[\s\|]/,$val); # SPLIT LIST $val = ''; foreach $oky (@av) { $oky = path_u2d($oky); $oky =~ s/\\\\/\\/ while ($oky =~ /\\\\/); # eliminate duplicate back slashes if (($oky =~ /^\w{1}:/)||($oky =~ /^-/)) { $src = sub_root_dir($oky); # already has a DRIVE beginning, so use AS IS } else { $src = sub_root_dir($a_dir.$oky); $src = path_u2d($src); $src =~ s/\\\\/\\/ while ($src =~ /\\\\/); # eliminate duplicate back slashes } $val .= ' ' if (length($val)); $val .= $src; } push(@{$htmp{$ms}}, [$key,$val]); } if ($dbg_s16) { $min = 0; prt("\n[16] Enumeration of the temporary HASH - only for DEBUG\n"); foreach $ms (keys %htmp) { $ky = $htmp{$ms}; $scnt = scalar @{$ky}; prt("[16] $scnt of type [$ms] file [$fil]\n"); for ($i = 0; $i < $scnt; $i++) { $src = ${$ky}[$i][0]; $len = length($src); $min = $len if ($len > $min); } $min = $max_of_type if ($min > $max_of_type); for ($i = 0; $i < $scnt; $i++) { $src = ${$ky}[$i][0]; $val = ${$ky}[$i][1]; $src .= ' ' while (length($src) < $min); prt(" $src = [$val]\n"); } } prt("[16] End enumeration of temporary hash...\n"); } # ======================================================================= if ($dbg_s02) { $val = scalar @skeys; prt("\n[02] List of $val items in the HASH from [$fil]...\n"); foreach $key (@skeys) { $val = $$rhash{$key}; next if (($key eq 'EXTRA_DIST')&&($ignore_EXTRA_DIST)); $key .= ' ' while (length($key) < $min); prt(" $key = $val\n" ); } prt("[02] Done List of $val items in the HASH from [$fil]...\n"); } # ### PROCESS LIBRARY SOURCES - stored in $rlibs # =========================== my $rlh = ${$rparams}{'REF_LIBS_HASH'}; my $dnskys = 0; # only display this 'SOURCE' set ONCE if (@libkeys) { $val = scalar @libkeys; prt( "[03] Find sources for $val LIBRARY keys ...\n" ) if ($dbg_s03); $tot_scnt = 0; foreach $key (@libkeys) { $val = ${$rhash}{$key}; #@av = split(/\s/,$val); @av = split(/[\s\|]/,$val); # SPLIT LIST prt( "[03] Find sources for LIBRARY [$key] [$val]\n" ) if ($dbg_s03); foreach $oky (@av) { $ky = $oky; $ky =~ s/-/_/g; $ky =~ s/\./_/g; $ky =~ s/\|//g; $ky = trim_all($ky); prt( "[03] Finding ORIGINAL [$oky] MODIFIED [$ky] Underscore and dot replaced\n" ) if ($dbg_s03); next if (length($ky) == 0); #next if (($ky =~ /\@/)||($ky =~ /\$/)); $vky = $ky.'_SOURCES'; $fnd = 0; #if (defined ${$rhash}{$vky}) { # $val = ${$rhash}{$vky}; # $fnd = 1; # prt("[03] Source list found with [$vky] = [$val]\n") if ($dbg_s03); #} else { my $src_list = ''; my @rhkeys = (); #prt("[03] NO source list found with [$vky]... searching harder...\n") if ($dbg_s03); prt("[03] Finding source list with [$vky]... and searching harder...\n") if ($dbg_s03); foreach $val (keys %{$rhash}) { #if (($val =~ /$oky/) && ($val =~ /SOURCE/i)) { if ( ($val eq $vky)||( (($val =~ /$oky/)||($val =~ /$ky/)) && ($val =~ /SOURCES/) )) { push(@rhkeys,$val); $vky = $val; $src_list .= ' ' if (length($src_list)); $src_list .= ${$rhash}{$vky}; $fnd++; } } if ($fnd) { prt("[03] Source list found with $fnd keys [".join(" ",@rhkeys)."]\n") if ($dbg_s03); $val = $src_list; prt("[03] Source list [$val] dupes will be removed...\n") if ($dbg_s03); } #} if ($fnd) { #@srcs = split(/\s/, $val); @srcs = split(/[\s\|]/,$val); # SPLIT LIST $scnt = scalar @srcs; @psrcs = (); prt("[03] Filter LIBRARY sources - $scnt...\n") if ($dbg_s03); # ensure DOS form, add $ff if add rel.. for ($i = 0; $i < $scnt; $i++) { $val = $srcs[$i]; # extract a SOURCE $src = path_u2d($val); # to DOS form next if (defined $dupes{$src}); $dupes{$src} = 1; # done this source if ($add_rel_sources) { $ff = sub_root_dir($a_dir.$src); if ($src ne $ff) { prt("[18] LIB: Changed src from [$src], to [$ff]. [$a_dir]\n") if ($dbg_s18); push(@psrcs,$ff); $srcs[$i] = $ff; } elsif ($src ne $val) { prt("[18] LIB: Changed src from [$val] to [$src]\n") if ($dbg_s18); push(@psrcs,$src); $srcs[$i] = $src; } else { push(@psrcs,$val); } } else { if ($src ne $val) { prt("[18] LIB: Changed src from [$val] to [$src]\n") if ($dbg_s18); $srcs[$i] = $src; } push(@psrcs,$src); } } # final source array $val = join(' ',@psrcs); $scnt = scalar @psrcs; $tot_scnt += $scnt; if (defined ${$rlibs}{$ky}) { $ms = ${$rlibs}{$ky}; if ( value_not_in_first($ms,\$val) ) { prtw( "WARNING: libraries [$ky] has value [$ms] ADDING [$val]!\n" ); ${$rlibs}{$ky} .= ' '.$val; } } else { ${$rlibs}{$ky} = $val; } prt( "[04] LIBRARY [$ky] has SOURCES $scnt [$val]\n" ) if ($dbg_s04); # my $rlh = ${$rparams}{'REF_LIBS_HASH'}; ${$rlh}{$ky} = $rhash; # keep the original Makefile.am hash scan } else { if (!$dnskys) { $dnskys = 1; $ms = ''; $scnt = 0; foreach $val (keys %{$rhash}) { if ($val =~ /SOURCE/i) { $ms .= ' ' if (length($ms)); $ms .= $val; $scnt++; } } prt("But found $scnt keys [$ms] in HASH! Is it ONE of these?\n") if (length($ms)); } prtw( "WARNING: No sources for LIBRARY [$ky] key [$vky] o [$oky],\n in file [$fil]\n" ); } } } $val = scalar @libkeys; prt( "[03] Done sources for $val LIBRARY keys ... found $tot_scnt...\n" ) if ($dbg_s03); } else { prt( "[03] No LIBRARY keys ...\n" ) if ($dbg_s03); } #### PROCESS PROGRAM SOURCES - stored in $rprogs #### ======================= my $rph = ${$rparams}{'REF_PROG_HASH'}; if (@progkeys) { foreach $key (@progkeys) { $val = $$rhash{$key}; #@av = split(/\s/,$val); @av = split(/[\s\|]/,$val); # SPLIT LIST foreach $oky (@av) { $ky = $oky; $ky =~ s/-/_/g; $ky =~ s/\./_/g; $ky = trim_all($ky); next if (length($ky) == 0); next if (($ky =~ /\@/)||($ky =~ /\$/)); $vky = $ky.'_SOURCES'; $fnd = 0; if (defined $$rhash{$vky}) { $val = $$rhash{$vky}; $fnd = 1; } else { foreach $val (keys %{$rhash}) { if (($val =~ /$oky/) && ($val =~ /SOURCE/i)) { $vky = $val; $val = $$rhash{$vky}; $fnd = 1; last; } } } if (!$fnd && $try_harder) { # search the HASH harder foreach $ky2 (keys %{$rhash}) { $val2 = $$rhash{$ky2}; @srcs = split(/[\s\|]/,$val2); # SPLIT LIST foreach $src (@srcs) { if (($src =~ /$oky\./) && is_c_source_extended($src) ) { $val = $src; $fnd = 1; last; } } } } if (!$fnd && $try_much_harder && ($oky =~ /^[-\w\.]+$/)) { # do_dir_scan($root_folder,0) if (!$done_dir_scan); @srcs = (); $fcnt = ac_match_dir_for_c_source($rparams,$oky,$a_dir,\@srcs); if ($fcnt) { $val = $srcs[0]; $fnd = 1; } } if ($fnd && length($val)) { #@srcs = split(/\s/, $val); @srcs = split(/[\s\|]/,$val); # SPLIT LIST $scnt = scalar @srcs; for ($i = 0; $i < $scnt; $i++) { $val = $srcs[$i]; $src = path_u2d($val); if ($add_rel_sources) { $ff = sub_root_dir($a_dir.$src); if ($src ne $ff) { prt("[18] PRG: Changed src from [$src], to [$ff]. [$a_dir]\n") if ($dbg_s18); $srcs[$i] = $ff; } elsif ($src ne $val) { prt("[18] PRG: Changed src from [$val], to [$src].\n") if ($dbg_s18); $srcs[$i] = $src; } } elsif ($src ne $val) { prt("[18] PRG: Changed src from [$val], to [$src].\n") if ($dbg_s18); $srcs[$i] = $src; } } $val = join(' ',@srcs); if (defined ${$rprogs}{$ky}) { $ms = ${$rprogs}{$ky}; if ( value_not_in_first($ms,\$val) ) { prtw( "WARNING: programs [$ky] has value [$ms] ADDING [$val]!\n" ); ${$rprogs}{$ky} .= ' '.$val; } } else { ${$rprogs}{$ky} = $val; } # my $rph = ${$rparams}{'REF_PROG_HASH'}; ${$rph}{$ky} = $rhash; # keep the original Makefile.am hash scan prt( "[04] PROGRAM [$ky] has SOURCES [$val]\n" ) if ($dbg_s04); } else { $fnd = 0; if ($try_harder) { $val = ''; if ( a_source_does_exist($a_dir,$oky,\$val) ) { $fnd = 1; if (defined ${$rprogs}{$ky}) { $ms = ${$rprogs}{$ky}; if ( value_not_in_first($ms,\$val) ) { prtw( "WARNING: programs [$ky] has value [$ms] ADDING [$val]!\n" ); ${$rprogs}{$ky} .= ' '.$val; } } else { ${$rprogs}{$ky} = $val; } # my $rph = ${$rparams}{'REF_PROG_HASH'}; ${$rph}{$ky} = $rhash; # keep the original Makefile.am hash scan prt("[04] PROGRAM [$ky] has existing SOURCE [$val]\n") if ($dbg_s04); } } if (!$fnd) { if (!$dnskys) { $dnskys = 1; $ms = ''; $scnt = 0; foreach $val (keys %{$rhash}) { if ($val =~ /SOURCE/i) { $ms .= ' ' if (length($ms)); $ms .= $val; $scnt++; } } prt("\nBut found $scnt keys\n [$ms] in HASH!\n Is it ONE of these?\n") if (length($ms)); } prtw("WARNING: No sources for PROGRAM [$ky] key [$vky] org [$oky] file [$fil]\n" ); } } } } } else { prt( "[03] No PROGRAM keys ...\n" ) if ($dbg_s03); } my $ramsdone = ${$rparams}{'REF_AMS_DONE'}; my $am_cnt = scalar keys(%{$ramsdone}); my $prog_cnt = scalar keys(%{$rprogs}); my $libs_cnt = scalar keys(%{$rlibs}); if ($am_cnt && (!$prog_cnt && !$libs_cnt)) { # did, one or more AM (or IN) files, but NO libraries, or programs # my $ref_targets = ${$rparams}{'AM_FILE_TARGETS'}; my $rtcnt = scalar keys(%{$ref_targets}); if ($rtcnt && (defined ${$rparams}{'SUPP_MAKE_IN'} ) && (${$rparams}{'SUPP_MAKE_IN'} > 0)) { process_target_list($rparams); } elsif ($rtcnt) { prt("NOTE: Would scan the $rtcnt TARGETS, if \$supp_make_in was set!\n"); } } prt( "[02] extract_from_hash: Done $acnt from [".sub_root_folder($fil)."]...\n" ) if ($dbg_s02); # return \%extract; } # 1: $(MACRO) # 2: ${MACRO} # 3: @MACRO@ sub is_macro_type($) { my ($txt) = @_; return 1 if ($txt =~ /^\$\(\w+\)$/); # 1: $(MACRO) return 2 if ($txt =~ /^\$\{\w+\}$/); # 2: ${MACRO} return 3 if ($txt =~ /^\@\w+\@$/); # 3: @MACRO@ return 0; } # lev = 1 = no plus sign, so should be first init of item # and warn if it is NOT # lev = 2 = Had a plus sign, is += so variable SHOULD exist # and warn if it does NOT, if $warn_on_plus #sub add_key_value_2_hash($$$$$$) { # my ($key,$val,$rhash,$i2,$sfil,$lev) = @_; sub add_key_value_2_hash($$) { my ($rparams,$lev) = @_; my $rhash = ${$rparams}{'CURR_REF_HASH'}; my $i2 = ${$rparams}{'CURR_LINENUM'}; my $ckey = ${$rparams}{'CURR_KEY'}; my $val = ${$rparams}{'CURR_VAL'}; my $sfil = ${$rparams}{'AM_FILE'}; my $warn_on_plus = ${$rparams}{'VALUE_WARN_ON_PLUS'}; my $key = $ckey; my ($tmp,$done,$cval,$msg); if ( is_macro_type($val) ) { prt("[12] $i2: key [$key] Avoided adding MACRO value [$val] type $lev\n") if ($dbg_s12); return 0; } if ($val =~ /^\w{1}:/) { # if the value is a DOS 'D:' path $tmp = path_u2d($val); $tmp =~ s/\\\\/\\/ while ($tmp =~ /\\\\/); # remove any double '\\' in string if ($val ne $tmp) { prt("[12] Modified [$val] to [$tmp]\n") if ($dbg_s12); $val = $tmp; } $tmp = ''; } $cval = ''; if (defined ${$rhash}{$key}) { $cval = ${$rhash}{$key}; prtw( "WARNING: $i2: hash [$key] exists with [$cval]! Adding [$val]! $lev! file [$sfil]\n" ) if ($lev == 1); # ${$rhash}{$key} .= '|'.$val; if ( length($cval) && !($cval =~ /^\s+$/) ) { ${$rhash}{$key} .= ' '.$val; $tmp = 'Added to'; } else { ${$rhash}{$key} = $val; $tmp = 'Setting2' } } else { # hmmm, maybe have a key like 'jack_freebob_la_SOURCES if HAVE_ALSA_MIDI@_TRUE@' $done = 0; if ($key =~ /\s/) { my @arr = split(/\s/,$key); my $cnt = scalar @arr; $tmp = $arr[0]; if (($cnt >= 3) && (defined ${$rhash}{$tmp})) { $key = $tmp; $cval = ${$rhash}{$key}; prtw( "WARNING: $i2: hash [$key] exists with [$cval]! Adding [$val]! $lev! file [$sfil]\n" ) if ($lev == 1); # ${$rhash}{$key} .= '|'.$val; if ( length($cval) && !($cval =~ /^\s+$/) ) { ${$rhash}{$key} .= ' '.$val; $tmp = 'Added (assume TRUE)'; } else { ${$rhash}{$key} = $val; $tmp = 'Set to (assume TRUE)'; } $done = 1; } } if (!$done) { prtw( "WARNING: $i2: hash [$key] DOES NOT EXIST! $lev! file [$sfil]\n" ) if (($lev == 2) && $warn_on_plus); ${$rhash}{$key} = $val; $tmp = 'Setting' } } if ($dbg_s12) { $msg = "[12] $i2: $tmp key [$key], with value [$val] "; $msg .= "had [$cval] " if (length($cval)); $msg .= "org [$ckey] " if ($key ne $ckey); $msg .= "typ $lev"; prt("$msg\n"); } return 1; } sub am_process_AM_file($$); sub am_process_AM_file($$) { my ($rparams,$lev) = @_; my $fil = ${$rparams}{'AM_FILE'}; my $ramsdone = ${$rparams}{'REF_AMS_DONE'}; if (defined ${$ramsdone}{$fil}) { return ${$ramsdone}{$fil}; } my $rprogs = ${$rparams}{'REF_PROGRAMS'}; my $rlibs = ${$rparams}{'REF_LIBRARIES'}; my $rexit_val = ${$rparams}{'REF_EXIT_VALUE'}; # 27/09/2010 - user conditionals, and missed conditionals my $rusrcond = ${$rparams}{'REF_DEF_CONDITIONS'}; my $rmiscond = ${$rparams}{'REF_MISSED_CONDITIONS'}; my ($a_nm, $a_dir) = fileparse($fil); $a_dir = $cwd."\\" if ($a_dir =~ /^\.(\\|\/)$/); my $sfil = sub_root_folder($fil); my %my_hash = (); my $refhash = \%my_hash; my %targets = (); my ($ff); my $dooldext = 0; if (!open INF, "<$fil") { prtw( "WARNING: Unable to open $fil ... $! ...\n" ); return $refhash; } my @lns = <INF>; close INF; my $cnt = scalar @lns; ${$rparams}{'TOTAL_LINE_COUNT'} += $cnt; prt("\n") if ($dbg_s07 && $dbg_s08 && ($lev == 0)); prt( "[08] Processing $cnt lines, from [$fil] ...\n" ) if ($dbg_s08); my ($i,$line,$fline,$i2,@av,$key,$val,$j,$acnt,$ifcond,$msg); my ($ind,$len,$tmp,$scnt); my ($irh,$k,$v,$sff); my @cond_stack = (); my $in_target = 0; my $target = ''; $fline = ''; for ($i = 0; $i < $cnt; $i++) { $line = $lns[$i]; $i2 = $i + 1; chomp $line; $line = trim_all($line); prt("[01] $i2: [$line]\n") if ($dbg_s01); next if ($line =~ /^#/); $fline .= $line; #$len = length($fline); #if ($len == 0) { # $in_target = 0; # next; #} # join continuation lines into one if ($fline =~ /\\$/) { $fline =~ s/\\$/ /; next; } # deal with the FULL line $fline = trim_all($fline); if ($fline ne $line) { prt("[01] $i2: [$fline] accumulated...\n") if ($dbg_s01); } $len = length($fline); if ($len == 0) { $in_target = 0; next; } ${$rparams}{'CURR_LINE'} = $fline; ${$rparams}{'CURR_REF_HASH'} = $refhash; ${$rparams}{'CURR_LINENUM'} = $i2; #$fline = test_for_substitution($fline,$refhash,$i2,$sfil); $fline = am_test_for_substitution($rparams); if (($fline =~ /$IF_PATTERN/o)||($fline =~ /$IFD_PATTERN/o)) { # open an IF $ifcond = $1; push(@cond_stack, $ifcond . "\@_TRUE\@"); $scnt = scalar @cond_stack; $msg = ''; $v = 'TRUE'; if ( defined ${$rusrcond}{$ifcond} ) { $v = ${$rusrcond}{$ifcond}; $msg = "UDEF $v"; } else { # put in MISSED conditionals $msg = 'MISSED'; if (defined ${$rmiscond}{$ifcond}) { ${$rmiscond}{$ifcond} .= '|'.$v; $msg .= '+'; } else { ${$rmiscond}{$ifcond} = $v; } } prt( "[06] IF:$scnt: Opened cond_stack with [".$cond_stack[$#cond_stack]."] $msg [$sfil]\n" ) if ($dbg_s06); #$in_target = 0; } elsif (($fline =~ /$NIF_PATTERN/o)||($fline =~ /$NIF_PATTERN2/o)) { # open an IF !(SOMETHING) $ifcond = $1; push(@cond_stack, $ifcond . "\@_FALSE\@"); $msg = ''; $v = 'FALSE'; if ( defined ${$rusrcond}{$ifcond}) { $v = ${$rusrcond}{$ifcond}; $msg = "UDEF $v"; } else { # put in MISSED conditionals $msg = 'MISSED'; if (defined ${$rmiscond}{$ifcond}) { ${$rmiscond}{$ifcond} .= '|'.$v; $msg .= '+'; } else { ${$rmiscond}{$ifcond} = $v; } } prt( "[06] NIF:$scnt: Opened cond_stack with [".$cond_stack[$#cond_stack]."] $msg [$sfil]\n" ) if ($dbg_s06); #$in_target = 0; } elsif ($fline =~ /$ELSE_PATTERN/o) { # switch to else $scnt = scalar @cond_stack; if ($scnt) { $ifcond = $cond_stack[$#cond_stack]; $msg = 'UNKNOWN'; if ($ifcond =~ /(\@_TRUE\@|\@_FALSE\@)/) { $msg = $1; $ifcond =~ s/(\@_TRUE\@|\@_FALSE\@)//; } if ($cond_stack[$#cond_stack] =~ /\@_TRUE\@$/) { $v = 'FALSE'; $cond_stack[$#cond_stack] =~ s/\@_TRUE\@$/\@_FALSE\@/; $msg .= " to $v"; } else { $v = 'TRUE'; $cond_stack[$#cond_stack] =~ s/\@_FALSE\@$/\@_TRUE\@/; $msg .= " to $v"; } if ( defined ${$rusrcond}{$ifcond}) { $msg .= " UDEF ".${$rusrcond}{$ifcond}; } else { # put in MISSED conditionals $msg .= ' MISSED'; if (defined ${$rmiscond}{$ifcond}) { ${$rmiscond}{$ifcond} .= '|'.$v; $msg .= '+'; } else { ${$rmiscond}{$ifcond} = $v; } } prt( "[06] Else:$scnt: Switched cond_stack to [".$cond_stack[$#cond_stack]."] $msg [$sfil]\n" ) if ($dbg_s06); } else { prtw( "POTENTIAL ERROR: else without if or nif! [$fil:$i2]\n" ); ${$rexit_val} = 1; } #$in_target = 0; } elsif ($fline =~ /$ENDIF_PATTERN/o) { # reached endif if (! @cond_stack) { prtw( "ERROR: endif without if! ($sfil:$i2)\n" ); } else { $ifcond = pop (@cond_stack); prt( "[06] Closed cond_stack with [$ifcond] $sfil\n" ) if ($dbg_s06); } #$in_target = 0; } elsif (($fline =~ /$INCLUDE_PATTERN2/)||($fline =~ /$INCLUDE_PATTERN/o)) { $key = $1; if ($key =~ /^\w{1}:/) { $ff = path_u2d($key); } else { $ff = path_u2d($a_dir.$key); } $ff =~ s/\\\\/\\/ while ($ff =~ /\\\\/); $ff = fix_rel_path($ff); $sff = sub_root_folder($ff); if (-f $ff) { if ($opt_do_includes) { prt( "[08] Processing INCLUDE file [$ff], from [$fil] ...\n" ) if ($dbg_s08); ${$rparams}{'AM_FILE'} = $ff; # set file to SCAN $irh = am_process_AM_file($rparams,($lev + 1)); $v = scalar keys(%{$irh}); prt( "[08] ADVICE: Merging include of $v items from [$sff]...\n") if ($dbg_s08); foreach $k (keys %{$irh}) { $v = ${$irh}{$k}; if (defined ${$refhash}{$k}) { ${$refhash}{$k} .= ' '.$v; } else { ${$refhash}{$k} = $v; } } ${$rparams}{'AM_FILE'} = $fil; # put it BACK } else { prt( "[08] INCLUDE file [$ff], from [$fil] NOT PROCESSED!\n" ) if ($dbg_s08); } } else { prtw( "ERROR: Unhandled INCLUDE 2 [$key], ($sfil:$i2) [$sff] NOT FOUND\n" ); } } elsif ($fline =~ /^(\w+)\s*=\s*(.*)$/) { #$key = $1; @av = split('=',$fline); $key = trim_all($av[0]); $acnt = scalar @av; $val = ''; # start with NO VALUE # if can be just 'JPEG_SERVER =' for ($j = 1; $j < $acnt; $j++) { if ($j == 1) { $val = trim_all($av[$j]); } else { $val .= '='.trim_all($av[$j]); } } #show_line_split($fline,$key,$val,\@av,$i2); if (@cond_stack) { $ifcond = $cond_stack[$#cond_stack]; $key .= ' if '.$ifcond; } if (length($key) == 0) { pgm_exit(1,"ERROR: Split of line [$fline] DID NOT YIELD key! Losing value [$val]\n"); } else { ${$rparams}{'CURR_REF_HASH'} = $refhash; ${$rparams}{'CURR_LINENUM'} = $i2; ${$rparams}{'CURR_KEY'} = $key; ${$rparams}{'CURR_VAL'} = $val; #add_key_value_2_hash($key,$val,$refhash,$i2,$sfil,1); # should NOT exist add_key_value_2_hash($rparams,1); # should NOT exist } } elsif ($fline =~ /^(\w+)\s*\+=\s*(.+)$/) { $key = $1; $val = $2; if (@cond_stack) { $ifcond = $cond_stack[$#cond_stack]; $key .= ' if '.$ifcond; } ${$rparams}{'CURR_REF_HASH'} = $refhash; ${$rparams}{'CURR_LINENUM'} = $i2; ${$rparams}{'CURR_KEY'} = $key; ${$rparams}{'CURR_VAL'} = $val; #add_key_value_2_hash($key,$val,$refhash,$i2,$sfil,2); # plus, so key SHOULD exist add_key_value_2_hash($rparams,2); # plus, so key SHOULD exist } elsif ($fline =~ /^([\.\w-]+)\s*:/) { $target = $1; $in_target = 1; $val = ''; $ind = index($fline,':'); if (($ind > 0) && (($ind+1) < $len)) { $val = trim_all(substr($fline,($ind+1))); } if (@cond_stack) { $ifcond = $cond_stack[$#cond_stack]; $target .= ' if '.$ifcond; } if (defined $targets{$target}) { ##prtw( "WARNING: targets[$target] exists with [".$targets{$target}."]! Adding [$val]!! file=$sfil\n" ); $targets{$target} .= "\n\t".$val; $tmp = 'Added to'; } else { $targets{$target} = $val; ##prtw( "WARNING: targets[$target] DOES NOT exist! Adding [$val]!! file=$sfil\n" ); $tmp = 'Started'; } prt("[11] $i2: [$tmp] TARGET [$target], with value [$val]\n") if ($dbg_s11); } elsif ($fline =~ /^([-\@\w]+)\s*=\s*(.*)$/) { $key = $1; $val = trim_all($2); if (@cond_stack) { $ifcond = $cond_stack[$#cond_stack]; $key .= ' if '.$ifcond; } if (length($key) == 0) { pgm_exit(1,"ERROR: Split of line [$fline] DID NOT YIELD key! Losing value [$val]\n"); } else { ${$rparams}{'CURR_REF_HASH'} = $refhash; ${$rparams}{'CURR_LINENUM'} = $i2; ${$rparams}{'CURR_KEY'} = $key; ${$rparams}{'CURR_VAL'} = $val; #add_key_value_2_hash($key,$val,$refhash,$i2,$sfil,1); # should NOT exist add_key_value_2_hash($rparams,1); # should NOT exist } } else { if ($in_target && length($target)) { if (defined $targets{$target}) { $targets{$target} .= "\n\t".$fline; } else { $targets{$target} = $fline; ##prtw( "WARNING: targets[$target] DOES NOT exist! Adding [$val]!! file=$sfil\n" ); } prt("[11] $i2: Added to targets [$target] value [$fline]\n") if ($dbg_s11); } else { prt("[01] $i2: [$fline] SKIPPED file=[$fil]\n" ) if ($dbg_s01); } } $fline = ''; # kill this processed line $key = ''; $val = ''; } ${$rparams}{'AM_FILE_TARGETS'} = \%targets; # return TARGETS found in scan # done all the LINES, now play with the HASH collected if ($lev == 0) { $acnt = scalar keys(%{$refhash}); if ($acnt) { #my $rextr = extract_from_hash( $fil, $refhash, $rprogs, $rlibs ); my $rextr = am_extract_from_hash($rparams); } else { prt( "NOTE: NO KEYS IN HASH! for [$fil] $cnt lines...\n" ); } } # WARN if conditional stack NOT closed if (@cond_stack) { $val = join("\n",@cond_stack); prtw( "WARNING: Items still in cond_stack! [$val]\n file [$fil]\n" ); } ${$ramsdone}{$fil} = $refhash; return $refhash; } # show a SCALAR only reference hash # that is where all the keys and values are scalar only sub show_scalar_ref_hash($) { my ($rhash) = @_; my $cnt = scalar keys(%{$rhash}); prt("Got $cnt keys for this HASH...\n"); my ($min,$key,$max,$val,$len); $min = 0; $max = 40; foreach $key (keys %{$rhash}) { $len = length($key); $min = $len if ($len > $min); } $min = $max if ($min > $max); foreach $key (keys %{$rhash}) { $val = ${$rhash}{$key}; $key .= ' ' while (length($key) < $min); prt("$key = [$val]\n"); } } sub create_anon_funct($$$) { my ($rp,$clibR,$clibD) = @_; my $nf = sub { my $flag = shift; return $clibR if ($flag & 1); return $clibD; }; bless ($nf); ${$rp}{'PROJECT_USER_LIBS'} = $nf; # store the NEW function } # add any LDADD library dependant # See 'LDADDS' but more usually prog_LDADD # Need to later check _LIBADD and/or _DEPENDENCIES # Check if is one of the 'built' libraries - only add it built?!?! # NOTE key changes ($ky =~ s/-/_/g; and $ky =~ s/\./_/g; MAY APPLY here sub check_for_LDADD($$$) { my ($rhash,$rp,$rparams) = @_; # my $roph = ${$rparams}{'REF_PROG_HASH'}; # ${$rp}{'PROJECT_USER_LIBS'} = ${$rparams}{'CURR_USER_LIBS'}; # normal fetch for 'libraries' my ($key,$val,@arr,$itm,$nm,$dir,$rel_path,$lpathD,$lpathR,$fnd,$fnd2,$nm2,$lib,$fnd3); my $libs = ''; my $libD = ''; my $libR = ''; my $vals = ''; my $auto_on = ${$rparams}{'CURR_AUTO_ON_FLAG'}; # = $auto_on_flag; my $proj_name = ${$rp}{'PROJECT_NAME'}; $nm = ''; $nm2 = ''; my %dupes = (); my @libsarr = (); my @goodkeys = (); $fnd = 0; $fnd2 = 0; $fnd3 = 0; @arr = (); # 1 - search for MOST likely foreach $key (keys %{$rhash}) { if ($key =~ /^${proj_name}_/) { $val = ${$rhash}{$key}; if ($key =~ /LDADD/) { $fnd++; push(@goodkeys,$key); $nm .= " $val"; } elsif ($key =~ /LIBADD/) { $fnd2++; push(@goodkeys,$key); $nm2 .= " $val"; } elsif ($key =~ /DEPENDENCIES/) { $fnd3++; push(@goodkeys,$key); $nm2 .= " $val"; } } } if (@goodkeys) { prt("[15] Good keys for LDADD:$proj_name: Search dependencies...LD=$fnd LIB=$fnd2 DEP=$fnd3 keys[".join(" ",@goodkeys)."]\n [$nm] [$nm2]\n") if ($dbg_s15); } else { # no quite specific key found - do a general search foreach $key (keys %{$rhash}) { $val = ${$rhash}{$key}; if ($key =~ /LDADD/) { $fnd++; push(@goodkeys,$key); $nm .= " $val"; } elsif ($key =~ /LIBADD/) { $fnd2++; push(@goodkeys,$key); $nm2 .= " $val"; } elsif ($key =~ /DEPENDENCIES/) { $fnd3++; push(@goodkeys,$key); $nm2 .= " $val"; } } prt("[15] General for LDADD:$proj_name: Search dependencies...LD=$fnd LIB=$fnd2 DEP=$fnd3 keys[".join(" ",@arr)."]\n [$nm] [$nm2]\n") if ($dbg_s15); prtw("WARNING: Found dependency keys NOT HANDLED!\n") if ($fnd2 || $fnd3); } $fnd = 0; $nm = ''; $nm2 = ''; $libs = ''; foreach $key (@goodkeys) { #foreach $key (keys %{$rhash}) { # if ($key =~ /LDADD/) { $fnd++; $val = ${$rhash}{$key}; #@arr = split(/[\s|]/,$val); @arr = split(/[\s\|]+/,$val); prt("[15] $proj_name:$key: Checking [$val]...\n") if ($dbg_s15); foreach $itm (@arr) { next if ((length($itm) == 0)||($itm =~ /^\s+$/)); $itm = path_u2d($itm); $itm =~ s/\\\\/\\/g while ($itm =~ /\\\\/); ($nm,$dir) = fileparse($itm); next if ((length($nm) == 0)||($nm =~ /^\s+$/)); # ***TBD*** for the moment, avoid tha PAIN if it is just say an '@MATH_LIB@' # next if ($nm =~ /^\@(.*)\@$/); next if (is_macro_type($nm)); next if ($nm =~ /^-/); # like -lm, etc $vals .= ' ' if (length($vals)); $vals .= $itm; $fnd2 = 0; $nm2 = $nm; $nm2 =~ s/-/_/g; $nm2 =~ s/\./_/g; $lib = ''; if (defined ${$rparams}{'CURR_LIB_SUBS'}) { my $ra = ${$rparams}{'CURR_LIB_SUBS'}; my ($v); $v = scalar @{$ra}; # prt("Got $v hashes in array...finding [$nm] [$itm]\n"); foreach $v (@{$ra}) { if (defined ${$v}{$nm}) { $lib = ${$v}{$nm}; $fnd2 = 1; last; } elsif (defined ${$v}{$nm2}) { $lib = ${$v}{$nm2}; $fnd2 = 2; last; } } if (!$fnd2) { if ($dbg_s15) { $v = scalar @{$ra}; prt("[15] Find FAILED! Got $v hashes in array...finding [$nm] or [$nm2] full [$itm]\n"); foreach $v (@{$ra}) { foreach my $k (keys %{$v}) { my $v2 = ${$v}{$k}; prt(" key [$k], with value [$v2]\n"); } } } } } else { prtw("WARNING: 'CURR_LIB_SUBS' NOT DEFINED! ie NO libraries built here!\n"); } if (length($lib)) { $lib =~ s/\.lib$//i; } if (length($lib)) { if (!defined $dupes{$lib}) { $dupes{$lib} = 1; $libD .= ' ' if (length($libD)); $libR .= ' ' if (length($libR)); if ($auto_on & 2) { $libD .= $lib.'D.lib'; $libR .= $lib.'.lib'; } else { $libD .= $lib.'.lib'; $libR .= $lib.'.lib'; } push(@libsarr,$lib); $lib .= '.lib'; $libs .= ' ' if (length($libs)); $libs .= $lib; } } } # } } if (length($libs)) { # this could have been established during the doing of the Library project(s) # --------------------------------------------------------------------------- if ($auto_on & 4) { $lpathD = "lib"; $lpathR = "lib"; } else { $lpathD = "Debug"; $lpathR = "Release"; } my $func = ${$rp}{'PROJECT_USER_LIBS'}; my $clibR = $func->(1,""); # get Release my $clibD = $func->(2,""); # get NOT Release = Debug $clibR .= ' ' if (length($clibR)); $clibR .= $libR; # establish Release $clibR .= " /libpath:\"$lpathR\""; $clibD .= ' ' if (length($clibD)); $clibD .= $libD; # establish Debug $clibD .= " /libpath:\"$lpathD\""; # create anonymous function create_anon_funct($rp,$clibR,$clibD); # MUST ADD DSW DEPENDENCY FOR THIS LOCALLY BUILT LIBRARY ${$rp}{'PROJECT_DEPENDS'} = [ @libsarr ]; prt("[15] LDADD:$proj_name: Found and added [$libs] to get Rel:[$clibR], and Dbg:[$clibD]\n") if ($dbg_s15); } elsif ($fnd) { prtw("WARNING:$proj_name: LDADD found, with value [$libs], but setup failed! Not found in built libs!\n") if ($dbg_s15); } else { prt("[15] :$proj_name: NO LDADD entry found in the ref HASH for project.\n") if ($dbg_s15); } } sub set_new_user_outs_prog($$) { my ($rp,$pn) = @_; my $dnm = $pn."D.exe"; my $rnm = $pn.".exe"; my $func = sub { my $flag = shift; return "/out:\"bin\\".$rnm."\"" if ($flag & 1); return "/out:\"bin\\".$dnm."\""; }; bless ($func); ${$rp}{'PROJECT_USER_OUTS'} = $func; } sub set_new_user_outs_libs($$) { my ($rp,$pn) = @_; my $dnm = $pn."D.lib"; my $rnm = $pn.".lib"; my $func = sub { my $flag = shift; return "/out:\"lib\\".$rnm."\"" if ($flag & 1); return "/out:\"lib\\".$dnm."\""; }; bless ($func); ${$rp}{'PROJECT_USER_OUTS'} = $func; } # if ($auto_on & 32), scan the sources for headers # ------------------------------------------------- sub enhance_with_headers($$$$$) { my ($rparams,$rsrcs,$rscans,$rdupes,$rp) = @_; my ($k2,$cnt,$tcnt,$ccnt,$file,$dir,$nam); my @allincs = (); my @allothers = (); my $dbg = 0; my $proj_name = ${$rp}{'PROJECT_NAME'}; # = $key $tcnt = scalar @{$rscans}; prt("[15] $proj_name: Processing $tcnt sources, for headers...\n") if ($dbg_s15); $ccnt = 0; my %done = (); my $rdh = \%done; my $line_cnt = 0; ${$rparams}{'TMP_DONE_HASH'} = $rdh; ${$rparams}{'TMP_LINE_TOTAL'} = $line_cnt; my $tot_cnt = 0; foreach $k2 (@{$rscans}) { $ccnt++; # prt("$ccnt of $tcnt: Scanning [$k2], got $cnt includes... "); #my $rih = full_src_scan($k2,$dbg,$rparams); #delete ${$rih}{$k2} if (defined ${$rih}{$k2}); #my @arr = sort keys(%{$rih}); recursive_src_scan($k2,$dbg,$rparams); if (! defined ${$rdh}{$k2}) { ${$rdh}{$k2} = 1; $tot_cnt++; } my @arr = keys(%{$rdh}); $cnt = scalar @arr; $cnt -= $tot_cnt; prt("[15] $ccnt:$tcnt: From [$k2], $cnt items... [") if ($dbg_s15); $cnt = 0; foreach $file (@arr) { if (! defined ${$rdupes}{$file}) { if (is_h_source_extended($file)) { ${$rdupes}{$file} = 1; push(@allincs,$file); $cnt++; ($nam,$dir) = fileparse($file); prt("$nam ") if ($dbg_s15); } else { push(@allothers,$file); } } } prt("] added $cnt to list...\n") if ($dbg_s15); $tot_cnt += $cnt; } $line_cnt = ${$rparams}{'TMP_LINE_TOTAL'}; ${$rparams}{'TOTAL_LINE_COUNT'} += $line_cnt; $cnt = scalar @allincs; if ($dbg_s15) { if ($cnt) { prt("[15] Got total includes $tot_cnt ["); prt(join(" ",@allincs)); prt("] from $line_cnt lines.\n"); } else { prt("[15] Got NO additional includes, from $line_cnt lines.\n"); } } $cnt = scalar @allincs; if ($cnt) { my $target_dir = ${$rparams}{'TARGET_DIR'}; my $fix_relative_sources = ${$rparams}{'FIX_REL_SOURCE'}; my ($rel_path,$rfil,$ff2,$ok,$fil,$msg); %done =(); foreach $fil (@{$rsrcs}) { $done{$fil} = 1; } foreach $k2 (@allincs) { $fil = sub_root_dir($k2); if ($fix_relative_sources) { ($nam,$dir) = fileparse($k2); my $rel_path = get_rel_dos_path($dir,$target_dir); # ***TBD*** Could ensure this RELATIVE PATH is added to the project INCLUDES # ========================================================================== my $rfil = $rel_path.$nam; my $ff2 = $target_dir.$rfil; $ff2 = fix_rel_path($ff2); if (-f $ff2) { $ok = "ok"; } else { $ok = "RELATIVE PROBLEM [$ff2]"; } $msg = "rel [$fil] [$rfil] [$ff2] $ok "; $fil = $rfil; } else { if (-f $k2) { $ok = "ok"; } else { $ok = "ERROR: CHECK ME!"; } $msg = "root [$k2] [$fil] $ok "; } if (defined $done{$fil}) { $ok = 'ALREADY IN SOURCES!'; } else { ######################################### # This is what this is ALL about $ok = 'Added to sources.'; push(@{$rsrcs},$fil); ######################################### } prt("$msg $ok\n") if ($dbg_s15); } } } # SUMMARY OUTPUTS # =============== # depends on the basic structure, for programs # bin_PROGRAMS = hello # hello_SOURCES = hello.c #sub list_to_arrays($$$$) { # my ($in_fil,$rprogs,$rlibs,$ramsdone) = @_; sub am_list_to_arrays($) { my ($rparams) = @_; # extract params my $in_fil = ${$rparams}{'AM_FILE'}; if (! defined $in_fil) { prtw("Appears NO Makefile.am files to scan!\n"); return; } if ((length($in_fil) == 0)||($in_fil =~ /^\s+$/)) { pgm_exit(1,"INTERNAL ERROR: 'AM_FILE' NOT correctly set in rparams!\n"); } my $rprogs = ${$rparams}{'REF_PROGRAMS'}; my $rlibs = ${$rparams}{'REF_LIBRARIES'}; # orginal Makefile.am scan hashes, if needed under same keys as above my $roph = ${$rparams}{'REF_PROG_HASH'}; my $rolh = ${$rparams}{'REF_LIBS_HASH'}; my $ramsdone = ${$rparams}{'REF_AMS_DONE'}; my $fix_relative_sources = ${$rparams}{'FIX_REL_SOURCE'}; my $target_dir = ${$rparams}{'TARGET_DIR'}; my $root_folder = ${$rparams}{'ROOT_FOLDER'}; my ($in_tit,$in_dir) = fileparse($in_fil); my %my_src_hash = (); my $rsh = \%my_src_hash; my %projects_hash = (); my $rph = \%projects_hash; #my @msvc_c_files = (); #my @msvc_h_files = (); my @c_files = (); my @h_files = (); my $am_cnt = scalar keys(%{$ramsdone}); my $prog_cnt = scalar keys(%{$rprogs}); my $libs_cnt = scalar keys(%{$rlibs}); if (($prog_cnt == 0) && ($libs_cnt == 0)) { if ($am_cnt == 1) { prt("Processed $am_cnt AM file, but NO programs nor libraries found. [$in_fil]\n"); } else { prt("\nAM files processed yielded NO programs nor libraries! (in $am_cnt am files)\n"); } # show targets, if any return $rsh; } my $prog_cnt2 = 0; my $lib_cnt2 = 0; my $total_sources = 0; my $source_missed = 0; my $found_count = 0; my $auto_on = ${$rparams}{'CURR_AUTO_ON_FLAG'}; # = $auto_on_flag; # ==================================================================================== # This is also the SUMMARY, and check if source found, or NOT # set my $total_sources = 0; and my $source_missed = 0; my ($key, $val, @av, $fil); my ($src, $tit, $dir, $ext, $cnt, $ok, $ff, $rfil, $msg); my ($ff2,$ok2,@arr,$k2,$v2); my @done = (); #my $sgrp = get_def_src_grp(); # "Source Files"; #my $sflt = get_def_src_filt(); #my $hgrp = get_def_hdr_grp(); # "Header Files"; #my $hflt = get_def_hdr_filt(); my $rel_path = ''; if ($fix_relative_sources) { $rel_path = get_rel_dos_path($in_dir,$target_dir); prt("Got relative [$rel_path], from in [$in_dir], and targ [$target_dir]\n"); } my ($rhash,$proj_name,$tmp); # original HASH of Makefile.am scan my %dupes = (); # avoid source duplications my %libdupes = (); my %project_dupes = (); # key is simple file name, contents an array [$ff,$relfile] my @header_scans = (); # process LIBRARIES before PROGRAMS - may use this/these libaries in the programs prt("\nAM files yielded the following library SOURCES... (from $am_cnt files)\n") if ($libs_cnt); foreach $key (sort keys %{$rlibs}) { next if ((length($key) == 0)||($key =~ /^\s+$/)); # ignore BLANKS $lib_cnt2++; $proj_name = $key; my %project = (); my $rp = \%project; my @srcs = (); ${$rp}{'PROJECT_TYPE'} = 'SL'; # static library ${$rp}{'PROJECT_NAME'} = $proj_name; # = $key ${$rp}{'PROJECT_USER_LIBS'} = ${$rparams}{'CURR_USER_LIBS'}; # normal fetch for 'libraries' ${$rp}{'PROJECT_USER_OUTS'} = ${$rparams}{'CURR_USER_OUTS'}; # normal fetch for 'out:puts' # my $rolh = ${$rparams}{'REF_LIBS_HASH'}; pgm_exit(1,"ERROR INTERNAL: key [$key] NOT defined in ref REF_LIBS_HASH! WHY?\n") if (!defined ${$rolh}{$key} ); $rhash = ${$rolh}{$key}; ### show_scalar_ref_hash($rhash); # if the $key made it here with macros, then try to adjust the project name if ($proj_name =~ /[\@\$]/) { prtw("WARNING: ***TBD*** This is NOT a good project name [$proj_name]! CHECK IT!\n"); } if ($auto_on & 2) { # = $auto_on_flag $proj_name =~ s/(\.|_)la//; set_new_user_outs_libs($rp,$proj_name); ${$rp}{'PROJECT_NAME'} = $proj_name; # != $key $msg = "auto output is ON. key [$key], set func to fetch R:'"; $msg .= ${$rp}{'PROJECT_USER_OUTS'}->(1,""); $msg .= "' D:'"; $msg .= ${$rp}{'PROJECT_USER_OUTS'}->(2,""); $msg .= "'"; prt("[15] $msg\n") if ($dbg_s15); if (! defined $libdupes{$proj_name}) { $libdupes{$proj_name} = 1; my %h = (); $h{$key} = $proj_name; ${$rparams}{'CURR_LIB_SUBS'} = [] if (!defined ${$rparams}{'CURR_LIB_SUBS'}); $tmp = ${$rparams}{'CURR_LIB_SUBS'}; push(@{$tmp}, \%h); } } else { prt("[15] auto output is OFF\n") if ($dbg_s15); } $val = ${$rlibs}{$key}; @av = split(/\s/,$val); $cnt = scalar @av; prt("LIBRARY [$key] $cnt SOURCES\n"); @done = (); # clear DONE %dupes = (); # clear source dupes @header_scans = (); # clear to scan list foreach $fil (@av) { next if ((length($fil) == 0)||($fil =~ /^\s+$/)); # ignore BLANKS $ff = $in_dir.$fil; $ff = fix_rel_path3($ff,"list_to_arrays"); next if (-d $ff); # ignore DIRECTORIES $total_sources++; if (-f $ff) { $ok = "ok"; push(@header_scans,$ff); $project_dupes{$ff} = 1; } else { if (is_c_source_extended($fil)) { $ok = "*** LIB SOURCE NOT FOUND [$ff]"; } else { $ok = "not found [$ff]"; } if ($find_bad_source) { # do_dir_scan($root_folder,0) if (!$done_dir_scan); @arr = (); ($tit,$dir) = fileparse($fil); $cnt = ac_is_file_in_scan($rparams,$tit,$dir,\@arr); if ($cnt) { $ff = $arr[0]; # for now take just the FIRST, but... $ok = "ok - found $cnt"; $found_count++; push(@header_scans,$ff); $project_dupes{$ff} = 1; } } if (!($ok =~ /^ok/)) { $source_missed++; } } ($tit,$dir) = fileparse($ff); if ($fix_relative_sources) { $rel_path = get_rel_dos_path($dir,$target_dir); $rfil = $rel_path.$tit; $ff2 = $target_dir.$rfil; if (-f $ff2) { $ok2 = "ok2"; } else { if ($ok eq 'ok') { $ok2 = "RELATIVE PROBLEM [$ff2]"; } else { $ok2 = ''; } } prt( " [15] rel [$rfil] [$fil] [$ff] $ok $ok2\n" ) if ($dbg_s15); $fil = $rfil; } else { prt( " [15] [$fil] $ok\n" ) if ($dbg_s15); } if (is_c_source_extended($fil)) { if (is_in_array($tit,@done)) { prtw("Duplicate of libs src FILE TITLE [$tit] file [$fil]!\n" ) if ($show_dup_title); } else { push(@done,$tit); } ###push(@msvc_c_files, $src); #push(@msvc_c_files, [$fil, $sgrp, $sflt]); push(@c_files, $fil); } else { ###push(@msvc_h_files, $src); #push(@msvc_h_files, [$fil, $hgrp, $hflt]); push(@h_files, $fil); } if (!defined $dupes{$fil}) { $dupes{$fil} = 1; push(@srcs,$fil); } #if (defined $project_dupes{$fil}) { # $project_dupes{$fil}++; #} else { # $project_dupes{$fil} = 1; #} } $cnt = scalar @srcs; if ($cnt) { # perhaps NOW would be a good time to search for 'missing' headers # (a) Could search for say include_HEADERS, in the rhash, # (b) or scan the source given for headers, or BOTH enhance_with_headers($rparams,\@srcs,\@header_scans,\%project_dupes,$rp) if ($auto_on & 32); # ====================================================================== # prt("Got $cnt sources for [$key]\n"); $cnt = scalar @srcs; ${$rp}{'PROJECT_SOURCES'} = \@srcs; # console application source ${$rph}{$key} = $rp; } else { prt("Got NO sources for [$key]\n"); } } @header_scans = (); prt( "\nAM files yielded programs $prog_cnt... (from $am_cnt file)\n" ) if ($prog_cnt); foreach $key (sort keys %{$rprogs}) { next if ((length($key) == 0)||($key =~ /^\s+$/)); # ignore BLANKS $prog_cnt2++; $proj_name = $key; my @srcs = (); %dupes = (); # avoid duplications for this project my %project = (); my $rp = \%project; ${$rp}{'PROJECT_TYPE'} = 'CA'; # console application ${$rp}{'PROJECT_NAME'} = $key; ${$rp}{'PROJECT_USER_LIBS'} = ${$rparams}{'CURR_USER_LIBS'}; # normal fetch for 'libraries' ${$rp}{'PROJECT_USER_OUTS'} = ${$rparams}{'CURR_USER_OUTS'}; # normal fetch for 'out:puts' # my $roph = ${$rparams}{'REF_PROG_HASH'}; pgm_exit(1,"ERROR INTERNAL: key [$key] NOT defined in ref REF_PROG_HASH! WHY?\n") if (! defined ${$roph}{$key} ); $rhash = ${$roph}{$key}; ###show_scalar_ref_hash($rhash); # if the $key made it here with macros, then try to adjust the project name if ($proj_name =~ /[\@\$]/) { prtw("WARNING: ***TBD*** Project name contains \@ or \$ [$proj_name]! Potential problems?\n"); } if ($auto_on & 6) { # = $auto_on_flag set_new_user_outs_prog($rp,$proj_name); prt("[15] auto output is ON. key [$key], set func to fetch R:'out:\"bin\\$proj_name.exe\"'\n") if ($dbg_s15); check_for_LDADD($rhash,$rp,$rparams); } $val = ${$rprogs}{$key}; # get source list @av = split(/\s/,$val); $cnt = scalar @av; prt( "PROGRAM [$key] $cnt SOURCES\n" ); @done = (); # clear DONE %dupes = (); # clear source dupes for this project @header_scans = (); # clear to scan list foreach $fil (@av) { next if ((length($fil) == 0)||($fil =~ /^\s+$/)); # ignore BLANKS $ff = $in_dir.$fil; $ff = fix_rel_path3($ff,"list_to_arrays"); next if (-d $ff); # ignore DIRECTORIES $total_sources++; if (-f $ff) { $ok = "ok"; push(@header_scans,$ff); $project_dupes{$ff} = 1; } else { if (is_c_source_extended($fil)) { $ok = "*** PROG SOURCE NOT FOUND [$ff]"; } else { $ok = "not found [$ff]"; } if ($find_bad_source) { #do_dir_scan($root_folder,0) if (!$done_dir_scan); @arr = (); ($tit,$dir) = fileparse($fil); $cnt = ac_is_file_in_scan($rparams,$tit,$dir,\@arr); if ($cnt) { $ff = $arr[0]; # for now take just the FIRST, but... $ok = "ok - found $cnt"; push(@header_scans,$ff); $project_dupes{$ff} = 1; if (!$fix_relative_sources) { # but have the FULL PATH ($tit,$dir) = fileparse($ff); $rel_path = get_rel_dos_path($dir,$root_folder); $fil = $rel_path.$tit; $fil =~ s/^\.\\//; } $found_count++; } } if (!($ok =~ /^ok/)) { $source_missed++; } } ($tit,$dir) = fileparse($ff); if ($fix_relative_sources) { $rel_path = get_rel_dos_path($dir,$target_dir); $rfil = $rel_path.$tit; $ff2 = $target_dir.$rfil; if (-f $ff2) { $ok2 = "ok2"; } else { if ($ok eq 'ok') { $ok2 = "RELATIVE PROBLEM [$ff2]"; } else { $ok2 = ''; } } prt( " [15] rel [$rfil] [$fil] [$ff2] $ok $ok2\n") if ($dbg_s15); $fil = $rfil; } else { prt( " [15] [$fil] $ok\n") if ($dbg_s15); } if ( is_c_source_extended($fil) ) { if ( is_in_array($tit,@done) ) { prtw("Duplicate of prog FILE TITLE [$tit] file [$fil]!\n" ) if ($show_dup_title); } else { push(@done,$tit); } #push(@msvc_c_files, $src); #push(@msvc_c_files, [$fil, $sgrp, $sflt]); push(@c_files, $fil); } else { #push(@msvc_h_files, $src); #push(@msvc_h_files, [$fil, $hgrp, $hflt]); push(@h_files, $fil); } if (!defined $dupes{$fil}) { $dupes{$fil} = 1; push(@srcs,$fil); } } if (@srcs) { enhance_with_headers($rparams,\@srcs,\@header_scans,\%project_dupes,$rp) if ($auto_on & 32); $cnt = scalar @srcs; # prt("Got $cnt sources for [$key]\n"); ${$rp}{'PROJECT_SOURCES'} = \@srcs; # console application source ${$rph}{$key} = $rp; # see if we need to adjust the dependant libraries # this is difficult } else { prt("Got NO sources for [$key]\n"); } } #$key = scalar @msvc_c_files; #$val = scalar @msvc_h_files; $key = scalar @c_files; $val = scalar @h_files; if ($key || $val || $prog_cnt2 || $lib_cnt2) { $ok = "Done AM file [$in_fil], "; $ok .= "and ".($am_cnt - 1)." more, " if ($am_cnt > 1); $ok .= "and found -"; prt("$ok\n"); prt("Set of $key C SOURCE files, and $val headers (and others)...for progs=$prog_cnt2, libs=$lib_cnt2\n" ); } # hmmm, since this is the LAST output, perhaps not a warning prt("NOTE: $source_missed of total $total_sources sources were NOT FOUND! [$in_fil]\n") if ($source_missed); prt("NOTE: $found_count files were found by a full directory scan of [$in_dir].\n") if ($found_count); #${$rsh}{'C_SOURCES'} = [ @msvc_c_files ]; #${$rsh}{'H_SOURCES'} = [ @msvc_h_files ]; ${$rparams}{'REF_SOURCES_HASH'} = $rsh; ${$rparams}{'REF_PROJECTS_HASH'} = $rph; return $rsh; } # this is more a DIAGNOSTIC output # ================================ sub am_out_dir_scan_info($) { my ($rparams) = @_; return if (! ${$rparams}{'CURR_DONE_SCAN'} ); my $dir = ${$rparams}{'CURR_FILE_DIR'}; my $rda = ${$rparams}{'CURR_DIR_SCAN'}; my $mslist = (defined ${$rparams}{'CURR_MISSED_SOURCES'}) ? ${$rparams}{'CURR_MISSED_SOURCES'} : ''; # = $missed_source_list my $cnt = scalar @{$rda}; prt("\n"); prt("[20] Checking $cnt files, from directory scan with those in DSP files... moment...\n") if ($dbg_s20); my ($i,$file,$fnd,$done,$sfil,$line,$msg); my ($missedC, $missedCE, $missedH); $done = 0; $missedC = 0; $missedCE = 0; $missedH = 0; my @cext = (); my @hext = (); my %dupes = (); $msg = ''; for ($i = 0; $i < $cnt; $i++) { $sfil = ${$rda}[$i][0]; $file = ${$rda}[$i][1]; # get FULL FILE $fnd = ${$rda}[$i][2]; if ($fnd) { $done++; } elsif (is_c_source($sfil)) { $missedC++; $sfil = sub_root_folder($file); prt(" [20] Missed C/C++ [$sfil]\n") if ($dbg_s20); $msg = "# Missed C/C++ files\n" if (length($msg) == 0); $msg .= "$sfil\n"; } elsif (is_h_source_extended($file)) { $missedH++; #prt("Missed HEADER extended [$file]\n"); push(@hext,$file); } elsif (is_c_source_extended($sfil)) { $missedCE++; #prt("Missed C/C++ extended [$file]\n"); push(@cext,$file); } } prt("DSP files have $done of total $cnt scan, missed $missedC C sources, $missedCE C extended, $missedH HEADER files...\n"); if ($missedH) { prt("[20] And $missedH HEADERS...\n") if ($dbg_s20); $line = ''; $msg .= "# Missing $missedH headers...\n"; foreach $file (@hext) { $sfil = sub_root_folder($file); if (length($line) && (length("$line $sfil") > 90)) { prt("$line\n") if ($dbg_s20); $line = ''; } $line .= "$sfil "; $msg .= "$sfil\n"; } prt("$line\n") if ($dbg_s20); prt("\n") if ($dbg_s20 && length($line)); } if ($dbg_s20) { foreach $file (@cext) { $sfil = sub_root_folder($file); prt("Missed C/C++ extended [$sfil]\n"); } } else { prt("Would display 'missing' lists, if -d 220 was added to the command.\n\n") if (!$dbg_s20); } # output a MISSING SOURCE FILE LIST if (length($mslist) && length($msg)) { write2file($msg,$mslist); prt("Written missed source list to [$mslist]\n"); } } 1; # eof - lib_amscam.pl