chkcmake02.pl to HTML.

index -|- end

Generated: Sat Oct 24 16:35:11 2020 from chkcmake02.pl 2016/10/15 47 KB. text copy

#!/usr/bin/perl -w
# NAME: chkcmake02.pl
# AIM: Original used to develop lib_cmakeread.pl, but later extended to tyr to find 
# and show an error in cmake syntax
# 2016-10-07 - A review
# 2014-04-02 - Some improvements
# 02/05/2012 - Looking quite smooth ;=))
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
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";
require 'lib_cmakeread.pl' or die "Unable to load 'lib_cmakeread.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 = $temp_dir.$PATH_SEP."temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.7 2016-10-07"; # review
# $VERS = "0.0.6 2014-01-18"; # start to reduce noisy debug output
# $VERS = "0.0.5 2012-05-02"; # using/developing lib_cmakeread.pl
# $VERS = "0.0.4 2012-04-26";  # load ALL 'CMakeModule' in advance, it it EXISTS
# $VERS = "0.0.3 2012-04-22";
# $VERS = "0.0.2 2012-01-29";
# $VERS = "0.0.1 2011-10-25";
my $inc_all_cmake = 0; # 26/04/2012 - If there exists a folder 'CMakeModules' load ALL from here...
my $load_log = 0;   # 1=notepad(np), 2=editplus(ep)
my $load_cmake_inst = 0;    # process the cmake installation folders of ALL *.cmake found
my $test_curr_file = 0; # see below for INPUT selected
my $do_test_case = 0;   # do ONLY specific canned test, written to test.cmake file...

my $tmp_cmake = $temp_dir.$PATH_SEP."temp.cmake.txt";
my $temp_cmake = $temp_dir.$PATH_SEP."tempcmake.cmake";

my $dump_cmake_file = 1;    # DUMP cleaned lines to a debug file dump_cmake()
my $load_dump_file = 0;     # load text in editor after writing file

# options for dump output
# -------------------------
my $add_line_nums = 1;
my $add_if_depth = 1;
my $add_uctag = 1;
my $add_skipped_lines = 0;
my $add_foreach_depth = 1;
my $add_macro_depth = 1;
my $add_tag_action = 0;     # duplicate the file line '$tag($act'\)'
# -------------------------

my $set_rh_debug = 0;       # set ALL debug flags ON
my $set_if_debug = 0;
my $set_set_debug = 0;
my $set_list_debug = 0;
my $set_list_debug2 = 0;
my $set_macro_debug = 0;    # ${$rh}{'show_macro_dbg'}
my $add_foreach_debug = 0;  # DEBUG FOREACH - but problem found
my $set_per_line_debug = 0;
my $set_processing_debug = 1;
my $set_processing_debug2 = 0;
my $set_processing_debug3 = 0;

my $show_if_actions = 1;    # output IF actions at END
my $show_set_items = 0;
my $show_list_items = 0;
my $write_directive_list = 0;
my $show_macro_items = 0;
my $show_function_items = 0;
my $show_if_items = 0;

# specific lines
my $test_cmake_line1 = 0;
my $test_cmake_line2 = 0;
my $test_cmake_line3 = 0;
my $test_cmake_line4 = 0;

my $debug_level_proc = 0;   # have defined 0x100 | 0x200 | 0x400;
my $debug_level_load = $debug_level_proc;

my $input_file = '';
my @in_files = ();
my $def_file1 = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\AddFileDependencies.cmake';
my $def_file2 = 'C:\FGCVS\flightgear\source\CMakeLists.txt';
my $def_file3 = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindHDF5.cmake';
my $def_file4 = 'C:\FGCVS\flightgear\source\CMakeModules\FlightGearComponent.cmake';
my $def_file5 = 'C:\FGCVS\flightgear\source\CMakeModules\FindSimGear.cmake';
my $def_file6 = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake';
my $def_file7 = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeDetermineCXXCompiler.cmake';
my $def_file8 = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeVerifyManifest.cmake';
my $def_file9 = 'C:\FGCVS\cmake\CMakeLists.txt';
#my $in_file = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCUDA\run_nvcc.cmake';
#my $in_file = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPack.cmake';
#my $in_file = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCUDA\run_nvcc.cmake';
#my $in_file = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindFLTK.cmake';
#my $in_file = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Platform\Windows-cl.cmake';
my @test_files = ( "$def_file1", "$def_file2", "$def_file3" );

if ($test_curr_file) {
    #$input_file = $def_file9;
    push(@in_files,$def_file2);
    push(@in_files,$def_file9);
    #push(@in_files,$def_file2);
}

my $chk_line1 = 'STRING(REGEX REPLACE "\\\\\\\\" "/" FLTK_DIR_SEARCH1 "$ENV{PATH}")';
my $chk_line2 = 'string(REPLACE "\\"" "\\\\\\"" arg ${arg})';
my $chk_line3 = 'string(REPLACE "\\\\\\\\\\\\\\\\\\"" "\\"\\\\\"" "\\"\\\\\\\\\\\\\"" arg ${arg})';
my $chk_line4 = 'string(REPLACE "\\"\\\\\\\\\\\\\\"" "\\"" arg ${arg})';

###my $in_file = '';
my $verbosity = 0;
my $debug_on = 0;
my $def_file = 'def_file';
my $out_xml = '';

### program variables
my @warnings = ();
my $cwd = cwd();
my ($ref_hash);
my @libs = ();
my @exes = ();

sub get_curr_ref_hash() { return $ref_hash; }

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

sub show_warnings($) {
    my ($val) = @_;
    if (@warnings) {
        my %dupes = ();
        my $cnt = scalar @warnings;
        prt( "\nShowing, up to $cnt WARNINGS...\n" );
        $cnt = 0;
        foreach my $itm (@warnings) {
            if (!defined $dupes{$itm}) {
                $dupes{$itm} = 1;
                prt("$itm\n");
                $cnt++;
            }
        }
        prt("Shown $cnt WARNINGS...\n");
    } else {
        prt( "\nNo warnings issued.\n\n" ) if (VERB9());
    }
}

sub get_proj_0($) {
    my $ra = shift;
    my ($ra2);
    my $projs = '';
    foreach $ra2 (@{$ra}) {
        $projs .= "," if (length($projs));
        $projs .= ${$ra2}[0];
    }
    return $projs;
}

sub get_proj_lines($) {
    my $ra = shift;
    my ($ra2,$proj);
    my $lines = '';
    my $cnt = scalar @{$ra};
    my $maxlen = 0;
    my $len = 0;
    foreach $ra2 (@{$ra}) {
        $proj = ${$ra2}[0];
        $len = length($proj);
        $maxlen = $len if ($len > $maxlen);
    }
    foreach $ra2 (@{$ra}) {
        $proj = ${$ra2}[0];
        $proj .= ' ' while (length($proj) < $maxlen);

        $lines .= $proj;
        $lines .= " ";
        $lines .= ${$ra2}[1];
        $lines .= "\n";
    }
    return $lines;
}


sub close_dump() {
    my $rh = get_curr_ref_hash();
    my ($msg);
    my $lcnt = scalar @libs;
    my $ecnt = scalar @exes;
    if (!defined ${$rh}{'CURR_DUMP_HANDLE'}) {
        return;
    }
    prt("Found $lcnt LIBS, and $ecnt EXES\n");
    if (VERB5()) {
        $msg = get_proj_lines(\@libs);
        prt("\nLIBS:$lcnt:\n$msg") if ($lcnt);
        $msg = get_proj_lines(\@exes);
        prt("\nEXES:$ecnt:\n$msg") if ($ecnt);
    } elsif (VERB1()) {
        $msg = get_proj_0(\@libs);
        prt("LIBS:$lcnt: $msg\n") if ($lcnt);
        $msg = get_proj_0(\@exes);
        prt("EXES:$ecnt: $msg\n") if ($ecnt);
    }
    my $fh = ${$rh}{'CURR_DUMP_HANDLE'};
    my $df = ${$rh}{'CURR_DUMP_NAME'};
    print $fh "# End of DUMP $df\n";
    close $fh;
    prt("Written DUMP to [$df]\n");

    system($df) if ($load_dump_file);
}

sub split_act_to_proj_srcs($$$$) {
    my ($act,$rp,$rs,$lib) = @_;
    $act =~ s/\(//g;
    $act =~ s/\)//g;
    $act = trim_all($act);
    my @arr = split(/\s+/,$act);
    my $acnt = scalar @arr;
    my $i = 1;
    ${$rp} = $arr[0];
    my $srcs = '';
    if ($lib && ($acnt > 1)) {
        $srcs = $arr[$i];
        if ($srcs =~ /^STATIC$/i) {
            ##${$rp} .= " STATIC";
            $i++;
        } elsif ($srcs =~ /^SHARED$/) {
            ${$rp} .= " SHARED";
            $i++;
        }
    }
    $srcs = '';
    for (; $i < $acnt; $i++) {
        $srcs .= ',' if (length($srcs));
        $srcs .= $arr[$i];
    }
    ${$rs} = $srcs;
    return $acnt;
}


# if ($dump_cmake_file) - dump cleaned lines to a debug file
sub dump_cmake($) {
    my $rh = shift;
    my ($fh);
    my ($rcln,$line,$clnn,$tag,$tdep);
    if (!defined ${$rh}{'CURR_DUMP_HANDLE'}) {
        if ( !open($fh,">$tmp_cmake") ) {   # open the TEMP DUMP file
            pgm_exit(1,"ERROR: Unable to OPEN dump [$tmp_cmake]\n");
        }
        ${$rh}{'CURR_DUMP_HANDLE'} = $fh;
        ${$rh}{'CURR_DUMP_NAME'} = $tmp_cmake;
        $line = "# Dianostic DUMP file created: ";
        $line .= lu_get_YYYYMMDD_hhmmss(time());
        print $fh "$line\n"
    }
    $fh = ${$rh}{'CURR_DUMP_HANDLE'};
    my $ara  = ${$rh}{"ACT_RA"};
    my $acnt = ${$rh}{"ACT_CNT"};    # = scalar @arr;
    my $rclines = ${$rh}{"CLEAN_LINES"};
    my $cnt = scalar @{$rclines};
    my $bfile = ${$rh}{'BASE_FILE'};
    $line = "\nContents of [$bfile] $cnt 'cleaned' lines";
      print $fh "$line\n";
    $rcln = ${$rclines}[-1];
    my $lnn = ${$rcln}[3];
    my $frm = sprintf("%d",length($lnn));
    $frm = '%'.$frm.'d';
    my $idep = 0;
    my $ind = '';
    my $isif = 0;
    my $pdep = 0;
    my $plnn = 1;
    my $endln = 0;
    my $fedep = 0;
    my $isfe = 0;
    my $pfedep = 0;
    my $comm = '';
    my $cind = "\t";
    my $mcdep = 0;
    my $pmcdep = 0;
    my $ismac = 0;
    my $act = '';
    my $msg = '';
    my ($proj,$srcs);
    foreach $rcln (@{$rclines}) {
        #                  0     1      2       3      4
        #push(@{$rclines},[$line,$ucdir,$action,$bgnln,$endln]);
        $line = ${$rcln}[0];
        $tag = ${$rcln}[1];
        $act = ${$rcln}[2];
        $lnn = ${$rcln}[3];
        $endln = ${$rcln}[4];
        $ind = '';
        $isif = 0;
        if ($add_uctag) {
            $comm = " # $tag $lnn:$endln";
        }
        if ($add_if_depth) {
            if ($tag eq 'IF') {
                $pdep = $idep;
                $idep++;
                $isif = 1;
            } elsif ($tag eq 'ENDIF') {
                $idep-- if ($idep > 0);
                $pdep = $idep;
                $isif = 1;
            } elsif ($tag eq 'ELSE') {
                $isif = 2;
            } elsif ($tag eq 'ELSEIF') {
                $isif = 3;
            }
            #if ($isif) {
            #    $ind = ' ' x $pdep;
            #} else {
            #    $ind = ' ' x $idep;
            #}
        }
        $isfe = 0;
        if ($add_foreach_depth) {
            if ($tag eq 'FOREACH') {
                $isfe = 1;
                $pfedep = $fedep;
                $fedep++;
            } elsif ($tag eq 'ENDFOREACH') {
                $isfe = 1;
                $fedep-- if ($fedep);
                $pfedep = $fedep;
            }
        }
        # $add_macro_depth
        $ismac = 0;
        if ($add_macro_depth) {
            if ($tag eq 'MACRO') {
                $ismac = 1;
                $pmcdep = $mcdep;
                $mcdep++;
            } elsif ($tag eq 'ENDMACRO') {
                $ismac = 1;
                $mcdep-- if ($mcdep);
                $pmcdep = $mcdep;
            }
        }

        if ($add_if_depth || $add_foreach_depth || $add_macro_depth) {
            $tdep = 0;
            if ($isif) {
                $tdep += $pdep;
            } else {
                $tdep += $idep;
            }
            if ($isfe) {
                $tdep += $pfedep;
            } else {
                $tdep += $fedep;
            }
            if ($ismac) {
                $tdep += $pmcdep;
            } else {
                $tdep += $mcdep;
            }
            $ind = $cind x $tdep;
        }

        # collect the INFORMATION
        $msg = '';
        if ($add_skipped_lines) {
            while ($plnn < $lnn) {
                if ($add_line_nums) {
                    $clnn = sprintf($frm,$plnn);
                    $msg .= "$clnn: # skipped\n";
                } else {
                    $msg .= "# skipped\n";
                }
                $plnn++;
            }
        }
        if ($add_line_nums) {
            $clnn = sprintf($frm,$lnn);
            $msg .= "$clnn: $ind$line$comm\n";
            if ($add_tag_action) {
                $msg .= "$clnn: $ind$tag$act\n";
            }
        } else {
            $msg .= "$ind$line$comm\n";
            if ($add_tag_action) {
                $msg .= "$ind$tag$act\n";
            }
        }

        if ($add_skipped_lines) {
            while ($lnn < $endln) {
                $lnn++;
                if ($add_line_nums) {
                    $clnn = sprintf($frm,$lnn);
                    $msg .= "$clnn:\n";
                } else {
                    $msg .= "\n";
                }
            }
        }
        if ($tag =~ /add_executable/i) {
            #prt("$line\n");
            #prt("EXE $act\n");
            split_act_to_proj_srcs($act,\$proj,\$srcs,0);
            prt("EXE $proj: $srcs\n") if (VERB9());
            push(@exes,[$proj,$srcs,$rh]);
        } elsif ($tag =~ /add_library/i) {
            #prt("$line\n");
            #prt("LIB $act\n");
            split_act_to_proj_srcs($act,\$proj,\$srcs,1);
            prt("LIB $proj: $srcs\n") if (VERB9());
            push(@libs,[$proj,$srcs,$rh]);
        }
        # output of the INFORMATION
        # ============================================
        print $fh $msg;
        # ============================================
        $plnn = $lnn + 1;   # update line number
    }
    $line = "# eof - from [$bfile]";
      print $fh "$line\n";
}


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


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

# =================================================
# enventual LIBRARY functions
# =================================================

sub get_cmake_install_paths_ra() {
    my $envstg = $ENV{"PATH"};
    my ($path,$up,@arr,$ver,$tmp,$cnt);
    my @paths = ();
    #prt("ENV(PATH) = $envstg\n");
    @arr = split(";",$envstg);
    $cnt = scalar @arr;
    #prt("Got $cnt paths to test...\n");
    foreach $path (@arr) {
        #prt("Testing [$path]\n");
        next if (length($path) == 0);
        if ($path =~ /CMake/i) {
            $path =~ s/(\\|\/)bin$//i;
            $ver = '';
            if (-d $path) {
                #$up = path_d2u($path);
                $up = path_u2d($path);
                prt("Adding path [$up]\n");
                @arr = split(/(\/|\\)+/,$up);
                foreach $tmp (@arr) {
                    if ($tmp =~ /cmake/i) {
                        $ver = $tmp;
                        last;
                    }
                }
                push(@paths,[$up,$ver]);
            } else {
                prtw("WARNING: Not a valid DIRECTORY! [$path]\n");
            }
        } else {
            # prt("Not 'CMake' related!\n");
        }
    }
    return \@paths;
}

sub scan_cmake_path($$);
sub scan_cmake_path($$) {
    my ($path,$rh) = @_;
    # my @installed_files = ();
    # ${$rh}{'CMAKE_INSTALLED_FILES'} = \@installed_files;
    my $rif = ${$rh}{'CMAKE_INSTALLED_FILES'};
    my @dirs = ();
    if (opendir(DIR,$path)) {
        my @files = readdir(DIR);
        closedir(DIR);
        my ($file,$ff);
        cmake_fix_directory(\$path);
        foreach $file (@files) {
            next if (($file eq '.')||($file eq '..'));
            $ff = $path.$file;
            if (-l $ff) {
                # ignore links
            } elsif (-d $ff) {
                push(@dirs,$ff);
            } elsif (-f $ff) {
                if ($file =~ /\.cmake$/i) {
                    #prt("adding file [$ff]\n");
                    push(@{$rif},$ff);
                }
            } else {
                prtw("WARNING: Unable to find file [$ff]!\n");
            }
        }
        foreach $path (@dirs) {
            scan_cmake_path($path,$rh);
        }
    } else {
        prtw("WARNING: Unable to open directory [$path]!\n");
    }
}

my $common_cmake_directory = '';
sub get_cmake_common_directory($) {
    my $fil1 = shift;
    my $fil2 = $common_cmake_directory;
    my $len1 = length($fil1);
    my $len2 = length($fil2);
    if ($len2) {
        my $comm = '';
        my ($i,$ch1,$ch2);
        for ($i = 0; (($i < $len1) && ($i < $len2)); $i++) {
            $ch1 = substr($fil1,$i,1);
            $ch2 = substr($fil2,$i,1);
            last if ($ch1 ne $ch2);
            $comm .= $ch1;
        }
        $common_cmake_directory = $comm;
    } else {
        $common_cmake_directory = $fil1 if ($len1);
    }
}

sub scan_cmake_install_paths($) {
    my $rh = shift;
    if (!defined ${$rh}{'CMAKE_INSTALLED_FILES'}) {
        pgm_exit(1,"ERROR: Ref has passed does not define 'CMAKE_INSTALLED_FILES'!\n");
    }
    my ($i,$path,$ver);
    my $rval = 0;
    my $rp = get_cmake_install_paths_ra();
    my $cnt = scalar @{$rp};
    if ($cnt) {
        for ($i = 0; $i < $cnt; $i++) {
            $path = ${$rp}[$i][0];
            scan_cmake_path($path,$rh);
        }
        my $rif = ${$rh}{'CMAKE_INSTALLED_FILES'};
        foreach $path (@{$rif}) {
            get_cmake_common_directory($path);
        }
        ${$rh}{'CMAKE_INSTALLED_PATH'} = $common_cmake_directory;
    } else {
        prtw("WARNING: Found NO Cmake install paths!\n");
        $rval = 1;
    }
    return $rval;
}


# =================================================

sub is_a_loaded_macro($$$$) {
    my ($tag,$rh,$rargs,$rmacro) = @_;
    my $dbg_flag = get_cmake_dbg_flag($rh);
    my $iret = 0;
    my $rmh = ${$rh}{'CMAKE_MACROS'};
    # if (defined ${$rma}{$mac}) {
    #                  0     1
    # ${$rma}{$mac} = [$args,$macro];
    my $min = 0;
    my $max = 32;
    my ($mac,$len,$rma,$args,$macro);
    my @arr = keys(%{$rmh});
    my $cnt = scalar @arr;
    # prt("\nDisplay of $cnt MACROS collected...\n");
    foreach $mac (@arr) {
        $rma = ${$rmh}{$mac};
        $args = ${$rma}[0];
        $macro = ${$rma}[1];
        #prt("$mac $args [$macro}\n");
        if ($tag eq uc($mac)) {
            $iret = 1;
            ${$rargs} = $args;
            ${$rmacro} = $macro;
            last;
        }
    }
    #if ($tag eq 'ADD_CMAKEONLY_TEST') {
    #    if ($iret) {
    #        prtw("WARNING: MACRO [$tag] NOT PROCESSED, FOUND in\n[".join(" ",sort @arr)."]!\n");
    #    } else {
    #        prtw("WARNING: MACRO [$tag] NOT FOUND in\n[".join(" ",sort @arr)."]????\n");
    #    }
    #}
    return $iret;
}

sub clean_cmake_action($) {
    my $act = shift;
    $act =~ s/^\(//;
    $act =~ s/\)$//;
    #$act = trim_all($act);
    return $act;
}

sub cmake_clean_action($) {
    my $act = shift;
    $act =~ s/^\(//;
    $act =~ s/\)$//;
    $act = trim_all($act);
    # 04/05/2012 CAN NOT DO THIS - consider the case of mutiple tokens, like
    # "${VAR}" MATCHES "this" - has quote begin and end. BUT MUST NOT BE REMOVED
    #if (($act =~ /^\"/) && ($act =~ /\"$/)) {
    #   $act = substr($act,1,length($act)-2);   # if ($act =~ /^".*"$/);
    #    $act = trim_all($act);
    #}
    return $act;
}


sub process_clean_ref_array($) {    # was process_cmake_script($)
    my $rh = shift;
    if (!defined ${$rh}{'BASE_FILE'}) {
        pgm_exit(1,"ERROR: Ref hash does NOT define 'BASE_FILE'!\n");
    }
    my $bfile = ${$rh}{'BASE_FILE'};
    if (!defined ${$rh}{"CLEAN_LINES"}) {
        prtw("WARNING: No 'CLEAN_LINES' in ref hash. No [$bfile] processing!\n");
        return 1;
    }
    my $rclines = ${$rh}{"CLEAN_LINES"};
    my $csrc   = ${$rh}{'CURR_LINE_SOURCE'};
    my $cnt = scalar @{$rclines};
    my $dbg_flag = 0;
    if (defined ${$rh}{'CURR_DBG_FLAG'}) {
        $dbg_flag = ${$rh}{'CURR_DBG_FLAG'};
    } else {
        ${$rh}{'CURR_DBG_FLAG'} = $debug_level_proc;
    }
    my $src = $bfile;
    my $dbg = 0;
    if ($csrc eq $bfile) {
        $dbg = ${$rh}{'show_process_dbg'};
    } else {
        # prt("\n") if ($dbg_flag & 0x100);;
        $src = $csrc;
        $dbg = ${$rh}{'show_process_dbg2'};
    }
    prt("[d100] Processing $cnt lines, from [$src]...\n") if (($dbg_flag & 0x100) && $dbg);
    #                   0     1    2       3    4
    # push(@{$rclines},[$line,$tag,$action,$bln,$eln]);
    my ($i,$line,$tag,$action,$func,$bln,$eln,$act,@arr,$tmp,$args,$macro);
    ${$rh}{"ACT_LCNT"} = $cnt# lines to process

    for ($i = 0; $i < $cnt; $i++) {
        $line = ${$rclines}[$i][0];
        next if ($line =~ /^\@/);   # skip these for now '@something@
        $tag = ${$rclines}[$i][1];
        $action = ${$rclines}[$i][2];
        $bln = ${$rclines}[$i][3];
        $eln = ${$rclines}[$i][4];
        $act = cmake_clean_action($action);
        #$act = clean_cmake_action($action);
        @arr = space_split($act);
        ${$rh}{"ACT_TAG"} = $tag;
        ${$rh}{"ACT_ACT"} = $act;
        ${$rh}{"ACT_RA"}  = \@arr;
        ${$rh}{"ACT_LNN"} = $bln;
        ${$rh}{"ACT_LNN"} .= ":$eln" if ($bln != $eln);
        ${$rh}{"ACT_LINE"} = $line;
        ${$rh}{"ACT_CNT"} = scalar @arr;
        ${$rh}{'ACT_I'} = $i; # current line position
        prt("[d80] $bln:$eln: $line\n") if (${$rh}{'per_line_dbg'});
        if (is_a_loaded_macro($tag,$rh,\$args,\$macro)) {
            prt("[d100] Run MACRO NOT YET CODED! [$tag $args \n[$macro]]\n") if (($dbg_flag & 0x100) && ${$rh}{'show_macro_dbg'});
        } elsif (is_a_known_directive($tag)) {
            $tmp = join(" ",@arr);
            #if ($tag eq 'LIST') {
            #    prt("[d200] Processing DIRECTIVE [$tag] $i of $cnt ($action) ($tmp) $bln:$eln [$src]\n") if ($dbg_flag & 0x200);
            #}
            $func = get_directive_function($tag);
            # =======================================
            $func->($rh); # CALL THE FUNCTION HANDLER
            # =======================================
            $i = ${$rh}{'ACT_I'}; # potentially updated line position
            ###prt("[d400] Done DIRECTIVE [$tag] $i of $cnt\n") if ($dbg_flag & 0x400);
        } else {
            my $rdirh = ${$rh}{'new_directives_found'};   # process_clean_ref_array; was process_cmake_script: adding to \%directives if NOT FOUND
            if (defined ${$rdirh}{$tag}) {
                ${$rdirh}{$tag}++;
                ${$rh}{'warnings_avoided'}++;
            } else {
                ${$rdirh}{$tag} = 1;
                prtw("WARNING: [$tag] is NOT a known directive, nor loaded MACRO act [$action] [$bfile]$bln:$eln\n");
            }
        }

    }

}

sub process_cmake_file($) {
    my $rh = shift;
    my $dbg_flag = get_cmake_dbg_flag($rh);
    my $ff = ${$rh}{'BASE_FILE'};  # $test_file;
    my $rflh = ${$rh}{'CMAKE_FILES_LOADED'};    # process_cmake_file: = \%cmake_files_loaded;
    if (defined ${$rflh}{$ff}) {
        # already loaded - silently forget it
        return;
    }
    ${$rflh}{$ff} = 1;
    my $fcnt = scalar keys(%{$rflh});
    if (load_cmake_script_file($rh)) {
        prtw("WARNING: process_cmake_file: Failed to load [$ff]\n");
    } else {
        my $rclines = ${$rh}{"CLEAN_LINES"};
        my $rcnt = ${$rh}{"ACT_LCNT"};
        my $cnt = scalar @{$rclines};
        prt("$fcnt: process_cmake_file: [$ff] ok, $cnt of $rcnt lines\n") if (${$rh}{'show_process_dbg3'});
        if ($cnt) {
            dump_cmake($rh) if ($dump_cmake_file);
            ${$rh}{'CURR_DBG_FLAG'} = $debug_level_proc;
            process_clean_ref_array($rh);   # was process_cmake_script($rh);  # from  process_cmake_file
        }
        ### prt("process_cmake_file: done [$ff]\n") if (${$rh}{'show_process_dbg'});
    }
}

sub process_in_file($$) {
    my ($ff,$rh) = @_;
    ${$rh}{'BASE_FILE'} = $ff# $test_file;
    ${$rh}{'CURR_LINE_SOURCE'} = $ff;   # set FILE source
    ${$rh}{'CURR_DBG_FLAG'} = -1 if (!defined ${$rh}{'CURR_DBG_FLAG'});
    process_cmake_file($rh);
}

sub process_test_file($$) {
    my ($ff,$rh) = @_;
    ${$rh}{'BASE_FILE'} = $ff;
    ${$rh}{'CURR_LINE_SOURCE'} = $ff;   # set FILE source
    ${$rh}{'CURR_DBG_FLAG'} = -1 if (!defined ${$rh}{'CURR_DBG_FLAG'});
    process_cmake_file($rh);
}

sub test_load_installed_cmake($) {
    my $rh = shift;
    my @a = ();
    my $svdebug = 0;
    $svdebug = ${$rh}{'CURR_DBG_FLAG'} if (defined ${$rh}{'CURR_DBG_FLAG'});
    # set the DEBUG for the INSTALL LOAD
    my $dbg_flag = -1;
    $dbg_flag &= ~(0x8000);
    $dbg_flag = 0;
    $dbg_flag |= 0x100;
    ${$rh}{'CMAKE_INSTALLED_FILES'} = \@a;
    ${$rh}{'CURR_DBG_FLAG'} = $dbg_flag;
    scan_cmake_install_paths($rh);
    my $rif = ${$rh}{'CMAKE_INSTALLED_FILES'};
    my $cnt = scalar @{$rif};
    prt("Got $cnt files to load...\n");
    my ($ff);
    my ($dir,$i,$ch);
    foreach $ff (@{$rif}) {
        process_in_file($ff,$rh);
    }
    my $rmh = ${$rh}{'CMAKE_MACROS'};
    my $mcnt = scalar keys(%{$rmh});
    my $rfh = ${$rh}{'CMAKE_FUNCTIONS'};
    my $fcnt = scalar keys(%{$rfh});

    prt("Done loading $cnt files... $cnt dirs, $mcnt macs, $fcnt funcs\n");
    $dir = ${$rh}{'CMAKE_INSTALLED_PATH'};
    prt("Common cmake 'install' directory [$dir]\n");
    ${$rh}{'CURR_DBG_FLAG'} = $svdebug;
}

sub do_cmake_subdirectories($) {
    my $rh = shift;
    my $dbg_flag = get_cmake_dbg_flag($rh);
    # ADD_SUBDIRECTORY
    # my %subdirs = ();
    # ${$rh}{'CMAKE_SUBDIRS'} = \%subdirs;
    #my %subs_done = ();
    # ${$rh}{'CMAKE_SUBSDONE'} = \%subs_done;
    my $rsh = ${$rh}{'CMAKE_SUBDIRS'};
    my $rsd = ${$rh}{'CMAKE_SUBSDONE'};
    my $max  = scalar keys(%{$rsh});
    my $done = scalar keys(%{$rsd});
    my ($i,$sd,$todo,$rsa,$key,$ff);
    while ($max != $done) {
        $todo = $max - $done;
        prt("[d100] ADD_SUBDIRECTORIES: Now loading $todo files from subdirectories added...\n")
            if (($dbg_flag & 0x100) && ${$rh}{'show_addsub_dbg'});
        #for ($i = 0; $i < $max; $i++) {
        foreach $key (keys %{$rsh}) {
            $rsa = ${$rsh}{$key};
            # push(@{$rsubs},[$item1,$ff]);
            #$sd = ${$rsa}[$i][0];
            #$ff = ${$rsa}[$i][1];
            $sd = ${$rsa}[0];
            $ff = ${$rsa}[1];
            if (!defined ${$rsd}{$ff}) {
                ${$rsd}{$ff} = 1;
                ###process_in_file($ff,$rh);
                process_test_file($ff,$rh);
            }
        }
        $max  = scalar keys(%{$rsh});
        $done = scalar keys(%{$rsd});
    }
}


sub test_lines($) {
    my $rh = shift;
    #my $chk_line1 = 'STRING(REGEX REPLACE "\\\\" "/" FLTK_DIR_SEARCH1 "$ENV{PATH}")';
    #my $chk_line2 = 'string(REPLACE "\"" "\\\"" arg ${arg})';
    my @arr = ();
    ${$rh}{'BASE_FILE'} = "TEST LINES";
    ${$rh}{'CURR_DBG_FLAG'} = -1;
    ${$rh}{"BASE_LINES"} = \@arr;
    if ($test_cmake_line1) {
        @arr = ();
        push(@arr,$chk_line1);
        ${$rh}{'BASE_FILE'} = "TEST LINE 1";
        process_cmake_raw_lines($rh);
    }
    if ($test_cmake_line2) {
        @arr = ();
        push(@arr,$chk_line2);
        ${$rh}{'BASE_FILE'} = "TEST LINE 2";
        process_cmake_raw_lines($rh);
    }
    if ($test_cmake_line3) {
        @arr = ();
        push(@arr,$chk_line3);
        ${$rh}{'BASE_FILE'} = "TEST LINE 3";
        process_cmake_raw_lines($rh);
    }
    if ($test_cmake_line4) {
        @arr = ();
        push(@arr,$chk_line4);
        ${$rh}{'BASE_FILE'} = "TEST LINE 4";
        process_cmake_raw_lines($rh);
    }
}

# $rih = ${$rh}{'CMAKE_SETMACROS'};
sub list_set_items($) {
    my $rh = shift;
    my $rih = ${$rh}{'CMAKE_SETMACROS'};
    my @arr = keys(%{$rih});
    my $cnt = scalar @arr;
    my ($set,$rsi,$val,$min,$len,$max);
    $min = 0;
    $max = 32;
    foreach $set (@arr) {
        $len = length($set);
        $min = $len if ($len > $min);
        last if ($min > $max);
    }
    $min = $max if ($min > $max);
    prt("\nDisplay of $cnt SET items, and their value...\n");
    foreach $set (sort @arr) {
        $rsi = ${$rih}{$set};
        $val = join(" ",@{$rsi});
        $set .= ' ' while (length($set) < $min);
        prt("$set = [$val]\n");
    }
    prt("Done display of $cnt SET items, and their value...\n");
}

# $rli = ${$rh}{'CMAKE_LISTS'};
sub list_list_items($) {
    my $rh = shift;
    my $rih = ${$rh}{'CMAKE_LISTS'};
    my @arr = keys(%{$rih});
    my $cnt = scalar @arr;
    my ($set,$rsi,$val,$min,$len,$max);
    $min = 0;
    $max = 32;
    foreach $set (@arr) {
        $len = length($set);
        $min = $len if ($len > $min);
        last if ($min > $max);
    }
    prt("\nDisplay of $cnt LIST items, and their value...\n");
    foreach $set (sort @arr) {
        $rsi = ${$rih}{$set};
        $val = join(" ",@{$rsi});
        $set .= ' ' while (length($set) < $min);
        prt("$set = [$val]\n");
    }
    prt("Done display of $cnt LIST items, and their value...\n");
}

sub get_body() {
    my $txt = <<EOF;
    my \$rh = shift;
    my \$dbg_flag = get_cmake_dbg_flag(\$rh);
    my \$bfile = \${\$rh}{'BASE_FILE'};
    my \$lnn = \${\$rh}{"ACT_LNN"};
    my \$tag = \${\$rh}{"ACT_TAG"};
    my \$act = \${\$rh}{"ACT_ACT"};
    my \$ra  = \${\$rh}{"ACT_RA"};
    my \$cnt = \${\$rh}{"ACT_CNT"};    # = scalar \@arr;
EOF
    return $txt;
}

sub list_directives($) {
    my $rh = shift;
    my ($dir,$tmp,$line,$msg,@arr,$cnt);
    my $rdirh = ${$rh}{'new_directives_found'};   # = \%directives;
    @arr = keys(%{$rdirh});
    $cnt = scalar @arr;
    if ($cnt == 0) {
        return;
    }
    my $outdirs = $temp_dir.$PATH_SEP."temp.directives.txt";
    my $loadfil = 'C:\GTools\perl\lib_cmakeread.pl';
    my %subs_found = ();
    my $body = get_body();
    my $min = 32;
    if (open INF, "<$loadfil") {    # open 'C:\GTools\perl\lib_cmakeread.pl
        my @lines = <INF>;
        close INF;
        foreach $line (@lines) {
            if ($line =~ /^sub\s+fn_(\w+)\W/) {
                $tmp = $1;
                $subs_found{$tmp} = 1;
            }
        }
    }
    @arr = keys(%subs_found);
    $cnt = scalar @arr;
    prt("Found $cnt existing directive subs...\n");

    $msg = '';
    @arr = keys(%{$rdirh});
    $cnt = scalar @arr;
    prt("Collected $cnt directives...\n");
    foreach $dir (sort @arr) {
        if (!defined $subs_found{$dir}) {
            $msg .= "sub fn_$dir {\n$body\n}\n";
        }
    }
    $msg .="\nmy \%directive_hash = (";
    foreach $dir (sort @arr) {
        $line = " '$dir' ";
        $line .= " " while (length($line) < $min);
        $tmp = "fn_$dir";
        $msg .= "\n $line=> \\\&$tmp,";
    }
    $msg =~ s/,$//g;
    $msg .= "\n);\n";
    write2file($msg,$outdirs);
    prt("Written directives hash to [$outdirs]\n");
}

sub list_macro_items($) { # if ($show_macro_items);
    my $rh = shift;
    my $rmh = ${$rh}{'CMAKE_MACROS'};
    # if (defined ${$rma}{$mac}) {
    #                  0     1
    # ${$rma}{$mac} = [$args,$macro];
    my $min = 0;
    my $max = 32;
    my ($mac,$len,$rma,$args,$macro);
    my @arr = sort keys(%{$rmh});
    my $cnt = scalar @arr;
    prt("\nDisplay of $cnt MACROS collected...\n");
    foreach $mac (@arr) {
        $rma = ${$rmh}{$mac};
        $args = ${$rma}[0];
        $macro = ${$rma}[1];
        prt("$mac $args [$macro}\n");
    }
    prt("\nDone display of $cnt MACROS collected...\n");
}
sub list_function_items($) { # if ($show_function_items);
    my $rh = shift;
}

sub set_specific_debug($) {
    my $rh = shift;
    ${$rh}{'CURR_DBG_FLAG'} = $debug_level_load;
    set_rh_debug_flags($rh,1) if ($set_rh_debug);
    set_foreach_debug_flags($rh,1) if ($add_foreach_debug);

    ${$rh}{'show_if_diags'} = 1 if ($set_if_debug);
    ${$rh}{'show_list_dbg'} = 1 if ($set_list_debug);
    ${$rh}{'show_list_dbg2'} = 1 if ($set_list_debug2);
    ${$rh}{'warn_list_no_code'} = 1 if ($set_list_debug2);
    ${$rh}{'show_set_dbg'} = 1 if ($set_set_debug);
    ${$rh}{'per_line_dbg'} = 1 if ($set_per_line_debug);
    ${$rh}{'show_process_dbg'} = 1 if ($set_processing_debug);
    ${$rh}{'show_process_dbg2'} = 1 if ($set_processing_debug2);
    ${$rh}{'show_process_dbg3'} = 1 if ($set_processing_debug3);
    ${$rh}{'show_macro_dbg'} = 1 if ($set_macro_debug);
}

sub scan_cmake_modules_path($$) {
    my ($itm,$rh) = @_;
    cmake_fix_directory(\$itm);
    my $mdir = $itm."CMakeModules";
    if ((-d $mdir) && $inc_all_cmake) {
        my $rif = ${$rh}{'CMAKE_INSTALLED_FILES'};
        my $pcnt = scalar @{$rif};
        prt("Scanning module path [$mdir]...\n") if (VERB9());
        scan_cmake_path($mdir,$rh);
        my $cnt = scalar @{$rif} - $pcnt;
        prt("Got $cnt files to load from [$mdir]\n") if (VERB9());
        foreach my $ff (@{$rif}) {
            process_in_file($ff,$rh);
        }
    } else {
        prt("Module path [$mdir] does not exist...\n") if (VERB9());
    }
}

sub process_item($$) {
    my ($itm,$rh) = @_;
    if (-f $itm) {
        my ($n,$d) = fileparse($itm);
        ${$rh}{'CMAKE_SOURCE_DIR'} = $d;
        ${$rh}{'CMAKE_BINARY_DIR'} = $d."build";
        scan_cmake_modules_path($d,$rh);
        process_in_file($itm,$rh);
    } elsif (-d $itm) {
        if (opendir( DIR, $itm)) {
            my @files = readdir(DIR);
            closedir(DIR);
            cmake_fix_directory(\$itm);
            my ($fil,$ff,$mdir);
            foreach $fil (@files) {
                if ($fil =~ /^CMakeLists\.txt$/i) {
                    ${$rh}{'CMAKE_SOURCE_DIR'} = $itm;
                    ${$rh}{'CMAKE_BINARY_DIR'} = $itm."build";
                    scan_cmake_modules_path($itm,$rh);
                    $ff = $itm.$fil;
                    process_in_file($ff,$rh);
                }
            }
        }
    }
    do_cmake_subdirectories($rh);
}

sub process_inputs($) {
    my $rh = shift;

    test_load_installed_cmake($rh) if ($load_cmake_inst);

    if (@in_files) {
        my $f = scalar @in_files;
        prt("Loading $f input files...\n");
        foreach $f (@in_files) {
            process_item($f,$rh);
        }
    } else {
        prt("No input files to load...\n");
    }
    if (length($input_file) && (-f $input_file)) {
        prt("Loading file $input_file...\n");
        process_item($input_file,$rh);
    } else {
        prt("No valid input file to load... [$input_file]\n") if (VERB9());
    }

    do_cmake_subdirectories($rh);
}

sub cmake_parse_if($$) {
    my ($act,$rh) = @_;
    my $rdh = ${$rh}{'CMAKE_DEFINES'};
    my $rta = cmake_token_split($act);
    my $res = 0;
    my ($tok,$val,$tmp,$str1,$str2,$cnt);
    my @braces = ();
    my @resarr = ();
    my $oper = '';
    my $isstr = 0;
    my @vals = ();
    my @svals = ();
    my @ops = ();
    $str1 = '';
    $str2 = '';
    $cnt = 0;
    foreach $tok (@{$rta}) {
        if ($tok =~ /\$\{(\w+)\}/) {
            # a macro token
            $tmp = $1;
            if (defined ${$rdh}{$tmp}) {
                $val = ${$rdh}{$tmp};
                $vals[$cnt] = ${$rdh}{$tmp};
                $svals[$cnt] = "${$rdh}{$tmp}";
            } elsif (cmake_macro_sub(\$tok,$rh)) {
                $val = $tok;
                $vals[$cnt] = $tok;
                $svals[$cnt] = "$tok";
            } else {
                $val = 0;
                $vals[$cnt] = 0;
                $svals[$cnt] = "";
            }
            $cnt++;
        } elsif ($tok =~ /\$ENV\{(\w+)\}/) {
            # an enviroment token
            $tmp = $1;
            if (exists $ENV{$tmp}) {
                $tmp = $ENV{$tmp};
            } else {
                $tmp = 0;
            }
            $vals[$cnt] = $tmp;
            $svals[$cnt] = "$tmp";
            $cnt++;
        # elsif (($txt =~ /^AND$/i)||($txt =~ /^OR$/i)||($txt =~ /^NOT$/i)||($txt =~ /^STREQUAL$/i)) {
        } elsif ($tok eq 'AND') {
            $oper = $tok;
            push(@ops,$tok);
        } elsif ($tok eq 'OR') {
            $oper = $tok;
            push(@ops,$tok);
        } elsif ($tok eq 'NOT') {
            $oper = $tok;
            push(@ops,$tok);
        } elsif ($tok eq 'STREQUAL') {
            $oper = $tok;
            $isstr = 1;
            push(@ops,$tok);
        } elsif ($tok eq 'MATCHES') {
            $oper = $tok;
            $isstr = 1;
            push(@ops,$tok);
        } elsif ($tok =~ /^\w+$/) {
            # also a macro?
            $tmp = "\${$tok}";
            if (defined ${$rdh}{$tok}) {
                $val = ${$rdh}{$tok};
            } elsif (!cmake_macro_sub(\$tmp,$rh)) {
                $val = $tmp;
            } else {
                $val = 0;
            }
            $vals[$cnt] = $val;
            $svals[$cnt] = ($val == 0) ? "" : "$val";
            $cnt++;
        } else {
            # what is this
        }
    }


    return $res;
}



sub list_if_actions($) { # if ($show_if_actions)
    my $rh = shift;
    my $riftags = ${$rh}{'CMAKE_IFTAGS'};
    my $rifma = ${$rh}{'CMAKE_IFACTS'};
    ### push(@{$ria},$act);
    ### ${$rh}{'CURR_IN_IF'}++;   # bump IF counter
    ### push(@{$rifstk},[$act,$lnn]);
    my ($txt,$i,$ch,$tag,%mods,$ra2,@arr,$lcnt,$tmp,$bfile,$lnn,$msg);
    $tag = '';
    %mods = ();
    ###my $rta = cmake_token_split($act)
    ##my $rta = cmake_token_split_ra($ra);
    #  ($txt =~ /\W*\$\{MSVC_VERSION\}/) {
    # if(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
    # elsif (($txt =~ /^AND$/i)||($txt =~ /^OR$/i)||($txt =~ /^NOT$/i)||($txt =~ /^STREQUAL$/i)) {
    my $rdh = ${$rh}{'CMAKE_DEFINES'};
    my $idcnt = 0;

    @arr = keys(%{$riftags});
    $ch = scalar @arr;
    my @macros = ();
    my $mcnt = 0;
    my @envs = ();
    my $ecnt = 0;
    my @itags = ();
    my $tcnt = 0;
    ###my @lines = ();
    my %dupes = ();
    #push(@{$ria},[$act,$bfile,$lnn]);
    foreach $ra2 (@{$rifma}) {
        $tag = ${$ra2}[0];
        $bfile = ${$ra2}[1];
        $lnn = ${$ra2}[2];
        if (!defined $dupes{$tag}) {
            $dupes{$tag} = [$tag,$bfile,$lnn];
            ##push(@linesm,[$tag,$bfile,$lnn]);
        }
    }
    ###$lcnt = scalar @linesm;
    $lcnt = scalar keys(%dupes);
    foreach $tag (@arr) {
        #               0       1      2
        # push(@{$ra2},[{%mods},$bfile,$lnn]);
        # $ra2 = ${$riftags}{$tag};
        if ($tag =~ /^__MACRO_/) {
            $tag =~ s/^__MACRO_//;
            push(@macros,$tag);
            $mcnt++;
        } elsif ($tag =~ /^__ENV_/) {
            $tag =~ s/^__ENV_//;
            push(@envs,$tag);
            $ecnt++;
        } else {
            push(@itags,$tag);
            $tcnt++;
        }
    }

    if ( ($ch == 0) && ($mcnt == 0) && ($ecnt == 0) && ($tcnt == 0) ) {
        return;
    }

    prt("List of $ch IF tags... $mcnt macros, $ecnt environment, and $tcnt others... from $lcnt lines\n");

    prt("TAGS: ${tcnt}\n".join(" ", sort @itags)."\n");

    #prt("ENV: ${ecnt}\n".join("\n", sort @envs)."\n");
    prt("\nENV: ${ecnt}\n");
    foreach $tag (sort @envs) {
        prt("\$ENV{$tag}\n");
    }

    #prt("MACROS: ${mcnt}\n".join("\n", sort @macros)."\n");
    prt("\nMACROS: ${mcnt}\n");
    $idcnt = 0;
    foreach $tag (sort @macros) {
        $tmp = $tag;
        if (defined ${$rdh}{$tag}) {
            $idcnt++;
            ##$tmp = ${$rdh}{$tag};
            ##prt("\${$tag} = [$tmp]\n");
        } elsif (cmake_macro_sub(\$tmp,$rh)) {
            ${$rdh}{$tag} = $tmp;
            $idcnt++;
        } else {
            prt("\${$tag}\n");
        }
    }
    prt("With $idcnt evaluated in 'CMAKE_DEFINES', or SET or LISTS\n");
    foreach $tag (sort @macros) {
        if (defined ${$rdh}{$tag}) {
            ##$idcnt++;
            $tmp = ${$rdh}{$tag};
            prt("\${$tag} eval to [$tmp]\n");
        } else {
            ##prt("\${$tag}\n");
        }
    }

    #prt("\nLINES: ${lcnt}\n".join("\n", sort @lines)."\n");
    prt("\nIF LINES: ${lcnt}\n");
    $idcnt = 0;
    my @lines = sort keys(%dupes);
    #foreach $tag (@lines) {
    #    $ra2 = $dupes{$tag};
    #    my $rta = cmake_token_split($act)
    #
    #}
    foreach $tag (@lines) {
        $ra2 = $dupes{$tag};
        $bfile = ${$ra2}[1];
        $lnn = ${$ra2}[2];
        $msg = '';
        if (defined ${$rdh}{$tag}) {
            $idcnt++;
            ##$tmp = ${$rdh}{$tag};
            ##prt("IF($tag) eval [$tmp]\n");
        } else {
            my $rta = cmake_token_split($tag);
            my $tc = scalar @{$rta};
            $msg = "($tc)";
            if ($tc > 1) {
                my $ntag = '';
                my $ltmp = '';
                foreach $tmp (@{$rta}) {
                    $ntag .= ' ' if (length($ntag));
                    $ntag .= $tmp;
                    $ltmp = $tmp;
                }
                if ($ltmp ne $ntag) {
                    $msg = "(=$tc)";
                } else {
                    prt("IF($ntag) CHECK CHANGE\n");
                }
            }
            #$res = cmake_parse_if($tag,$rh);
            prt("IF($tag) $msg [$bfile]$lnn\n");
        }
    }
    prt("With $idcnt evaluated from 'CMAKE_DEFINES'\n");
    foreach $tag (@lines) {
        $ra2 = $dupes{$tag};
        $bfile = ${$ra2}[1];
        $lnn = ${$ra2}[2];
        if (defined ${$rdh}{$tag}) {
            ##$idcnt++;
            $tmp = ${$rdh}{$tag};
            prt("IF($tag) eval [$tmp] [$bfile]$lnn\n");
        } else {
            ##prt("IF($tag)\n");
        }
    }
}

sub show_new_directives($) {
    my $rh = shift;
    my $rndh = ${$rh}{'new_directives_found'};    # = \%new_directives;
    my @arr = sort keys(%{$rndh});
    my $cnt = scalar @arr;
    if ($cnt) {
        prt("WARNING: Found $cnt NEW directives - in \${\$rh}{'new_directives_found'}\n[".join(" ",@arr)."]\n");
        #prt("my \%new_cmake_directives = (\n");
        #$ch = ',';
        #for ($i = 0; $i < $cnt; $i++) {
        #    $dir = $arr[$i];
        #   prt("  '$dir' => \\\&hand$ch\n");
        #    $ch = '' if (($i + 1) == $cnt);
        #}
        #prt(");\n");
        #prt("# Listed $cnt directives...\n");
    }
}

sub output_list_items($) {
    my $rh = shift;
    list_macro_items($rh) if ($show_macro_items);
    list_function_items($rh) if ($show_function_items);
    list_set_items($rh) if ($show_set_items);
    list_list_items($rh) if ($show_list_items);
    list_directives($rh) if ($write_directive_list);
    list_if_actions($rh) if ($show_if_actions);
    my $rflh = ${$rh}{'CMAKE_FILES_LOADED'};    # output_list_items: show total load count = \%cmake_files_loaded;
    my $cnt = scalar keys(%{$rflh});
    prt("Loaded a total of $cnt files...\n");
}

# ---- write a test case ----
sub write_test_case($$) {
    my ($fil,$rh) = @_;
    my $txt = <<EOF;

  if ("\$ENV{Boost_DIR}" STREQUAL "")
    if (NOT "\$ENV{BOOST_ROOT}" STREQUAL "")
      set(ENV{Boost_DIR} \$ENV{BOOST_ROOT})
    elseif (NOT "\$ENV{BOOSTROOT}" STREQUAL "")
      set(ENV{Boost_DIR} \$ENV{BOOSTROOT})
    endif()
  endif()

EOF
    write2file($txt,$fil);
    prt("Test text written to [$fil]\n");
}

sub  process_test_case($) {
    my $rh = shift;
    $debug_level_load = -1;
    $debug_level_proc = $debug_level_load;
    ${$rh}{'CURR_DBG_FLAG'} = $debug_level_load;
    set_rh_debug_flags($rh,1); # if ($set_rh_debug);
    ${$rh}{'per_line_dbg'} = 1;
    write_test_case($temp_cmake,$rh);
    process_item($temp_cmake,$rh);
}

#########################################
### MAIN ###
$ref_hash = get_cmake_ref_hash();
set_specific_debug($ref_hash);

if ($test_cmake_line1 || $test_cmake_line2 || $test_cmake_line3 || $test_cmake_line4) {
    test_lines($ref_hash);
} elsif ($do_test_case) {
    process_test_case($ref_hash);
} else {
    parse_args(@ARGV);
    process_inputs($ref_hash);
}
output_list_items($ref_hash);
show_new_directives($ref_hash);

pgm_exit(0,"");
########################################
sub give_help {
    prt("$pgmname: version $VERS\n");
    prt("Usage: $pgmname [options] in-file\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --out <file>  (-o) = Write output to this file.\n");
    prt("\n");
    prt(" Original used to help develop lib_cmakeread.pl, but subsequently used\n");
    prt(" to test and report errors in cmake syntax, since cmake generally only\n");
    prt(" reached EOF, without reporting where the problem started.\n");
    prt(" Lots of switches that have no option yet, so very much a WIP!\n");
    prt("\n");
}

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

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg);
    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 =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                prt("Verbosity = $verbosity\n") if (VERB1());
            } elsif ($sarg =~ /^l/) {
                $load_log = 2;
                prt("Set to load log at end.\n") if (VERB1());
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_xml = $sarg;
                prt("Set out file to [$out_xml].\n") if (VERB1());
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            $arg = File::Spec->rel2abs($arg);
            push(@in_files,$arg);
            if ((! -f $arg) && (! -d $arg)) {
                pgm_exit(1,"ERROR: Unable to find in file or folder [$arg]! Check name, location...\n");
            }
            prt("Added [$arg] to input files...\n") if (VERB1());
        }
        shift @av;
    }

    if (!@in_files && !$load_cmake_inst && !length($input_file)) {
        pgm_exit(1,"ERROR: No input files or directories found in command!\n");
    }
    if (VERB9()) {
        $debug_level_proc = -1;   # have defined 0x100 | 0x200 | 0x400;
        $debug_level_load = -1;
        $set_rh_debug = 1;
        set_specific_debug($ref_hash);
        prt("Got VERB9() so have set maximum debug ON\n");

    }
}

# eof - chkcmake02.pl

index -|- top

checked by tidy  Valid HTML 4.01 Transitional