#!/usr/bin/perl -w
# NAME: in2cmake.pl
# AIM: Try to convert an *.in file to cmake format
# 14/12/2014 - Deal with STDC_HEADERS
# 20140928 - Do NOT add a check_symbol_exists without a header to check
# 29/05/2014 - add --full to include comments as well
# 27/05/2014 - some improvements
# 06/02/2014 geoff mclane http://geoffair.net/mperl
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
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.3 2014-05-27";
#my $VERS = "0.0.2 2014-02-06";
my $load_log = 0;
my $in_file = '';
my $verbosity = 0;
my $out_file = '';
my $full_output = 0;
my $failed_output = 0;

# ### DEBUG ###
my $debug_on = 0;
my $def_file = 'F:\FG\18\libiconv-1.14\config.h.in';
###my $def_file = 'F:\FG\18\gdal-1.9.1\port\cpl_config.h.in';

### 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());
    }
}

my %type_2_hdr = (
    "ptrdiff_t" => "stddef.h",
    "sig_atomic_t" => "signal.h",
    "size_t" => "stddef.h",
    "wchar_t" => "wchar.h",
    "wint_t" => "wchar.h"
    );

my %in_stdint_h = (
    "uint8_t" => 1,
    "uint16_t" => 1,
    "uint32_t" => 1,
    "uint64_t" => 1,
    "int8_t" => 1,
    "int16_t" => 1,
    "int32_t" => 1,
    "int64_t" => 1,
    "uintptr_t" => 1
    );

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);
}

# from : http://cmake.org/Wiki/CMake:How_To_Write_Platform_Checks
# Module: INCLUDE (CheckSymbolExists) Usage: CHECK_SYMBOL_EXISTS(symbol headers variable)
# Example: CHECK_SYMBOL_EXISTS((LC_MESSAGES "locale.h" HAVE_LC_MESSAGES)
# Module: INCLUDE (CheckLibraryExists) Usage : CHECK_LIBRARY_EXISTS(library function location variable)
# Example: CHECK_LIBRARY_EXISTS(volmgt volmgt_running "" HAVE_VOLMGT)
# Checks whether the given library exists and contains the given function. This is done by linking a 
# small program which uses the function and links to the library. In the location parameter an 
# additional link directory (-Ldir) can be given if required.
# Module: INCLUDE (CheckTypeSize) Usage: SET(CMAKE_EXTRA_INCLUDE_FILES header) CHECK_TYPE_SIZE(type variable) SET(CMAKE_EXTRA_INCLUDE_FILES)
# Example: SET(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) CHECK_TYPE_SIZE("struct ucred" STRUCT_UCRED) SET(CMAKE_EXTRA_INCLUDE_FILES)
# Checks whether the specified type exists and returns the size of the type. In the variable the size 
# of the type will be returned, additionally a variable HAVE_STRUCT_UCRED will be set to true if the type 
# exists. Please not that you have to set CMAKE_EXTRA_INCLUDE_FILES to the required headers for this type, 
# and you should reset it after calling CHECK_TYPE_SIZE. If you are not really interested in the size of 
# the type, but only whether it exists or not, you can also use STRUCT_UCRED directly, if the type doesn't 
# exist, it will be empty and so also evaluate to FALSE (as will HAVE_STRUCT_UCRED).

my %symbols_checked = ();

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;
    my $lncnt = scalar @lines;
    prt("Processing $lncnt lines, from [$inf]...\n");
    my ($line,$inc,$lnn,$len,$l,$i,$i2,$l2,$tline,$incomm,$ch,$nc,$comment);
    my ($res,$off,$cmake,$tmp,$cmake2,$nxline,$deflen,$def);
    my ($cmvar,$var,$hdr,$var2,$hvar2,$sovar,$done);
    # need to handle more comment types
    my $def1 = "Define to 1 if you have the ";
    my $def2 = "Define to 1 if ";

    my $def1len = length($def1);
    my $def2len = length($def2);
    # needed include
    my $needfe = 0; # $tmp .= "include (CheckFunctionExists)\n" if ($needfe);
    my $needhe = 0; # $tmp .= "include (CheckIncludeFile)\n" if ($needhe);
    my $needbe = 0; # $tmp .= "include (TestBigEndian)\n" if ($needbe);
    my $needts = 0; # $tmp .= "include (CheckTypeSize)\n" if ($needts);
    my $needse = 0; # $tmp .= "include (CheckSymbolExists)\n" if ($needse);
    my $commlines = 0;
    $lnn = 0;
    $incomm = 0;
    $comment = '';
    #$cmake = '';
    #$cmake2 = '';
    my @cmlinesf = ();  # check_function_exists
    my @cmlinesi = ();  # check_include_file
    my @cmlinescts = ();  # check_type_size
    my @cmlinescse = ();  # check_symbol_exists

    my @hdrlines = ();
    my @faillines = ();
    my @unslines = ();
    my $unservcnt = 0;
    my $hdrfailed = 0;
    my $funcfailed = 0;
    my $declfailed = 0;
    my $attfailed = 0;
    my $unkfailed = 0;
    my $itemsdone = 0;
    my $hadfailed = 0;
    my $nxlncnt = 0;
    for ($l = 0; $l < $lncnt; $l++) {
        $lnn = $l + 1;
        $line = $lines[$l];
        chomp $line;
        $tline = trim_all($line);
        $len = length($tline);
        next if ($len == 0);    # skip blank lines
        $nxline = '';
        $l2 = $l + 1;
        $nxlncnt = 0;
        if ($l2 < $lncnt) {
            $nxline = trim_all($lines[$l2]);
            $nxlncnt = 1;
            if ($nxline =~ /^\s*\#\s*if/) {
                $l2++;
                while ($i2 < $lncnt) {
                    $tmp = trim_all($lines[$l2]);
                    $l2++;
                    $nxline .= "\n";
                    $nxline .= $tmp;
                    $nxlncnt++;
                    if ($tmp =~ /^\s*\#\s*endif/) {
                        $l2--;  # why this backup???
                        last;
                    }
                }
            }
        }
        $len = length($line);
        for ($i = 0; $i < $len; $i++) {
            $i2 = $i + 1;
            $ch = substr($line,$i,1);
            $nc = ($i2 < $len) ? substr($line,$i2,1) : "";
            if ($incomm) {
                if (($ch eq "*")&&($nc eq '/')) {
                    # out of comment
                    $comment .= "*/";
                    $incomm = 0;
                    $done = 0;
                    $hadfailed = 0;
                    $deflen = $def1len;
                    $def = $def1;
                    $off = index($comment,$def);
                    if ($off == -1) {
                        # type for second type
                        $def = $def2;
                        $off = index($comment,$def);
                        $deflen = $def2len;
                    }
                    if ($off == -1) {
                        if (($comment =~ /Generated/i) && ($comment =~ /autoheader/)) {
                            # can skip this
                            prt("$comment\n") if (VERB9());
                            $done = 1;
                        } elsif (($commlines > 3) && ($comment =~ /Copyright/ig)) {
                            # big top comment - can skip this
                            prt("$comment\n") if (VERB9());
                            $done = 1;
                        } elsif ($comment =~ /WORDS_BIGENDIAN/) {
                            $needbe = 1;
                            push(@hdrlines,"$comment\n") if ($full_output);
                            push(@hdrlines,"#cmakedefine WORDS_BIGENDIAN 1\n");
                            push(@hdrlines,"\n") if ($full_output);
                            $l = $l2;
                            $done = 1;
                        } elsif ($comment =~ /Define\s+to\s+the\s+number\s+of\s+bits\s+in\s+type\s+'(\w+)'/) {
                            $tmp = $1;
                            if (defined $type_2_hdr{$tmp}) {
                                $done = 1;
                                $needhe = 1;
                                $needts = 1;
                                $hdr = $type_2_hdr{$tmp};
                                $var = uc($hdr);
                                $var2 = uc($tmp);
                                $sovar = 'SIZEOF_'.$var2;
                                $hvar2 = 'HAVE_'.$var2;
                                if (! defined $symbols_checked{$hvar2}) {
                                    $needse = 1;
                                    if (length($hdr)) {
                                        push(@cmlinesi,"check_symbol_exists( $tmp $hdr $hvar2 )\n");
                                    } else {
                                        push(@cmlinesi,"# check_symbol_exists( $tmp 'MISSED_HDR' $hvar2 )  # *** FIX ME ***\n");
                                    }
                                    push(@hdrlines,"$comment\n") if ($full_output);
                                    push(@hdrlines,"#cmakedefine $hvar2 1\n");
                                    if (($nxlncnt == 1) && ($nxline =~ /BITSIZEOF_$var2/)) {
                                        push(@hdrlines,"#ifdef $hvar2\n");
                                        push(@hdrlines,"#define BITSIZEOF_$var2 \@$sovar@\n");
                                        push(@hdrlines,"#endif\n");
                                    }
                                    push(@hdrlines,"\n") if ($full_output);
                                }

                                push(@cmlinesi,"if ( $hvar2 )\n");
                                push(@cmlinesi,"    set(CMAKE_EXTRA_INCLUDE_FILES $hdr)\n");
                                push(@cmlinesi,"    check_type_size($tmp $sovar)\n");
                                push(@cmlinesi,"    set(CMAKE_EXTRA_INCLUDE_FILES)\n");
                                push(@cmlinesi,"else ()\n");
                                push(@cmlinesi,"    set($sovar 4)\n");
                                push(@cmlinesi,"    message(STATUS \"*** set $sovar to 4! CHECK ME\")\n");
                                push(@cmlinesi,"endif ()\n");
                                $symbols_checked{$hvar2} = 1;
                                $l = $l2;   # skip next
                            } else {
                                prtw("WARNING: Bits in '$tmp'\n$comment\n$nxline\n");
                            }
                        #} elsif ($comment =~ /Define\s+to\s+1\s+if\s+the\s+system\s+has\s+the\s+type\s+('|`)(\w+)'/) {
                        #    $tmp = $2;

                        } else {
                            if ($nxline =~ /PACKAGE_(\w+)/) {
                                $tmp = $1;
                                # is one of PACKAGE_BUGREPORT, PACKAGE_NAME, PACKAGE_RELEASE, PACKAGE_STRING,
                                # PACKAGE_TARNAME, PACKAGE_URL, PACKAGE_VERSION, ...
                                #$off = index($nxline,"PACKAGE_");
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#ifndef PACKAGE_$tmp\n");
                                push(@hdrlines,"#define PACKAGE_$tmp \"undefined\"\n");
                                push(@hdrlines,"#endif\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $l = $l2;   # skip next
                                $done = 1;
                            } elsif ($nxline =~ /\s+PACKAGE\s+/) {
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#ifndef PACKAGE\n");
                                push(@hdrlines,"#define PACKAGE \"undefined\"\n");
                                push(@hdrlines,"#endif\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $l = $l2;   # skip next
                                $done = 1;
                            } elsif ($nxline =~ /\s+STDC_HEADERS\s+/) {
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#ifndef STDC_HEADERS\n");
                                push(@hdrlines,"#define STDC_HEADERS 1 /* who does not! */\n");
                                push(@hdrlines,"#endif\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $l = $l2;   # skip next
                                $done = 1;
                            } elsif ($nxline =~ /HAVE_(\w+)/) {
                                $tmp = $1;
                                $hvar2 = 'HAVE_'.$tmp;
                                if (! defined $symbols_checked{$hvar2}) {
                                    push(@hdrlines,"$comment\n") if ($full_output);
                                    push(@hdrlines,"#cmakedefine $hvar2 1\n");
                                    push(@hdrlines,"\n") if ($full_output);
                                    $symbols_checked{$hvar2} = 1;
                                }
                                $l = $l2;   # skip next
                                $done = 1;
                            } elsif ($nxline =~ /(\w+)_ENABLED/) {
                                $tmp = $1;
                                # things like CSVFMTS_ENABLED FILTERS_ENABLED
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#ifndef ".$tmp,"_ENABLED\n");
                                push(@hdrlines,"#cmakedefine ".$tmp."_ENABLED 1\n");
                                push(@hdrlines,"#endif\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $l = $l2;   # skip next
                                $done = 1;
                            } else {
                                $unservcnt++;
                                if (VERB1()) {
                                    prt("\n");
                                    prt("$lnn: An unserviced comment - *** fix me ***\n");
                                    prt("$comment\n");
                                    prt("$nxline\n") if (length($nxline));
                                    # NO, this is done in $hadfailed
                                    #if ($full_output && length($nxline)) {
                                    #    push(@unslines,"$comment\n");
                                    #    push(@unslines,"$nxline\n");
                                    #
                                }
                                $hadfailed = 1;
                            }
                        }
                    } else {
                        # Comment HAS 'Define to 1 if'
                        $res = substr($comment,$off+$deflen);
                        if ($res =~ /header/) {
                            if ($res =~ /<(.+)>\s+header/) {
                                # check_include_file(windows.h   HAVE_WINDOWS_H)
                                $tmp = $1;
                                $var = $tmp;
                                $var = uc($var);
                                $var =~ s/\./_/g;
                                $var =~ s/\//_/g;
                                $cmvar = 'HAVE_'.$var;
                                #$cmake .= "check_include_file($tmp $cmvar)\n";
                                #$cmake2 .= "#cmakedefine $cmvar 1\n";
                                push(@cmlinesi,"check_include_file($tmp $cmvar)\n");
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#cmakedefine $cmvar 1\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $needhe = 1;
                                $itemsdone++;
                                if ($nxline =~ /$cmvar/) {
                                    # this is GOOD
                                    $l = $l2;
                                    $done = 1;
                                } else {
                                    prt("Next line [$nxline] does NOT contain '$cmvar'!\n");
                                }
                            } else {
                                $hdrfailed++;
                                if (VERB1()) {
                                    $res = trim_all($res);
                                    prt("\n");
                                    prt("$lnn:1: $def [".$res."] header *** fix me ***\n");
                                    prt("$comment\n"); # if (VERB9());
                                    prt("$nxline\n") if (length($nxline));
                                }
                                $hadfailed = 1;
                            }
                        } elsif ($res =~ /function/) {
                            # If you have [`snprintf' function. */]
                            if ($res =~ /`(.+)'\s+function/) {
                                $tmp = $1;
                                $var = $tmp;
                                $var = uc($var);
                                $var =~ s/\./_/g;
                                $var =~ s/\//_/g;
                                $cmvar = 'HAVE_'.$var;
                                #$cmake .= "check_function_exists($tmp $cmvar)\n";
                                #$cmake2 .= "#cmakedefine $cmvar 1\n";
                                push(@cmlinesf,"check_function_exists($tmp $cmvar)\n");
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#cmakedefine $cmvar 1\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $itemsdone++;
                                $needfe = 1;
                                if ($nxline =~ /$cmvar/) {
                                    # this is GOOD
                                    $l = $l2;
                                    $done = 1;
                                } else {
                                    prt("Next line [$nxline] does NOT contain '$cmvar'!\n");
                                }
                            } else {
                                $funcfailed++;
                                if (VERB1()) {
                                    $res = trim_all($res);
                                    prt("\n");
                                    prt("$lnn:2: $def [".$res."] function *** fix me ***\n");
                                    prt("$comment\n"); # if (VERB9());
                                    prt("$nxline\n") if (length($nxline));
                                }
                                $hadfailed = 1;
                            }
                        } elsif ($res =~ /declaration/) {
                            $res = trim_all($res);
                            if ($res =~ /`(.+)',\s+and/) {
                                $tmp = $1;
                                $var = uc($tmp);
                                $cmvar = 'HAVE_DECL_'.$var;
                                #$cmake .= "check_function_exists($tmp $cmvar)\n";
                                #$cmake2 .= "#cmakedefine $cmvar 1\n";
                                push(@cmlinesf,"check_function_exists($tmp $cmvar)\n");
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#cmakedefine $cmvar 1\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $itemsdone++;
                                $needfe = 1;
                                if ($nxline =~ /$cmvar/) {
                                    # this is GOOD
                                    $l = $l2;
                                    $done = 1;
                                } else {
                                    prtw("WARNING: Next line [$nxline] does NOT contain '$cmvar'!\n");
                                }
                            } else {
                                $declfailed++;
                                if (VERB1()) {
                                    prt("\n");
                                    prt("$lnn:3: $def [".$res."] declaration *** fix me ***\n");
                                    prt("$comment\n"); # if (VERB9());
                                    prt("$nxline\n") if (length($nxline));
                                }
                                $hadfailed = 1;
                            }
                        } elsif ($res =~ /__attribute__/) {
                            if ($nxline =~ /^\s*\#\s*undef\s+(\w+)$/) {
                                $cmvar = $1;
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#cmakedefine $cmvar 1\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $itemsdone++;
                                $done = 1;
                            } else {
                                $attfailed++;
                                $res = trim_all($comment);
                                if (VERB1()) {
                                    prt("\n");
                                    prt("$lnn:4: [".$res."] *** FIX ME ***\n");
                                    prt("$nxline\n") if (length($nxline));
                                }
                                $hadfailed = 1;
                            }
                        } elsif (($nxlncnt == 1) && ($res =~ /\s+type\s+('|`)(\w+)'/)) {
                            $tmp = $2;
                            $var = uc($tmp);
                            $cmvar = 'HAVE_'.$var;
                            $hdr = '';
                            if ($nxline =~ /$cmvar/) {
                                # for cmake
                                $needse = 1;
                                if (defined $type_2_hdr{$tmp}) {
                                    $hdr = $type_2_hdr{$tmp};
                                }
                                if (defined $in_stdint_h{$tmp}) {
                                    $hdr = 'stdint.h';
                                }
                                if (length($hdr)) {
                                    push(@cmlinesi,"check_symbol_exists( $tmp $hdr $cmvar )\n");
                                } else {
                                    push(@cmlinesi,"# check_symbol_exists( $tmp 'MISSED_HDR' $cmvar ) # *** FIX ME ***\n");
                                }
                                push(@hdrlines,"$comment\n") if ($full_output);
                                push(@hdrlines,"#cmakedefine $cmvar 1\n");
                                push(@hdrlines,"\n") if ($full_output);
                                $itemsdone++;
                                $done = 1;
                            } else {
                                prtw("WARNING: Next line [$nxline] does NOT contain '$cmvar'!\n");
                                $hadfailed = 1;
                            }
                        } else {
                            $res = trim_all($res);
                            $res = trim_all($comment);
                            $unkfailed++;
                            if (VERB1()) {
                                prt("\n");
                                prt("$lnn:5: [".$res."] *** FIX ME ***\n");
                                ##prt("$comment\n"); # if (VERB9());
                                prt("$nxline\n") if (length($nxline));
                            }
                            $hadfailed = 1;
                        }
                    }
                    if ($hadfailed) {
                        push(@faillines,"$comment\n");
                        if ($nxline =~ /^\#/) {
                            push(@faillines,"/* $nxline */\n");
                            $l = $l2;
                            $l2++;
                            while ($l2 < $lncnt) {
                                 $nxline = trim_all($lines[$l2]);
                                 if ($nxline =~ /^\#/) {
                                    push(@faillines,"/* $nxline */\n");
                                    $l2++;
                                 } else {
                                     $l = $l2 - 1;
                                     last;
                                 }
                            }
                        }
                        push(@faillines,"\n");
                    }
                    $i++;
                    $commlines = 0;
                } else {
                    $comment .= $ch;
                }
            } else {
                if (($ch eq '/') && ($nc eq '*')) {
                    $incomm = 1;
                    $i++;
                    $comment = "/*";
                }
            }
        }
        if ($incomm) {
            $comment .= "\n";
            $commlines++;
        }
    }
    #if (length($cmake)) {
    if (@cmlinesf || @cmlinesi || (@faillines && $failed_output)) {
        prt("Dealt with $itemsdone items...\n");
        if (length($out_file)) {
            $tmp = "\n# For top of CMakeLists.txt file\n";
            $tmp .= "############################################################\n";
            $tmp .= "include (CheckFunctionExists)\n" if ($needfe);
            $tmp .= "include (CheckIncludeFile)\n"if ($needhe);
            $tmp .= "include (TestBigEndian)\n"if ($needbe);
            $tmp .= "include (CheckTypeSize)\n" if ($needts);
            $tmp .= "include (CheckSymbolExists)\n" if ($needse);
            $tmp .= "############################################################\n";
            $tmp .= "\n";

            #$tmp .= $cmake;
            #$tmp .= join("",@cmlines);
            $tmp .= "############################################################\n";
            $tmp .= "# for configuration section of CMakeLists.txt\n";
            $ch = scalar @cmlinesi;
            if ($ch) {
                $tmp .= "# $ch check_include_file items\n";
                $tmp .= join("",@cmlinesi);
            }
            $ch = scalar @cmlinesf;
            if ($ch) {
                $tmp .= "# $ch check_function_exists items\n";
                $tmp .= join("",@cmlinesf);
            }
            if ($needbe) {
                $tmp .= "# test WORD_ENDIANS\n";
                $tmp .= "test_big_endian(BIGENDIAN)\n";
                $tmp .= "if (BIGENDIAN)\n";
                $tmp .= "    message(STATUS \"*** Compiling in big endian architecture - WORDS_BIGENDIAN=1\")\n";
                $tmp .= "    set(WORDS_BIGENDIAN 1)\n";
                $tmp .= "else ()\n";
                $tmp .= "    message(STATUS \"*** Compiling in little endian architecture - WORDS_BIGENDIAN=0\")\n";
                $tmp .= "    set(WORDS_BIGENDIAN 0)\n";
                $tmp .= "endif ()\n";
            }
            $tmp .= "\n";
            $tmp .= "configure_file( \${CMAKE_SOURCE_DIR}/config.h.cmake \${CMAKE_BINARY_DIR}/config.h )\n";
            $tmp .= "include_directories( \${CMAKE_BINARY_DIR} )\n";
            $tmp .= "add_definitions( -DHAVE_CONFIG_H )\n";
            $tmp .= "############################################################\n";
            $tmp .= "\n";
            $tmp .= "/* ==========================================================\n";
            $tmp .= "    *** DO NOT MODIFY config.h ***\n";
            $tmp .= "    Instead modify config.cmake.h, and re-run cmake configure\n";
            $tmp .= "   ========================================================== */\n";
            $tmp .= "#ifndef _CONFIG_H_\n";
            $tmp .= "#define _CONFIG_H_\n";
            $tmp .= "\n";
            $tmp .= "\n// For config.h.cmake file\n";
            #$tmp .= $cmake2;
            $tmp .= join("",@hdrlines);
            if (@faillines && $failed_output) {
                $tmp .= "\n// The following failed in this script\n";
                $tmp .= "#if 0 // 000000000000000000000000000000000000000\n";
                $tmp .= "\n";
                $tmp .= join("",@faillines);
                $tmp .= "\n";
                $tmp .= "#endif // 000000000000000000000000000000000000000\n";
            }
            if (@unslines) {
                $tmp .= "\n// The following need to be CHECKED\n";
                $tmp .= join("",@unslines);
            }

            $tmp .= "\n// Original generated ".lu_get_YYYYMMDD_hhmmss_UTC(time())." UTC, by $pgmname\n";
            $tmp .= "#endif // _CONFIG_H_\n";
            $tmp .= "// eof\n";

            write2file($tmp,$out_file);
            prt("cmake results written to $out_file\n");
        } else {
            prt("\nFor CMakeLists.txt file\n");
            #prt($cmake);
            prt(join("",@cmlinesi)) if (@cmlinesi);
            prt(join("",@cmlinesf)) if (@cmlinesf);
            prt("\nFor config.h.cmake file\n");
            #prt($cmake2);
            prt(join("",@hdrlines));
            prt("No -o out-file given...\n");
        }
    }
    if ($unservcnt) {
        if (VERB1()) {
            prt("Note the $unservcnt 'UNSERVICED' comments above, and add fixes\n");
        } else {
            prt("Note: There were $unservcnt UNSERVICED comments. Use -v to output for fix.\n");
        }
    }

    $tmp = $hdrfailed + $funcfailed + $declfailed + $unkfailed + $attfailed;
    if ($tmp) {
        prt("Note: The $tmp 'FAILED' comments, and add fixes. (hdr=$hdrfailed,func=$funcfailed,decl=$declfailed,att=$attfailed,unk=$unkfailed)\n");
        if (!VERB1()) {
            prt("Add -v to ouput the failed items\n");
        }
    }
}

#########################################
### 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);
            } elsif ($sarg =~ /^a/) {
                $full_output = 1;
                prt("Set to include full comments as well.\n") if ($verb);
            } elsif ($sarg =~ /^f/) {
                $failed_output = 1;
                prt("Set to add failed comments to output.\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");
            $verbosity++;
            $load_log = 1;
            $full_output = 1;
        }
    }
    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");
    prt(" --add         (-a) = To add comments as well.\n");
    prt(" --failed      (-f) = To add failed items to output.\n");
    prt("AIM: Try to convert an automake 'config.in' file to cmake format\n");
    prt("Suggested output file name 'config.h.cmake'\n");

}

# eof - in2cmake.pl
