find_in_inctrail.pl to HTML.

index -|- end

Generated: Sat Oct 12 17:23:00 2013 from find_in_inctrail.pl 2012/06/06 50.8 KB. text copy

#!/perl -w
# NAME: find_in_inctrail.pl
# AIM: Given an in C/C++ file, check for #include "file" and #include <file>
# statements, and follow the trail, listing ALL included files, included ...
# And SEARCH each for a $find text, and advise ...
# 30/05/2012 - Another attempt to improve UI
# 17/03/2012 - some fixes
# 20/07/2011 - add some enhancement
# 02/08/2008 geoff mclane http://geoffair.net/mperl
# 2009-07-08 - minor adjustment, to know who included who...
# 2009/09/16 - massive FIXES - now looks GOOD
###################################################################
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
use File::Spec; # File::Spec->rel2abs($rel); # we are IN the SLN directory, get ABSOLUTE from RELATIVE
use Cwd;
my $os = $^O;
my $perl_dir = '/home/geoff/bin';
my $PATH_SEP = '/';
my $temp_dir = '/tmp';
if ($os =~ /win/i) {
    $perl_dir = 'C:\GTools\perl';
    $temp_dir = $perl_dir;
    $PATH_SEP = "\\";
}
unshift(@INC, $perl_dir);
require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n";
# log file stuff
our ($LF);
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
    my @tmpsp = split(/(\\|\/)/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $outfile = $perl_dir."\\temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.3 2012-05-30";
##my $VERS = "0.0.2 2012-03-17";
my $load_log = 0;

# options
my $show_by_folder = 0;
my $post_process_incs = 1;
my $use_windows_includes = 0;    # to process WIN32 include folders
my $verbosity = 0;
my $win_inc_dbg = 0;
my @warnings = ();

my $in_file = '';
my $find = '';
my $rel_list = '';
#my $rel_list = '.;..\..\..\ffmpeg;..\..\..\mpeg2;..\..\..\a52dec;..\..\..\libdca\include;..\..\..\mp4v2\include;..\..\..\libiconv\include;..\..\..\libsamplerate\src;..\..\..\libdvdnav;..\..\..\libdvdread;..\..\..\lame;..\..\..\faac\include;..\..\..\theora\include;..\..\..\libogg\include;..\..\..\libvorbis\include;..\..\..\x264;..\..\..\libmkv\include;..\..\..\libwinport\include';

my $shown_msvc_incs = 0; # prt("Got $cnt 'MSVC' directories... using vcvarsall.bat\n") if (VERB1());
my $shown_msvc_cnt = 0; # prt("$dir - with $cnt files...\n");

# program variables
my %inc_files_done = ();
my %files_process = ();
my $tmp_env_file = "C:\\DTEMP\\tempenv.txt";
my $show_no_added = 1;
my @findlist = ();
my $fndcnt = 0;

my @included = ();
my $inccount = 0;
my %byfolder = ();
my @foundlst = ();
my $cicnt = 0;
my $i = 0;
my $addcnt = 0;
my $oldcnt = 0;
my $newcnt = 0;
my $diffcnt = 0;
my @added_folder_set = ();

my $done_dir_scans = 0;
my %ref_dir_scans = ();

my ($fin_name, $fin_folder);
my @include_folders = ();
my $incfcnt = 0;

my @missed = ();    # collect the MISSED

sub VERB1() { return $verbosity >= 1; }
sub VERB2() { return $verbosity >= 2; }
sub VERB5() { return $verbosity >= 5; }
sub VERB9() { return $verbosity >= 9; }

my $debug_on = 0;
my $def_file = 'C:\FG\16\apr-dev\apr-1.4.6\include\apr_dso.h';
my $def_find = 'apr_dso_handle_t';
my $def_rel = 'C:\FG\TG2;C:\FG\TG2\terragear-cs\src\Lib;C:\FG\TG2\simgear-cs';

#my $fin_file = 'C:\Projects\hb\HandBrake\libhb\decomb.c';
#my $sln_dir = 'C:\Projects\hb\HandBrake\build\msvc';
#my $find = 'av_log_set_level';
#my $fin_file = 'C:\FG\27\Atlas-04\src\Atlas.cxx';
#my $find = 'INT32';
##my $fin_file = 'C:\Projects\Tidy\tidy4p5\include\tidy.h';
##my $find = 'EXPORT';
###my $find = 'TIDY_STRUCT';

# debug
my $dbg_01 = 0; # show system include search
my $dbg_02 = 0; # show all includes found
my $dbg_03 = 0; # show list of includes found
my $dbg_04 = 0; # show added directories tried

my $dbg1 = 0;   # show all config lines
my $dbg2 = 0;   # show 'Processing ...'
my $dbg3 = 0;   # show expansionss ...
my $dbg4 = 0;   # show vc8 BAT loading ...
my $dbg5 = 0;   # show folder about to be searched
my $dbg6 = 0;   # show INVALID INCLUDE folders ...
my $dbg7 = 0;   # show ALL paths TRIED ...
my $verb3 = 0;   # show sorting
my $dbg8 = 0;   # show "\nGot $lc lines of [$inf] to process ...
my $dbg9 = 0;   # show "$addcnt:$ic $line - $ifil - [$ff] - $msg
my $dbg10 = 0;  # show "Found $ic in [$inf] ...
my $dbg11 = 0;  # show solving relative paths
my $dbg12 = 0;  # prt( "[dbg7|12] For include [$ifil], trying [$ff] LOCAL\n" ) if ($dbg7 | $dbg12);
my $dbg13 = 0;  # prt( "[dbg13] Checking [$rfld] $msg\n" );
my $dbg13a = 0; # prt( "[dbg13] Checking [$cff]\n" ) if ($dbg13a);
my $dbg14 = 0;  # prt( " tried: [$tmp]\n" );
my $dbg15 = 0;  # show the realtive folder set
my $dbg16 = 0;  # prt( "[$dbg16] $lev: Found $fnd more files to process...\n" ) if ($dbg16);

sub show_warnings($) {
    my ($val) = @_;
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
        foreach my $itm (@warnings) {
           prt("$itm\n");
        }
        prt("\n");
    } else {
        #prt( "\nNo warnings issued.\n\n" );
    }
}

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg);
    }
    show_warnings($val);
    close_log($outfile,$load_log);
    exit($val);
}

sub prtw {
    my ($tx) = shift;
    $tx =~ s/\n$//;
    prt("$tx\n");
    push(@warnings,$tx);
}

sub unix_2_dos($) {
   my ($f) = shift;
   $f =~ s/\//\\/g;
   return $f;
}

sub path_per_os($) {
    my $path = shift;
    if ($os =~ /Win/i) {
        $path = path_u2d($path);
    } else {
        $path = path_d2u($path);
    }
    return $path;
}

sub fix_dir_string($) {
    my ($rdir) = @_;
    if (! ( ${$rdir} =~ /(\\|\/)$/) ) {
        ${$rdir} .= $PATH_SEP;
    }
}

########################################################
### DIRECTORY SCANNING ###
sub do_dir_scan($$$);
sub do_dir_scan($$$) {
    my ($rparams,$dir,$lv) = @_;
    my $rda = ${$rparams}{'CURR_DIR_SCAN'};
    $dir = path_per_os($dir);
    fix_dir_string(\$dir);
    my ($file,$ff,$n,$d);
    my @dirs = ();
    prt("Moment, doing full directory scan of [$dir]...\n") if (($lv == 0) && VERB9());
    if (opendir(DIR,$dir)) {
        my @files = readdir(DIR);
        closedir(DIR);
        foreach $file (@files) {
            next if (($file eq '.')||($file eq '..'));
            $ff = $dir.$file;
            if (-d $ff) {
                push(@dirs,$ff);
                next;
            }
            #             0     1   2 3
            push(@{$rda},[$file,$ff,0,0]);
        }
    } else {
        prtw("WARNING: FAILED to OPEN [$dir]\n");
    }
    foreach $file (@dirs) {
        do_dir_scan($rparams,$file,$lv+1);
    }
    if ($lv == 0) {
        $file = scalar @{$rda};
        prt("Done scan... got $file files...\n") if (VERB9());
        ${$rparams}{'CURR_DONE_SCAN'} = 1;
        ${$rparams}{'CURR_FILE_COUNT'} = $file;
    }
}

sub get_anon_hash() {
    my %h = ();
    return \%h;
}

sub get_dir_scan_rh($) {
    my ($dir) = @_;
    my $rparams = get_anon_hash();
    ${$rparams}{'CURR_DONE_SCAN'} = 0;
    ##             0     1   2 3
    #push(@{$rda},[$file,$ff,0,0]);
    ${$rparams}{'CURR_DIR_SCAN'} = [];
    do_dir_scan($rparams,$dir,0);
    return $rparams;
}


sub get_dir_scan_hash($) {
    my ($src) = @_;
    $src = path_per_os($src);
    if (defined $ref_dir_scans{$src}) {
        return $ref_dir_scans{$src};
    }
    $ref_dir_scans{$src} = get_dir_scan_rh($src);
    $done_dir_scans++;
    return $ref_dir_scans{$src};
}

###################################################
sub get_PSDK_directory() {
    my $dir = 'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include';
    return $dir if (-d $dir);
    # 20120529 - Add Win7_-PC platform SDK directory
    $dir = 'C:\Program Files\Microsoft SDKs\Windows\v7.1\include';
    return $dir if (-d $dir);
    prtw("WARNING: Platform SDK directory NOT found! FIX ME!!\n");
    return "";
}

sub is_in_sdk_directory($$) {
    my ($inc,$rff) = @_;
    my $dir = get_PSDK_directory();
    return 0 if (length($dir) == 0);
    fix_dir_string(\$dir);
    my $ff = $dir.$inc;
    if (-f $ff) {
        ${$rff} = $ff;
        return 1;
    }
    return 0;
}

sub same_folder($$) {
   my ($fd1, $fd2) = @_;
   $fd1 = unix_2_dos($fd1);
   $fd2 = unix_2_dos($fd2);
   $fd1 =~ s/\\$//;
   $fd2 =~ s/\\$//;
   my $lfd = length($fd1);
   if ($lfd != length($fd2)) {
      return 0;   # NOT same length
   }
   for (my $k = 0; $k < $lfd; $k++) {
      if (lc(substr($fd1,$k,1)) ne lc(substr($fd2,$k,1))) {
         return 0;   # different
      }
   }
   return 1;   # ARE THE DOS SAME
}


sub is_same_file($$) {
   my ($f1, $f2) = @_;
   my $flen = length($f1);
   if ($flen != length($f2)) {
      return 0;   # not the SAME
   }
   $f1 =~ s/\//\\/g;
   $f2 =~ s/\//\\/g;
   my $lcf1 = lc($f1);
   my $lcf2 = lc($f2);
   my $li = 0;
   while ($li < $flen) {
      if (substr($lcf1,$li,1) ne substr($lcf2,$li,1)) {
         return 0;
      }
      $li++;
   }
   return 1;
}


sub in_this_array($$) {
    my ($f,@a) = @_;
    my $ac = scalar @a;
    ### prt( "Comparing [$f] with $ac others...\n" );
    foreach my $ff (@a) {
        if (is_same_file($f,$ff)) {
            return 1;
        }
    }
    return 0;
}

sub show_all_missed($) {
    my ($rm) = @_;
    my ($k, $ffn, $tmp, $j);
    my $ct = scalar @{$rm};
    if (VERB9()) {
        prt( "Missed finding $ct includes...\n" );
        for ($k = 0; $k < $ct; $k++) {
            $ffn = ${$rm}[$k][0];
            prt( "".($k + 1).": $ffn\n" );
            if ($dbg14) {
                for ($j = 0; ;$j++) {
                    if (defined ${$rm}[$k][$j]) {
                        $tmp = ${$rm}[$k][$j];
                        prt( " tried: [$tmp]\n" );
                    } else {
                        last;
                    }
                }
            }
        }
    } else {
        prt( "Missed finding $ct includes... " );
        my $max = 70;
        $tmp = '';
        for ($k = 0; $k < $ct; $k++) {
            $ffn = ${$rm}[$k][2];
            $tmp .= "[$ffn] ";
            if (length($tmp) > $max) {
                prt("$tmp\n");
                $tmp = '';
                $max = 90;
            }
        }
        prt("$tmp\n") if (length($tmp));
    }
}


sub add_2_included {
   my ($fil, $in) = @_;
   my $lcfil = lc($fil);
   my $cicnt = scalar @included;
   for (my $j = 0; $j < $cicnt; $j++) {
      my $got = $included[$j][0];   # extract full file name
      my $lcgot = lc($got);      # to lower case
      if ($lcfil eq $lcgot) {      # if equal
         my $cin = $included[$j][2];   # get (list) of in
         my @carr = split(/\*/,$cin);   # split list
         my $fnd = 0;   # not found yet
         foreach my $tin (@carr) {   # process each in
            if ($tin eq $in) {
               $fnd = 1;   # found it
               last;
            }
         }
         if (!$fnd) {
            $cin .= '*'.$in;   # append a new 'in'
            $included[$j][2] = $cin;   # store this included in ...
         }
         return 0;            # do NOT add
      }
   }
   $inccount++;
   push(@included, [$fil, $inccount, $in]);
   return 1;
}

sub add_2_found_list {
   my ($inf, $ic, $fls) = @_;
   my ($nm, $dir) = fileparse($inf);
   if ($nm =~ /^pshpack/i) {
      return 0;
   }
   if ($nm =~ /^poppack/i) {
      return 0;
   }
   my $cnt = scalar @foundlst;
   for (my $f = 0; $f < $cnt; $f++) {
      my $ff = $foundlst[$f][1];
      if (is_same_file($inf, $ff)) {
         return 0;
      }
   }
   push(@foundlst, [$ic, $inf, $fls]);
   return 1;
}

# put least first
sub mycmp_ascend {
   if (${$a}[0] < ${$b}[0]) {
      prt( "-[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
      return -1;
   }
   if (${$a}[0] > ${$b}[0]) {
      prt( "+[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
      return 1;
   }
   prt( "=[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
   return 0;
}


sub show_found_list {
   my @sfoundlst = sort mycmp_ascend @foundlst;
   my $cnt = scalar @sfoundlst;
   my $fc = 0;
   my ($f, $ff, $ic, $nm, $dir, $len, $min, $msg, $fs);
   $min = 0;
    prt( "\nOutput list of $cnt headers found starting with $in_file ...\n" );
   for ($f = 0; $f < $cnt; $f++) {
      $ff = $sfoundlst[$f][1];
      ($nm,$dir) = fileparse($ff);
      $len = length($nm);
      $min = $len if ($len > $min);
   }
   $min += 6;
   for ($f = 0; $f < $cnt; $f++) {
      $fs = $sfoundlst[$f][2];
      $ff = $sfoundlst[$f][1];
      $ic = $sfoundlst[$f][0];
      $fc++;
      ($nm,$dir) = fileparse($ff);
      $msg = "$fc";
      $msg = ' '.$msg while (length($msg) < 3);
      $msg .= ": $nm";
      $msg .= ' ' while (length($msg) < $min);
      $msg .= "$ic ";
      $fs =~ s/\*/, /g;
      $msg .= $fs;
      prt( "$msg\n" );
   }
    prt( "Done list of $cnt headers found starting with $in_file ...\n" );
}

sub C_comment_starts {
    my ($txt) = shift;
    my $len = length($txt);
    my $ptxt = '';
    my $ttxt = '';
    my ($k, $ch, $pch, $k2, $nch);
    for ($k = 0; $k < $len; $k++) {
        $k2 = $k + 1;
        $ch = substr($txt,$k,1);
        $nch = (($k2 < $len) ? substr($txt,$k2,1) : '');
        if (($ch eq '/')&&($nch eq '*')) {
            $ttxt = substr($txt,($k2+1));
            return $k2, $ptxt, $ttxt;   # return offset, previous and begin comment
        }
        $pch = $ch;
        $ptxt .= $ch;
    }
    return 0, $ptxt, $ttxt;
}

sub inline_comment_starts {
    my ($txt) = shift;
    my $len = length($txt);
    my $ptxt = '';
    my ($k, $ch, $pch, $k2, $nch);
    for ($k = 0; $k < $len; $k++) {
        $k2 = $k + 1;
        $ch = substr($txt,$k,1);
        $nch = (($k2 < $len) ? substr($txt,$k2,1) : '');
        if (($ch eq '/')&&($nch eq '/')) {
            return $k2, $ptxt;   # return offset, previous
        }
        $pch = $ch;
        $ptxt .= $ch;
    }
    return 0, $ptxt;
}

sub C_comment_ends {
    my ($txt) = shift;
    my $len = length($txt);
    my $ttxt = '';
    my ($k, $ch, $pch, $k2, $nch);
    for ($k = 0; $k < $len; $k++) {
        $k2 = $k + 1;
        $ch = substr($txt,$k,1);
        $nch = (($k2 < $len) ? substr($txt,$k2,1) : '');
        if (($ch eq '*')&&($nch eq '/')) {
            $ttxt = substr($txt,($k2+1));
            return $k2, $ttxt# return trailing 
        }
        $pch = $ch;
    }
    return 0, $ttxt;
}

sub process_file($$$);

sub process_file($$$) {
   my ($inf, $lev, $rmiss) = @_;
    return if (defined $files_process{$inf});
    $files_process{$inf} = 1;
   my $ic = 0;
   my $fils = '';
    my $lnnum = 0;
    my ($isc,$ptxt,$ttxt,$ise,$atxt,$ctxt);
    my $incomm = 0;
    my @incsfound = ();
    my ($nm, $dir, $lc, $msg, $rpt, $tmp, $cnt);
    my ($lbal, $ifil, $rfld, $ff1, $ff2, $add, $ifld, $fnd, $ff);
    $inf = unix_2_dos($inf) if ($os =~ /win/i);
   if (open INF, "<$inf") {
      my @lines = <INF>;
      close INF;
      ($nm, $dir) = fileparse( $inf );
      $lc = scalar @lines;
      prt( "\nGot $lc lines of [$inf] to process ...\n" ) if ($dbg8);
      $msg = '';
      $rpt = 0;
      foreach my $line (@lines) {
            $lnnum++;
         chomp $line;
         $line = trim_all($line);
            if ($incomm) {
                ($ise,$atxt) = C_comment_ends($line);
                if ($ise) {
                    $incomm = 0;
                    $ctxt = trim_all($atxt);
                    if (length($ctxt)) {
                        $line = $ctxt;
                    } else {
                        next;
                    }
                } else {
                    next;
                }
            }
            ($isc,$ptxt,$ttxt) = C_comment_starts($line);
            if ($isc) {
                # C comment starting ...
                ($ise,$atxt) = C_comment_ends($ttxt);
                if ($ise) {
                    $ptxt = trim_all($ptxt);
                    $atxt = trim_all($atxt);
                    $ctxt = $ptxt;
                    $ctxt .= ' ' if (length($ctxt) && length($atxt) && ($atxt ne ';'));
                    $ctxt .= $atxt if length($atxt);
                    $ctxt = trim_all($ctxt);
                    if (length($ctxt)) {
                        $line = $ctxt;
                    } else {
                        next;
                    }
                } else {
                    $incomm = 1;
                    $ptxt = trim_all($ptxt);
                    if (length($ptxt)) {
                        $line = $ptxt;
                    } else {
                        next;
                    }
                }
            } else {
                ($isc,$ptxt) = inline_comment_starts($line);
                if ($isc) {
                    $ctxt = trim_all($ptxt);
                    if (length($ctxt)) {
                        $line = $ctxt;
                    } else {
                        next;
                    }
                }
            }

            if ($line =~ /$find/) {
                push(@findlist, [$lnnum, $line, $inf]);
            }
         if ($line =~ /^#\s*include\s+(.+)\s*/) {
            $ic++;
            $lbal = $1;
            $ifil = '';
            if ($lbal =~ /<(.+)>/) {
               $ifil = $1;
            } elsif ($lbal =~ /"(.*)"/) {
               $ifil = $1;
            }
            if (length($ifil) == 0) {
               prt( "CHECK ME:$lnnum: line[$line] tail[$lbal] ... from $inf ...\n" );
               next;
            }
                $ifil = unix_2_dos($ifil) if ($os =~ /win/i);
                if ($post_process_incs) {
                    push(@incsfound,$ifil);
                $fils .= '*' if (length($fils));
                $fils .= $ifil;
                    next;
                }

            $fnd = 0;
            #$ifil =~ s/<//;
            #$ifil =~ s/>//;
            #$ifil =~ s/"//g;
            $ff = $dir;
            $ff .= $PATH_SEP if !(substr($dir,-1) =~ /(\\|\/)/);
            $ff .= $ifil;
            $fils .= '*' if (length($fils));
            $fils .= $ifil;
            $msg = "FAILED";
            $rpt = 0;
            $msg = (-f $ff) ? "OK" : "FAILED";
            prt( "[dbg7|12] For include [$ifil] in [$nm], trying [$ff] LOCAL [$msg]\n" ) if ($dbg7 | $dbg12);
                my @trials = ();
                push(@trials,$ff) if (!in_this_array($ff,@trials));
            if (-f $ff) {
               $msg = "OK";
               $add = add_2_included( $ff, $inf );
               if ($add) {
                  $msg .= " ADDED";
                  $addcnt++;
                  process_file( $ff, ($lev + 1), $rmiss );
               } else {
                  $msg .= " REPEAT";
                  $rpt = 1;
               }
               $fnd = 1;
            } else {
               # NOT found in LOCAL folder
               foreach $rfld (@added_folder_set) {
                  $ff1 = $dir;
                  $ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
                  $ff1 .= $rfld;
                  $ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
                  $ff1 .= $ifil;
                  $ff1 = fix_rel($ff1);
                  prt( "Trying [$ff1] ADDED\n" ) if ($dbg7 || $dbg_04);
                        push(@trials,$ff1) if (!in_this_array($ff1,@trials));
                  if (-f $ff1) {
                     $ff = $ff1;
                     $msg = "OK";
                     $add = add_2_included( $ff, $inf );
                     if ($add) {
                        $msg .= " ADDED";
                        $addcnt++;
                        process_file( $ff, ($lev + 1), $rmiss );
                     } else {
                        $msg .= " REPEAT";
                        $rpt = 1;
                     }
                     $fnd = 1;
                     last;
                  }
               }
               if (!$fnd) {
                  foreach $ifld (@include_folders) {
                     $ff2 = $ifld;
                     $ff2 .= $PATH_SEP if !(substr($ff2,-1) =~ /(\\|\/)/);
                     $ff2 .= $ifil;
                     prt( "Trying [$ff2] SYSTEM\n" ) if ($dbg7);
                            push(@trials,$ff2) if ( !in_this_array($ff2,@trials));
                     if (-f $ff2) {
                        $ff = $ff2;
                        $msg = "OK";
                        $add = add_2_included( $ff, $inf );
                        if ($add) {
                           $msg .= " ADDED";
                           $addcnt++;
                           process_file( $ff, ($lev + 1), $rmiss );
                        } else {
                           $msg .= " REPEAT";
                           $rpt = 1;
                        }
                        $fnd = 1;
                        last;
                     }
                  }
               }
            }
                if (!$fnd) {
                    ###########################################################
#                    foreach $rfld (@{$rrf}) {
#                        $rfld .= $PATH_SEP if (!($rfld =~ /(\\|\/)$/));
#                        $rfld .= $ifil;
#                    $msg = (-f $rfld) ? "OK" : "FAILED";
#                        prt( "[dbg13] Checking [$rfld] $msg\n" ) if ($dbg13);
#                        push(@trials,$rfld) if ( !in_this_array($rfld,@trials));
#                  if (-f $rfld) {
#                     $ff = $rfld;
#                     $msg = "OK";
#                     $add = add_2_included( $ff, $inf );
#                     if ($add) {
#                        $msg .= " ADDED";
#                        $addcnt++;
#                        process_file( $ff, ($lev + 1), $rm, $rrf );
#                     } else {
#                        $msg .= " REPEAT";
#                        $rpt = 1;
#                     }
#                     $fnd = 1;
#                     last;
#                  }
#                    }
                }
                if (!$fnd) {
                    $cnt = scalar @added_folder_set;
                    if ($cnt) {
                        prt("[04] Checking $cnt added folders...\n") if ($dbg_04);
                        foreach $rfld (@added_folder_set) {
                            $ff1 = $dir;
                            $ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
                            $ff1 .= $rfld;
                            $ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
                            $ff1 .= $ifil;
                            $ff1 = fix_rel($ff1);
                            prt( "[04] Trying [$ff1] ADDED\n" ) if ($dbg7 || $dbg_04);
                            push(@trials,$ff1) if (!in_this_array($ff1,@trials));
                            if (-f $ff1) {
                                $ff = $ff1;
                                $msg = "OK";
                                $add = add_2_included( $ff, $inf );
                                if ($add) {
                                    $msg .= " ADDED";
                                    $addcnt++;
                                    process_file( $ff, ($lev + 1), $rmiss );
                                } else {
                                    $msg .= " REPEAT";
                                    $rpt = 1;
                                }
                                $fnd = 1;
                                last;
                            }
                        }
                    } else {
                        prt("No added user folders to try...\n");
                    }
                }
                if (($fnd == 0) && $use_windows_includes) {
                    prt("[04] Checking [$ifil] in msvc include folders...\n") if ($dbg_04);
                    if (in_msvc_includes2($ifil,\$ff)) { # $ff
                        $msg = 'Found [$ifil] as [$ff]';
                        $add = add_2_included( $ff, $inf );
                        if ($add) {
                            $msg .= " ADDED and processing.";
                            $addcnt++;
                            prt("$msg\n");
                            process_file( $ff, ($lev + 1), $rmiss );
                        } else {
                            $msg .= " REPEAT";
                            $rpt = 1;
                            prt("$msg\n");
                        }
                        $fnd = 9;
                    }
                }
                if (!$fnd) {
                    prt( "[2] FAILED to find [$ff], so trail DEAD!\n" ) if (VERB9());
                    my @nt = ();
                    foreach my $nf (@trials) {
                        if ( !is_same_file($ff,$nf) && !in_this_array($nf,@nt)) {
                            push(@nt,$nf);
                        }
                    }
                    #push(@{$rm}, [$ff, @nt]);
                    $tmp = "[$ifil] in=[$nm] dir=[$dir]";
                    #                1     2    3
                    push(@{$rmiss}, [$tmp, \@nt, $ifil]);
                }
            prt( "$addcnt:$ic $line - $ifil - [$ff] - $msg\n" ) if (!$rpt && $dbg9);
         }
      }   # DONE all the LINES in this file
      prt( "Found $ic in [$inf] ...\n" ) if ($dbg10);
      add_2_found_list( $inf, $ic, $fils );
      prt( "Done $lc lines of [$inf]...\n" ) if ($dbg8);

        if ($post_process_incs && @incsfound) {
            my @files_to_process = ();
            foreach $ifil (@incsfound) {
                next if (defined $inc_files_done{$ifil});
                $inc_files_done{$ifil} = '';
            $fnd = 0;
            #$ifil =~ s/<//;
            #$ifil =~ s/>//;
            #$ifil =~ s/"//g;
            $ff = $dir;
            $ff .= $PATH_SEP if !(substr($dir,-1) =~ /(\\|\/)/);
            $ff .= $ifil;
            #$fils .= '*' if (length($fils));
            #$fils .= $ifil;
            $msg = "FAILED";
            $rpt = 0;
            $msg = (-f $ff) ? "OK" : "FAILED";
            prt( "[dbg7|12] For include [$ifil] in [$nm], trying [$ff] LOCAL [$msg]\n" ) if ($dbg7 | $dbg12);
                my @trials = ();
                push(@trials,$ff) if (!in_this_array($ff,@trials));
            if (-f $ff) {
               $msg = "OK";
               $add = add_2_included( $ff, $inf );
               if ($add) {
                        $inc_files_done{$ifil} = $ff;
                  $msg .= " ADDED";
                  $addcnt++;
                  #process_file( $ff, ($lev + 1), $rm, $rrf );
                        push(@files_to_process,$ff);
               } else {
                  $msg .= " REPEAT";
                  $rpt = 1;
               }
               $fnd = 1;
            } else {
               # NOT found in LOCAL folder
#               foreach $rfld (@rel_folders) {
#                  $ff1 = $dir;
#                  $ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
#                  $ff1 .= $rfld;
#                  $ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
#                  $ff1 .= $ifil;
#                  $ff1 = fix_rel($ff1);
#                  prt( "Trying [$ff1] RELATIVE\n" ) if ($dbg7);
#                        push(@trials,$ff1) if (!in_this_array($ff1,@trials));
#                  if (-f $ff1) {
#                     $ff = $ff1;
#                     $msg = "OK";
#                     $add = add_2_included( $ff, $inf );
#                     if ($add) {
#                        $msg .= " ADDED";
#                        $addcnt++;
#                        # process_file( $ff, ($lev + 1), $rm, $rrf );
#                                push(@files_to_process,$ff);
#                     } else {
#                        $msg .= " REPEAT";
#                        $rpt = 1;
#                     }
#                     $fnd = 1;
#                     last;
#                  }
#               }
               if (!$fnd) {
                  foreach $ifld (@include_folders) {
                     $ff2 = $ifld;
                     $ff2 .= $PATH_SEP if !(substr($ff2,-1) =~ /(\\|\/)/);
                     $ff2 .= $ifil;
                     prt( "Trying [$ff2] SYSTEM\n" ) if ($dbg7);
                            push(@trials,$ff2) if ( !in_this_array($ff2,@trials));
                     if (-f $ff2) {
                        $ff = $ff2;
                        $msg = "OK";
                        $add = add_2_included( $ff, $inf );
                        if ($add) {
                           $msg .= " ADDED";
                           $addcnt++;
                           # process_file( $ff, ($lev + 1), $rm, $rrf );
                                    push(@files_to_process,$ff);
                        } else {
                           $msg .= " REPEAT";
                           $rpt = 1;
                        }
                        $fnd = 1;
                        last;
                     }
                  }
               }
            }
                if (!$fnd) {
                    ###########################################################
#                    foreach my $fldr (@{$rrf}) {
#                        my $cff = $fldr;
#                        prt( "[dbg13] Checking [$cff]\n" ) if ($dbg13a);
#                        $cff .= $PATH_SEP if (!($ff =~ /(\\|\/)$/));
#                        $cff .= $ifil;
#                    $msg = (-f $cff) ? "OK" : "FAILED";
#                        prt( "[dbg13] Checking [$cff] $msg\n" ) if ($dbg13);
#                        push(@trials,$cff) if ( !in_this_array($cff,@trials));
#                  if (-f $cff) {
#                     $ff = $cff;
#                     $msg = "OK";
#                     $add = add_2_included( $ff, $inf );
#                     if ($add) {
#                        $msg .= " ADDED";
#                        $addcnt++;
#                        # process_file( $ff, ($lev + 1), $rm, $rrf );
#                                push(@files_to_process,$ff);
#                     } else {
#                        $msg .= " REPEAT";
#                        $rpt = 1;
#                     }
#                     $fnd = 1;
#                     last;
#                  }
#                    }
                }
                if (!$fnd) {
                    $cnt = scalar @added_folder_set;
                    if ($cnt) {
                        prt("[04] Checking $cnt added folders...\n") if ($dbg_04);
                        foreach $rfld (@added_folder_set) {
                            $ff1 = '';
                            #$ff1 .= $dir;
                            #$ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
                            $ff1 .= $rfld;
                            $ff1 .= $PATH_SEP if !(substr($ff1,-1) =~ /(\\|\/)/);
                            $ff1 .= $ifil;
                            $ff1 = fix_rel($ff1);
                            prt( "[04] Trying [$ff1] IN ADDED\n" ) if ($dbg7 || $dbg_04);
                            push(@trials,$ff1) if (!in_this_array($ff1,@trials));
                            if (-f $ff1) {
                                $ff = $ff1;
                                $msg = "OK";
                                $add = add_2_included( $ff, $inf );
                                if ($add) {
                                    $msg .= " ADDED";
                                    $addcnt++;
                                    $inc_files_done{$ifil} = $ff;
                                    process_file( $ff, ($lev + 1), $rmiss );
                                } else {
                                    $msg .= " REPEAT";
                                    $rpt = 1;
                                }
                                $fnd = 1;
                                last;
                            }
                        }
                    } else {
                        prt("There are NO added folders to try...\n") if ($show_no_added);
                        $show_no_added = 0;
                    }
                }
                if (($fnd == 0) && $use_windows_includes) {
                    prt("[04] Checking [$ifil] in msvc include folders...\n") if ($dbg_04);
                    if (in_msvc_includes2($ifil,\$ff)) { # $ff
                        $msg = "MSVC FOUND [$ifil] as [$ff]";
                        $add = add_2_included( $ff, $inf );
                        if ($add) {
                            $addcnt++;
                            $msg .= " ADDED $addcnt, and processing.";
                            prt("[v9] $msg\n") if (VERB9());
                            $inc_files_done{$ifil} = $ff;
                            process_file( $ff, ($lev + 1), $rmiss );
                        } else {
                            $msg .= " REPEAT";
                            $rpt = 1;
                            prt("[v9] $msg\n") if (VERB9());
                        }
                        $fnd = 9;
                    } elsif (is_in_sdk_directory($ifil,\$ff)) {
                        $msg = "SDK FOUND [$ifil] as [$ff]";
                        $add = add_2_included( $ff, $inf );
                        if ($add) {
                            $addcnt++;
                            $msg .= " ADDED $addcnt, and processing.";
                            prt("[v9] $msg\n") if (VERB9());
                            $inc_files_done{$ifil} = $ff;
                            process_file( $ff, ($lev + 1), $rmiss );
                        } else {
                            $msg .= " REPEAT";
                            $rpt = 1;
                            prt("[v9] $msg\n") if (VERB9());
                        }
                        $fnd = 10;
                    }
                }
                if (!$fnd) {
                    my @nt = ();
                    foreach my $nf (@trials) {
                        if ( !is_same_file($ff,$nf) && !in_this_array($nf,@nt)) {
                            push(@nt,$nf);
                            prt( "[1] FAILED to find [$ifil], so trail DEAD!\n" ) if (VERB9());
                        }
                    }
                    #push(@{$rm}, [$ff, @nt]);
                    $tmp = "[$ifil] in=[$nm] dir=[$dir]";
                    push(@{$rmiss}, [$tmp, \@nt, $ifil]);
                }
            # prt( "$addcnt:$ic $line - $ifil - [$ff] - $msg\n" ) if (!$rpt && $dbg9);
            }
            if (@files_to_process) {
                $fnd = scalar @files_to_process;
                prt( "[$dbg16] $lev: Found $fnd more files to process...\n" ) if ($dbg16);
                foreach $ff (@files_to_process) {
                    process_file( $ff, ($lev + 1), $rmiss );
                }
            }
        } # end if ($post_process_incs && @incsfound) {

   } else {
      prt( "ERROR: Failed to open file [$inf] ...\n" );
   }
}

#####################################################################
######### getting the INCLUDE folders, either from the ENVIRONMENT
######### or from where MSVC8 stroes its stuff

sub load_vc8_cfg {
   my ($vc8c) = shift;
   my @v8_incs = ();
   if (open INF, "<$vc8c") {
      my @clns = <INF>;
      close INF;
      foreach my $cln (@clns) {
         chomp $cln;
         $cln = trim_all($cln);
         prt( "$cln\n" ) if ($dbg1);
         if ($cln =~ /include=\"(.+)\"/i) {
            my $iln = $1;
            my @vc8i = split(';',$iln);
            prt( "INCLUDE=[$iln]\n" ) if ($dbg_01);
            foreach my $itm (@vc8i) {
               push(@v8_incs, $itm);
            }
         }
      }
   } else {
      prt( "WARNING: can not open [$vc8c] ... $! ...\n" );
   }
   return @v8_incs;
}


sub load_vc8_bat {
   my ($vc8b) = shift;
   my @v8_folders = ();
   my @v8_incs = ();
   my %v8_hash = ();
   if (open INB, "<$vc8b") {
      my @lns = <INB>;
      close INB;
      foreach my $ln (@lns) {
         chomp $ln;
         $ln = trim_all($ln);
         if ($ln =~ /\@*SET\s+(.*)/) {
            my @arr = split(/=/,$1);
            my $sz = scalar @arr;
            if ($sz == 2) {
               my $ky = uc($arr[0]);
               my $val = $arr[1];
               $v8_hash{$ky} = $val;
               prt( "[$ky]=[$val]\n" ) if ($dbg4);
               if ($ky =~ /^VCINSTALLDIR$/i) {
                  # got the INSTALL DIECTORY
                  my $vc8_cfg = $val. "\\vcpackages\\vcprojectengine.dll.config";
                  if (-f $vc8_cfg) {
                     @v8_incs = load_vc8_cfg($vc8_cfg);
                  } else {
                     prt( "WARNING: [$vc8_cfg] does not exist ...\n" );
                  }
               }

            } else {
               prt( "SET $1\n" );
            }
         }
      }
      foreach my $item (@v8_incs) {
         # expand
         if ($item =~ /.*\$\((.+)\).+/) {
            my $eit = uc($1);
            prt( "Item [$eit] in [$item] needs expansion ...\n" ) if ($dbg3);
            foreach my $key (keys %v8_hash) {
               if ($key eq $eit) {
                  $item =~ s/\$\($key\)/$v8_hash{$key}\\/i;
                  prt( "New item = [$item] ...\n" ) if ($dbg3);
                  last;
               }
            }
         }
         push(@v8_folders, $item) if (length($item));
      }
   } else {
      prt( "WARNING: No open of [$vc8b] ... $! ...\n" );
   }
   return @v8_folders;
}

# sort of need to RUN 
# %comspec% /k ""C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86
# in ["C:\Program Files\Microsoft Visual Studio 9.0\VC\"]
# Then the ENVIRONMENT is FILLED out with important stuff, like
# ComSpec=C:\Windows\system32\cmd.exe
# DevEnvDir=C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE
# DXSDK_DIR=C:\Program Files\Microsoft DirectX SDK (March 2008)\
# INCLUDE=C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE;C:\Program Files\Microsoft SDKs\Windows\v6.1\include;
# LIB=C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\LIB;C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;C:\Program Files\Microsoft SDKs\Windows\v6.1\lib;
# LIBPATH=Framework32\;Framework32\v2.0.50727;C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\LIB;C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;
sub get_tmp90_txt() {
    my $tmpenvbat = <<EOF;
cd "C:\\Program Files\\Microsoft Visual Studio 9.0\\VC"
call "C:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\vcvarsall.bat" x86
\@echo Done... collecting the environment items...
set > $tmp_env_filee
\@echo All done... return to perl...
EOF
    return $tmpenvbat;
}

sub get_INCLUDE_Folders {
   my ($inf) = shift;   # this is the LOCAL folder
   my @fldrs1 = ();
   my @fldrs2 = ();
   my @fldrs3 = ();
   my @fldrsok = ();
   my $okcnt = 0;
   my $failed = 0;
   my $valcnt = 0;
    my $dupcnt = 0;
    my $is90 = 0;
   my $envstg = $ENV{"INCLUDE"};   # check INLCUDE in environment
    # 20090916 - add 9.0 and 7.1 environments
   my $msvc_env = $ENV{"VS80COMNTOOLS"};
    if (!defined $msvc_env) {
        $msvc_env = $ENV{"VS90COMNTOOLS"};
        if (!defined $msvc_env) {
            $msvc_env = $ENV{"VS71COMNTOOLS"};
            if (!defined $msvc_env) {
                prtw("WARNING: Failed to find MSVC environment variable! CHEKCME!!!\n");
            }
        } else {
            $is90 = 1;
        }
    }
   my $psdk = $ENV{"PSDK_DIR"};
   my $dxsdk = $ENV{"DXSDK_DIR"};   # =C:\Program Files\Microsoft DirectX SDK (October 2006)\
   my $fdr = '';
    if ($is90) {
        my %msvcenv = ();
        unlink $tmp_env_file if (-f $tmp_env_file);
        write2file(get_tmp90_txt(),"C:\\DTEMP\\tempenv.bat");
        system("C:\\Windows\\system32\\cmd.exe /C C:\\DTEMP\\tempenv.bat");
        if (-f $tmp_env_file) {
            my (@lines,$line,$var,$val);
            if (open INF, "<$tmp_env_file") {
                @lines = <INF>;
                foreach $line (@lines) {
                    chomp $line;
                    if ($line =~ /^(\w+)=(.+)$/) {
                        $var = $1;
                        $val = $2;
                        $msvcenv{$var} = $val;
                    } else {
                        prtw("WARNING: HEY: WHAT IS THIS LINE! [$line]???\n");
                    }
                }
            } else {
                prtw("WARNING: Failed to OPEN [$tmp_env_file]...\n");
            }
        } else {
            prtw("WARNING: Failed to write [$tmp_env_file]...\n");
        }
        if (!defined $envstg) {
            if (defined $msvcenv{'INCLUDE'}) {
                $envstg = $msvcenv{'INCLUDE'};
            }
        }
    }
   if (defined $envstg) {
      @fldrs1 = split(';',$envstg);
   } else {
      prt( "INLCUDE NOT found in environment ...\n" ) if ($dbg_01);
   }
   if (defined $msvc_env) {
      # we have MSVC8
      my $vc8_bat = $msvc_env . "vsvars32.bat";
      if (-f $vc8_bat) {
         push(@fldrs2, load_vc8_bat($vc8_bat));
      } else {
         prt( "WARNING: [$vc8_bat] not found ...\n" );
      }
   }
   if (defined $psdk) {
      push(@fldrs3,$psdk);
   } else {
      prt( "PSDK_DIR NOT found in environment ...\n" );
   }
   if (defined $dxsdk) {
      push(@fldrs3,$dxsdk);
   } else {
      prt( "DXSDK_DIR NOT found in environment ...\n" );
   }
   foreach $fdr (@fldrs1) {
      if (-d $fdr) {
         push(@fldrsok, $fdr) if (!same_folder($fdr,$inf));
         prt( "VALID [$fdr] ...\n" );
         $valcnt++;
      } else {
         prt( "Discarding [$fdr] as INVALID ...\n" ) if ($dbg6);
         $failed++;
      }
   }
   foreach $fdr (@fldrs2) {
      if (-d $fdr) {
         push(@fldrsok, $fdr) if (!same_folder($fdr,$inf));
         prt( "VALID [$fdr] ...\n" );
         $valcnt++;
      } else {
         prt( "Discarding [$fdr] as INVALID ...\n" ) if ($dbg6);
         $failed++;
      }
   }
   foreach $fdr (@fldrs3) {
      if (-d $fdr) {
            if (!in_this_array($fdr,@fldrsok) && !same_folder($fdr,$inf)) {
             push(@fldrsok, $fdr);
             prt( "VALID [$fdr] ...\n" );
             $valcnt++;
            } else {
                $dupcnt++;
            }
      } else {
         prt( "Discarding [$fdr] as INVALID ...\n" ) if ($dbg6);
         $failed++;
      }
   }
   $okcnt = scalar @fldrsok;
   prt( "Found $okcnt ($valcnt) folders, $dupcnt duplicates, and $failed failed ...\n" );
   return @fldrsok;
}

#####################################################################

# fix relative path
sub fix_rel { # fixed 26/12/2007 to remove '\\' entries
   my ($path) = shift;
   $path = unix_2_dos($path);   # ensure DOS separator
   my @a = split(/\\/, $path);   # split on DOS separator
   my $npath = '';
   my $max = scalar @a;
   my @na = ();
   for (my $i = 0; $i < $max; $i++) {
      my $p = $a[$i];
      if ($p eq '.') {
         # ignore this
      } elsif ($p eq '..') {
         if (@na) {
            pop @na;   # discard previous
         } else {
            prtw("WARNING: Got relative .. without previous!!! [$path]");
         }
      } elsif (length($p)) {   # added 26/12/2007
         push(@na,$p);
      }
   }
   foreach my $pt (@na) {
      $npath .= $PATH_SEP if length($npath);
      $npath .= $pt;
   }
   return $npath;
}


sub get_relative_dirs($$$) {
    my ($inf,$slnd,$rrelf) = @_;
   my ($nm, $dir, $ext) = fileparse( $inf, qr/\.[^.]*/ );  # get the SOURCE directory
    my ($np,$ct,$rdp,$ct2);
    $slnd .= $PATH_SEP if (!($slnd =~ /(\\|\/)$/));
    $rdp = get_rel_dos_path($dir,$slnd);
    prt( "[dbg11] Target is \n[$dir] from \n[$slnd] use\n[$rdp]\n" ) if ($dbg11);
    my %h = ();
    $ct = 0;
    foreach $nm (@{$rrelf}) {
        $ext = $slnd.$nm;
        $np = fix_rel($ext);
        prt("[dbg11] From [$ext] to [$np]\n") if ($dbg11);
        $h{$np} = 1;
        $ct++;
    }
    my @a = keys(%h);
    $ct2 = scalar @a;
    prt( "Returning $ct2 search paths...($ct)\n"if ($dbg11);
    return \@a;
}

sub show_rel_fold_set($) {
    my ($rf) = @_;
    prt( "[dbg15] Showing ".(scalar @{$rf})." relative folders...\n" );
    foreach my $f (@{$rf}) {
        prt("$f\n");
    }
}

sub get_msvc_includes() {
    my ($insdir);
    my @vc8 = ();
    my %dirs = ();
    my $cnt = 0;
    my %h = ();
    $h{'*CURR_TOTAL_CNT*'} = 0;
    if (vc_get_include_dirs2(\$insdir,$win_inc_dbg) ) {
        $cnt = scalar @{$insdir};
        # prt("OK got $cnt\n");
        my $rd = \%dirs;
        my ($dir,$min,$len);
        $cnt = 0;
        $min = 0;
        foreach $dir (@{$insdir}) {
            if (-d $dir) {
                # if ( add_to_files_lc($dir,$rd) ) # check NOT duplicate
                if (defined ${$rd}{$dir}) {
                    # already in LIST
                } else {
                    push(@vc8,$dir);
                    $cnt++;
                    ${$rd}{$dir} = $cnt;
                    $len = length($dir);
                    $min = $len if ($len > $min);
                }
            }
        }
        if (@vc8) {
            $cnt = scalar @vc8;
            prt("Got $cnt 'MSVC' directories... using vcvarsall.bat\n") if (VERB1() && !$shown_msvc_incs );
            $shown_msvc_incs = 1;
            $min = 0;
            foreach $dir (@vc8) {
                $len = length($dir);
                $min = $len if ($len > $min);
            }
            foreach $dir (@vc8) {
                # my $rh = get_dir_scan_rh($dir);
                my $rh = get_dir_scan_hash($dir);
                $h{$dir} = $rh;
                $cnt = ${$rh}{'CURR_FILE_COUNT'};
                $h{'*CURR_TOTAL_CNT*'} += $cnt;
                if (VERB9() && !$shown_msvc_cnt) {
                    $dir .= " " while (length($dir) < $min);
                    prt("$dir - with $cnt files...\n");
                    $shown_msvc_cnt = 1;
                }
            }
        }
    } else {
        prt("Failed to get include directories!\n");
    }
    $h{'*MSVC_DIR_LIST*'} = \@vc8# array list of KEYS to directory scan hash
    return \%h;
}

my %msvc_checked = ();

sub in_msvc_includes2($$) {
    my ($inc,$rff) = @_;
    my ($ra,$dir,$ff);
    if (defined $msvc_checked{$inc}) {
        $ff = $msvc_checked{$inc};
        if (length($ff)) {
            ${$rff} = $ff;
            return 1;
        }
        return 0;
    }
    if (vc_get_include_dirs2(\$ra,0) ) {
        foreach $dir (@{$ra}) {
            fix_dir_string(\$dir);
            $ff = $dir.$inc;
            ###prt("Checking for [$ff] ");
            if (-f $ff) {
                ${$rff} = $ff;
                ###prt("Found [$inc] [$ff]\n");
                $msvc_checked{$inc} = $ff;
                return 1;
            }
            #prt("Check for [$ff] FAILED!\n");
        }
    }
    $msvc_checked{$inc} = '';
    return 0;
}

sub in_msvc_includes($) {
    my ($inc) = @_;
    my $rh = get_msvc_includes();
    # my $rdsh = get_dir_scan_rh($dir);
    # stored $h{$dir} = $rdsh;
    my $tcnt = ${$rh}{'*CURR_TOTAL_CNT*'};
    my $rkya = ${$rh}{'*MSVC_DIR_LIST*'};  # array list of KEYS to directory scan hash
    my ($key,$fil,$dir,$cnt);
    my ($i,$fn,$ff,$lcfn);
    my $lcinc = path_per_os($inc); # file name to OS form
    $lcinc = lc($lcinc) if ($os =~ /Win/i); #all lower case in WIN32
    foreach $key (@{$rkya}) {
        if (defined ${$rh}{$key}) {
            my $rka = ${$rh}{$key}; # list of files in this directory
            #my $rda = ${$rparams}{'CURR_DIR_SCAN'};
            #${$rparams}{'CURR_DONE_SCAN'} = 1;
            $cnt = ${$rka}{'CURR_FILE_COUNT'};
            my $rda = ${$rka}{'CURR_DIR_SCAN'};
            $cnt = scalar @{$rda};  # should equal CURR_FILE_COUNT
            $dir = path_per_os($key);
            fix_dir_string(\$dir);
            for ($i = 0; $i < $cnt; $i++) {
                $fn = ${$rda}[$i][0];  # get FILE name
                $lcfn = lc($fn);
                $ff = $dir.$inc;
                if ($lcfn eq $lcinc) {
                    return 1;
                } elsif ( -f $ff ) {
                    return 2;
                }
            }
        }
    }
    return 0;
}


#########################################################################
### main

parse_args(@ARGV);

($fin_name, $fin_folder) = fileparse($in_file);
#if ($use_windows_includes) {
#    @include_folders = get_INCLUDE_Folders($fin_folder);
#    $incfcnt = scalar @include_folders;
#    prt( "Got $incfcnt INCLUDE folders ...\n" ) if ($dbg_01);
#}

# 1 - get list of 'search PATHS
my @list = split(";",$rel_list);
push(@added_folder_set, @list);
#my $rrf = get_relative_dirs($in_file,$sln_dir,\@rel_folder_set);
#show_rel_fold_set($rrf) if ($dbg15);

process_file($in_file, 0, \@missed);
$cicnt = scalar @included;
prt( "\nGot TOTAL $cicnt includes from [$in_file] ...\n" );
for ($i = 0; $i < $cicnt; $i++) {
   my $f = $included[$i][0];
   my $ord = $included[$i][1];
    if (-f $f) {
       prt( "$ord $f - ok\n" ) if ($dbg_02);
    } else {
        prt( "$ord $f - NOT FOUND\n" );
    }
   my ($nam, $dir) = fileparse($f);
   if (defined $byfolder{$dir}) {
      $byfolder{$dir} .= '*'.$nam;
   } else {
      $byfolder{$dir} .= $nam;
   }
}
$fndcnt = scalar @findlist;
if ($fndcnt) {
    prt( "\nFOUND [$find] $fndcnt times, start with [$in_file]...\n" );
    # push(@findlist, [$lnnum, $line, $inf]);
    for ($i = 0; $i < $fndcnt; $i++) {
        prt( $findlist[$i][2].":".$findlist[$i][0].": [".$findlist[$i][1]."]\n" );
    }
    prt( "DONE FIND of [$find] $fndcnt times...\n" );
} else {
    prt( "NO FINDS of $find, start with $in_file ...\n" );
}

if ($show_by_folder) {
   prt( "\nBY FOLDER - TOTAL $cicnt includes from [$in_file] ...\n" );
   foreach my $dir (sort (keys(%byfolder))) {
      my $fnms = $byfolder{$dir};
      my @nms = split(/\*/,$fnms);
      my @nmss = sort @nms;
      prt( "$dir - ".scalar @nms." headers ...\n" );
      prt( join(", ", @nmss)."\n"if ($dbg_03);
   }
   show_found_list() if ($dbg_03);
}

if (@missed) {
    show_all_missed(\@missed);
}

pgm_exit(0,"");

###################################################

sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have following argument!\n") if (!@av);
}

sub load_folders_from_file($) {
    my $file = shift;
    if (!open INF, "<$file") {
        pgm_exit(1,"ERROR: Can NOT open the input file [$file]\n");
    }
    my @lines = <INF>;
    close INF;
    my $line = '';
    foreach $line (@lines) {
        chomp $line;
        $line = trim_all($line);
        next if (length($line) == 0);
        next if ($line =~ /^\#/);
        next if ($line =~ /^;/);
        push(@added_folder_set,$line);
        prt("Added [$line] to INCLUDE folder to search.\n") if (VERB1());
    }
}

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg,$cnt);
    $cnt = 0;
    while (@av) {
        $arg = $av[0];
        if ($arg =~ /^-/) {
            $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /^-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^l/) {
                $load_log = 1;
                prt("Set to load log at end.\n") if (VERB1());
            } elsif ($sarg =~ /^i/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                if ($sarg =~ /^@/) {
                    $sarg = substr($sarg,1);
                    if (-f $sarg) {
                        load_folders_from_file($sarg);
                    } else {
                        pgm_exit(1,"ERROR: Invalid input file [$sarg]! Does NOT exist\n");
                    }
                } else {
                    if (-d $sarg) {
                        push(@added_folder_set,$sarg);
                        prt("Added [$sarg] to INCLUDE folder to search.\n") if (VERB1());
                    } else {
                        pgm_exit(1,"ERROR: Invalid INCLUDE directory [$sarg]! Does NOT exist\n");
                    }
                }
            } elsif ($sarg =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                prt("Verbosity = $verbosity\n") if (VERB1());
            } elsif ($sarg =~ /^w/) {
                $use_windows_includes = 1;
                prt("Set to include 'windows' system folders.\n") if (VERB1());
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            if ($cnt == 0) {
                $find = $arg;
                prt("Set find to [$find]\n");
            } elsif ($cnt == 1) {
                $in_file = File::Spec->rel2abs($arg);
                prt("Set input to [$in_file]\n");
            } else {
                pgm_exit(1,"ERROR: Only 2 bare items allowed. 1: item to find 2: file to find in\n");
            }
            $cnt++;
        }
        shift @av;
    }

    if ((length($in_file) ==  0) && $debug_on) {
        $in_file = $def_file;
        $load_log = 1;
        ##$rel_list = $def_rel;
        $use_windows_includes = 1;
        #$win_inc_dbg = 0x200;   # -1;
        #$verbosity = 9;
    }
    if ((length($find) == 0) && $debug_on) {
        $find = $def_find;
    }
    if (length($find) ==  0) {
        pgm_exit(1,"ERROR: No find item found in command!\n");
    }
    if (length($in_file) ==  0) {
        pgm_exit(1,"ERROR: No input files found in command!\n");
    }
    if (! -f $in_file) {
        pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n");
    }
}

sub give_help {
    prt("$pgmname: version $VERS\n");
    prt("Usage: $pgmname [options] item-to-find in-file\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --inc dir     (-i) = Search this INCLUDE directory for includes. (\@inp also accepted)\n");
    prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    prt(" --windows     (-w) = Also search the 'windows' system include folders.\n");
    prt("AIM: Given an item-to-find, and an input file, search for the 'item-to-find'\n");
    prt("     in the input file, and then search any #include (\"|<)files(\"|>)\n");
    prt("     That is follow the include trail searching for a 'word'...\n");
}

# eof - find_in_inctrail.pl

index -|- top

checked by tidy  Valid HTML 4.01 Transitional