#!/usr/bin/perl -w # lib_amscan.pl # Library of services for scanning Makefile.am files # 14/10/2011 - Elevate output 'AM files processed yielded NO programs nor libraries!' to a WARNING # 03/08/2011 - FIX20110803 - Found macro in Makefile.am like E00 = # src1.c - This should yield NO source # FIX20110421 - eliminate dupes in a sometimes very long set of libs, and libpaths... # 28/01/2011 - Fix in PGM: section # 25/12/2010 - more robust, when NO 'Makefile.am' found... # 04/10/2010 - put more to missed source file # 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; my $avoid_adding_macro = 0; my $set_srcdir_local = 1; my $cairo_special_fix = 1; 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, $dbg_s23, $dbg_s24 ); # 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 $IFEQ_PATTERN = "^ifeq[ \t]+\(.+\)[ \t]*\(#.*\)?\$"; my $IFNEQ_PATTERN = "^ifneq[ \t]+\(.+\)[ \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+(.+)\$"; # FORWARD sub am_process_AM_file($$); ##################################################### ##################################################### # 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 1 if ($txt =~ /if\s+test\s+(.+);\s+then/); return 1 if ((($txt =~ /\brm\b/)||($txt =~ /\bmv\b/)) && ($txt =~ /\bsed\b/)); 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_cond_FALSE($$$) { my ($key,$rhash,$rval) = @_; my ($tmp); foreach $tmp (keys %{$rhash}) { if ($tmp =~ /^$key\s+.+\@_FALSE\@/) { ${$rval} = $tmp; return 2; } } return 0; } sub key_in_cond_TRUE_or_FALSE($$$) { my ($key,$rhash,$rkey) = @_; my $ret = 0; my $valT = ''; my $valF = ''; my @nkeys = (); $ret |= 1 if (key_in_cond_TRUE($key,$rhash,\$valT)); $ret |= 2 if (key_in_cond_FALSE($key,$rhash,\$valF)); if (($ret & 1)&&(length($valT))) { push(@nkeys,$valT); } if (($ret & 2)&&(length($valF))&&($valF ne $valT)) { push(@nkeys,$valF); } ${$rkey} = \@nkeys; return $ret; } sub key_in_a_conditional($$$$) { my ($key,$rhash,$rparams,$rtmp) = @_; # 27/09/2010 - user conditionals my $rusrcond = ${$rparams}{'REF_DEF_CONDITIONS'}; my $auto_on = ${$rparams}{'CURR_AUTO_ON_FLAG'}; # = $auto_on_flag; my ($tmp,$cond,$val,$tf,$prev,$k1,$k2,$v2,$msg,$cnt,$res,$user); $prev = key_in_cond_TRUE($key,$rhash,\$k2); $v2 = ($prev ? ${$rhash}{$k2} : ''); $val = ''; $tf = 'TRUE'; $cnt = 0; $res = ''; foreach $tmp (keys %{$rhash}) { if ($tmp =~ /^$key\s+if\s+(\w+)\@_(TRUE|FALSE)\@/) { $k1 = $1; $cond = $2; $cnt++; $val = ${$rhash}{$tmp}; $tf = 'TRUE'; $msg = 'Assumed'; $user = 0; if (defined ${$rusrcond}{$k1}) { $tf = ${$rusrcond}{$k1}; $msg = 'as SET by user'; $user = 1; } if ($cond eq $tf) { ${$rtmp} = $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; } elsif (($user == 0) && ($auto_on & 1024)) { ${$rtmp} = $tmp; $msg .= ', auto-bit=1024'; if ($prev) { if ($val ne $v2) { prt("[22] CHANGED:6: [$tmp] key [$key] cond [$cond] Was [$v2], now [$val] $tf $msg\n") if ($dbg_s22); } else { prt("[22] NOCHANGE:6: [$tmp] key [$key] cond [$cond] stays [$val] $tf $msg\n") if ($dbg_s22); } } else { prt("[22] CHANGED:7: [$tmp] key [$key] cond [$cond] Was [$v2] NOTHING, now [$val] $tf $msg\n") if ($dbg_s22); } return 1; } $res .= " + " if (length($res)); $res .= "[$k1] [$val] [$cond] ne [$tf]"; } } if ($cnt) { # found a key or 2 that matched prt("[22] MISSED CHANGE:5: FOUND $cnt key [$key], BUT $res!\n") if ($dbg_s22); return 0; } if ($prev) { prt("[22] MISSED CHANGE:3: key [$key] [$k2] Was [$v2], now NOT FOUND!\n") if ($dbg_s22); } else { prt("[22] MISSED CHANGE:4: key [$key] NOT FOUND!\n") if ($dbg_s22); # special # if ($key eq 'PRINTF_SUBDIR') { # prt("Additional: HOW COME THIS NOT FOUND? List of keys...\n"); # foreach $tmp (keys %{$rhash}) { # if ($tmp =~ /^(\w+)\s+if\s+(\w+)\@_(TRUE|FALSE)\@$/) { # $v2 = $1; # $val = $2; # $tf = $3; # prt(" Cond: [$v2] if [$val] [$tf]\n"); # } else { # prt(" Key: $tmp\n"); # } # } # } } 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 # WHY [13|14] 28:1: NO sub FOUND for [$(PRINTF_SUBDIR)] key [PRINTF_SUBDIR] file [glib\Makefile.am] # WHEN [12] 6: Setting key [PRINTF_SUBDIR if HAVE_GOOD_PRINTF@_FALSE@], with value [gnulib] typ 1 # CAUSING: WARNING:1: Substitution DONE [PRINTF_SUBDIR] to [gnulib]. [1] WHY WAS THIS NOT DONE EARLIER? 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 @item_arr = am_macro_split($line,0); my ($item,$key,$nval,$tmp,$done,$cnt,$typ,$fnd,$dncnt,$totcnt); $totcnt = scalar @item_arr; prt("[13] am macro split to $totcnt items [$line]\n") if ($dbg_s13); $cnt = 0; $fnd = 0; my @subs = (); foreach $item (@item_arr) { $dncnt++; prt("[13] $dncnt of $totcnt: item [$item]\n") if ($dbg_s13); $typ = 0; if ($item =~ /^\$\((\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:$item:$key:$nval"); $done = 1; $cnt++; } elsif (defined ${$rcomsubs}{$key}) { # try in the common, which can be user expanded $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:$item:$key:$nval"); $done = 1; $cnt++; } elsif (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:$item:$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:$item:$key:$nval"); $done = 1; $cnt++; } elsif ( 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:$item:$key:$nval"); $done = 1; $cnt++; # } } if (!$done) { prt("[13|14] $i2:$typ: NO sub FOUND for [$item] key [$key] file [$sfil]\n") if ($dbg_s13 || $dbg_s14); #$subs_not_found{$key} = $sfil; if (! defined ${$rsnf}{$key}) { ${$rsnf}{$key} = "$i2:$sfil"; } } } elsif ($item =~ /^\$\{(\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:$item:$key:$nval"); $done = 1; $cnt++; } elsif (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:$item:$key:$nval"); $done = 1; $cnt++; } elsif (defined ${$rglobhash}{$key}) { # try global (known) items $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:$item:$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:$item:$key:$nval"); $done = 1; $cnt++; } elsif ( 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:$item:$key:$nval"); $done = 1; $cnt++; # } } if (!$done) { prt("[13|14] $i2:$typ: NO sub FOUND for [$item] key [$key] file [$sfil]\n") if ($dbg_s13 || $dbg_s14); #$subs_not_found{$key} = $sfil; if (! defined ${$rsnf}{$key}) { ${$rsnf}{$key} = "$i2:$sfil"; } } } elsif ($item =~ /^\@(\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:$item:$key:$nval"); $done = 1; $cnt++; } elsif (defined ${$rcomsubs}{$key}) { # try in the common, which can be user expanded $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:$item:$key:$nval"); $done = 1; $cnt++; } elsif (defined ${$rglobhash}{$key}) { # try global (known) items $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:$item:$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:$item:$key:$nval"); $done = 1; $cnt++; } elsif ( 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:$item:$key:$nval"); $done = 1; $cnt++; # } } if (!$done) { #$subs_not_found{$key} = $sfil; prt("[13|14] $i2:$typ: NO sub FOUND for [$item] 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! [$item]\n"); } } # for each item # ================================================ # done all items 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 my $itm (@subs) { $cnt++; $nval .= " $cnt: [$item]\n"; } pgm_exit(1,"$nval\n"); } } return $line; } sub am_test_for_substitution_VERY_OK_BUT($) { 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, $tmp); 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 = (); # Try do do ALL substitutions # An earlier susbstitution was only by the CONDITION rules, # but here, ANY value found is added, whatever the CONDITION $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; prt("[02]:1: Substitution DONE [$ms] to [$val2]. [$fnd] IGNORING CONDITIONS!\n") if ($dbg_s02); } 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)' $val2 = ''; foreach $ky2 (keys %{$rhash}) { if ($ky2 =~ /^$ms/) { $tmp = trim_all(${$rhash}{$ky2}); if (length($tmp)) { $val2 .= ' ' if (length($val2)); $val2 .= $tmp; } $fnd = 4; } } } if ($fnd > 0) { $val =~ s/\$\($ms\)/$val2/g; prt("[02]:2: Substitution DONE [$ms] to [$val2]. [$fnd] IGNORING CONDITIONS!\n") if ($dbg_s02); } 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/)) { # note: _LIBRARIES = static libraries # and : _LTLIBRARIES = shared libraries push(@libkeys,$key); push(@libs,$val); $ms = "LIBRARIES"; } elsif (($key =~ /_SOURCES/)||($key =~ /_EXTRASOURCES/)||($key =~ /_AUXSOURCES/)) { # note: $(proj)_a_SOURCES - for static libraries .a # and : $(proj)_la_SOURCES - for shared libraries .so 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/)) ) { prt("WARNING: exit_value being set!\n"); ${$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 (($key =~ /_LIBRARIES/)||($key =~ /_LTLIBRARIES/)) { 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) { next if (length($oky) == 0); $ky = $oky; $ky =~ s/-/_/g; $ky =~ s/\./_/g; $ky =~ s/\|//g; $ky = trim_all($ky); next if (length($ky) == 0); if (($ky =~ /\@/)||($ky =~ /\$/)) { prtw("WARNING:1: Skipping a MACRO [$ky], in library [$key]! [$val] CHECK ME!\n"); next; } 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 = (); %dupes = (); # FIX20101028 - CLEAR dupes for EACH LIBRARY # ==================================================================== 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 next if ((length($val) == 0)||($val =~ /^\s+$/)); # FIX20101028 - filter BLANKS $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) { next if (length($oky) == 0); $ky = $oky; $ky =~ s/-/_/g; $ky =~ s/\./_/g; $ky = trim_all($ky); next if (length($ky) == 0); if (($ky =~ /\@/)||($ky =~ /\$/)) { prtw("WARNING:2: Skipping a MACRO [$ky], in program [$key]! [$val] CHECK ME!\n"); next; } $vky = $ky.'_SOURCES'; $fnd = 0; if (defined $$rhash{$vky}) { $val = $$rhash{$vky}; $ky2 = $vky; $fnd = 1; } else { $fnd = 0; foreach $ky2 (keys %{$rhash}) { if (($ky2 =~ /$oky/) && ($ky2 =~ /_SOURCE/)) { $fnd++; } } prtw("WARNING: Found $fnd candidates seeking [$oky]\n") if ($fnd > 1); $fnd = 0; foreach $ky2 (keys %{$rhash}) { if (($ky2 =~ /$oky/) && ($ky2 =~ /_SOURCE/)) { $val = ${$rhash}{$ky2}; $fnd = 2; 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 = 3; 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) { $scnt = scalar @srcs; $val = $srcs[0]; prtw("WARNING: Found $scnt in match for c source (like ".$srcs[1].")! Using [$val]\n") if ($scnt > 1); $ky2 = $oky; $fnd = 4; } } if ($fnd && length($val)) { #@srcs = split(/\s/, $val); @srcs = split(/[\s+\|]/,$val); # SPLIT LIST $scnt = scalar @srcs; @psrcs = (); %dupes = (); # FIX20101028 - Added dupes for EACH PROGRAM # ==================================================================== prt("[03] Filter PROGRAM sources - $scnt... f=$fnd k=$ky2 \n") if ($dbg_s03); for ($i = 0; $i < $scnt; $i++) { $val = $srcs[$i]; next if ((length($val) == 0)||($val =~ /^\s+$/)); # FIX20101028 - filter BLANKS $src = path_u2d($val); next if (defined $dupes{$src}); # FIX20101028 - Avoid dupes for EACH PROGRAM $dupes{$src} = 1; 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; push(@psrcs,$ff); } elsif ($src ne $val) { prt("[18] PRG: Changed src from [$val], to [$src].\n") if ($dbg_s18); $srcs[$i] = $src; push(@psrcs,$src); } } elsif ($src ne $val) { prt("[18] PRG: Changed src from [$val], to [$src].\n") if ($dbg_s18); $srcs[$i] = $src; push(@psrcs,$src); } } $val = join(' ',@psrcs); $scnt = scalar @psrcs; 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 $scnt 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("[03] NOTE: Would scan the $rtcnt TARGETS, if \$supp_make_in was set!\n") if ($dbg_s03); } } 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; } sub add_2_hoh_subs($$$$) { my ($fil,$rparams,$key,$val) = @_; my $rhohsubs = ${$rparams}{'REF_HOH_SUBS'}; if (defined ${$rhohsubs}{$fil}) { if (defined ${$rhohsubs}{$fil}{$key}) { ${$rhohsubs}{$fil}{$key} .= ' '.$val; # if (length($val)); prt("[23] HOH_SUBS: Added VALUE [$fil] [$key] [$val]\n") if ($dbg_s23); } else { ${$rhohsubs}{$fil}{$key} = $val; prt("[23] HOH_SUBS: Set VALUE [$fil] [$key] [$val]\n") if ($dbg_s23); } } else { ${$rhohsubs}{$fil}{$key} = $val; prt("[23] HOH_SUBS: Set NEW [$fil] [$key] [$val]\n") if ($dbg_s23); } } # 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,$first,$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) ) { if ($avoid_adding_macro) { prt("[12] $i2: key [$key] Avoided adding MACRO value [$val] type $first, lev $lev\n") if ($dbg_s12); return 0; } prt("[12] $i2: key [$key] NOTE: Adding MACRO value [$val] type $first, lev $lev\n") if ($dbg_s12); } 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 = ''; } add_2_hoh_subs($sfil,$rparams,$key,$val) if (($key =~ /^SUBDIRS/) && (length($val)) && (!($val =~ /^\s+$/))); # add_2_hoh_subs($sfil,$rparams,$key,$val) if ($key =~ /^SUBDIRS/); $cval = ''; if (defined ${$rhash}{$key}) { $cval = ${$rhash}{$key}; $val = get_only_new_items($cval,$val) if (length($cval)); # try to reduce addition, if poss... if (length($val)) { prtw( "WARNING:1: $i2: hash [$key] exists with [$cval]! Adding [$val]! typ=$first, lev=$lev! file [$sfil]\n" ) if (($first == 1) && length($cval)); # ${$rhash}{$key} .= '|'.$val; if ( length($cval) && !($cval =~ /^\s+$/) ) { ${$rhash}{$key} .= ' '.$val; $tmp = 'Added to'; } else { ${$rhash}{$key} = $val; $tmp = 'Setting2' } } else { $tmp = 'None2Add' } } else { # hmmm, maybe have a key like 'jack_freebob_la_SOURCES if HAVE_ALSA_MIDI@_TRUE@' # double hmmm, if it is like the above, then SHOULD I store it under 'jack_freebob_la_SOURCES' # or if necessary create a NEW key ????? $done = 0; if ($key =~ /\s/) { my @arr = split(/\s/,$key); my $cnt = scalar @arr; $tmp = $arr[0]; if ($cnt >= 3) { if ( defined ${$rhash}{$tmp} ) { $key = $tmp; $cval = ${$rhash}{$key}; $val = get_only_new_items($cval,$val) if (length($cval)); # try to reduce addition, if poss... if (length($val)) { if ( length($cval) && !($cval =~ /^\s+$/) ) { ${$rhash}{$key} .= ' '.$val; $tmp = 'Added (assume TRUE)'; prtw( "WARNING:2: $i2: hash [$key] exists with [$cval]!\n Adding [$val]! typ=$first, lev=$lev! file [$sfil]\n" ) if ($first == 1); } else { ${$rhash}{$key} = $val; $tmp = 'Set to (assume TRUE)'; } } else { $tmp = 'No New to Add'; } $done = 1; } } else { prtw("WARNING: Key [$key] DID NOT SPLIT into 3 or more parts! WHAT IS THIS??\n"); } } if (!$done) { prtw( "WARNING: $i2: hash [$key] DOES NOT EXIST! typ=$first, lev=$lev! file [$sfil]\n" ) if (($first == 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=$first, lev=$lev"; prt("$msg\n"); } return 1; } sub not_same_dirs($$) { my ($d1,$d2) = @_; # like ($ifcond,$curr_srcdir) my $dd1 = uc(path_u2d($d1)); my $dd2 = uc(path_u2d($d2)); $dd1 .= "\\" if ( !($dd1 =~ /\\$/) ); $dd2 .= "\\" if ( !($dd2 =~ /\\$/) ); return 0 if ($dd1 eq $dd2); return 1; } # Process a Makefile.am file sub am_process_AM_file($$) { my ($rparams,$lev) = @_; my ($fil,$pfil); if ($lev > 0) { $fil = ${$rparams}{'AM_FILE_INC'}; $pfil = ${$rparams}{'AM_FILE'}; } else { # level 0 $fil = ${$rparams}{'AM_FILE'}; $pfil = ''; } ### my $ref_progs = ${$rparams}{'REF_PROGRAMS'}; ### my $ref_libs = ${$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 $rcs = ${$rparams}{'CURR_COMMON_SUBS'}; if (($lev == 0) && $set_srcdir_local) { # set 'srcdir' to directory of THIS am file... ${$rcs}{'srcdir'} = $a_dir; } my $curr_srcdir = ${$rcs}{'srcdir'}; my $sfil = sub_root_folder($fil); my ($refhash,$reftarg); $refhash = ${$rparams}{'CURR_REF_HASH'}; $reftarg = ${$rparams}{'AM_FILE_TARGETS'}; my ($ff); my $dooldext = 0; if (!open INF, "<$fil") { prtw( "WARNING: Unable to open $fil ... $! ...\n" ); return $refhash; } my @lns = ; close INF; my $cnt = scalar @lns; ${$rparams}{'TOTAL_LINE_COUNT'} += $cnt; prt("\n") if ($dbg_s07 && $dbg_s08); prt( "[08] AM: 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_LINENUM'} = $i2; #$fline = test_for_substitution($fline,$refhash,$i2,$sfil); $fline = am_test_for_substitution($rparams); if ($fline =~ /$IFEQ_PATTERN/o) { # open an IF $ifcond = $1; @av = split(',',$ifcond); $ifcond = trim_all($av[0]); $acnt = scalar @av; $v = 'TRUE'; if ($acnt > 1) { $v = 'FALSE' if ($ifcond ne $av[1]); } else { $v = 'FALSE' if (not_same_dirs($ifcond,$curr_srcdir)); } $key = $ifcond."\@_".$v."\@"; push(@cond_stack,$key); $scnt = scalar @cond_stack; $msg = ''; prt( "[06] IFEQ:$scnt: Opened cond_stack with [".$cond_stack[$#cond_stack]."] $msg [$sfil]\n" ) if ($dbg_s06); } elsif ($fline =~ /$IFNEQ_PATTERN/o) { # open an IF $ifcond = $1; @av = split(',',$ifcond); $ifcond = trim_all($av[0]); $acnt = scalar @av; $v = 'FALSE'; if ($acnt > 1) { $v = 'TRUE' if ($ifcond ne $av[1]); } else { $v = 'TRUE' if (not_same_dirs($ifcond,$curr_srcdir)); } $key = $ifcond."\@_".$v."\@"; push(@cond_stack,$key); $scnt = scalar @cond_stack; $msg = ''; prt( "[06] IFNEQ:$scnt: Opened cond_stack with [".$cond_stack[$#cond_stack]."] $msg [$sfil]\n" ) if ($dbg_s06); } elsif (($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" ); prt("WARNING: exit_value being set!\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_PATTERN/o) { } elsif (($fline =~ /$INCLUDE_PATTERN/o)||($fline =~ /$INCLUDE_PATTERN2/)) { $key = $1; if ($key =~ /^\w{1}:(.+)$/) { $ff = $key; } else { $ff = $a_dir.$key; } $ff = path_d2u($ff); $ff = fix_rel_path3($ff,'process_AM_file'); $ff =~ s/\\\\/\\/ if ($ff =~ /\\\\/); if ($cairo_special_fix) { # special FIX for cairo project, where this is done in m4 macros if ($ff =~ /Makefile\.am/) { $val = $ff; $val =~ s/Makefile\.am/Makefile\.win32/; if (-f $val) { prt( "[08] cairo_special_fix: CHANGED INCLUDE to file [$val], from [$ff] ...\n" ) if ($dbg_s08); $ff = $val } } } $sff = sub_root_folder($ff); if (-f $ff) { prt( "[08] Processing INCLUDE file [$ff], from [$fil] ...\n" ) if ($dbg_s08); ${$rparams}{'AM_FILE_INC'} = $ff; # set INC file to SCAN $irh = am_process_AM_file($rparams,($lev+1)); prt( "[08] DONE Processing INCLUDE file [$ff], from [$fil] ...\n\n" ) if ($dbg_s08); } else { prtw("WARNING: Unhandled INCLUDE [$key], [$ff] NOT FOUND! in [$sfil] at $i2\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]); } } # FIX20110803 - watch out for # E01 = e01_8.c # e01_2.c e01_3.c e01_4.c e01_5.c e01_6.c e01_7.c if ($val =~ /\#/) { $tmp = $val; $val =~ s/\#.*$//; if ($val =~ /\#/) { pgm_exit(1,"INTERNAL ERROR: Removal of '#...' FAILED!\nline [$fline] val [$val] file: [$fil]\n"); } $val = trim_all($val); prt( "[08] Removed '#' from [$tmp], to [$val], from [$fil]\n" ) if ($dbg_s08); } #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_LINENUM'} = $i2; ${$rparams}{'CURR_KEY'} = $key; ${$rparams}{'CURR_VAL'} = $val; # this can be a BLANK #add_key_value_2_hash($key,$val,$refhash,$i2,$sfil,1); # should NOT exist add_key_value_2_hash($rparams,1,$lev); # should NOT exist } } elsif ($fline =~ /^(\w+)\s*\+=\s*(.+)$/) { $key = $1; $val = $2; if (@cond_stack) { $ifcond = $cond_stack[$#cond_stack]; $key .= ' if '.$ifcond; } # FIX20110803 - watch out for # E01 = e01_8.c # e01_2.c e01_3.c e01_4.c e01_5.c e01_6.c e01_7.c if ($val =~ /\#/) { $val =~ s/\#.*$//; if ($val =~ /\#/) { pgm_exit(1,"INTERNAL ERROR: Removal of '#...' FAILED!\nline [$fline] val [$val] file: [$fil]\n"); } $val = trim_all($val); prt( "[08] +Removed '#' from [$tmp], to [$val], from [$fil]\n" ) if ($dbg_s08); } ${$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,$lev); # 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 ${$reftarg}{$target}) { ##prtw( "WARNING: targets[$target] exists with [".$targets{$target}."]! Adding [$val]!! file=$sfil\n" ); ${$reftarg}{$target} .= "\n\t".$val; $tmp = 'Added to'; } else { ${$reftarg}{$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_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,$lev); # should NOT exist } } else { if ($in_target && length($target)) { if (defined ${$reftarg}{$target}) { ${$reftarg}{$target} .= "\n\t".$fline; } else { ${$reftarg}{$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 = ''; } if ($lev == 0) { # done all the LINES, now play with the HASH collected $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" ); } ${$refhash}{':_AM_FILE_SRC_:'} = $fil; add_2_hoh_subs($fil,$rparams,'SUBDIRS',"."); # ensure a SUBDIRS entry, whether one or not } # 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" ); } 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 } # FIX20110421 - eliminate dupes in a sometimes very long set of libs, and libpaths... sub eliminate_libpath_duplicates($) { my $libs = shift; my @arr = space_split($libs); my $nlibs = ''; my %dupes = (); my ($lib); my %dups =(); my $cnt = 0; foreach $lib (@arr) { if ( !defined $dupes{$lib} ) { $nlibs .= ' ' if (length($nlibs)); $nlibs .= $lib; $dupes{$lib} = 1; } else { $cnt++; if (defined $dups{$lib}) { $dups{$lib}++; } else { $dups{$lib} = 1; } } } if ($dbg_s15 && ($libs ne $nlibs) && $cnt) { my @dup = sort keys(%dups); my $c2 = scalar @dup; prt("[15] eliminate_libpath_duplicates: [".join(' ',@dup)."]$c2, $cnt items REMOVED\n"); } return $nlibs; } # FIX20110421 - eliminate dupes in a sometimes very long set of libs, and libpaths... sub elim_the_lib_path_dupes($$) { my ($rlibR,$rlibD) = @_; # = \$clibR,\$clibD my $libR = eliminate_libpath_duplicates(${$rlibR}); my $libD = eliminate_libpath_duplicates(${$rlibD}); ${$rlibR} = $libR; ${$rlibD} = $libD; } # 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'}; 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}; @arr = split(/\s+/,$val); $val = ''; foreach $itm (@arr) { if (!defined $dupes{$itm}) { $val .= ' ' if (length($val)); $val .= $itm; $dupes{$itm} = 1; } } if ($key =~ /LDADD/) { $fnd++; push(@goodkeys,$key); $nm .= " $val" if (length($val)); } elsif ($key =~ /LIBADD/) { $fnd2++; push(@goodkeys,$key); $nm2 .= " $val" if (length($val)); } elsif ($key =~ /DEPENDENCIES/) { $fnd3++; push(@goodkeys,$key); $nm2 .= " $val" if (length($val)); } } if ($fnd2 || $fnd3) { prt("General for LDADD:$proj_name: Search dependencies...LD=$fnd LIB=$fnd2 DEP=$fnd3 keys[".join(" ",@goodkeys)."]\n [$nm] [$nm2]\n"); prtw("WARNING: Found dependency keys NOT HANDLED!\n"); } else { prt("[15] General for LDADD:$proj_name: Search dependencies...LD=$fnd LIB=$fnd2 DEP=$fnd3 keys[".join(" ",@goodkeys)."]\n [$nm] [$nm2]\n") if ($dbg_s15); } } $fnd = 0; $nm = ''; $nm2 = ''; $libs = ''; %dupes = (); 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,$proj_name); # get_user_libs - get Release my $clibD = $func->(2,$proj_name); # get_user_libs - 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\""; elim_the_lib_path_dupes(\$clibR,\$clibD); # FIX20110421 - eliminate dupes in a sometimes very long set of libs, and libpaths... # 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) { if (is_project_all_excluded($proj_name)) { prt("[15] :$proj_name: Dep keys $fnd found, but no value for this project, but it is EXCLUDED!\n") if ($dbg_s15); } else { prtw("WARNING:$proj_name: Dep keys $fnd found, but no value for this project!\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($$$) { my ($rp,$pn,$pt) = @_; my ($dnm,$rnm,$od,$dstg,$rstg); if (($pt eq 'CA')||($pt eq 'WA')) { # these are EXE outputs to 'bin' $dnm = $pn."D.exe"; $rnm = $pn.".exe"; $od = 'bin'; $rstg = "/out:\"".$od."\\".$rnm."\""; $dstg = "/out:\"".$od."\\".$dnm."\""; } elsif ($pt eq 'SL') { # these are LIB outputs to 'lib' $dnm = $pn."D.lib"; $rnm = $pn.".lib"; $od = 'lib'; $rstg = "/out:\"".$od."\\".$rnm."\""; $dstg = "/out:\"".$od."\\".$dnm."\""; } elsif ($pt eq 'DLL') { # these are DLL outputs to 'bin' $dnm = $pn."D.dll"; $rnm = $pn.".dll"; $od = 'bin'; $rstg = "/out:\"".$od."\\".$rnm."\""; $dstg = "/out:\"".$od."\\".$dnm."\""; # AND LIB outputs to 'lib' $dnm = $pn."D.lib"; $rnm = $pn.".lib"; $od = 'lib'; $rstg .= " /implib:\"".$od."\\".$rnm; $dstg .= " /implib:\"".$od."\\".$dnm; } else { pgm_exit(1,"ERROR: INTERNAL: function 'set_new_user_outs' called with INVALID type [$pt]!\n"); } my $func = sub { my $flag = shift; return $rstg if ($flag & 1); return $dstg; }; 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); } } } sub reprocess_the_lists($) { my ($rparams) = @_; my $auto_on = ${$rparams}{'CURR_AUTO_ON_FLAG'}; # = $auto_on_flag; 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 ($tmp,$key,$val,$proj_name,$msg,$src,@srcs,$cnt,$rhash,$am_file); # check if no conflict of 'name' between LIBRARIES and PROGRAMS prt("\n[24] List of LIBRARIES and PROGRAMS being placed in individual \$rp HASH...\n") if ($dbg_s24); $tmp = scalar keys(%{$rlibs}); prt("[24] LIST of $tmp LIBRARY keys...\n") if ($dbg_s24); $tmp = 0; foreach $key (sort keys %{$rlibs}) { $src = ${$rlibs}{$key}; # get source list $rhash = ${$rolh}{$key}; $am_file = ${$rhash}{':_AM_FILE_SRC_:'}; $msg = " [$key]"; $proj_name = $key; @srcs = split(/\s+/,$src); $cnt = scalar @srcs; if ($auto_on & 2) { # = $auto_on_flag # modifying the library project name - should this be done??? # =========================================================== $proj_name =~ s/(\.|_)la//; if ( !($proj_name =~ /^lib/i) ) { $proj_name = 'lib'.$proj_name; } } $msg .= " [$proj_name]" if ($key ne $proj_name); $msg .= " sources: $cnt"; $msg .= " am [$am_file]"; prt("$msg\n") if ($dbg_s24); foreach $val (keys %{$rprogs}) { if ($key eq $val) { prtw("WARNING: There is a duplication of the name [$key]\n"); $tmp++; } } } $tmp = scalar keys(%{$rprogs}); prt("[24] LIST of $tmp PROGRAM keys...\n") if ($dbg_s24); foreach $key (sort keys %{$rprogs}) { $src = ${$rprogs}{$key}; # get source list $rhash = ${$roph}{$key}; $am_file = ${$rhash}{':_AM_FILE_SRC_:'}; $msg = " [$key]"; $proj_name = $key; @srcs = split(/\s+/,$src); $cnt = scalar @srcs; $msg .= " sources: $cnt"; $msg .= " am [$am_file]"; prt("$msg\n") if ($dbg_s24); } } sub get_anon_proj_hash() { my %project; return \%project; } # 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'}; my ($msg); if (! defined $in_fil) { $msg = "\n sub am_list_to_arrays called with in file ('AM_FILE') NOT defined"; prtw("WARNING: Appears NO Makefile.am files to scan! $msg\n"); # 25/12/2010 - no 'Makefile.am' 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 $auto_on = ${$rparams}{'CURR_AUTO_ON_FLAG'}; # = $auto_on_flag; 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 { prtw("\nWARNING: AM 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; # ==================================================================================== # 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); my ($ff2,$ok2,@arr,$k2,$v2,$am_file); 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,$proj_type,$tmp,$addsrcs); # original HASH of Makefile.am scan my %dupes = (); # avoid source duplications my $rlib_dupes = ${$rparams}{'REF_LIB_DUPES'}; # = \%lib_dupes; my %project_dupes = (); # key is simple file name, contents an array [$ff,$relfile] my @header_scans = (); reprocess_the_lists($rparams); # process LIBRARIES before PROGRAMS - may use this/these libaries in the programs $addsrcs = ''; 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; if ($auto_on & 2) { # = $auto_on_flag # modifying the library project name - should this be done??? # =========================================================== $proj_name =~ s/(\.|_)la//; if ( !($proj_name =~ /^lib/i) ) { $proj_name = 'lib'.$proj_name; } } #my %project = (); #my $rp = \%project; my $rp = get_anon_proj_hash(); my @srcs = (); # GET -T project:type[:source_list] $addsrcs = ''; $proj_type = get_user_proj_type($proj_name,'SL',\$addsrcs); # static library ${$rp}{'PROJECT_TYPE'} = $proj_type; ${$rp}{'PROJECT_NAME'} = $proj_name; # = $key ${$rp}{'PROJECT_USER_LIBS'} = ${$rparams}{'CURR_USER_LIBS'}; # get_user_libs ${$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}; # extract from LIBRARY hash ${$rp}{'PROJECT_AM_RHASH'} = $rhash; # add to PROJECT hash $am_file = ${$rhash}{':_AM_FILE_SRC_:'}; ### show_scalar_ref_hash($rhash); # if the $key made it here with macros, then try to adjust the project name $val = ${$rlibs}{$key}; @av = split(/\s/,$val); $cnt = scalar @av; prt("LIBRARY [$key] $cnt SOURCES [".($dbg_s15 ? $am_file : sub_root_dir($am_file))."]\n"); if ($proj_name =~ /[\@\$\s]/) { prtw("WARNING:L: ***TBD*** Project name contains space, \@ or \$ [$proj_name]! Potential problems?\n"); } if ($auto_on & 2) { # = $auto_on_flag set_new_user_outs($rp,$proj_name,$proj_type); $msg = "Bit: 2: key [$key], pn [$proj_name] [$proj_type] - fetch R:'"; $msg .= ${$rp}{'PROJECT_USER_OUTS'}->(1,$proj_name); $msg .= "' D:'"; $msg .= ${$rp}{'PROJECT_USER_OUTS'}->(2,$proj_name); $msg .= "'"; prt("[15] $msg\n") if ($dbg_s15); if (! defined ${$rlib_dupes}{$proj_name}) { ${$rlib_dupes}{$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); } @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; #} } if (length($addsrcs)) { @av = split(/;/,$addsrcs); $cnt = scalar @av; prt( " [15] LIBRARY: Adding $cnt user defined sources\n") if ($dbg_s15); foreach $fil (@av) { if (!defined $dupes{$fil}) { $dupes{$fil} = 1; $total_sources++; push(@srcs,$fil); $ff = $target_dir.$fil; $ff = fix_rel_path($ff); if (-f $ff) { $ok = "ok"; push(@header_scans,$ff); $project_dupes{$ff} = 1; } else { $ok = "not found [$ff]"; } prt( " [15] [$fil] $ok\n" ) if ($dbg_s15); if (!($ok =~ /^ok/)) { $source_missed++; } } } } $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; } else { prt("Got NO sources for LIBRARY [$key], [$proj_name], but NULL project created\n"); } ${$rp}{'PROJECT_SOURCES'} = \@srcs; # static library source ${$rph}{$key} = $rp; } # process PROGRAMS afer LIBRARIES - may use the libaries in these programs @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; my $rp = get_anon_proj_hash(); $addsrcs = ''; # GET -T project:type[:source_list] $proj_type = get_user_proj_type($proj_name,'CA',\$addsrcs); # console application ${$rp}{'PROJECT_TYPE'} = $proj_type; ${$rp}{'PROJECT_NAME'} = $key; ${$rp}{'PROJECT_USER_LIBS'} = ${$rparams}{'CURR_USER_LIBS'}; # get_user_libs ${$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}; # extract from PROGRAM hash ${$rp}{'PROJECT_AM_RHASH'} = $rhash; # add to PROJECT hash $am_file = ${$rhash}{':_AM_FILE_SRC_:'}; # get AM file name ###show_scalar_ref_hash($rhash); # if the $key made it here with macros, then try to adjust the project name $val = ${$rprogs}{$key}; # get source list @av = split(/\s/,$val); $cnt = scalar @av; prt( "PROGRAM [$key] $cnt SOURCES [".($dbg_s15 ? $am_file : sub_root_dir($am_file))."]\n" ); if ($proj_name =~ /[\@\$\s]/) { prtw("WARNING:P: ***TBD*** Project name contains space, \@ or \$ [$proj_name]! Potential problems?\n"); } if ($auto_on & 2) { # = $auto_on_flag set_new_user_outs($rp,$proj_name,$proj_type); $msg = "Bit: 2: key [$key], pn [$proj_name] [$proj_type] - fetch R:'"; $msg .= ${$rp}{'PROJECT_USER_OUTS'}->(1,$proj_name); $msg .= "' D:'"; $msg .= ${$rp}{'PROJECT_USER_OUTS'}->(2,$proj_name); $msg .= "'"; prt("[15] $msg\n") if ($dbg_s15); } if ($auto_on & 4) { # = $auto_on_flag prt("[15] Bit: 4: Check and add library dependence.\n") if ($dbg_s15); check_for_LDADD($rhash,$rp,$rparams); } @done = (); # clear DONE %dupes = (); # clear source dupes for this project @header_scans = (); # clear to scan list $cnt = scalar @av; prt( "[15] Processing $cnt sources for [$proj_name]...\n") if ($dbg_s15); 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); } } # done the AM file sources - any USER sources to process? if (length($addsrcs)) { @av = split(/;/,$addsrcs); $cnt = scalar @av; prt( " [15] PROGRAM: Adding $cnt user defined sources\n") if ($dbg_s15); foreach $fil (@av) { if (!defined $dupes{$fil}) { $dupes{$fil} = 1; $total_sources++; push(@srcs,$fil); $ff = $target_dir.$fil; $ff = fix_rel_path($ff); if (-f $ff) { $ok = "ok"; push(@header_scans,$ff); $project_dupes{$ff} = 1; } else { $ok = "not found [$ff]"; } prt( " [15] [$fil] $ok\n" ) if ($dbg_s15); if (!($ok =~ /^ok/)) { $source_missed++; } } } } $cnt = scalar @srcs; if ($cnt) { enhance_with_headers($rparams,\@srcs,\@header_scans,\%project_dupes,$rp) if ($auto_on & 32); $cnt = scalar @srcs; # prt("Got $cnt sources for [$key]\n"); } else { prt("Got NO sources for PROGRAM [$key], [$proj_name], but NULL project created\n"); } ${$rp}{'PROJECT_SOURCES'} = \@srcs; # console application source ${$rph}{$key} = $rp; } #$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; } sub am_mycmp_decend { return 1 if (${$a}[0] gt ${$b}[0]); return -1 if (${$a}[0] lt ${$b}[0]); return 0; } sub am_ignored_extent($) { my $fil = shift; return 1 if ($fil =~ /\.html$/); return 1 if ($fil =~ /\.png$/); return 1 if ($fil =~ /\.htm$/); return 1 if ($fil =~ /\.po$/); return 1 if ($fil =~ /\.gmo$/); return 1 if ($fil =~ /\.sgml$/); return 1 if ($fil =~ /\.gif$/); #return 1 if ($fil =~ /\.in$/); return 1 if ($fil =~ /(\\|\/)Makefile$/); return 0; } # 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 $targ_dir = ${$rparams}{'TARGET_DIR'}; # ${$rp}{'PROJECT_TARGET'} = $target_dir; my $mslist = (defined ${$rparams}{'CURR_MISSED_SOURCES'}) ? ${$rparams}{'CURR_MISSED_SOURCES'} : ''; # = $missed_source_list my $msdsp = (defined ${$rparams}{'CURR_MISSED_SRCDSP'}) ? ${$rparams}{'CURR_MISSED_SRCDSP'} : ''; # = $missed_source_dsp 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,$msg); my ($missedC, $missedCE, $missedH, $missedO); my ($snam,$sdir,$rel_path,$rfil,$dmsg,$ndir,$dupe,$ignored); $done = 0; $dupe = 0; $ignored = 0; $missedC = 0; $missedCE = 0; $missedH = 0; $missedO = 0; my @cfil = (); my @cext = (); my @hext = (); my @coth = (); my @ignore = (); my %dupes = (); $msg = ''; $dmsg = ''; $ndir = ''; for ($i = 0; $i < $cnt; $i++) { $fnd = ${$rda}[$i][2]; if ($fnd) { $done++; } else { #$sfil = ${$rda}[$i][0]; $file = ${$rda}[$i][1]; # get FULL FILE if ( defined $dupes{$file} ) { $dupe++; } else { $dupes{$file} = 1; $sfil = sub_root_folder($file); ($snam,$sdir) = fileparse($file); $rel_path = get_rel_dos_path($sdir,$targ_dir); $rfil = $rel_path.$snam; if (is_c_source($sfil)) { $missedC++; push(@cfil,[$file,$rfil,$sdir,$sfil]); } elsif (is_h_source_extended($file)) { $missedH++; push(@hext,[$file,$rfil,$sdir,$sfil]); } elsif (is_c_source_extended($sfil)) { $missedCE++; push(@cext,[$file,$rfil,$sdir,$sfil]); } else { if (($file =~ /\\temp\\/)||(am_ignored_extent($file))) { # these are in the 'temp' folder, or # some html, sg $ignored++; push(@ignore,[$file,$rfil,$sdir,$sfil]); } else { $missedO++; push(@coth,[$file,$rfil,$sdir,$sfil]); } } } } } prt("STATS: DSP files have $done of total $cnt scan, missed $missedC C sources, $missedCE C extended, $missedH HEADER\n files, $missedO OTHERS, $ignored ignored, $dupe dupes...\n"); # 20101014 - add a DSP like output my ($rarr); @cfil = sort am_mycmp_decend @cfil; @hext = sort am_mycmp_decend @hext; @cext = sort am_mycmp_decend @cext; @coth = sort am_mycmp_decend @coth; # ignore ignored output... if ($missedC) { $rarr = \@cfil; prt("[20] Missed $missedC C/C++ ...\n") if ($dbg_s20); $msg .= "\n# Missing $missedC C/C++ sources...\n"; $dmsg .= "\n// Missing $missedC C/C++ sources...\n"; $ndir = ''; for ($i = 0; $i < $missedC; $i++) { $file = ${$rarr}[$i][0]; $rfil = ${$rarr}[$i][1]; $sdir = ${$rarr}[$i][2]; $sfil = ${$rarr}[$i][3]; prt(" Missed C/C++ [$sfil]\n") if ($dbg_s20); $msg .= "$sfil\n"; $dmsg .= "\n// =============================\n// Missing in [$sdir] directory...\n// =============================\n" if ($ndir ne $sdir); $dmsg .= "# Begin Source File\n"; $dmsg .= "\n"; $dmsg .= "SOURCE=".add_dotrel_if_none($rfil)."\n"; $dmsg .= "# End Source File\n"; $ndir = $sdir; } } if ($missedH) { $rarr = \@hext; prt("[20] And $missedH HEADERS...\n") if ($dbg_s20); $msg .= "\n# Missing $missedH headers...\n"; $dmsg .= "\n\n// Missing $missedH headers...\n"; $ndir = ''; for ($i = 0; $i < $missedH; $i++) { $file = ${$rarr}[$i][0]; $rfil = ${$rarr}[$i][1]; $sdir = ${$rarr}[$i][2]; $sfil = ${$rarr}[$i][3]; prt(" Missed Header [$sfil]\n") if ($dbg_s20); $msg .= "$sfil\n"; $dmsg .= "\n// =============================\n// Missing in [$sdir] directory...\n// =============================\n" if ($ndir ne $sdir); $dmsg .= "# Begin Source File\n"; $dmsg .= "\n"; $dmsg .= "SOURCE=".add_dotrel_if_none($rfil)."\n"; $dmsg .= "# End Source File\n"; $ndir = $sdir; } } if ($missedCE) { $rarr = \@cext; prt("[20] And $missedCE Extended...\n") if ($dbg_s20); $msg .= "\n# Missing $missedCE Extended items...\n"; $dmsg .= "\n\n// Missing $missedCE Extended items...\n"; $ndir = ''; for ($i = 0; $i < $missedCE; $i++) { $file = ${$rarr}[$i][0]; $rfil = ${$rarr}[$i][1]; $sdir = ${$rarr}[$i][2]; $sfil = ${$rarr}[$i][3]; prt(" Missed C/C++ extended [$sfil]\n") if ($dbg_s20); $msg .= "$sfil\n"; $dmsg .= "\n// =============================\n// Missing in [$sdir] directory...\n// =============================\n" if ($ndir ne $sdir); $dmsg .= "# Begin Source File\n"; $dmsg .= "\n"; $dmsg .= "SOURCE=".add_dotrel_if_none($rfil)."\n"; $dmsg .= "# End Source File\n"; $ndir = $sdir; } } if ($missedO) { $rarr = \@coth; prt("[20] Plus $missedO OTHERS...\n") if ($dbg_s20); $msg .= "\n# Missing $missedO OTHER items...\n"; $dmsg .= "\n\n// Missing $missedO OTHER items...\n"; $ndir = ''; for ($i = 0; $i < $missedO; $i++) { $file = ${$rarr}[$i][0]; $rfil = ${$rarr}[$i][1]; $sdir = ${$rarr}[$i][2]; $sfil = ${$rarr}[$i][3]; prt(" Missed OTHER [$sfil]\n") if ($dbg_s20); $msg .= "$sfil\n"; $dmsg .= "\n// =============================\n// Missing in [$sdir] directory...\n// =============================\n" if ($ndir ne $sdir); $dmsg .= "# Begin Source File\n"; $dmsg .= "\n"; $dmsg .= "SOURCE=".add_dotrel_if_none($rfil)."\n"; $dmsg .= "# End Source File\n"; $ndir = $sdir; } } # ignore ignored output... but put the count... if ($ignored) { $rarr = \@ignore; prt("[20] Plus $ignored IGNORED, in '\\temp\\' folder, *.png, *.html, *.po, Makefile, etc...\n") if ($dbg_s20); $msg .= "\n# Plus $ignored IGNORED, in '\\temp\\' folder, *.png, *.html, *.po, Makefile, etc...\n"; } prt("Would display 'missing' lists, $missedC, $missedH, $missedCE, 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] file.\n"); } if (length($msdsp) && length($dmsg)) { write2file($dmsg,$msdsp); prt("Written missed source list DSP like [$msdsp] file.\n"); } } 1; # eof - lib_amscam.pl