#!/usr/bin/perl -w
# NAME: blog2cmake.pl
# AIM: Take an nmake log, and build a CMakeLists.txt from it
# *** THIS FAILED - JUST TOO COMPLICATED, especially with regard to the directory changing
# 08/03/2014 geoff mclane http://geoffair.net/mperl
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 = $temp_dir.$PATH_SEP."temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.2 2014-01-13";
my $load_log = 0;
my $in_file = '';
my $verbosity = 0;
my $out_file = '';

# ### DEBUG ###
my $debug_on = 1;
my $def_file = 'Z:\software\src\gdal-1.10.1\bldlog-1.txt';

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

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) {
        prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
        foreach my $itm (@warnings) {
           prt("$itm\n");
        }
        prt("\n");
    } else {
        prt( "\nNo warnings issued.\n\n" ) if (VERB9());
    }
}

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 starts_with_root($$) {
    my ($line,$root) = @_;
    my $llen = length($line);
    my $rlen = length($root);
    return 0 if ($llen < $rlen);
    my ($i,$rc,$lc);
    for ($i = 0; $i < $rlen; $i++) {
        $rc = lc(substr($root,$i,1));
        $lc = lc(substr($line,$i,1));
        return 0 if ($rc ne $lc);
    }
    return 1;
}

sub strip_root($$) {
    my ($src,$root) = @_;
    ut_fix_directory(\$root);
    my $llen = length($src);
    my $rlen = length($root);
    return $src if ($llen < $rlen);
    my ($i,$rc,$lc);
    for ($i = 0; $i < $rlen; $i++) {
        $rc = lc(substr($root,$i,1));
        $lc = lc(substr($src,$i,1));
        return $src if ($rc ne $lc);
    }
    return substr($src,$rlen);
}


# \s+cl\s+/nologo /MD /EHsc /Ox /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DNDEBUG 
# /W4 /wd4127 /wd4251 /wd4275 /wd4786 /wd4100 /wd4245 /wd4206 /wd4018 /wd4389 
# /DHAVE_SSE_AT_COMPILE_TIME 
# -I..\..\..\port -I..\..\..\ogr -I..\..\..\gcore -I..\..\..\alg -I..\..\..\ogr\ogrsf_frmts -I. -I.. 
# -I..\.. -DOGR_ENABLED /c 
# ogrgeojsondriver.cpp ogrgeojsondatasource.cpp ogrgeojsonlayer.cpp ogrgeojsonwritelayer.cpp 
# ogrgeojsonutils.cpp ogrgeojsonreader.cpp ogrgeojsonwriter.cpp ogresrijsonreader.cpp

# 2657: [ cl  /nologo /MD /EHsc /Ox /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DNDEBUG 
# /W4 /wd4127 /wd4251 /wd4275 /wd4786 /wd4100 /wd4245 /wd4206 /wd4018 /wd4389 /DHAVE_SSE_AT_COMPILE_TIME 
# -I..\port -I..\ogr -I..\gcore  -I..\alg -I..\ogr\ogrsf_frmts  -DOGR_ENABLED  -I..\frmts -I..\alg -I..\ogr 
# -I..\ogr\ogrsf_frmts gdal_translate.cpp commonutils.cpp  ..\gdal_i.lib  /link - ???
my %defines = ();
my %include = ();
sub  process_lines($$) {
    my ($inf,$ra) = @_;
    my $lncnt = scalar @{$ra};
    prt("Processing $lncnt lines, from [$inf]...\n");
    my ($line,$tmp,$lnn,@arr,%srcs,$itm,$cnt,$ok,$i,$ind);
    my ($tline,$len,@arr2,$dcnt,$ln,$ff,$iss,$litm,$ch);
    my ($alen,$a);
    my $abs = File::Spec->rel2abs($inf);
    my ($name,$dir) = fileparse($inf);
    $lnn = 0;
    my $curr_dir = path_u2d($dir);
    $curr_dir =~ s/\\$//;
    my $root_dir = $curr_dir;
    my $cdir_len = length($curr_dir);
    my @dir_arr = split(/\\/,$curr_dir);
    my $min_dcnt = scalar @dir_arr;
    my @post = ();
    my $prev_dir = $curr_dir;
    my $prev_prev = $prev_dir;
    my $last_itm = '';
    my $last_cd = '';
    my $prev_cd = '';
    my $prev2_cd = '';
    my $prev3_cd = '';
    my @sources = ();
    my %dirs_entered = ();
    for ($ln = 0; $ln < $lncnt; $ln++) {
        $line = ${$ra}[$ln];
        chomp $line;
        $lnn++;
        $tline = trim_all($line);
        $len = length($tline);
        next if ($len == 0);
        $ind = index($line,'>');
        if ($ind > 0) {
            if (starts_with_root($line,$root_dir)) {
                $tmp = substr($line,0,$ind);
                if ($tmp =~ /\w\(\d+\)\s+:\s+/) {
                    prt("$lnn: As IS    [$line]\n");
                } elsif ($tmp =~ /\w\s+-$/) {
                    prt("$lnn: AS IS    [$line]\n");
                } else {
                    $line = substr($line,$ind + 1);
                    $line = " ".$line;
                    prt("$lnn: New line [$line]\n");
                }
            } else {
                prt("$lnn: Left as  [$line]\n");
            }
        }
        if ($line =~ /^\s+cl\s+(.+)$/) {
            $tmp = trim_all($1);
            @arr = space_split($tmp);
            prt("Compile: [$tmp]\n") if (VERB9());
            %srcs = ();
            if ($last_itm eq '..') {
                $dir = $prev_dir;
            } else {
                $dir = $curr_dir;
            }
            ut_fix_directory(\$dir);
            $alen = scalar @arr;
            for ($a = 0; $a < $alen; $a++) {
                $itm = $arr[$a];
                $iss = 0;
                $litm = length($itm);
                if ($itm =~ /^\/(.+)$/) {
                    $iss = 1; # switch
                } elsif ($itm =~ /^-(.+)$/) {
                    $iss = 2; # switch
                } else {
                    $ff = $dir.$itm;
                    $ok = 'NF';
                    if (-f $ff) {
                        $ok = 'ok';
                    } else {
                        # 224: CD C [Z:\software\src\gdal-1.10.1\ogr\ogrsf_frmts\jsonc] jsonc 
                        # P [Z:\software\src\gdal-1.10.1\ogr\ogrsf_frmts\geojson] pcd geojson lcd jsonc
                        # ogr\ogrsf_frmts\jsonc\arraylist.c NF is really [ogr\ogrsf_frmts\geojson\jsonc\arraylist.c
                        $tmp = $prev_dir;
                        ut_fix_directory(\$tmp);
                        $tmp .= $last_cd;
                        ut_fix_directory(\$tmp);
                        $ff = $tmp.$itm;
                        if (-f $ff) {
                            $ok = 'ok';
                            $dir = $tmp;
                        } else {
                            # 811: cd P [Z:\software\src\gdal-1.10.1\frmts\jpeg] C [Z:\software\src\gdal-1.10.1\frmts] jpeg   
                            #       && nmake /nologo /f makefile.vc   && cd ..   || exit 1  pcd frmts lcd jpeg
                            # 812: CD C [Z:\software\src\gdal-1.10.1\frmts\libjpeg12] libjpeg12 
                            #       P [Z:\software\src\gdal-1.10.1\frmts\jpeg] pcd jpeg lcd libjpeg12
                            # 924: cd P [Z:\software\src\gdal-1.10.1\frmts\libjpeg12] C [Z:\software\src\gdal-1.10.1\frmts]
                            # .. pcd jpeg lcd libjpeg12
                            # frmts\libjpeg12\libjpeg12\jpgdataset.cpp NF found in frmts\jpeg\jpgdataset.cpp
                            $tmp = $curr_dir;
                            ut_fix_directory(\$tmp);
                            $tmp .= $prev_cd;
                            ut_fix_directory(\$tmp);
                            $ff = $tmp.$itm;
                            if (-f $ff) {
                                $ok = 'ok';
                                $dir = $tmp;
                            } else {
                                # 937: CD C [Z:\software\src\gdal-1.10.1\frmts\libjpeg] libjpeg 
                                #       P [Z:\software\src\gdal-1.10.1\frmts\libjpeg12] pcd libjpeg12 lcd libjpeg p2 jpeg
                                # Z:\software\src\gdal-1.10.1\frmts\libjpeg\jcapimin.c NF FOUND frmts\jpeg\libjpeg
                                @arr2 = @dir_arr;
                                pop @arr2;
                                $tmp = join("\\",@arr2);
                                ut_fix_directory(\$tmp);
                                $tmp .= $prev2_cd;
                                ut_fix_directory(\$tmp);
                                $tmp .= $last_cd;
                                ut_fix_directory(\$tmp);
                                $ff = $tmp.$itm;
                                if (-f $ff) {
                                    $ok = 'ok';
                                    $dir = $tmp;
                                } else {
                                    # 1044: CD C [Z:\software\src\gdal-1.10.1\frmts\libjpeg12] libjpeg12 
                                    #           P [Z:\software\src\gdal-1.10.1\frmts\libjpeg] pcd libjpeg lcd libjpeg12 p2 libjpeg12 p3 jpeg
                                    # Z:\software\src\gdal-1.10.1\frmts\libjpeg12\jcapimin12.c NF FOUND frmts\jpeg\libjpeg12
                                    @arr2 = @dir_arr;
                                    pop @arr2;
                                    $tmp = join("\\",@arr2);
                                    ut_fix_directory(\$tmp);    # back to 'frmts'
                                    $tmp .= $prev3_cd;
                                    ut_fix_directory(\$tmp);    # back to 'frmts\jpeg'
                                    $tmp .= $prev2_cd;
                                    ut_fix_directory(\$tmp);    # back to 'frmts\jpeg\libjpeg12'
                                    $ff = $tmp.$itm;
                                    if (-f $ff) {
                                        $ok = 'ok';
                                        $dir = $tmp;
                                    } else {
                                        # 1236: CD C [Z:\software\src\gdal-1.10.1\gtiff\libtiff] ../../gtiff/libtiff 
                                        #   P [Z:\software\src\gdal-1.10.1\jpeg] pcd gtiff lcd libtiff p2 libjpeg12 p3 jpeg
                                        # gtiff\libtiff\tif_aux.c NF FOUND frmts\gtiff\libtiff
                                        @arr2 = keys %dirs_entered; # get ALL directories entered
                                        foreach $tmp (@arr2) {
                                            ut_fix_directory(\$tmp);
                                            $ff = $tmp.$itm;
                                            if (-f $ff) {
                                                $ok = 'ok';
                                                $dir = $tmp;
                                                last;
                                            }
                                        }
                                        if ($ok ne 'ok') {
                                            prt("Wow: NOT one of ".scalar @arr2." directories!\n");
                                            prt(join("\n",sort @arr2)."\n");
                                            prt($dir."$itm $ok\n");
                                            pgm_exit(1,"NOT FOUND - *** FIX ME ***\n");
                                        }
                                    }
                                }
                            }
                        }
                    }
                    $itm = strip_root($ff,$root_dir);
                    $srcs{$itm} = 1;
                    prt("$itm $ok\n");
                }
                if ($iss) {
                    $tmp = substr($itm,1);
                    $ch = substr($tmp,0,1);
                    if ($tmp eq 'nologo') {
                        # /nologo
                    } elsif ($tmp eq 'link') {
                        # /link
                    } elsif ($ch eq 'D') {
                        if ($litm > 2) {
                            # /DHAVE_SSE_AT_COMPILE_TIME /D_CRT_NONSTDC_NO_DEPRECATE /DNDEBUG
                            $tmp = substr($tmp,1);
                            $defines{$tmp} = 1;
                        } else {
                            prt("/D switch NO LENGTH [$ch] [$itm]\n$lnn: [$line]\n");
                            pgm_exit(1,"*** FIX ME ***\n");
                        }
                    } elsif ($ch eq 'I') {
                        if ($litm > 2) {
                            # -I..\..\..\port
                            $tmp = substr($tmp,1);
                        } else {
                            if (($a + 1) < $alen) {
                                $a++;
                                $tmp = $arr[$a];
                            } else {
                                prt("-I switch NO LENGTH [$ch] [$itm]\n$lnn: [$line]\n");
                                pgm_exit(1,"*** FIX ME ***\n");
                            }
                        }
                    } elsif ($ch eq 'c') {
                        # /c
                    } elsif ($ch eq 'O') {
                        # /Ox
                    } elsif ($ch eq 'W') {
                        # /W4
                    } elsif ($ch eq 'w') {
                        # /wd4018 /wd4389
                    } elsif ($ch eq 'M') {
                        # /MD
                    } elsif ($ch eq 'E') {
                        # /EHsc
                    } elsif ($ch eq 'F') {
                        # /Fopcidskdataset2.obj
                    } else {
                        prt("Uncased switch [$ch] [$itm]\n$lnn: [$line]\n");
                        pgm_exit(1,"*** FIX ME ***\n");
                    }
                }
            }
            @arr = keys %srcs;
            $cnt = scalar @arr;
            ###prt("$lnn: $cnt sources: ".join(" ",@arr)."\n");
            #prt("$lnn: $cnt sources\n");
        } elsif ($line =~ /^\s+cd\s+(.+)$/) {
            $tmp = $1;
            prt("$lnn: CD $tmp\n") if (VERB9());
            @arr = split(/\s+/,$tmp);
            $cnt = scalar @arr;
            $itm = $arr[0]; # dir to change to
            $itm = path_u2d($itm);
            @arr2 = split(/\\/,$itm);
            foreach $itm (@arr2) {
                $last_itm = $itm;
                if ($itm eq '..') {
                    $prev_prev = $prev_dir;
                    $prev_dir = join("\\",@dir_arr);
                    $dirs_entered{$prev_dir} = 1;
                    $dcnt = scalar @dir_arr;
                    if ($dcnt > $min_dcnt) {
                        pop @dir_arr if (@dir_arr);
                    } else {
                        prt("$lnn: Backup BLOCKED\n");
                    }
                } else {
                    $prev3_cd = $prev2_cd;
                    $prev2_cd = $prev_cd;
                    $prev_cd = $last_cd;
                    $last_cd = $itm;
                    push(@dir_arr,$itm);
                }
            }
            for ($i = 1; $i < $cnt; $i++) {
                $itm = $arr[$i];
                last if ($itm eq '||');
                $last_itm = $itm;
                if ($itm eq '..') {
                    $prev3_cd = $prev2_cd;
                    $prev2_cd = $prev_cd;
                    $prev_prev = $prev_dir;
                    $prev_dir = join("\\",@dir_arr);
                    $dirs_entered{$prev_dir} = 1;
                    $dcnt = scalar @dir_arr;
                    if ($dcnt > $min_dcnt) {
                        pop @dir_arr if (@dir_arr);
                    } else {
                        prt("$lnn: BACKUP BLOCKED\n");
                    }
                } elsif ($itm eq '&&') {
                    # $no = 0;
                } elsif ($itm =~ /nmake/i) {
                    # $no = 1;
                    $i++;
                    for (; $i < $cnt; $i++) {
                        $itm = $arr[$i];
                        last if ($itm eq '&&');
                    }
                } elsif ($itm eq 'cd') {
                } else {
                    $prev_cd = $last_cd;
                    $last_cd = $itm;
                    push(@dir_arr,$itm);
                }
            }
            $curr_dir = join("\\",@dir_arr);
            $dirs_entered{$curr_dir} = 1;   # store directories entered
            if ($last_itm eq '..') {
                prt("$lnn: cd P [$prev_dir] C [$curr_dir] $tmp pcd $prev_cd lcd $last_cd p2 $prev2_cd p3 $prev3_cd\n"); # if (VERB9());
            } else {
                prt("$lnn: CD C [$curr_dir] $tmp P [$prev_dir] pcd $prev_cd lcd $last_cd p2 $prev2_cd p3 $prev3_cd\n"); # if (VERB9());
            }
        } elsif ($line =~ /^\s+nmake\s+(.+)$/) {
        } elsif ($line =~ /^\s+copy\s+(.+)$/) {
        } elsif ($line =~ /^\s+(\d+)\s+file\(s\)\s+copied/) {
            #         1 file(s) copied.
        } elsif ($line =~ /^\s+lib\s+(.+)$/) {
        } elsif ($line =~ /^\s+xcopy\s+(.+)$/) {
        } elsif ($line =~ /^\s+for\s+(.+)$/) {
        } elsif ($line =~ /^\s+Creating\s+(.+)$/) {
        } elsif ($line =~ /^\s+if\s+(.+)$/) {
        } elsif ($line =~ /^\s+rc\s+(.+)$/) {
        } elsif ($line =~ /^\s+ren\s+(.+)$/) {
        } elsif ($line =~ /^\s+link\s+(.+)$/) {
        } elsif ($line =~ /\w\(\d+\)\s+:\s+/) {
        } elsif ($line =~ /^\s+/) {
            prt("Unparsed line with space - *** FIX ME ***\n$lnn: [$line]\n");
            pgm_exit(1,"*** FIX ME FIRST ***\n");
        }
    }
    $load_log = 1;
}

sub process_in_file($) {
    my ($inf) = @_;
    if (! open INF, "<$inf") {
        pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); 
    }
    my @lines = <INF>;
    close INF;
    process_lines($inf,\@lines);
}

#########################################
### MAIN ###
parse_args(@ARGV);
process_in_file($in_file);
pgm_exit(0,"");
########################################

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);
    my $verb = VERB2();
    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);
                    }
                }
                $verb = VERB2();
                prt("Verbosity = $verbosity\n") if ($verb);
            } elsif ($sarg =~ /^l/) {
                if ($sarg =~ /^ll/) {
                    $load_log = 2;
                } else {
                    $load_log = 1;
                }
                prt("Set to load log at end. ($load_log)\n") if ($verb);
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_file = $sarg;
                prt("Set out file to [$out_file].\n") if ($verb);
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            $in_file = $arg;
            prt("Set input to [$in_file]\n") if ($verb);
        }
        shift @av;
    }

    if ($debug_on) {
        prtw("WARNING: DEBUG is ON!\n");
        if (length($in_file) ==  0) {
            $in_file = $def_file;
            prt("Set DEFAULT input to [$in_file]\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] 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");
}

# eof - template.pl
