Generated: Tue Feb 2 17:54:19 2010 from am2dsp6.pl 2006/04/29 114.2 KB.
#!/Perl # use strict; use Cwd; my $vers = "6"; my $pack = "am2dsp".$vers; # String constants. my $IGNORE_PATTERN = "^##([^#].*)?\$"; my $WHITE_PATTERN = "^[ \t]*\$"; my $COMMENT_PATTERN = "^#"; my $RULE_PATTERN = "^([\$a-zA-Z_.][-.a-zA-Z0-9_(){}/\$]*) *:([^=].*|)\$"; my $SUFFIX_RULE_PATTERN = "^\\.([a-zA-Z]+)\\.([a-zA-Z]+)\$"; my $MACRO_PATTERN = "^([A-Za-z][A-Za-z0-9_]*)[ \t]*([:+]?)=[ \t]*(.*)\$"; my $BOGUS_MACRO_PATTERN = "^([^ \t]*)[ \t]*([:+]?)=[ \t]*(.*)\$"; my $IF_PATTERN = "^if[ \t]+\([A-Za-z][A-Za-z0-9_]*\)[ \t]*\(#.*\)?\$"; my $ELSE_PATTERN = "^else[ \t]*\(#.*\)?\$"; my $ENDIF_PATTERN = "^endif[ \t]*\(#.*\)?\$"; my $PATH_PATTERN='(\\w|/|\\.)+'; # This will pass through anything not of the prescribed form. my $INCLUDE_PATTERN = "^include[ \t]+((\\\$\\\(top_srcdir\\\)/${PATH_PATTERN})|(\\\$\\\(srcdir\\\)/${PATH_PATTERN})|([^/\\\$]${PATH_PATTERN}))[ \t]*(#.*)?\$"; my $AM_CONDITIONAL_PATTERN = "AM_CONDITIONAL\\((\\w+)"; my $AM_INIT_AUTOMAKE = "AM_INIT_AUTOMAKE\\(([^,]+),[ \t]*([^)]+)"; # Hash table of AM_CONDITIONAL variables seen in configure. my %configure_cond = (); # This holds the names which are targets. These also appear in # %contents. my %targets = (); # This holds the line numbers at which various elements of # %contents are defined. my %content_lines = (); my %content_seen = (); # This maps the source extension of a suffix rule to its # corresponding output extension. my %suffix_rules = (); # Hash table of discovered configure substitutions. Keys are names, # values are `FILE:LINE' strings which are used by error message # generation. my %configure_vars = (); # This holds the set of included files. my @include_stack = (); my $verbose = 0; my $vcond; my @conditional_stack = (); my %contents = (); my %conditional = (); # This holds our (eventual) exit status. We don't actually exit until # we have processed all input files - except when 'critical' ... my $exit_status = 0; my @make_input_list = (); my %make_list = (); # Names used in AC_CONFIG_HEADER call. @config_fullnames holds the # name which appears in AC_CONFIG_HEADER, colon and all. # @config_names holds the file names. @config_headers holds the '.in' # files. Ordinarily these are similar, but they can be different if # the weird "NAME:FILE" syntax is used. my @config_fullnames = (); my @config_names = (); my @config_headers = (); # Line number at which AC_CONFIG_HEADER appears in configure.ac. my $config_header_line = 0; # Relative location of top build directory. my $top_builddir = ''; my $relative_dir = '.'; my $output_vars = ''; my $output_trailer = ''; # List of Makefile.am's to process, and their corresponding outputs. my @input_files = (); my %output_files = (); # List of files in AC_OUTPUT without Makefile.am, and their outputs. my @other_input_files = (); my @var_list = (); my %am_vars = (); my %def_type = (); my @excluded_dirs = (); my @excluded_files = (); my $msvc_cflags = ""; my $msvc_threads = ""; my $msvc_libs = ""; my @extra_sources = (); my @extra_projects = (); my %used_inc_paths = (); my %used_lib_paths = (); # new variables my $verbose2 = 0; my $verbose3 = 1; my $msvc_dlibs = ""; my $msvc_rlibs = ""; my $in_debug = 0; my $in_release = 0; my $do_check = 0; my $def_cfg = "am2dsp".$vers.".cfg"; my $src_cfg = $def_cfg; my $root_dir = ''; my @msvc_dlibs_list = (); my @msvc_rlibs_list = (); my @msvc_libs_list = (); my @msvc_dlibs_paths = (); my @msvc_rlibs_paths = (); my @msvc_libs_paths = (); my @msvc_inc_paths = (); my @test_headers = ( 'zlib.h', 'AL/al.h', 'AL/alut.h', 'simgear/compiler.h', 'simgear/debug/logstream.hxx', 'plib/pu.h', 'Main/main.hxx', 'config.h', 'include/general.hxx', 'FGJSBBase.h'); my $add_groups = 0; # default to single, put duplicates 'Dupes' folder ... my @msvc_c_files = (); my @msvc_h_files = (); my @msvc_titles = (); # just to deal with duplicate names # EXTRA_DIST file lists from Makefile.am list my @msvc_c_extra = (); my @msvc_h_extra = (); my @msvc_o_extra = (); my $err_msg = ''; # am2dsp?.cfg define = AAA my %cfg_defines = (); # configure.ac equivalent my %def_defines = ( 'FG_JPEG_SERVER', 'ENABLE_JPEG_SERVER' ); # Extracted from AM_INIT_AUTOMAKE(package,version) my $dsp_package = 'FGFS'; my $dsp_version = '0.2'; my $static_lib = 0; my $write_old_dsp = 0; my $write_log = 1; # msvc8 stuff my $mod_vcproj = 0; my $debug_on = 0; my $debug_on2 = 0; my $debug_on3 = 0; my $debug_on4 = 0; my $debug_on5 = 0; my $vc8_root = 'projects\\VC8\\'; my $vc8_def_lib = $vc8_root.'FlightGearLib.vcproj'; my $vc8_def_main = $vc8_root.'FlightGear.vcproj'; my $add_vc8_path = '..\\..\\'; # relative from vcproj to DSW/DSP # VC8 project files and lines my $vc8_src_lib = $root_dir . $vc8_def_lib; my $vc8_src_main = $root_dir . $vc8_def_main; my @vc8_lib_lines = (); # storage of RAW lines my @vc8_main_lines = (); # VC8 information extracted from lines ... # VC8 headers and sources ############################################## my @vc8_main_hdrs = (); my @vc8_main_srcs = (); my @vc8_lib_hdrs = (); my @vc8_lib_srcs = (); my @vc8_dup_hdrs = (); my @vc8_dup_srcs = (); # VC8 include path, libraries and library paths ############################################### # MAIN storeage # configuration stuff my %main_msvc8_confi = (); my $main_msvc8_dintd = ''; my $main_msvc8_rintd = ''; # compiler stuff my @main_msvc8_dincs = (); my @main_msvc8_ddefs = (); my @main_msvc8_rincs = (); my @main_msvc8_rdefs = (); # linker stuff my @main_msvc8_dlibs = (); my @main_msvc8_dpath = (); my @main_msvc8_rlibs = (); my @main_msvc8_rpath = (); # other items my $main_warn = ''; # LIBRARY storage # configuration stuff my %lib_msvc8_confi = (); my $lib_msvc8_dintd = ''; my $lib_msvc8_rintd = ''; # compiler stuff my @lib_msvc8_dincs = (); my @lib_msvc8_ddefs = (); my @lib_msvc8_rincs = (); my @lib_msvc8_rdefs = (); # linker stuff my @lib_msvc8_dlibs = (); my @lib_msvc8_dpath = (); my @lib_msvc8_rlibs = (); my @lib_msvc8_rpath = (); # other items my $lib_warn = ''; my @not_in_vc8 = (); my @not_in_am = (); my %am_to_vc8 = (); # storeage of lines to DELETE my @vc8_main_delete = (); my @vc8_lib_delete = (); ############################################### # temporary collector variables # configuration stuff my %msvc8_confi = (); my $msvc8_dintd = ''; my $msvc8_rintd = ''; # compiler stuff my @msvc8_dincs = (); my @msvc8_ddefs = (); my @msvc8_rincs = (); my @msvc8_rdefs = (); # linker stuff my @msvc8_dlibs = (); my @msvc8_dpath = (); my @msvc8_rlibs = (); my @msvc8_rpath = (); # other items my $warn = ''; my ($LOG); my $outfile = 'templog'.$vers.'.txt'; if ( open $LOG, ">$outfile" ) { $write_log = 1; } else { $write_log = 0; prt( "WARNING: Unable to open $outfile LOG ...\n" ); } my $cwdir = getcwd(); parse_arguments(@ARGV); # Read project configuration file. read_am2dsprc($src_cfg); scan_configure(); mydie( "$pack: no input_files, so no 'Makefile.am' found or specified\n" ) if ! @input_files; if ($write_old_dsp) { if ($static_lib) { static_lib_dsp_init($dsp_package); } else { console_app_dsp_init($dsp_package); } } my $am_file; if ( ! $add_groups && $write_old_dsp ) { add_group_start($dsp_package); } foreach $am_file (@input_files) { prt( "\nProcessing [$am_file] from input_files array ...\n" ) if $verbose2; dsp_add_group($dsp_package, $am_file) if !exclude_dir($am_file); } if ( ! $add_groups && $write_old_dsp ) { add_group_end($dsp_package); } if ($write_old_dsp) { dsp_finish($dsp_package); generate_dsw( $dsp_package ); prt( "Done ".$root_dir.$dsp_package." DSP and DSW files ...\n" ); } if ($do_check) { check_includes(); } if ( ! $write_old_dsp) { write_new_dsp(); # experimental NEW DSP separating source and headers } if ( $mod_vcproj ) { amend_vcproj(); # experimental - amend the VCPROJ files } exit $exit_status; # end of process sub add_group_start { my $dsp_name = shift; my $dsp_file = $root_dir . $dsp_name . '.dsp'; open(DSP, ">>$dsp_file") || mydie( "Can't append to $dsp_file: $!\n" ); print DSP "# Begin Group \"Source Files\"\r\n"; print DSP "\r\n"; print DSP "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;h;hpp;hxx;hm;inl\"\r\n"; close(DSP); } sub add_group_end { my $dsp_name = shift; my $dsp_file = $root_dir . $dsp_name . '.dsp'; open(DSP, ">>$dsp_file") || mydie( "Can't append to $dsp_file: $!\n" ); print DSP "# End Group\r\n"; close(DSP); } sub exclude_dir { my $dir = shift; foreach my $d (@excluded_dirs) { if ($dir =~ "/$d/") { return 1; } } return 0; } sub exclude_file { my $file = shift; foreach my $f (@excluded_files) { if ($file =~ /$f/) { return 1; } } return 0; } # # TODO: option to specify static library or console app. # sub give_little_help { prt( "am2dsp".$vers.": Just a little help ...\n" ); prt( "--help (or -h, -?) - This brief help!\n" ); prt( "--verbose (or -v) - Sets verbose mode. (-v2 for MORE)\n" ); prt( "--package name - Set the DSP package name (default = $dsp_package)\n" ); prt( "--lib (or -l) - To create static library (Default is console app.)\n" ); prt( "--groups (or -g) - Output source into 'group' folders, as original!\n" ); prt( "--dir path - Establish input path for source, and the $def_cfg.\n" ); prt( "--check (or -c) - Check libraries, and some known include files, and exit.\n" ); prt( "--cfg path\\file - Use a specific configuration file, if not with source.\n" ); prt( "--msvc8 - Modify, or check, the vcproj files, if found.\n" ); prt( "Note, this --cfg path\\file MUST be after the --dir path, if used.\n" ); prt( "Any other option beginning with '-' will abort, with a complaint ...\n" ); mydie( "Any other input - is ignored ...\n" ); } sub set_input_dir { my $cfg = shift; if ( !(($cfg =~ /\/$/) || ($cfg =~ /\\$/)) ) { $cfg .= '\\'; } my $fil = $cfg . $def_cfg; $src_cfg = $fil; $root_dir = $cfg; $vc8_src_lib = $root_dir . $vc8_def_lib; $vc8_src_main = $root_dir . $vc8_def_main; prt( "Using root path [$root_dir] ...\n" ); } sub parse_arguments { my @av = @_; my $arg = ''; while (@av) { $arg = $av[0]; if ($arg eq '--help' || $arg eq '-h' || $arg eq '-?') { give_little_help(); # show help and exit } elsif ($arg eq '--verbose' || $arg eq '-v') { $verbose = 1; } elsif ($arg eq '--package' || $arg eq '-p') { require_argument(@av); shift @av; $dsp_package = $av[0]; } elsif ($arg eq '--lib' || $arg eq '-l') { # Create a static library $static_lib = 1; } elsif ($arg eq '--dir') { require_argument(@av); shift @av; set_input_dir($av[0]); } elsif ($arg eq '--check' || $arg eq '-c') { $do_check = 1; # perform check and exit } elsif ($arg eq '--cfg') { require_argument(@av); shift @av; $src_cfg = $av[0]; } elsif ($arg eq '-v2' ) { $verbose2 = 1; } elsif ($arg eq '-v3' ) { $verbose3 = 1; } elsif ($arg eq '-dbg' ) { $verbose = 1; $verbose2 = 1; $verbose3 = 1; $debug_on = 1; $debug_on2 = 1; $debug_on3 = 1; $debug_on4 = 1; $debug_on5 = 1; } elsif ($arg eq '--groups' || $arg eq '-g') { $add_groups = 1; # use original 'group' folders ... } elsif ($arg eq '--msvc8') { $mod_vcproj = 1; } elsif ($arg =~ /^-/) { mydie( "$pack: unrecognised option, namely '$arg'\nTry --help or -? for some information.\n" ); } else { # quietly IGNORE other inputs??? } shift @av; } if ( !( -f $src_cfg) ) { if ( -f $def_cfg) { prt( "Warning: Unable to locate file [$src_cfg] ...\n" ); prt( "Using file [$def_cfg], in [".getcwd()."], in its place ...\n" ); $src_cfg = $def_cfg; } else { mydie("ERROR: Unable to locate file [$src_cfg] ... \ncheck input, and/or folder ... aborting ...\n"); } } } sub add_2_msvc { my $flg = shift; if ($in_debug) { $msvc_dlibs .= $flg; } elsif ($in_release) { $msvc_rlibs .= $flg; } else { $msvc_libs .= $flg; } } sub add_2_libs { my $flg = shift; if ($in_debug) { push(@msvc_dlibs_list, $flg); } elsif ($in_release) { push(@msvc_rlibs_list, $flg); } else { push(@msvc_libs_list, $flg); } } sub add_2_libpaths { my $flg = shift; if ($in_debug) { push(@msvc_dlibs_paths, $flg); } elsif ($in_release) { push(@msvc_rlibs_paths, $flg); } else { push(@msvc_libs_paths, $flg); } } sub read_am2dsprc { my $rc_file = shift; open( RC_FILE, $rc_file ) or mydie( "Can't open $rc_file: $!\n" ); my $line; my @cond_stack = (); while (defined($line = <RC_FILE>)) { chomp $line; if ($line =~ s/\\$//) { # continuation line $line .= "%"; $line .= <RC_FILE>; redo unless eof(RC_FILE); } prt( "Processing line [$line] ...\n" ) if ($debug_on3); next if $line =~ /^$/; # ignore blank lines next if $line =~ /^#/; # ignore comments if ($line =~ /exclude_dir\s*=\s*(\S+)/) { push( @excluded_dirs, $1 ); } elsif ($line =~ /exclude_file\s*=\s*(\S+)/) { my $f; ($f = $1) =~ s/\\/\\\\/g; # escape path separators, "\" -> "\\" push( @excluded_files, $f ); prt( "Excluding file: $f\n" ) if $verbose; } elsif ($line =~ /include_path\s*=\s*(\S+)/) { $msvc_cflags .= " /I \"$1\""; push(@msvc_inc_paths, $1); } elsif ($line =~ /add_vc8_path\s*=\s*(\S+)/) { $add_vc8_path = $1; prt( "Got from VC8 to root path: [$1]\n" ) if $verbose; } elsif ($line =~ /define\s*=\s*(\S+)/) { if ($debug_on) { if (defined $def_defines{$1} ) { prt( "Got define of $1 ... which is $def_defines{$1} ...\n" ); $cfg_defines{$def_defines{$1}} = 1; # add configure.ac } else { prt( "Got define of $1 ...\n" ); } if ( defined $cfg_defines{$1} ) { prt( "Warning: cfg_defines of $1 already defined ...\n" ); } } $cfg_defines{$1} = 1; $msvc_cflags .= " /D \"$1\""; } elsif ($line =~ /lib_path\s*=\s*(\S+)/) { add_2_msvc( " /libpath:\"$1\"" ); add_2_libpaths( "$1" ); } elsif ($line =~ /add_lib\s*=\s*(\S+)/) { add_2_msvc( " $1.lib" ); add_2_libs( "$1.lib" ); } elsif ($line =~ /type\s*=\s*(\S+)/) { my ($type,$threads,$debug) = split /,/, $1; prt( "type=$type, threading=$threads, debug=$debug\n" ) if $verbose; if ($type =~ "ConsoleApplication") { $static_lib = 0 } elsif ($type =~ "StaticLibrary") { $static_lib = 1 } else { # Invalid type } my $flags = " /ML"; # single threaded. if ($threads =~ /Multithreaded/) { $flags = " /MT"; } elsif ($threads =~ /Singlethreaded/) { $flags = " /ML"; } else { # Invalid threading option. } if ($debug =~ /Debug/) { $flags .= "d"; } $msvc_cflags .= $flags; } elsif ($line =~ /add_source_file\s*=\s*(.*)/) { my $rule; ($rule = $1) =~ s/%/\r\n/g; push( @extra_sources, $rule ); } elsif ($line =~ /add_project\s*=\s*(.*)/) { push( @extra_projects, $1 ); } elsif ($line =~ /$IF_PATTERN/o) { my $ifcond = $1; if ($ifcond =~ /Debug/io) { prt( "Entering DEBUG ...\n" ) if $verbose2; $in_debug = 1; $in_release = 0; } elsif ($ifcond =~ /Release/io) { prt( "Entering RELEASE ...\n" ) if $verbose2; $in_release = 1; $in_debug = 0; } else { prt( "EEK! Got $ifcond ...\n" ); mydie( "Presently ONLY if switch is 'Debug' or 'Release'!\n" ); } push (@cond_stack, "\@" . $ifcond . "_TRUE\@"); } elsif ($line =~ /$ELSE_PATTERN/o) { if (! @cond_stack) { mydie( "else without if!\n" ); } elsif ($cond_stack[$#cond_stack] =~ /_FALSE\@$/) { mydie( "else after an else!\n" ); } else { if ($in_debug) { prt( "Switch to RELEASE ...\n" ) if $verbose2; $in_debug = 0; $in_release = 1; } else { prt( "Switch to DEBUG ...\n" ) if $verbose2; $in_debug = 1; $in_release = 0; } $cond_stack[$#cond_stack] =~ s/_TRUE\@$/_FALSE\@/; } } elsif ($line =~ /$ENDIF_PATTERN/o) { if (! @cond_stack) { mydie( "endif without if!\n" ); } prt( "Exit $cond_stack[$#cond_stack] ...\n" ) if $verbose2; pop (@cond_stack); $in_debug = 0; $in_release = 0; } } # end while close(RC_FILE); } # Ensure argument exists, or die. sub require_argument { my ($arg, @arglist) = @_; mydie( "$pack: no argument given for option '$arg'\n" ) if ! @arglist; } sub scan_configure { my $ff = $root_dir . 'configure.ac'; scan_one_configure_file($ff); $ff = $root_dir . 'aclocal.m4'; scan_one_configure_file($ff) if -f $ff; if (! @input_files) { prt( "Copying " . scalar @make_input_list . " make_input_list to input_files.\n" ) if $verbose2; @input_files = @make_input_list; %output_files = %make_list; } else { prt( "input_files has list of " . scalar @input_files . " ...\n" ) if $verbose2; } if ($verbose2) { my $cnt = scalar @input_files; prt( "\nOutput of $cnt input_files list ...\n" ); $cnt = 0; foreach $ff (@input_files) { $cnt++; prt( "$cnt $ff\n" ); } prt( "Done $cnt input_files list ...\n" ); } } sub scan_one_configure_file { my $filename = shift; open(CONFIGURE, $filename) || mydie( "$pack: can't open '$filename': $!\nCurrently running in $cwdir ...\n" ); prt( "$pack: reading $filename\n" ) if $verbose; my $in_ac_output = 0; my $ac_output_line = ''; my $ff = ''; while (<CONFIGURE>) { # Remove comments from current line. s/\bdnl\b.*$//; s/\#.*$//; # Skip macro definitions. Otherwise we might be confused into # thinking that a macro that was only defined was actually # used. next if /AC_DEFUN/; # Follow includes. This is a weirdness commonly in use at # Cygnus and hopefully nowhere else. if (/sinclude\((.*)\)/ && -f ($root_dir . $1)) { $ff = $root_dir . $1; &scan_one_configure_file ($ff); } if (! $in_ac_output && ( s/AC_OUTPUT\s*\(\[?// || s/AC_CONFIG_FILES\s*\(\[?// ) ) { $in_ac_output = 1; $ac_output_line = $.; } if ($in_ac_output) { my $closing = 0; if (s/[\]\),].*$//) { $in_ac_output = 0; $closing = 1; } # Look at potential Makefile.am's foreach (split) { # Must skip empty string for Perl 4. next if $_ eq "\\" || $_ eq ''; my ($local,$input,@rest) = split(/:/); if (! $input) { $input = $local; } else { $input =~ s/\.in$//; } $ff = $root_dir . $input . '.am'; if (-f $ff) { prt( "Adding $input [$ff] to make_input_list ...\n" ) if $verbose2; push(@make_input_list, $input); $make_list{$input} = join(':', ($local,@rest)); } else { prt( "Adding $input [$ff] to other_input_files ...\n" ) if $verbose2; # We have a file that automake should cause to be # rebuilt, but shouldn't generate itself. push (@other_input_files, $_); } } } # Handle configuration headers. A config header of `[$1]' # means we are actually scanning AM_CONFIG_HEADER from # aclocal.m4. if (/A([CM])_CONFIG_HEADER\s*\((.*)\)/ && $2 ne '[$1]') { &am_conf_line_error ($filename, $., "\`automake requires \`AM_CONFIG_HEADER', not \`AC_CONFIG_HEADER'") if $1 eq 'C'; $config_header_line = $.; my ($one_hdr); foreach $one_hdr (split (' ', $2)) { push (@config_fullnames, $one_hdr); if ($one_hdr =~ /^([^:]+):(.+)$/) { push (@config_names, $1); push (@config_headers, $2); } else { push (@config_names, $one_hdr); push (@config_headers, $one_hdr . '.in'); } } } if (/$AM_CONDITIONAL_PATTERN/o) { if ( defined $cfg_defines{$1} ) { # has been DEFINED in am2dsp?.cfg file prt( "Storing configure_cond key $1 ... value=2\n" ) if ($debug_on3); $configure_cond{$1} = 2; } else { prt( "Storing configure_cond key $1 ... value=1\n" ) if ($debug_on3); $configure_cond{$1} = 1; } } if (/$AM_INIT_AUTOMAKE/o) { $dsp_package = $1; $dsp_version = $2; } } close(CONFIGURE); } sub read_main_am_file { $am_file = shift; read_am_file($am_file); my @topdir = (); foreach (split(/\//, $relative_dir)) { next if $_ eq '.' || $_ eq ''; if ($_ eq '..') { pop @topdir; } else { push(@topdir, '..'); } } @topdir = ('.') if ! @topdir; my $top_builddir = join('/', @topdir); } sub read_am_file { $am_file = shift; open( AM_FILE, $am_file ) or mydie( "Can't open $am_file: $!\n" ); prt( "$pack: reading $am_file\n" ) if $verbose; my $saw_bk = 0; my $was_rule = 0; my $spacing = ''; my $comment = ''; my $last_var_name = ''; my $blank = 0; my $cond_true = 2; # undetermined ... while (<AM_FILE>) { if (/$IGNORE_PATTERN/o) { # Merely delete comments beginning with two hashes. } elsif (/$WHITE_PATTERN/o) { # Stick a single white line before the incoming macro or rule. $spacing = "\n"; $blank = 1; } elsif (/$COMMENT_PATTERN/o) { # Stick comments before the incoming macro or rule. Make # sure a blank line preceeds first block of comments. $spacing = "\n" unless $blank; $blank = 1; $comment .= $spacing . $_; $spacing = ''; } else { last; } } $output_vars .= $comment . "\n"; $comment = ''; $spacing = "\n"; my $source_suffix_pattern = ''; my $is_ok_macro = 0; while ($_) { if ($debug_on3) { my $aml = $_; chomp $aml; $aml =~ s/\r$//; # and remove CR, if present prt( "$. [$aml]\n" ); } $_ .= "\n" unless substr ($_, -1, 1) eq "\n"; if (/$IGNORE_PATTERN/o) { # Merely delete comments beginning with two hashes. } elsif (/$WHITE_PATTERN/o) { # Stick a single white line before the incoming macro or rule. $spacing = "\n"; &am_line_error ($., "blank line following trailing backslash") if $saw_bk; } elsif (/$COMMENT_PATTERN/o) { # Stick comments before the incoming macro or rule. $comment .= $spacing . $_; $spacing = ''; &am_line_error ($., "comment following trailing backslash") if $saw_bk; } elsif ($saw_bk) { # continuation of previous line(s) ... if ($was_rule) { $output_trailer .= join ('', @conditional_stack) . $_; $saw_bk = /\\$/; } else { $saw_bk = /\\$/; # Chop newline and backslash if this line is # continued. ensure trailing whitespace exists. chop if $saw_bk; chop if $saw_bk; # decide if to be added to 'contents' ... my $add_it = 0; # assume NO if ( defined $contents{$last_var_name} ) { if ( @conditional_stack ) { if ( $conditional_stack[$#conditional_stack] =~ /_TRUE\@$/ ) { # we are in the if TRUE state if ($cond_true == 1) { $add_it = 1; } } else { # we are in a FALSE state if ($cond_true != 1) { $add_it = 1; } } } else { ###prt( "No conditional stack for this macro! lv=[$last_var_name] ". ### "add_it\n" ) if ($debug_on3); $add_it = 1; # so add it } } else { # NO contents for this var prt( "NO contents for [$last_var_name]! ". "Technical this is an ERROR, but for now add_it...\n" ) if ($debug_on3); $add_it = 1; } if ($add_it) { $contents{$last_var_name} .= ' ' unless $contents{$last_var_name} =~ /\s$/; $contents{$last_var_name} .= $_; if (@conditional_stack) { $conditional{$last_var_name} .= "e_cond_val ($_); } prt( "End $last_var_name = [". trim_line($contents{$last_var_name})."]...\n" ) if ( ! $saw_bk && $debug_on3); } else { prt( "Warning: Discarding this [$_] ... CHECK ME!\n" ) if ($debug_on3); } } } elsif (/$IF_PATTERN/o) { if ( defined $configure_cond{$1} ) { ###if ( defined $cfg_defines{$1} ) if ($configure_cond{$1} == 2) { prt( "Found if $1, and condition is TRUE (see cfg_defines) ...\n" ) if ($debug_on3); $cond_true = 1; } else { prt( "Found if $1, but NOT in cfg_defines ...\n" ) if ($debug_on3); $cond_true = 0; } } else { &am_line_error ($., "$1 does not appear in AM_CONDITIONAL"); } push (@conditional_stack, "\@" . $1 . "_TRUE\@"); } elsif (/$ELSE_PATTERN/o) { if (! @conditional_stack) { &am_line_error ($., "else without if"); } elsif ($conditional_stack[$#conditional_stack] =~ /_FALSE\@$/) { &am_line_error ($., "else after else"); } else { $conditional_stack[$#conditional_stack] =~ s/_TRUE\@$/_FALSE\@/; } } elsif (/$ENDIF_PATTERN/o) { if (! @conditional_stack) { &am_line_error ($., ": endif without if"); } else { pop @conditional_stack; } $cond_true = 2; # undetermined ... } elsif (/$RULE_PATTERN/o) { # Found a rule. $was_rule = 1; if (defined $contents{$1} && (@conditional_stack ? ! defined $conditional{$1} : defined $conditional{$1})) { &am_line_error ($1, "$1 defined both conditionally and unconditionally"); } # Value here doesn't matter; for targets we only note # existence. $contents{$1} = 1; $targets{$1} = 1; my $cond_string = join ('', @conditional_stack); if (@conditional_stack) { if ($conditional{$1}) { &check_ambiguous_conditional ($1, $cond_string); $conditional{$1} .= ' '; } else { $conditional{$1} = ''; } $conditional{$1} .= $cond_string . ' 1'; } $content_lines{$1} = $.; $output_trailer .= $comment . $spacing . $cond_string . $_; $comment = $spacing = ''; $saw_bk = /\\$/; # Check the rule for being a suffix rule. If so, store in # a hash. my $source_suffix; my $object_suffix; if (($source_suffix, $object_suffix) = ($1 =~ $SUFFIX_RULE_PATTERN)) { $suffix_rules{$source_suffix} = $object_suffix; prt( "Sources ending in .$source_suffix become .$object_suffix\n" ) if $verbose; $source_suffix_pattern = "(" . join('|', keys %suffix_rules) . ")"; } # FIXME: make sure both suffixes are in SUFFIXES? Or set # SUFFIXES from suffix_rules? } elsif (($is_ok_macro = /$MACRO_PATTERN/o) || /$BOGUS_MACRO_PATTERN/o) { prt( "Found a macro definition. 1[$1] 2[$2] 3[$3] ...\n" ) if ($debug_on3); $was_rule = 0; $last_var_name = $1; if (defined $contents{$1} && (@conditional_stack ? ! defined $conditional{$1} : defined $conditional{$1})) { &am_line_error ($1, "$1 defined both conditionally and unconditionally"); } my $value; if ($3 ne '' && substr ($3, -1) eq "\\") { $value = substr ($3, 0, length ($3) - 1); } else { $value = $3; } my $type = $2; if ($type eq '+') { if (! defined $contents{$last_var_name} && defined $configure_vars{$last_var_name}) { $contents{$last_var_name} = '@' . $last_var_name . '@'; } $contents{$last_var_name} .= ' ' . $value; } else { if ( defined $contents{$last_var_name} ) { if ( @conditional_stack ) { if ( $conditional_stack[$#conditional_stack] =~ /_TRUE\@$/ ) { # we are in the if TRUE state if ($cond_true == 1) { if ($debug_on3) { if ( $contents{$last_var_name} ne $value ) { prt( "NB: [$last_var_name] = [$contents{$last_var_name}]" . " replaced with [$value] (am_file=$am_file line=$.)". (/\\$/ ? "saw_bk" : "end") . "\n" ); } } $contents{$last_var_name} = $value; $content_lines{$last_var_name} = $.; } } else { # we are in the else FALSE state if ($cond_true != 1) { if ($debug_on3) { if ( $contents{$last_var_name} ne $value ) { prt( "NB: [$last_var_name] = [$contents{$last_var_name}]" . " replaced with [$value] (am_file=$am_file line=$.)". (/\\$/ ? "saw_bk" : "end") . "\n" ); } } $contents{$last_var_name} = $value; $content_lines{$last_var_name} = $.; } } } } else { prt( "First setting [$last_var_name] = [$value] " . "(am_file=$am_file line=$.) ". (/\\$/ ? "saw_bk" : "end") . "\n" ) if ($debug_on3); $contents{$last_var_name} = $value; # The first assignment to a macro sets the line # number. Ideally I suppose we would associate line # numbers with random bits of text. $content_lines{$last_var_name} = $.; } } my $cond_string = join ('', @conditional_stack); if (@conditional_stack) { my $found = 0; my $val; if ($conditional{$last_var_name}) { if ($type eq '+') { # If we're adding to the conditional, and it # exists, then we might want to simply replace # the old value with the new one. my (@new_vals, @cond_vals); @cond_vals = split (' ', $conditional{$last_var_name}); while (@cond_vals) { $vcond = shift (@cond_vals); push (@new_vals, $vcond); if (&conditional_same ($vcond, $cond_string)) { $found = 1; $val = (&unquote_cond_val (shift (@cond_vals)) . ' ' . $value); push (@new_vals, "e_cond_val ($val)); } else { push (@new_vals, shift (@cond_vals)); } } if ($found) { $conditional{$last_var_name} = join (' ', @new_vals); } } if (! $found) { &check_ambiguous_conditional ($last_var_name, $cond_string); $conditional{$last_var_name} .= ' '; $val = $value; } } else { $conditional{$last_var_name} = ''; $val = $contents{$last_var_name}; } if (! $found) { $conditional{$last_var_name} .= ($cond_string . ' ' . "e_cond_val ($val)); } } # FIXME: this doesn't always work correctly; it will group # all comments for a given variable, no matter where # defined. $am_vars{$last_var_name} = $comment . $spacing; $def_type{$last_var_name} = ($type eq ':') ? ':' : ''; push (@var_list, $last_var_name); $comment = $spacing = ''; $saw_bk = /\\$/; # Error if bogus. &am_line_error ($., "bad macro name \`$last_var_name'") if ! $is_ok_macro; } elsif (/$INCLUDE_PATTERN/o) { my ($path) = $1; if ($path =~ s/^\$\(top_srcdir\)\///) { push (@include_stack, "\$\(top_srcdir\)/$path"); } else { $path =~ s/\$\(srcdir\)\///; push (@include_stack, "\$\(srcdir\)/$path"); $path = $relative_dir . "/" . $path; } &read_am_file ($path); } else { # This isn't an error; it is probably a continued rule. # In fact, this is what we assume. $was_rule = 1; $output_trailer .= ($comment . $spacing . join ('', @conditional_stack) . $_); $comment = $spacing = ''; $saw_bk = /\\$/; } $_ = <AM_FILE>; } close(AM_FILE); $output_trailer .= $comment; &am_error ("unterminated conditionals: " . join (' ', @conditional_stack)) if (@conditional_stack); } sub initialize_per_input { # These two variables are used when generating each Makefile.in. # They hold the Makefile.in until it is ready to be printed. $output_vars = ''; $output_trailer = ''; # This holds the contents of a Makefile.am, as parsed by # read_am_file. %contents = (); # This holds the names which are targets. These also appear in # %contents. %targets = (); # For a variable or target which is defined conditionally, this # holds an array of the conditional values. The array is composed # of pairs of condition strings (the variables which configure # will substitute) and values (the value of a target is # meaningless). For an unconditional variable, this is empty. %conditional = (); # This holds the line numbers at which various elements of # %contents are defined. %content_lines = (); # This holds a 1 if a particular variable was examined. %content_seen = (); # This is the conditional stack. @conditional_stack = (); # This holds the set of included files. @include_stack = (); # This holds the "relative directory" of the current Makefile.in. # Eg for src/Makefile.in, this is "src". $relative_dir = ''; # This maps the source extension of a suffix rule to its # corresponding output extension. %suffix_rules = (); } # Quote a value in order to put it in $conditional. We need to quote # spaces, and we need to handle null strings, so that we can later # retrieve values by splitting on space. sub quote_cond_val { my ($val) = @_; $val =~ s/ /\001/g; $val =~ s/\t/\003/g; $val = "\002" if $val eq ''; return $val; } # this function seems MISSING - maybe never used! sub unquote_cond_val { my ($val) = @_; $val =~ s/\001/ /g; $val =~ s/\003/\t/g; $val = '' if $val eq "\002"; return $val; } # See if a conditional is true. Both arguments are conditional # strings. This returns true if the first conditional is true when # the second conditional is true. sub conditional_true_when { my ($cond, $when) = @_; # Check the easy case first. if ($cond eq $when) { return 1; } # Check each component of $cond, which looks @COND1@@COND2@. foreach my $comp (split ('@', $cond)) { # The way we split will give null strings between each # condition. next if ! $comp; if (index ($when, '@' . $comp . '@') == -1) { return 0; } } return 1; } # Check for an ambiguous conditional. This is called when a variable # or target is being defined conditionally. If we already know about # a definition that is true under the same conditions, then we have an # ambiguity. sub check_ambiguous_conditional { my ($var_name, $cond) = @_; my (@cond_vals) = split (' ', $conditional{$var_name}); while (@cond_vals) { my ($vcond) = shift (@cond_vals); shift (@cond_vals); if (&conditional_true_when ($vcond, $cond) || &conditional_true_when ($cond, $vcond)) { prt( "$var_name multiply defined in condition\n" ); } } } sub am_error { my $msg = shift; mydie( $msg."\n" ); } sub am_line_error { my ($symbol, @args) = @_; prt( "am_line_error: am_file=[$am_file] sym=[$symbol] arg0=[$args[0]] ...\n" ) if ($debug_on3); if ($symbol && "$symbol" ne '-1') { my ($file) = "${am_file}"; if ($symbol =~ /^\d+$/) { # SYMBOL is a line number, so just add the colon. $file .= ':' . $symbol; } elsif (defined $content_lines{$symbol}) { # SYMBOL is a variable defined in Makefile.am, so add the # line number we saved from there. $file .= ':' . $content_lines{$symbol}; } elsif (defined $configure_vars{$symbol}) { # SYMBOL is a variable defined in configure.ac, so add the # appropriate line number. $file = $configure_vars{$symbol}; } else { # Couldn't find the line number. } warn $file, ": ", join (' ', @args), "\n"; $exit_status = 1; } else { &am_error (@args); } } sub generate_dsw { my $name = shift; my $dsw_name = $root_dir . $name . '.dsw'; open(DSW, ">$dsw_name") || mydie( "Can't create $dsw_name: $!\n" ); prt( "Creating $dsw_name\n" ) if $verbose; print DSW <<"EOF"; Microsoft Developer Studio Workspace File, Format Version 6.00\r # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r \r ###############################################################################\r \r EOF print DSW 'Project: ', "\"$name\"=\".\\", $name, ".dsp\" - Package Owner=<4>\r\n"; print DSW <<"EOF"; \r Package=<5>\r {{{\r }}}\r \r Package=<4>\r {{{\r }}}\r \r EOF foreach my $p (@extra_projects) { print DSW "###############################################################################\r\n\r\n"; my ($dsp,$name) = split ',', $p; prt( "Project $name=$dsp\n" ) if $verbose; print DSW "Project: \"$name\"=\"$dsp\" - Package Owner=<4>\r\n\r\n"; print DSW <<"EOF"; Package=<5>\r {{{\r }}}\r \r Package=<4>\r {{{\r }}}\r \r EOF } print DSW <<"EOF"; ###############################################################################\r \r Global:\r \r Package=<5>\r {{{\r }}}\r \r Package=<3>\r {{{\r }}}\r \r ###############################################################################\r \r EOF close(DSW); } sub expand_here { local $_ = shift; s/\%cflags\%/$msvc_cflags/g; s/\%libs\%/$msvc_libs/g; s/\%dlibs\%/$msvc_dlibs/g; s/\%rlibs\%/$msvc_rlibs/g; return $_; } sub console_app_dsp_init { my $name = shift; my $dsp_name = $root_dir . $name . '.dsp'; open(DSP, ">$dsp_name") || mydie( "Can't create $dsp_name: $!\n" ); prt( "Creating $dsp_name\n" ) if $verbose; print DSP expand_here(<<"EOF"); # Microsoft Developer Studio Project File - Name="$name" - Package Owner=<4>\r # Microsoft Developer Studio Generated Build File, Format Version 6.00\r # ** DO NOT EDIT **\r \r # TARGTYPE "Win32 (x86) Console Application" 0x0103\r \r CFG=$name - Win32 Debug\r !MESSAGE This is not a valid makefile. To build this project using NMAKE,\r !MESSAGE use the Export Makefile command and run\r !MESSAGE \r !MESSAGE NMAKE /f "$name.mak".\r !MESSAGE \r !MESSAGE You can specify a configuration when running NMAKE\r !MESSAGE by defining the macro CFG on the command line. For example:\r !MESSAGE \r !MESSAGE NMAKE /f "$name.mak" CFG="$name - Win32 Debug"\r !MESSAGE \r !MESSAGE Possible choices for configuration are:\r !MESSAGE \r !MESSAGE "$name - Win32 Release" (based on "Win32 (x86) Console Application")\r !MESSAGE "$name - Win32 Debug" (based on "Win32 (x86) Console Application")\r !MESSAGE \r \r # Begin Project\r # PROP AllowPerConfigDependencies 0\r # PROP Scc_ProjName ""\r # PROP Scc_LocalPath ""\r CPP=cl.exe\r RSC=rc.exe\r \r !IF "\$(CFG)" == "$name - Win32 Release"\r \r # PROP Use_MFC 0\r # PROP Use_Debug_Libraries 0\r # PROP Output_Dir "Release"\r # PROP Intermediate_Dir "Release"\r # PROP Target_Dir ""\r # ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c %cflags%\r # SUBTRACT CPP /YX\r # ADD RSC /l 0xc09 /d "NDEBUG"\r BSC32=bscmake.exe\r # ADD BSC32 /nologo\r LINK32=link.exe\r # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 %libs% %rlibs%\r \r !ELSEIF "\$(CFG)" == "$name - Win32 Debug"\r \r # PROP Use_MFC 0\r # PROP Use_Debug_Libraries 1\r # PROP Output_Dir "Debug"\r # PROP Intermediate_Dir "Debug"\r # PROP Ignore_Export_Lib 0\r # PROP Target_Dir ""\r # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c %cflags%\r # ADD RSC /l 0xc09 /d "_DEBUG"\r BSC32=bscmake.exe\r # ADD BSC32 /nologo\r LINK32=link.exe\r # ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib gdi32.lib shell32.lib advapi32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept %libs% %dlibs%\r \r !ENDIF \r \r # Begin Target\r \r # Name "$name - Win32 Release"\r # Name "$name - Win32 Debug"\r EOF close(DSP); } sub static_lib_dsp_init { my $name = shift; my $dsp_name = $root_dir . $name . '.dsp'; open(DSP, ">$dsp_name") || mydie( "Can't create $dsp_name: $!\n" ); prt( "Creating $dsp_name\n" ) if $verbose; print DSP expand_here(<<"EOF"); # Microsoft Developer Studio Project File - Name="$name" - Package Owner=<4>\r # Microsoft Developer Studio Generated Build File, Format Version 6.00\r # ** DO NOT EDIT **\r \r # TARGTYPE "Win32 (x86) Static Library" 0x0104\r \r CFG=$name - Win32 Debug\r !MESSAGE This is not a valid makefile. To build this project using NMAKE,\r !MESSAGE use the Export Makefile command and run\r !MESSAGE \r !MESSAGE NMAKE /f "$name.mak".\r !MESSAGE \r !MESSAGE You can specify a configuration when running NMAKE\r !MESSAGE by defining the macro CFG on the command line. For example:\r !MESSAGE \r !MESSAGE NMAKE /f "$name.mak" CFG="$name - Win32 Debug"\r !MESSAGE \r !MESSAGE Possible choices for configuration are:\r !MESSAGE \r !MESSAGE "$name - Win32 Release" (based on "Win32 (x86) Static Library")\r !MESSAGE "$name - Win32 Debug" (based on "Win32 (x86) Static Library")\r !MESSAGE \r \r # Begin Project\r # PROP AllowPerConfigDependencies 0\r # PROP Scc_ProjName ""\r # PROP Scc_LocalPath ""\r CPP=cl.exe\r RSC=rc.exe\r \r !IF "\$(CFG)" == "$name - Win32 Release"\r \r # PROP Use_MFC 0\r # PROP Use_Debug_Libraries 0\r # PROP Output_Dir "Release"\r # PROP Intermediate_Dir "Release"\r # PROP Target_Dir ""\r # ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_MBCS" /FD /c %cflags%\r # ADD RSC /l 0x409 /d "NDEBUG"\r BSC32=bscmake.exe\r # ADD BASE BSC32 /nologo\r # ADD BSC32 /nologo\r LINK32=link.exe -lib\r # ADD BASE LIB32 /nologo\r # ADD LIB32 /nologo\r \r !ELSEIF "\$(CFG)" == "$name - Win32 Debug"\r \r # PROP Use_MFC 0\r # PROP Use_Debug_Libraries 1\r # PROP Output_Dir "Debug"\r # PROP Intermediate_Dir "Debug"\r # PROP Target_Dir ""\r # ADD CPP /nologo /W3 /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_MBCS" /FR /FD /GZ /c %cflags%\r # ADD RSC /l 0x409 /d "_DEBUG"\r BSC32=bscmake.exe\r # ADD BASE BSC32 /nologo\r # ADD BSC32 /nologo\r LINK32=link.exe -lib\r # ADD BASE LIB32 /nologo\r # ADD LIB32 /nologo\r \r !ENDIF \r \r # Begin Target\r \r # Name "$name - Win32 Release"\r # Name "$name - Win32 Debug"\r EOF close(DSP); } sub dsp_add_source_rule { my ($fh,$dsp_name,$group,$file,$dup) = @_; print $fh "# Begin Source File\r\n"; print $fh "\r\n"; print $fh "SOURCE=$file\r\n"; if ($add_groups) { print $fh "\r\n"; print $fh "!IF \"\$(CFG)\" == \"$dsp_name - Win32 Release\"\r\n"; print $fh "\r\n"; print $fh "# PROP Intermediate_Dir \"Release\\$group\"\r\n"; print $fh "# PROP Exclude_From_Build 1\r\n" if exclude_file($file); print $fh "\r\n"; print $fh "!ELSEIF \"\$(CFG)\" == \"$dsp_name - Win32 Debug\"\r\n"; print $fh "\r\n"; print $fh "# PROP Intermediate_Dir \"Debug\\$group\"\r\n"; print $fh "# PROP Exclude_From_Build 1\r\n" if exclude_file($file); print $fh "\r\n"; print $fh "!ENDIF \r\n"; print $fh "\r\n"; } elsif ($dup) { add_dupes_dir( \*$fh, $dsp_name ); } print $fh "# End Source File\r\n"; } sub dsp_add_group { my ($dsp_name,$makefile) = @_; my $base_dir = './'; my $dsp_file = $root_dir . $dsp_name .'.dsp'; prt( "dsp_add_group: using dsp_name=$dsp_file, and makefile=$makefile ...\n" ) if $verbose2; initialize_per_input(); my $relative_dir = dirname($makefile); my $dupe = 0; my @files = (); my $key = ''; my $group = 'Lib_Special'; my $file = ''; read_main_am_file($root_dir . $makefile . '.am'); if ($write_old_dsp) { ###open(DSP, ">>$dsp_name" . '.dsp') open(DSP, ">>$dsp_file") || mydie( "Can't append to $dsp_file: $!\n" ); } # preview the 'contents' to find 'group' # use 'noinst_LIBRARIES' macro foreach $key (keys %contents) { if ($key eq 'noinst_LIBRARIES') { @files = split(' ', $contents{$key}); foreach $file (@files) { if ($file =~ /^lib([\w-]+)\.a/) { $group = 'Lib_' . $1; prt( "Group set to [$group] ...\n" ) if ($debug_on3); last; } } } } # now extract SOURCES from 'contents' hash foreach $key (sort keys %contents) { #if ($key eq "include_HEADERS") { #} # not found in Makefile.am files? if ($key =~ /^lib(.*)_a_SOURCES/) { $group = 'Lib_' . $1; if ($add_groups && $write_old_dsp) { print DSP "# Begin Group \"$group\"\r\n"; print DSP "\r\n"; print DSP "# PROP Default_Filter \"\"\r\n"; } @files = split(' ', $contents{$key}); foreach (@files) { my $src_dir = $base_dir . $relative_dir . '/'; $src_dir =~ s/\//\\/g; # fixup DOS path separators if (/^\$\(([^\)]*)\)$/) { # Found a variable. my $varname = $1; prt( "Expanding variable $varname ...\n" ) if ($debug_on3); foreach (split(' ', $contents{$varname})) { $file = $src_dir . $_; $dupe = add_2_source_list( $file, $group ); if ($write_old_dsp) { dsp_add_source_rule(\*DSP, $dsp_name, $group, $file, $dupe); } } prt( "Done expanding variable $varname ...\n" ) if ($debug_on3); } else { $file = $src_dir . $_; $dupe = add_2_source_list( $file, $group ); if ($write_old_dsp) { dsp_add_source_rule(\*DSP, $dsp_name, $group, $file, $dupe); } } } if ($add_groups && $write_old_dsp) { print DSP "# End Group\r\n"; } } #elsif ($key =~ /(.*)_SOURCES/) { elsif ($key eq "fgfs_SOURCES") { $group = 'main'; if ($add_groups && $write_old_dsp) { print DSP "# Begin Group \"$group\"\r\n"; print DSP "\r\n"; print DSP "# PROP Default_Filter \"\"\r\n"; } @files = split(' ', $contents{$key}); foreach (@files) { my $src_dir = $base_dir . $relative_dir . '/'; $src_dir =~ s/\//\\/g; # fixup DOS path separators $file = $src_dir . $_; $dupe = add_2_source_list( $file, $group ); if ($write_old_dsp) { dsp_add_source_rule(\*DSP, $dsp_name, $group, $file, $dupe); } } if ($add_groups && $write_old_dsp) { print DSP "# End Group\r\n"; } } else { # key is NOT ( Lib(.*)_a_SOURCES fgfs_SOURCES ) if (($key eq 'EXTRA_DIST')||($key eq 'fgjs_SOURCES')) { @files = split(' ', $contents{$key}); foreach my $fi (@files) { my $ext = file_extension($fi); $file = $base_dir . $relative_dir . '/' . $fi; $file =~ s/\//\\/g; # use DOS path sep if (is_c_source_ext($ext)) { push(@msvc_c_extra, $file); prt( "Added [$file] to C EXTRA list\n" ) if $verbose2; } elsif (is_h_source_ext($ext)) { push(@msvc_h_extra, $file); prt( "Added [$file] to H EXTRA list\n" ) if $verbose2; } else { push(@msvc_o_extra, $file); prt( "Added [$file] to other EXTRA list\n" ) if $verbose2; } } } elsif ($key eq 'noinst_HEADERS') { # JSBSim has put the HEADERS in HERE @files = split(' ', $contents{$key}); foreach (@files) { $file = $base_dir . $relative_dir . '/' . $_; $file =~ s/\//\\/g; # use DOS path sep $dupe = add_2_source_list( $file, $group ); } } } } close(DSP) if $write_old_dsp; } sub dsp_finish { my $dsp_name = shift; my $dsp_file = $root_dir . $dsp_name . '.dsp'; open(DSP, ">>$dsp_file") || mydie( "Can't append to $dsp_file: $!\n" ); foreach my $r (@extra_sources) { print DSP "# Begin Source File\r\n\r\n"; print DSP "$r\r\n"; print DSP "# End Source File\r\n"; } print DSP "# End Target\r\n"; print DSP "# End Project\r\n"; close(DSP); } # Return directory name of file. sub dirname { my ($file) = @_; my ($sub); ($sub = $file) =~ s,/+[^/]+$,,g; $sub = '.' if $sub eq $file; return $sub; } sub add_2_used_libs { my ($fil,$in) = @_; if (exists( $used_lib_paths{$in} ) ) { my @incs = split(/\|/ , $used_lib_paths{$in}); my $got = 0; foreach my $i (@incs) { if ($i eq $fil) { $got = 1; last; } } if ( ! $got ) { $used_lib_paths{$in} .= '|'.$fil; # add new } } else { $used_lib_paths{$in} = $fil; # set first } } sub check_lib_paths { my $fil = shift; my $inc = ''; my $ff = ''; my $finc = ''; my $fincr = ''; my $fincd = ''; my $found1 = 0; my $found2 = 0; my $found3 = 0; foreach $inc (@msvc_libs_paths) { $ff = $root_dir . $inc; if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) { $ff .= '\\'; } $ff .= $fil; if( -f $ff ) { $finc = $inc; $found1 = 1; last; } } foreach $inc (@msvc_rlibs_paths) { $ff = $root_dir . $inc; if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) { $ff .= '\\'; } $ff .= $fil; if( -f $ff ) { $fincr = $inc; $found2 = 1; last; } } foreach $inc (@msvc_dlibs_paths) { $ff = $root_dir . $inc; if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) { $ff .= '\\'; } $ff .= $fil; if( -f $ff ) { $fincd = $inc; $found3 = 1; last; } } if( $found1 || $found2 || $found3 ) { prt( "Found [$fil] in [$finc] [$ff] ...\n" ) if ($verbose2 && $found1); prt( "Found [$fil] in [$fincr] [$ff] ...\n" ) if ($verbose2 && $found2); prt( "Found [$fil] in [$fincd] [$ff] ...\n" ) if ($verbose2 && $found3); add_2_used_libs( $fil, $finc ) if $found1; add_2_used_libs( $fil, $fincr ) if $found2; add_2_used_libs( $fil, $fincd ) if $found3; } else { prt( "WARNING: Unable to locate $fil ...\n" ) if $verbose2; } return ($found1 + $found2 + $found3); } sub check_inc_paths { my $fil = shift; my $inc = ''; my $ff = ''; my $found = 0; if( ! $found ) { foreach $inc (@msvc_inc_paths) { $ff = $root_dir . $inc; if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) { $ff .= '\\'; } $ff .= $fil; ### print "Checking for $fil in $ff ...\n" if $verbose9; if( -f $ff ) { if (exists( $used_inc_paths{$inc} ) ) { my @incs = split(/\|/ , $used_inc_paths{$inc}); my $got = 0; foreach my $i (@incs) { if ($i eq $fil) { $got = 1; last; } } if ( ! $got ) { $used_inc_paths{$inc} .= '|'.$fil; # add new } } else { $used_inc_paths{$inc} = $fil; # set first } $found = 1; last; } } } if( $found ) { prt( "Found $fil in $inc [$ff] ...\n" ) if $verbose2; } else { prt( "WARNING: Unable to locate $fil ...\n" ) if $verbose2; } return $found; } sub show_lib_found { my (@arr) = @_; foreach my $in (@arr) { if (exists( $used_lib_paths{$in} ) ) { my @ip = split(/\|/, $used_lib_paths{$in}); prt( "On path [$root_dir][$in] found ".scalar @ip." items ...\n" ); my $cntr = 0; $in .= '\\' if !($in =~ /(\\|\/)$/); foreach my $f (@ip) { $cntr++; prt( "$cntr ".$root_dir.$in.$f."\n" ); } } else { prt( "Warning: Found nothing on [$root_dir][$in] ...\n" ); } } } sub find_rel_file { # ( $sp1[1], @vc8_main_srcs ); my ($fil, @arr) = @_; my $fil1 = lc($fil); $fil1 =~ s/^\.(\\|\/)//; $fil1 =~ s/\//\\/g; ###prt( "Finding [$fil1] ...\n" ); foreach my $src (@arr) { my @sp = split(/\|/, $src); my $fil2 = lc($sp[0]); $fil2 =~ s/^\.\.(\\|\/)\.\.(\\|\/)//; $fil2 =~ s/\//\\/g; ###prt( "Comparing with [$fil2] ...\n" ); if ($fil1 eq $fil2) { ###$am_to_vc8{$fil} = $sp[0]; ###$am_to_vc8{$sp[0]} = ($fil . '=' . $src); if (exists($am_to_vc8{$sp[0]})) { $am_to_vc8{$sp[0]} .= '+' . $fil . '=' . $src; } else { $am_to_vc8{$sp[0]} = $fil . '=' . $src; } return 1; } } return 0; } sub find_vc8_file { my ($fil, @arr) = @_; my $fil2 = lc($fil); $fil2 =~ s/^\.\.(\\|\/)\.\.(\\|\/)//; # remove RELATIVE $fil2 =~ s/\//\\/g; # swap to DOS ###prt( "Finding [$fil2] ...\n" ); foreach $fil (@arr) { my $fil1 = lc($fil); ###prt( "Comparing with [$fil1] ...\n" ); $fil1 =~ s/^\.(\\|\/)//; # remove relative $fil1 =~ s/\//\\/g; # swap to DOS if ($fil2 eq $fil1) { return 1; } } return 0; } # The EXTRA_DIST have been put in # @msvc_c_extra or @msvc_h_extra or @msvc_o_extra sub is_in_extra { my $fil2 = shift; my $ext = file_extension($fil2); ###prt( "Finding [$fil2] ext[$ext]...\n" ); if (is_c_source_ext($ext)) { ###prt( "Checking [$fil2] ext[$ext] in msvc_c_extra ...\n" ); # check out @msvc_c_extra return (find_vc8_file( $fil2, @msvc_c_extra )); } elsif (is_h_source_ext($ext)) { ###prt( "Checking [$fil2] ext[$ext] in msvc_h_extra ...\n" ); # check out @msvc_h_extra return (find_vc8_file( $fil2, @msvc_h_extra )); } else { prt( "NOT checking [$fil2] ext[$ext]...\n" ) if ($debug_on3); # check out @msvc_o_extra - not really } return 0; } sub find_in_vc8_srcs { my $fnd = 0; my ($fil, $im, $src) = @_; if ($im) { $fnd = find_rel_file( $fil, @vc8_main_srcs ); } else { $fnd = find_rel_file( $fil, @vc8_lib_srcs ); } if ($fnd == 0) { # try searching the opposite source set ... if ($im) { $fnd = find_rel_file( $fil, @vc8_lib_srcs ); } else { $fnd = find_rel_file( $fil, @vc8_main_srcs ); } if ($fnd == 0) { my $fl = $fil; $fl =~ s/^\.(\\|\/)//; my $ff = $root_dir.$fl; if( -f $ff ) { prt( "NOT FOUND, but file [$ff] EXISTS!\n" ); } } else { $fnd = 2; # set found in 'other' prt( "NOTE: [$src] NOT Found in ". ($im ? "Main" : "Library") . " but FOUND in other???\n" ); } } return $fnd; } sub find_in_vc8_hdrs { my $fnd = 0; my ($fil, $im, $src) = @_; if ($im) { $fnd = find_rel_file( $fil, @vc8_main_hdrs ); } else { $fnd = find_rel_file( $fil, @vc8_lib_hdrs ); } if ($fnd == 0) { # try searching the opposite source set ... if ($im) { $fnd = find_rel_file( $fil, @vc8_lib_hdrs ); } else { $fnd = find_rel_file( $fil, @vc8_main_hdrs ); } if ($fnd == 0) { my $fl = $fil; $fl =~ s/^\.(\\|\/)//; my $ff = $root_dir.$fl; if( -f $ff ) { prt( "NOT FOUND, but file [$ff] EXISTS!\n" ); } } else { $fnd = 2; # set found in 'other' prt( "NOTE: [$src] NOT Found in ". ($im ? "Main" : "Library") . " but FOUND in other???\n" ); } } return $fnd; } # file_in_dupes( $fil, $im, @vc8_dup_srcs ) sub file_in_dupes { my $fnd = 0; my ($fil, $im, @arr) = @_; my $fil1 = lc($fil); $fil1 =~ s/^\.(\\|\/)//; # remove relative $fil1 =~ s/\//\\/g; # ensure DOS seps ###prt( "Finding [$fil1] ...\n" ); foreach my $src (@arr) { $fnd++; my @sp = split(/\|/, $src); my $fil2 = lc($sp[0]); $fil2 =~ s/^\.\.(\\|\/)\.\.(\\|\/)//; # remove relative $fil2 =~ s/\//\\/g; # ensure DOS seps ###prt( "Comparing with [$fil2] ...\n" ); if ($fil1 eq $fil2) { return $fnd; # return offset plus 1 } } return 0; } ########################################################################## ## check_vc8_proj ## Have loaded and parsed am2dsp?.cfg file ## Have loaded and parsed configure.ac file ## Have loaded and parsed each Makefile.am file ## and have a set of SOURCES, HEADERS, EXTRA_DIST (including fgfs_SOURCES), ## and could now WRITE the DSW/DSP files ... ## ## Finally, LOAD and parse the vcproj files, ## and do a COMPARE of sources, headers with ## those from the Makefile.am files ... try to find what has to be ## ADDED, DELETED or MODIFIED so the vcproj files will function. ## ########################################################################## sub check_vc8_proj { my $fil = ''; if (read_vcproj() == 0) { my $cnt = 0; my $amsrcs = scalar @msvc_c_files; my $amhdrs = scalar @msvc_h_files; my $vc8srcs = (scalar @vc8_main_srcs + scalar @vc8_lib_srcs); my $vc8hdrs = (scalar @vc8_main_hdrs + scalar @vc8_lib_hdrs); my $amtotal = $amsrcs + $amhdrs; my $vc8total = $vc8srcs + $vc8hdrs; my $vc8dh = scalar @vc8_dup_hdrs; my $vc8dc = scalar @vc8_dup_srcs; # we have all the SOURCES, HEADERS, and CONFIGURATION information prt( "Load of VC8 project files: $vc8srcs sources, $vc8hdrs headers, ". "duplicates $vc8dc source, $vc8dh headers ...\n" ); # check SOURCES (sources and headers) # the makefile.am sources and headers are in # foreach $src (@msvc_c_files) # foreach $src (@msvc_h_files) # each would be a relative path to $root_dir ... # and each in the form group|relsource|filename, # like 'Lib_Time|.\src\Time\light.cxx|light' # the VC8 project sources and headers are in # each is in the form 'relativepath|bgnline-endline' # like '..\..\src\main\main.cxx|279-282' # @vc8_main_hdrs = find_headers('main', @vc8_main_lines); # @vc8_main_srcs = find_sources('main', @vc8_main_lines); # @vc8_lib_hdrs = find_headers('library', @vc8_lib_lines); # @vc8_lib_srcs = find_sources('library', @vc8_lib_lines); # the 'relativepath' would be relative to $root_dir.$vc8_root = 'projects\\VC8\\'; # Essentially 'Lib_Main' should be in @vc8_main_srcs, others in @vc8_lib_srcs # NOTE WELL: There MAY be DUPLICATED headers (and sources) in VC8!!! #################################################################### prt( "\nSOURCE files - Comparing $amsrcs am with $vc8srcs vc8 sources...\n" ); foreach my $src1 (@msvc_c_files) { my @sp1 = split(/\|/,$src1); $fil = $sp1[1]; ###my $im = (lc($sp1[0]) eq 'lib_main') ? 1 : 0; my $im = ( $sp1[0] =~ /Main/i ) ? 1 : 0; my $fnd = find_in_vc8_srcs( $fil, $im, $src1 ); if ( exclude_file( $fil ) ) { prt( "File [$src1] EXCLUDED FROM BUILD " . ($fnd ? "but FOUND!" : "so NOT FOUND")."\n" ); next; } if ($fnd == 0) { prt( "$fil NOT FOUND! $src1\n" ) if ($debug_on); push(@not_in_vc8, $src1); } else { $fnd = file_in_dupes( $fil, $im, @vc8_dup_srcs ); if ($fnd) { $fnd--; # remove plus 1 prt( "File [$src1] also in dupes [$vc8_dup_srcs[$fnd]]! " ); # Note, stored main=library my @sp2 = split( /=/, $vc8_dup_srcs[$fnd] ); # storeage of lines to DELETE if ($im) { # delete 'library' item prt( "DELETE lib $sp2[1]\n" ); push(@vc8_lib_delete, $sp2[1]); } else { # delete 'main' item prt( "DELETE main $sp2[0]\n" ); push(@vc8_main_delete, $sp2[0]); } } } } prt( "\nHEADER files - Comparing $amhdrs am with $vc8hdrs vc8 headers...\n" ); foreach my $src1 (@msvc_h_files) { my @sp1 = split(/\|/,$src1); $fil = $sp1[1]; my $im = (lc($sp1[0]) =~ /Main/i) ? 1 : 0; my $fnd = find_in_vc8_hdrs( $fil, $im, $src1 ); if ( exclude_file( $fil ) ) { prt( "File [$src1] EXCLUDED FROM BUILD " . ($fnd ? "but FOUND!" : "so NOT FOUND")."\n" ); next; } if ($fnd == 0) { prt( "$fil NOT FOUND! $src1\n" ) if ($debug_on); push(@not_in_vc8, $src1); } else { # @vc8_dup_hdrs $fnd = file_in_dupes( $fil, $im, @vc8_dup_hdrs ); if ($fnd) { $fnd--; # remove plus 1 prt( "File [$src1] also in dupes [$vc8_dup_hdrs[$fnd]]! " ); # Note, stored main=library my @sp2 = split( /=/, $vc8_dup_hdrs[$fnd] ); # storeage of lines to DELETE if ($im) { # delete 'library' item prt( "DELETE lib $sp2[1]\n" ); push(@vc8_lib_delete, $sp2[1]); } else { # delete 'main' item prt( "DELETE main $sp2[0]\n" ); push(@vc8_main_delete, $sp2[0]); } } } } # RESULTS of Makefile.am files with VC8 files if (@not_in_vc8) { prt( "In comparing $amtotal Makefile.am sources with ". "$vc8total vcproj files,\n" ); prt( "the following ".scalar @not_in_vc8." file(s) were NOT found?\n" ); $cnt = 0; foreach $fil (@not_in_vc8) { my @sp1 = split(/\|/,$fil); # split into 3 - Librarygroup|relativesource|lcfiletitle my $ext = lc(file_extension( $sp1[1] )); $cnt++; prt( "$cnt [$fil] [$ext=". (is_c_source_ext($ext) ? "source" : "header") . "]\n" ); } } else { prt( "Appears ALL $amtotal Makefile.am sources are in the ". "$vc8total vcproj files ...\n" ); } # reverse compare VC8 that is NOT in am files # each FIND was put in this HASH $am_to_vc8{$sp[0]} = $fil; # Four (4) arrays to check # But have NOTED many ARE in EXTRA_DIST, thus should be # DELETED from the vcproj files # The EXTRA_DIST have been put in # @msvc_c_extra or @msvc_h_extra or @msvc_o_extra prt( "\nReverse compare: Those of $vc8total VC8 NOT in ". "$amtotal am files ...\n" ); my $fcnt = 0; # $fil, @vc8_main_srcs foreach $fil (@vc8_main_srcs) { my @sp = split(/\|/, $fil); if ( exists($am_to_vc8{$sp[0]}) ) { $fcnt++; } else { push(@not_in_am, $fil); } } # $fil, @vc8_lib_srcs foreach $fil (@vc8_lib_srcs) { my @sp = split(/\|/, $fil); if ( exists($am_to_vc8{$sp[0]}) ) { $fcnt++; } else { push(@not_in_am, $fil); } } # $fil, @vc8_main_hdrs foreach $fil (@vc8_main_hdrs) { my @sp = split(/\|/, $fil); if ( exists($am_to_vc8{$sp[0]}) ) { $fcnt++; } else { push(@not_in_am, $fil); } } # $fil, @vc8_lib_hdrs ); foreach $fil (@vc8_lib_hdrs) { my @sp = split(/\|/, $fil); if ( exists($am_to_vc8{$sp[0]}) ) { $fcnt++; } else { push(@not_in_am, $fil); } } my $diff = ($vc8total - (scalar @not_in_am + $vc8dh + $vc8dc + keys(%am_to_vc8))); if (@not_in_am) { $cnt = scalar @not_in_am; prt( "In comparing $vc8total vcproj sources with $amtotal Makefile.am files,\n" ); prt( "the following $cnt file(s) were NOT found? (f=$fcnt)\n" ); $cnt = 0; foreach $fil (@not_in_am) { my @sp1 = split(/\|/,$fil); # split into 3 - relativepath|line-numbers|group my $im = ($sp1[2] eq 'main') ? 1 : 0; my $ext = lc(file_extension( $sp1[0] )); $cnt++; if ( is_in_extra( $sp1[0] ) ) { prt( "$cnt [$fil] [$ext=". (is_c_source_ext($ext) ? "source" : "header") . "] IS IN EXTRA_DIST!\n" ); } else { prt( "$cnt [$fil] [$ext=". (is_c_source_ext($ext) ? "source" : "header") . "]\n" ); } if ($im) { # delete 'main' item prt( "DELETE main [$fil]\n" ); push(@vc8_main_delete, $fil); } else { # delete 'library' item prt( "DELETE lib [$fil]\n" ); push(@vc8_lib_delete, $fil); } } $fcnt = keys(%am_to_vc8); prt( "This missed count $cnt + ".($vc8dh + $vc8dc)." dupes + $fcnt found should equal total ". "$vc8total, diff = $diff ". ($diff ? 'CHECK DIFFERENCE!' : 'ok')."\n"); prt( "This LIST of $cnt file(s) SHOULD BE REMOVED from the vcproj files!\n" ); } else { prt( "Appears ALL $vc8total vcproj sources are in $amtotal Makefile.am files,\n" ); } if ($debug_on4 || $diff) { $cnt = 0; prt( "\nDebug list of ". keys(%am_to_vc8) . " am files FOUND in VC8 lists ...\n" ); foreach my $key (keys %am_to_vc8) { $cnt++; #prt( "$cnt $key -> ".$am_to_vc8{$key}."\n" ); prt( "$cnt ".$am_to_vc8{$key}."\n" ); } } check_vc8_config(); # check the OUTPUT # amend_vcproj(); } else { prt( "FAILED to load of VC8 project files ...\n" ); } } sub check_includes { my $fil = ''; my $ff = ''; my $cnt1 = 0; my $cnt2 = 0; my @missed = (); my @missed2 = (); my $inc = ''; my @incpath = (); $cnt1 = scalar @msvc_dlibs_list + scalar @msvc_rlibs_list + scalar @msvc_libs_list; prt( "\nCheck 1: each $cnt1 additional library, in each library include path ...\n" ); foreach $fil (@msvc_dlibs_list) { if( check_lib_paths( $fil ) == 0 ) { push(@missed, $fil); } } foreach $fil (@msvc_rlibs_list) { if( check_lib_paths( $fil ) == 0 ) { push(@missed, $fil); } } foreach $fil (@msvc_libs_list) { if( check_lib_paths( $fil ) == 0 ) { push(@missed, $fil); } } show_lib_found(@msvc_libs_paths); show_lib_found(@msvc_rlibs_paths); show_lib_found(@msvc_dlibs_paths); if( @missed ) { prt( "WARNING: Missed ". join(' ',@missed) . ".\n" ); prt( "Check 'add_lib' and 'lib_path' in $src_cfg ...\n" ); } else { prt( "Appears no libraries are is missing ...\n" ); } prt( "Done 1: each $cnt1 additional library, in each library include path ...\n" ); # check for a known set of INCLUDE (or source) files $cnt2 = scalar @test_headers; prt( "\nCheck 2: each of $cnt2 test headers, in each include path ...\n" ); foreach $fil (@test_headers) { if( check_inc_paths( $fil ) == 0 ) { push(@missed2, $fil); } } foreach $inc (@msvc_inc_paths) { if (exists( $used_inc_paths{$inc} ) ) { @incpath = split(/\|/, $used_inc_paths{$inc}); prt( "On path [$root_dir][$inc] found ".scalar @incpath." items ...\n" ); my $cntr = 0; foreach $fil (@incpath) { $cntr++; if ( ! ($inc =~ /(\\|\/)$/) ) { $inc .= '\\'; } prt( "$cntr ".$root_dir.$inc.$fil."\n" ); } } else { prt( "Warning: Found nothing on [$root_dir][$inc] ...\n" ); } } if( @missed2 ) { prt( "WARNING: Missed ". join(' ',@missed2) . ".\n" ); prt( "Check 'include_path' in $src_cfg ...\n" ); } else { prt( "Appears no test sources, headers are missing ...\n" ); } prt( "Done checking $cnt1 libraries, and $cnt2 test includes ...\n" ); check_vc8_proj(); # NO RETURN FROM HERE mydie( "End check of libraries and include files ... aborting ...\n" ); } # some simple utility functions sub pos_of_last_slash { my $fil = shift; my $in1 = rindex( $fil, '/' ); my $in2 = rindex( $fil, '\\' ); my $pos = -1; # if BOTH exist if (($in1 >= 0) && ($in2 >= 0)) { # get the LAST if ($in1 > $in2) { $pos = $in1; } else { $pos = $in2; } } elsif ($in1 >= 0 ) { $pos = $in1; } elsif ($in2 >= 0 ) { $pos = $in2; } return $pos; } sub file_extension { my $fil = shift; my $pos = pos_of_last_slash($fil); my $last = rindex( $fil, '.' ); my $ext = ''; if ( $last >= 0 ) { if ($pos >= 0) { if ($last > $pos) { $ext = substr($fil, $last + 1); } } else { $ext = substr($fil, $last + 1); } } return $ext; } sub file_title { my $fil = shift; my $pos = pos_of_last_slash($fil); my $last = rindex( $fil, '.' ); my $tit = ''; if ($last >= 0) { if ($pos >= 0) { if ($last > $pos) { ###print "Using 1 substr( $fil, $pos+1, $last - $pos - 1 ) ...\n"; $tit = substr( $fil, $pos+1, $last - $pos - 1 ); } else { ###print "Using 2 substr( $fil, $pos+1 ) ...\n"; $tit = substr( $fil, $pos+1 ); } } else { ###print "Using 3 substr( $fil, 0, $last ) ...\n"; $tit = substr( $fil, 0, $last ); } } elsif ($pos >= 0) { ###print "Using 4 substr( $fil, $pos+1 ) ...\n"; $tit = substr( $fil, $pos+1 ); } else { ###print "Using 5 no slash, no dot ...\n"; $tit = $fil; } return $tit; } sub is_c_source_ext { my $fil = shift; my $fe = lc($fil); if (($fe eq 'c')||($fe eq 'cxx')||($fe eq 'cpp')) { return 1; } return 0; } sub is_h_source_ext { my $fil = shift; my $fe = lc($fil); if (($fe eq 'h')||($fe eq 'hxx')||($fe eq 'hpp')) { return 1; } return 0; } sub add_2_source_list { my ($fil, $grp) = @_; my $fe = file_extension($fil); my $ft = lc(file_title($fil)); my $src = ($grp . '|' . $fil . '|' . $ft); my $ret = 0; ###if (($fe eq 'c')||($fe eq 'cxx')||($fe eq 'cpp')) { if ( is_c_source_ext($fe) ) { prt( "Add $src to C list\n" ) if $verbose2; push(@msvc_c_files, $src); foreach my $tt (@msvc_titles) { # just to deal with duplicate names if( $tt eq $ft ) { $ret = 1; last; } } push(@msvc_titles, $ft); } else { prt( "Add $src to H list\n" ) if $verbose2; push(@msvc_h_files, $src); } return $ret; } sub add_dupes_dir { my ($fh, $pack) = @_; print $fh "\r\n"; print $fh "!IF \"\$(CFG)\" == \"$pack - Win32 Release\"\r\n"; print $fh "\r\n"; print $fh "# PROP Intermediate_Dir \"Release\\Dupes\"\r\n"; print $fh "\r\n"; print $fh "!ELSEIF \"\$(CFG)\" == \"$pack - Win32 Debug\"\r\n"; print $fh "\r\n"; print $fh "# PROP Intermediate_Dir \"Debug\\Dupes\"\r\n"; print $fh "\r\n"; print $fh "!ENDIF\r\n"; print $fh "\r\n"; } sub write_new_dsp { ###my $new_pack = 'FGFS'; my $new_pack = $dsp_package; my $src; my $dsp_file = $root_dir . $new_pack .'.dsp'; my @bits = (); my @done = (); my $group = ''; my $pgrp = ''; my $tit = ''; my $isdupe = 0; if ($static_lib) { static_lib_dsp_init($new_pack); } else { console_app_dsp_init($new_pack); } open(DSP, ">>$dsp_file") || mydie( "Can't append to $dsp_file: $!\n" ); if ( ! $add_groups) { print DSP "# Begin Group \"Source Files\"\r\n"; print DSP "\r\n"; print DSP "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n"; } foreach $src (@msvc_c_files) { prt( "Processing $src from array ...\n" ) if $verbose2; @bits = split( /\|/, $src ); # get file title, name and group $group = 'Lib_' . $bits[0]; $tit = $bits[2]; $isdupe = 0; if ($add_groups && ($group ne $pgrp)) { print DSP "# Begin Group \"$group\"\r\n"; print DSP "\r\n"; print DSP "# PROP Default_Filter \"\"\r\n"; } else { # not adding groups, check duplicate names foreach my $tt (@done) { if( $tt eq $tit ) { $isdupe = 1; last; } } } dsp_add_source_rule(\*DSP, $new_pack, $group, $bits[1], $isdupe); if ( !$add_groups && $isdupe) { prt( "Processed a DUPLICATE $tit from array ...\n" ) if $verbose2; prt( "Bits = ".$bits[0]."|".$bits[1].'|'.$bits[2]. " ...\n" ) if $verbose2; } push(@done, $tit); if ($add_groups && ($group ne $pgrp)) { print DSP "# End Group\r\n"; } $pgrp = $group; } if ( !$add_groups) { print DSP "# End Group\r\n"; } # just the HEADER files print DSP "# Begin Group \"Header Files\"\r\n"; print DSP "\r\n"; print DSP "# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n"; my $savgrp = $add_groups; $add_groups = 0; foreach $src (@msvc_h_files) { @bits = split( /\|/, $src ); # get file title, name and group $group = 'Lib_' . $bits[2]; dsp_add_source_rule(\*DSP, $new_pack, $group, $bits[1], 0); } print DSP "# End Group\r\n"; close(DSP); $add_groups = $savgrp; dsp_finish($new_pack); generate_dsw($new_pack); prt( "Done ".$root_dir.$new_pack." DSP and DSW files ...\n" ); } sub prt { my $msg = shift; print $msg; if ($write_log) { print $LOG $msg; } } sub mydie { my (@msg) = @_; prt( @msg ); die "ABORTING\n"; } sub trim_line { my ($l) = shift; chomp $l; $l =~ s/\r$//; # and remove CR, if present $l =~ s/\t/ /g; $l =~ s/\s\s/ /g while ($l =~ /\s\s/); #$l = substr($l,1) while ($l =~ /^\s/); #$l = substr($l,0,length($l)-1) while (($l =~ /\s$/)&&(length($l))); for ($l) { s/^\s+//; s/\s+$//; } return $l; } ############################################################################### ## VC8 STUFF BELOW ############################################################################### sub find_item3 { my ($grp, $st1, $st2, $st3, $st31, $st3x, $stf, @ll) = @_; my @hdrs = (); my $ln1 = ''; my $ln = ''; my $lb = 0; my $le = 0; my $lc = 0; my $st = 0; my $lns = ''; # accumulate until stack closed my $tok = ''; my $lnsb = 0; prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf]... \n" ) if $debug_on2; foreach $ln1 (@ll) { chomp $ln1; $ln1 =~ s/\r$//; # and remove CR, if present prt( "$lc [$ln1] state=$st\n" ) if ($debug_on3); $ln .= $ln1; # accumulate line if ($ln1 =~ /</) { $lb = $lc; } if ($ln1 =~ />/) { $le = $lc; # xml ends on this line } if ($ln =~ />/) { if ($st == 0) { # searching for 'VisualStudioProject' #if ($ln =~ /<VisualStudioProject/) { if ($ln =~ /$st1/) { $st = 1; } } elsif ($st == 1) { # seraching for 'Files' if ($ln =~ /$st2/) { $st = 2; } } elsif ($st == 2) { # searching for 'Filter' if ($ln =~ /$st3/) { #if ($ln =~ /Name=\"Header Files\"/) { if ($ln =~ /$st31/) { prt( "Enter 3 ... found $st31 ... ".trim_line($ln)."\n") if $debug_on2; $st = 3; } } } elsif ($st == 3) { #if ($ln =~ /<\/Filter/) { if ($ln =~ /$st3x/) { $st = 2; #} elsif ( $ln =~ /(<File)+(\s)+(RelativePath=\")+([\.\\\w]+)+(\")+(.)+/ ) { } elsif ( $ln =~ /$stf/ ) { $tok = $4; $lns = trim_line($ln); $lnsb = $lb; $st = 4; prt( "1[$1] 2[$2] 3[$3] 4[$4] 5[$5] 6[$6] (".trim_line($ln).")\n" ) if $debug_on2; } } elsif ($st == 4) { $lns .= trim_line($ln); if ( $ln =~ /<\/File>/ ) { push(@hdrs, $tok . '|' . $lnsb . '-' . $le . '|' . $grp); prt( "End file $tok, $lnsb - $le (".trim_line($lns).")\n" ) if $debug_on2; $st = 3; # back to level 3 $lns = ''; } } $ln = ''; # restart line accumuation } $lc++; # bump line counter } return @hdrs; } sub find_headers { my ($grp, @ll) = @_; my $st1 = '<VisualStudioProject'; my $st2 = '<Files'; my $st3 = '<Filter'; my $st31 = 'Name="Header Files"'; my $st3x = '<\/Filter'; my $stf = '(<File)(\\s+)(RelativePath=\\")([\\.\\\\\\w-]+)(\\"+)(.+)'; ###prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf]... \n" ); my @hdrs = find_item3( $grp, $st1, $st2, $st3, $st31, $st3x, $stf, @ll ); return @hdrs; } sub find_sources { my ($grp, @ll) = @_; my $st1 = '<VisualStudioProject'; my $st2 = '<Files'; my $st3 = '<Filter'; my $st31 = 'Name="Source Files"'; my $st3x = '<\/Filter'; ###my $stf = '(<File)+(\\s)+(RelativePath=\\")+([\\.\\\\\\w]+)+(\\")+(.)+'; my $stf = '(<File)(\\s+)(RelativePath=\\")([\\.\\\\\\w-]+)(\\"+)(.)'; ###prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf]... \n" ); my @hdrs = find_item3( $grp, $st1, $st2, $st3, $st31, $st3x, $stf, @ll ); return @hdrs; } sub find_hash3 { my ($st1, $st2, $st3, $st31, $st3x, $stf1, $stf2, @ll) = @_; my %hdrs = (); my $ln1 = ''; my $ln = ''; my $lb = 0; my $le = 0; my $lc = 0; my $st = 0; my $nm = ''; prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf1] [$stf2 ... \n" ) if $debug_on2; foreach $ln1 (@ll) { chomp $ln1; $ln1 =~ s/\r$//; # and remove CR, if present $ln .= $ln1; if ($ln1 =~ /</) { $lb = $lc; } if ($ln1 =~ />/) { $le = $lc; } if ($ln =~ />/) { if ($st == 0) { # searching for 'VisualStudioProject' #if ($ln =~ /<VisualStudioProject/) { if ($ln =~ /$st1/) { $st = 1; } } elsif ($st == 1) { # searching for 'Configurations' if ($ln =~ /$st2/) { $st = 2; } } elsif ($st == 2) { # searching for 'Configuration' if ($ln =~ /$st3/) { #if ($ln =~ /Name=\"Debug|Win32\"/) { if ($ln =~ /$st31/) { prt( "Enter 3 ... found $st31 1[$1] 2[$2] 3[%3]... ".trim_line($ln)."\n") if $debug_on2; $nm = $2 . '|'; # set the NAME if ($ln =~ /(IntermediateDirectory=\")(\w+?)(\")/) { $hdrs{$nm.'IntermediateDirectory'} = '' . $lb . '-' . $le; prt( "Got IntDir 1[$1] 2[$2] 3[$3] ...\n" ) if $debug_on2; } $st = 3; } } } elsif ($st == 3) { my $tln = trim_line($ln); #if ($ln =~ /<\/Configuration/) { if ($tln =~ /$st3x/) { prt( "Exit 3 ... found $st3x ... ".trim_line($ln)."\n") if $debug_on2; $st = 2; } elsif ( $tln =~ /(^<Tool)+(\s)+(Name=\"VCCLCompilerTool\")+(.+)+(>)/ ) { ###} elsif ( $ln =~ /$stf/ ) { $hdrs{$nm.'VCCLCompilerTool'} = '' . $lb . '-' . $le; prt( "1[$1] 2[$2] 3[$3] 4[$4] 5[$5] 6[$6] \n(".trim_line($ln).")\n" ) if $debug_on2; } elsif ( $tln =~ /(^<Tool)+(\s)+(Name=\"VCLinkerTool\")+(.+)+(>)/ ) { $hdrs{$nm.'VCLinkerTool'} = '' . $lb . '-' . $le; prt( "1[$1] 2[$2] 3[$3] 4[$4] 5[$5] 6[$6] \n(".trim_line($ln).")\n" ) if $debug_on2; } } $ln = ''; # restart line accumuation } $lc++; # bump line counter } return %hdrs; } ##sub find_debug { sub find_config { my (@ll) = @_; my $st1 = '<VisualStudioProject'; my $st2 = '<Configurations'; my $st3 = '<Configuration'; my $st31 = '(Name=")(Debug|Release)(\|Win32")'; my $st3x = '<\/Configuration'; my $stf1 = '(<Tool)+(\\s)+(Name="VCCLCompilerTool")'; my $stf2 = '(<Tool)+(\\s)+(Name="VCCLCompilerTool")'; ###prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf1] [$stf2] ... \n" ); my %hdrs = find_hash3( $st1, $st2, $st3, $st31, $st3x, $stf1, $stf2, @ll ); return %hdrs; } # sub get_lines( $configd{$key}, @main_lines ); # extract a line, like 5-5, or set of lines, like 23-27 # from an array of lines - return 'massaged' single line sub get_lines { my ($lns, @arr) = @_; my $rln = ''; my @ft = split( /-/, $lns ); my $cnt = scalar @arr; if (($ft[0] < $cnt)&&($ft[0] <= $ft[1])&&($ft[1] < $cnt)) { if ($ft[0] == $ft[1]) { # ONE line $rln = trim_line($arr[$ft[0]]); } else { # multiple lines for (my $i = $ft[0]; $i <= $ft[1]; $i++ ) { $rln .= trim_line( $arr[$i] ); if ($rln =~ /\s$/) { # ok, got a space } elsif ($i < $ft[1]) { $rln .= ' '; } } } } return trim_line($rln); } sub get_raw_lines { my ($lns, @arr) = @_; my @rln = (); my @ft = split( /-/, $lns ); my $cnt = scalar @arr; if (($ft[0] < $cnt)&&($ft[0] <= $ft[1])&&($ft[1] < $cnt)) { if ($ft[0] == $ft[1]) { # ONE line push(@rln, $arr[$ft[0]] ); } else { # multiple lines for (my $i = $ft[0]; $i <= $ft[1]; $i++ ) { push(@rln, $arr[$i] ); } } } return @rln; } sub clear_arrays { # configuration stuff %msvc8_confi = (); $msvc8_dintd = ''; $msvc8_rintd = ''; # compiler stuff @msvc8_dincs = (); @msvc8_ddefs = (); @msvc8_rincs = (); @msvc8_rdefs = (); # linker stuff @msvc8_dlibs = (); @msvc8_dpath = (); @msvc8_rlibs = (); @msvc8_rpath = (); # other items $warn = ''; } sub process_vc8_lines { my (@mlines) = @_; my ($key, $line, $nm, $tool, $msg, $item); clear_arrays(); %msvc8_confi = find_config(@mlines); for my $key (keys %msvc8_confi) { prt( "key = $key => value = " . $msvc8_confi{$key} . "\n" ) if $debug_on2; $line = get_lines( $msvc8_confi{$key}, @mlines ); my ($nm,$tool) = split( /\|/, $key ); ###prt( "line[$line]nm=$nm tool=$tool\n" ); if ($tool eq 'VCCLCompilerTool') { if ($line =~ /(AdditionalIncludeDirectories)(=)(\")(.+?)(\")(.+)/) { $item = $4; $msg = "$nm Incs=4[$item] 5[$5] "; if ($nm eq 'Debug') { @msvc8_dincs = split(/;/, $item); $msg .= 'added to msvc8_dincs'; } elsif ($nm eq 'Release') { @msvc8_rincs = split(/;/, $item); $msg .= 'added to msvc8_rincs'; } else { prt( "WARNING: Unknown configuration ... $nm ???\n" ); $warn .= "WARNING: Unknown configuration ... $nm ???\n"; } prt( "$msg\n" ) if $debug_on2; } if ($line =~ /(PreprocessorDefinitions)(=)(\")(.+?)(\")(.+)/) { $item = $4; $msg = "$nm Defs=4[$item] 5[$5] "; if ($nm eq 'Debug') { @msvc8_ddefs = split(/;/, $item); $msg .= 'added to msvc8_ddefs'; } elsif ($nm eq 'Release') { @msvc8_rdefs = split(/;/, $item); $msg .= 'added to msvc8_rdefs'; } else { prt( "WARNING: Unknown configuration ...$nm ???\n" ); $warn .= "WARNING: Unknown configuration ...$nm ???\n"; } prt( "$msg\n" ) if $debug_on2; } } elsif ($tool eq 'VCLinkerTool') { if ($line =~ /(AdditionalDependencies)(=)(\")(.+?)(\")(.+)/) { $item = $4; $msg = "$nm Libs=4[$item] 5[$5] "; if ($nm eq 'Debug') { @msvc8_dlibs = split(/ /, $item); $msg .= 'added to msvc8_dlibs'; } elsif ($nm eq 'Release') { @msvc8_rlibs = split(/ /, $item); $msg .= 'added to msvc8_rlibs'; } else { prt( "WARNING: Unknown configuration ...$nm ???\n" ); $warn .= "WARNING: Unknown configuration ...$nm ???\n"; } prt( "$msg\n" ) if $debug_on2; } if ($line =~ /(AdditionalLibraryDirectories)(=)(\")(.+?)(\")(.+)/) { $item = $4; ###prt( "Paths=4[$4] 5[$5]\n" ); $item =~ s/"/\"/g; $msg = "$nm Paths=$item 5[$5] "; if ($nm eq 'Debug') { @msvc8_dpath = split(/;/, $item); $msg .= 'added to msvc8_dpath'; } elsif ($nm eq 'Release') { @msvc8_rpath = split(/;/, $item); $msg .= 'added to msvc8_rpath'; } else { prt( "WARNING: Unknown configuration ...$nm ???\n" ); $warn .= "WARNING: Unknown configuration ...$nm ???\n"; } prt( "$msg\n" ) if $debug_on2; } } elsif ($tool = 'IntermediateDirectory') { if ($line =~ /(IntermediateDirectory)(=)(\")(.+?)(\")(.+)/) { $item = $4; $msg = "$nm Paths=$item 5[$5] "; if ($nm eq 'Debug') { $msvc8_dintd = $item; $msg .= 'added to msvc8_dintd'; } elsif ($nm eq 'Release') { $msvc8_rintd = $item; $msg .= 'added to msvc8_rintd'; } else { prt( "WARNING: Unknown configuration ...$nm ???\n" ); $warn .= "WARNING: Unknown configuration ...$nm ???\n"; } prt( "$msg\n" ) if $debug_on2; } } else { prt( "WARNING: Unknown Tool [$tool] ...\n" ); $warn .= "WARNING: Unknown Tool [$tool] ...\n"; } } } sub copy_main_items { %main_msvc8_confi = %msvc8_confi; $main_msvc8_dintd = $msvc8_dintd; $main_msvc8_rintd = $msvc8_rintd; # compiler stuff @main_msvc8_dincs = @msvc8_dincs; @main_msvc8_ddefs = @msvc8_ddefs; @main_msvc8_rincs = @msvc8_rincs; @main_msvc8_rdefs = @msvc8_rdefs; # linker stuff @main_msvc8_dlibs = @msvc8_dlibs; @main_msvc8_dpath = @msvc8_dpath; @main_msvc8_rlibs = @msvc8_rlibs; @main_msvc8_rpath = @msvc8_rpath; $main_warn = $warn; } sub copy_lib_items { %lib_msvc8_confi = %msvc8_confi; $lib_msvc8_dintd = $msvc8_dintd; $lib_msvc8_rintd = $msvc8_rintd; # compiler stuff @lib_msvc8_dincs = @msvc8_dincs; @lib_msvc8_ddefs = @msvc8_ddefs; @lib_msvc8_rincs = @msvc8_rincs; @lib_msvc8_rdefs = @msvc8_rdefs; # linker stuff @lib_msvc8_dlibs = @msvc8_dlibs; @lib_msvc8_dpath = @msvc8_dpath; @lib_msvc8_rlibs = @msvc8_rlibs; @lib_msvc8_rpath = @msvc8_rpath; $lib_warn = $warn; } ############################################################# ## read_vcproj ## Load and parse - ## = $root_dir . 'projects\VC8\FlightGearLib.vcproj'; ## = $root_dir . 'projects\VC8\FlightGear.vcproj'; ## ## Original files lines are stored in ## @vc8_lib_lines, and @vc8_main_lines ## Extract the SOURCES and HEADERS to ## @vc8_main_srcs, @vc8_lib_srcs, ## @vc8_main_hdrs, @vc8_lib_hdrs ## Process the vc8 configuration section, and store info in ## ## For MAIN %main_msvc8_confi on @vc8_main_lines gives ## $main_msvc8_dintd, $main_msvc8_rintd ## @main_msvc8_dincs, @main_msvc8_ddefs ## @main_msvc8_rincs, @main_msvc8_rdefs ## @main_msvc8_dlibs, @main_msvc8_dpath ## @main_msvc8_rlibs, @main_msvc8_rpath ## $main_warn ## ## For LIBRARY %lib_msvc8_confi on @vc8_lib_lines gives ## $lib_msvc8_dintd, $lib_msvc8_rintd ## compiler stuff ## @lib_msvc8_dincs, @lib_msvc8_ddefs ## @lib_msvc8_rincs, @lib_msvc8_rdefs ## linker stuff ## @lib_msvc8_dlibs, @lib_msvc8_dpath ## @lib_msvc8_rlibs, @lib_msvc8_rpath ## $lib_warn ## ## each array contains the 'relativefilename | filelines' ## The filelines will allow modification of those lines in ## the original line array, so NEW modified files can be ## written ... ## Added a search for file in BOTH 'library' and 'main' ## and results to @vc8_dup_hdrs and @vc8_dup_srcs, ## which holds the two lines, separated by '=' sign. ############################################################# sub read_vcproj { my $line = ''; my $line1 = ''; my $cnt = 0; if ( ! -f $vc8_src_lib ) { prt( "AWK: Unable to locate [$vc8_src_lib] file ...\n" ); return 1; } if ( ! -f $vc8_src_main ) { prt( "AWK: Unable to locate [$vc8_src_main] file ...\n" ); return 2; } open IF, "<$vc8_src_lib" or mydie( "Can not OPEN $vc8_src_lib!\n" ); @vc8_lib_lines = <IF>; # slurp whole file, to an array of lines close(IF); open IF, "<$vc8_src_main" or mydie( "Can not OPEN $vc8_src_main!\n"); @vc8_main_lines = <IF>; # slurp whole file, to an array of lines close(IF); my $lc_lib = scalar @vc8_lib_lines; my $lc_main = scalar @vc8_main_lines; prt( "Loaded $vc8_src_lib of $lc_lib lines ...\n" ); prt( "Loaded $vc8_src_main of $lc_main lines ...\n" ); prt( "Finding headers in vc8_main_lines ...\n" ); @vc8_main_hdrs = find_headers('main', @vc8_main_lines); if ($debug_on3) { prt( "Listing ".scalar @vc8_main_hdrs." header lines in vc8_main_lines ...\n" ); $cnt = show_sh_lines(1, @vc8_main_hdrs); prt( "Listed $cnt headers in vc8_main_lines ...\n" ); } prt( "Finding source in vc8_main_lines ...\n" ); @vc8_main_srcs = find_sources('main', @vc8_main_lines); if ($debug_on3) { prt( "Listing ".scalar @vc8_main_srcs." source lines in vc8_main_lines ...\n" ); $cnt = show_sh_lines(2, @vc8_main_srcs); prt( "Listed $cnt sources in vc8_main_lines ...\n" ); } prt( "Finding headers in lib_lines ...\n" ); @vc8_lib_hdrs = find_headers('library', @vc8_lib_lines); if ($debug_on3) { prt( "Listing ".scalar @vc8_lib_hdrs." header lines in vc8_lib_lines ...\n" ); $cnt = show_sh_lines(3, @vc8_lib_hdrs); prt( "Listed $cnt headers in vc8_lib_lines ...\n" ); } prt( "Finding source in vc8_lib_lines ...\n" ); @vc8_lib_srcs = find_sources('library', @vc8_lib_lines); if ($debug_on3) { prt( "Listing ".scalar @vc8_lib_srcs." source lines in vc8_lib_lines ...\n" ); $cnt = show_sh_lines(4, @vc8_lib_srcs); prt( "Listed $cnt sources in vc8_lib_lines ...\n" ); } # check if there are any duplicate file names # sort of SANITY CHECK ONLY, since it is to be EXPECTED for HEADERS # Note, if found, stored main=library prt( "Doing a 'duplicate' check ...\n" ); $cnt = 0; foreach $line (@vc8_main_hdrs) { my @sp1 = split( /\|/, $line ); my $ext1 = file_extension($sp1[0]); if ( ! is_h_source_ext($ext1) ) { prt( "WARNING 3: NOT correct file extension! [$line]\n" ); } foreach my $ln (@vc8_lib_hdrs) { my @sp2 = split( /\|/, $ln ); my $ext2 = file_extension($sp2[0]); if ( ! is_h_source_ext($ext2) ) { prt( "WARNING 3: NOT correct file extension! [$ln]\n" ); } if (lc($sp1[0]) eq lc($sp2[0])) { push(@vc8_dup_hdrs, ($line . '=' . $ln)); prt( "WARNING 2: Duplicate headers [$line][$ln]\n" ); $cnt++; } } } # BUT NOT FOR SOURCES foreach $line (@vc8_main_srcs) { my @sp1 = split( /\|/, $line ); my $ext1 = file_extension($sp1[0]); if ( ! is_c_source_ext($ext1) ) { prt( "WARNING 3: NOT correct file extension! [$line]\n" ); } foreach my $ln (@vc8_lib_srcs) { my @sp2 = split( /\|/, $ln ); my $ext2 = file_extension($sp2[0]); if ( ! is_c_source_ext($ext2) ) { prt( "WARNING 3: NOT correct file extension! [$ln]\n" ); } if (lc($sp1[0]) eq lc($sp2[0])) { # Note, if found, stored main=library push(@vc8_dup_srcs, ($line . '=' . $ln)); prt( "WARNING 2: Duplicate sources [$line][$ln]\n" ); $cnt++; } } } if ($cnt) { prt( "Above list of $cnt DUPLICATE items. Duplicate SOURCES should be resolved ...\n" ); } prt( "\nProcessing vc8_main_lines ... to extract configuration items ...\n" ); process_vc8_lines(@vc8_main_lines); copy_main_items(); # copy into persistant variables show_main_arrays() if $debug_on3; prt( "Done vc8_main_lines for configuration items ...\n" ); prt( "\nProcessing vc8_lib_lines ... to extract configuration items ...\n" ); process_vc8_lines(@vc8_lib_lines); copy_lib_items(); # copy into persistant variables show_lib_arrays() if $debug_on3; prt( "Done vc8_lib_lines for configuration items ...\n" ); return 0; } ###################################################################### ## MAINLY DEBUG ONLY THINGS ###################################################################### ######################################################################## ## show_arrays ## Used only for a DEBUG display ######################################################################## sub show_arrays { my $line = ''; prt( "\nDebug IntDir=$msvc8_dintd, and Release IntDir=$msvc8_rintd ...\n" ); # compiler stuff prt( "\nDebug compiler includes ... msvc8_dincs\n" ); foreach $line (@msvc8_dincs) { prt( "$line\n" ); } prt( "\nDebug compiler DEFINES ... msvc8_ddefs\n" ); foreach $line (@msvc8_ddefs) { prt( "$line\n" ); } prt( "\nRelease compiler includes ... msvc8_rincs\n" ); foreach $line (@msvc8_rincs) { prt( "$line\n" ); } prt( "\nRelease compiler DEFINES ... msvc8_rdefs\n" ); foreach $line (@msvc8_rdefs) { prt( "$line\n" ); } # linker stuff prt( "\nDebug linker LIBS ... msvc8_dlibs\n" ); foreach $line (@msvc8_dlibs) { prt( "$line\n" ); } prt( "\nDebug linker PATHS ... msvc8_dpath\n" ); foreach $line (@msvc8_dpath) { prt( "$line\n" ); } prt( "\nRelease linker LIBS ... msvc8_rlibs\n" ); foreach $line (@msvc8_rlibs) { prt( "$line\n" ); } prt( "\nRelease linker PATHS ... msvc8_rpath\n" ); foreach $line (@msvc8_rpath) { prt( "$line\n" ); } prt( "\nWARNINGS, if any\n$warn\n" ); } ######################################################################## ## show_main_arrays ## Used only for a DEBUG display ######################################################################## sub show_main_arrays { my $line = ''; prt( "\nDebug IntDir=$main_msvc8_dintd, and Release IntDir=$main_msvc8_rintd ...\n" ); # compiler stuff prt( "\nDebug compiler includes ... main_msvc8_dincs\n" ); foreach $line (@main_msvc8_dincs) { prt( "$line\n" ); } prt( "\nDebug compiler DEFINES ... main_msvc8_ddefs\n" ); foreach $line (@main_msvc8_ddefs) { prt( "$line\n" ); } prt( "\nRelease compiler includes ... main_msvc8_rincs\n" ); foreach $line (@main_msvc8_rincs) { prt( "$line\n" ); } prt( "\nRelease compiler DEFINES ... main_msvc8_rdefs\n" ); foreach $line (@main_msvc8_rdefs) { prt( "$line\n" ); } # linker stuff prt( "\nDebug linker LIBS ... main_msvc8_dlibs\n" ); foreach $line (@main_msvc8_dlibs) { prt( "$line\n" ); } prt( "\nDebug linker PATHS ... main_msvc8_dpath\n" ); foreach $line (@main_msvc8_dpath) { prt( "$line\n" ); } prt( "\nRelease linker LIBS ... main_msvc8_rlibs\n" ); foreach $line (@main_msvc8_rlibs) { prt( "$line\n" ); } prt( "\nRelease linker PATHS ... main_msvc8_rpath\n" ); foreach $line (@main_msvc8_rpath) { prt( "$line\n" ); } prt( "\nWARNINGS, if any\n$main_warn\n" ); } ######################################################################## ## show_lib_arrays ## Used only for a DEBUG display ######################################################################## sub show_lib_arrays { my $line = ''; prt( "\nDebug IntDir=$lib_msvc8_dintd, and Release IntDir=$lib_msvc8_rintd ...\n" ); # compiler stuff prt( "\nDebug compiler includes ... lib_msvc8_dincs\n" ); foreach $line (@lib_msvc8_dincs) { prt( "$line\n" ); } prt( "\nDebug compiler DEFINES ... lib_msvc8_ddefs\n" ); foreach $line (@lib_msvc8_ddefs) { prt( "$line\n" ); } prt( "\nRelease compiler includes ... lib_msvc8_rincs\n" ); foreach $line (@lib_msvc8_rincs) { prt( "$line\n" ); } prt( "\nRelease compiler DEFINES ... lib_msvc8_rdefs\n" ); foreach $line (@lib_msvc8_rdefs) { prt( "$line\n" ); } # linker stuff prt( "\nDebug linker LIBS ... lib_msvc8_dlibs\n" ); foreach $line (@lib_msvc8_dlibs) { prt( "$line\n" ); } prt( "\nDebug linker PATHS ... lib_msvc8_dpath\n" ); foreach $line (@lib_msvc8_dpath) { prt( "$line\n" ); } prt( "\nRelease linker LIBS ... lib_msvc8_rlibs\n" ); foreach $line (@lib_msvc8_rlibs) { prt( "$line\n" ); } prt( "\nRelease linker PATHS ... lib_msvc8_rpath\n" ); foreach $line (@lib_msvc8_rpath) { prt( "$line\n" ); } prt( "\nWARNINGS, if any\n$lib_warn\n" ); } ######################################################################## ## show_sh_lines ## Used only for a DEBUG display ######################################################################## sub show_sh_lines { my ($t, @arr) = @_; my $cnt = 0; foreach my $ln (@arr) { $cnt++; prt( $ln."\n" ); if ($debug_on2) { my @sp = split( /\|/, $ln ); # get source, LINE NUMBERS, and GROUP if (scalar @sp >= 3) { if ($t == 1) { # @vc8_main_lines - headers prt( get_lines( $sp[1], @vc8_main_lines ) ); prt( "\n" ); } elsif ($t == 2) { # @vc8_main_lines - sources prt( get_lines( $sp[1], @vc8_main_lines ) ); prt( "\n" ); } elsif ($t == 3) { # @vc8_lib_lines - headers prt( get_lines( $sp[1], @vc8_lib_lines ) ); prt( "\n" ); } elsif ($t == 4) { # @vc8_lib_lines - sources prt( get_lines( $sp[1], @vc8_lib_lines ) ); prt( "\n" ); } else { prt( "\nWARNING: Can NOT pass [$t] to this service ...\n" ); } } else { prt( "\nWARNING: Line is NOT name|lines format ...\n" ); } } } } ##################################################### ## prt_list ## Debug output of line list, with some rough ## indenting ... ##################################################### sub prt_list { my (@list) = @_; my $ind = ''; foreach my $line (@list) { if ($line =~ /^</) { if ($line =~ /\/>/) { # end xml same line } elsif ($line =~ /^<\//) { $ind = substr($ind, 1) if (length($ind)); } else { # $ind .= ' '; } } prt( $ind.$line."\n" ); if ($line =~ /^</) { if ($line =~ /\/>/) { # end xml same line } elsif ($line =~ /^<\//) { # $ind = substr($ind, 1) if (length($ind)); } else { $ind .= ' '; } } } } ################################################################ ## amend_vcproj ## The idea it to 'copy' the original line arrays, making ## modifications, adding or subtracting lines, into to a ## new array, then write that out to an .tmp file. ## Then, rename the original to .old, or .bak, if .old ## already exists, then rename the .tmp to vcproj ## In this way attempting to RETAIN the original file, ## in case it all fails, or some other problem is encountered, ## the USER still has the ORIGINAL file available. ## ## There may be files to DELETE, or ADD, and configuration ## lines may need to be MODIFIED ... ## ################################################################ sub amend_vcproj { my $cl = 0; my $org_vc1 = $root_dir . $vc8_def_lib; my $org_vc2 = $root_dir . $vc8_def_main; my $out_vc1 = $org_vc1 . '.tmp'; my $out_vc2 = $org_vc2 . '.tmp'; my $bak_vc1 = $org_vc1 . '.old'; my $bak_vc2 = $org_vc2 . '.old'; # create the TEMPORARY FILES, aborting if either FAIL open OF1, ">$out_vc1" or mydie( "YEEK! Unable to create [$out_vc1] ...\n" ); open OF2, ">$out_vc2" or mydie( "YEEK! Unable to create [$out_vc2] ...\n" ); my $line = ''; my @new_vclib = (); my @new_vcmain = (); my %del_lines = (); my @sp = (); my @sp2 = (); my $num = 0; my @deleted = (); prt( "Modifying the vc8_lib_lines ...\n" ); $cl = 0; # storeage of lines to DELETE # delete 'library' item # push(@vc8_lib_delete, $sp2[1]); # typical line [..\..\src\main\renderer.cxx|2905-2908|library] %del_lines = (); foreach $line (@vc8_lib_delete) { @sp = split( /\|/, $line ); @sp2 = split( /-/, $sp[1] ); $num = $sp2[0]; $del_lines{$num} = 1; while ($num < $sp2[1]) { $num++; # bump to next $del_lines{$num} = 1; } } foreach $line (@vc8_lib_lines) { # do any fix, deletion, or addition chomp $line; $line =~ s/\r$//; # and remove CR, if present if ( exists $del_lines{$cl}) { push(@deleted, ($cl . '[' . $line . ']') ); } else { push(@new_vclib, $line); } $cl++; } if ($debug_on3 && @deleted) { prt( "Deleted following ".scalar @deleted." lines ...\n" ); foreach $line (@deleted) { prt( "$line\n" ); } } prt( "Modifying the vc8_main_lines ...\n" ); $cl = 0; # delete 'main' item # push(@vc8_main_delete, $sp2[0]); %del_lines = (); @deleted = (); foreach $line (@vc8_main_delete) { @sp = split( /\|/, $line ); @sp2 = split( /-/, $sp[1] ); $num = $sp2[0]; $del_lines{$num} = 1; while ($num < $sp2[1]) { $num++; # bump to next $del_lines{$num} = 1; } } foreach $line (@vc8_main_lines) { # do any fix, deletion, or addition chomp $line; $line =~ s/\r$//; # and remove CR, if present if ( exists $del_lines{$cl}) { push(@deleted, ($cl . '[' . $line . ']') ); } else { push(@new_vcmain, $line); } $cl++; } if ($debug_on3 && @deleted) { prt( "Deleted following ".scalar @deleted." lines ...\n" ); foreach $line (@deleted) { prt( "$line\n" ); } } prt( "Writing the new lib lines to $out_vc1 ...\n" ); foreach $line (@new_vclib) { print OF1 "$line\n"; } prt( "Writing the new main lines to $out_vc2 ...\n" ); foreach $line (@new_vcmain) { print OF2 "$line\n"; } # close the output files close OF1; close OF2; # PERFORM THE RENAMING ############################################### # IF either .old already exist, change to .bak if (( -f $bak_vc1 ) || ( -f $bak_vc1 )) { $bak_vc1 = $org_vc1 . '.bak'; $bak_vc2 = $org_vc2 . '.bak'; # remove any existing .bak, if exists unlink $bak_vc1 if ( -f $bak_vc1 ); unlink $bak_vc2 if ( -f $bak_vc2 ); } # rename the CURRENT to .old or .bak rename $org_vc1, $bak_vc1; rename $org_vc2, $bak_vc2; # rename the NEW to current rename $out_vc1, $org_vc1; rename $out_vc2, $org_vc2; # all DONE!!! ############################################## } sub check_vc8_config { # have collected show_main_arrays # %main_msvc8_confi contains configuration keys, which can produce - # Debug IntDir=$main_msvc8_dintd, and Release IntDir=$main_msvc8_rintd # compiler stuff # Debug compiler includes ... @main_msvc8_dincs # Debug compiler DEFINES ... @main_msvc8_ddefs # Release compiler includes ... @main_msvc8_rincs # Release compiler DEFINES ... @main_msvc8_rdefs # linker stuff # Debug linker LIBS ... @main_msvc8_dlibs # Debug linker PATHS ... @main_msvc8_dpath # Release linker LIBS ... @main_msvc8_rlibs # Release linker PATHS ... @main_msvc8_rpath # WARNINGS, if any ... $main_warn # # Similarly, for library, collected show_lib_arrays # %lib_msvc8_confi contains configuration keys, which can produce - # Debug IntDir=$lib_msvc8_dintd, and Release IntDir=$lib_msvc8_rintd # compiler stuff # Debug compiler includes ... @lib_msvc8_dincs # Debug compiler DEFINES ... @lib_msvc8_ddefs # Release compiler includes ... @lib_msvc8_rincs # Release compiler DEFINES ... @lib_msvc8_rdefs # linker stuff # Debug linker LIBS ... @lib_msvc8_dlibs # Debug linker PATHS ... @lib_msvc8_dpath # Release linker LIBS ... @lib_msvc8_rlibs # Release linker PATHS ... @lib_msvc8_rpath # and WARNINGS, if any ... $lib_warn # check HEADERS and INCLUDE folders # check DEFINES ###my @items = qw(AdditionalIncludeDirectories PreprocessorDefinitions AdditionalDependencies ### AdditionalLibraryDirectories); my %hitems = ( AdditionalIncludeDirectories => ';', PreprocessorDefinitions => ';', AdditionalDependencies => ' ', AdditionalLibraryDirectories => ';', IntermediateDirectory => ';' ); my %config_set = (); my $icnt = keys(%hitems); prt( "\nList of MAIN configuration items ...\n" ) if ($debug_on5); my $nums = ''; my $num = 0; my @sp = (); my @arr = (); my $ln = ''; my $i = 0; my $item = ''; my $sep = ';'; my $it = ''; my $itm = ''; my $key = ''; my $ckey = ''; foreach $key (keys %main_msvc8_confi) { $nums = $main_msvc8_confi{$key}; @sp = split( /-/, $nums ); $num = $sp[0]; prt( "$key -> $nums\n" ) if ($debug_on5); @arr = get_raw_lines($nums, @vc8_main_lines); foreach $ln (@arr) { chomp $ln; $ln =~ s/\r$//; # and remove CR, if present @sp = (); foreach $item (keys %hitems) { $sep = $hitems{$item}; if ($ln =~ /\s+$item=\"(.+)\"/ ) { $itm = $1; $itm =~ s/"/\"/g; prt( "$num FOUND $item=[$itm] ($key)\n" ) if ($debug_on5); @sp = split( /$sep/, $itm ); if ($debug_on5) { foreach $it (@sp) { prt( "$it\n" ); } } # put into config set $ckey = ($key . '|' . $item . '|main'); $config_set{$ckey} = join('|',@sp); last; } } if ( ! @sp ) { prt( "$num [$ln]\n" ) if ($debug_on5); } $num++; } } prt( "\nList of LIBRARY configuration items ...\n" ) if ($debug_on5); foreach $key (keys %lib_msvc8_confi) { $nums = $lib_msvc8_confi{$key}; @sp = split( /-/, $nums ); $num = $sp[0]; prt( "$key -> $nums\n" ) if ($debug_on5); @arr = get_raw_lines($nums, @vc8_lib_lines); foreach $ln (@arr) { chomp $ln; $ln =~ s/\r$//; # and remove CR, if present @sp = (); foreach $item (keys %hitems) { $sep = $hitems{$item}; if ($ln =~ /\s+$item=\"(.+)\"/ ) { $itm = $1; $itm =~ s/"/\"/g; prt( "$num FOUND $item=[$itm] ($key)\n" ) if ($debug_on5); @sp = split( /$sep/, $itm ); if ($debug_on5) { foreach $it (@sp) { prt( "$it\n" ); } } $ckey = ($key . '|' . $item . '|library'); $config_set{$ckey} = join('|',@sp); last; } } if ( ! @sp ) { prt( "$num [$ln]\n" ) if ($debug_on5); } $num++; } } if ($debug_on5) { prt( "\nSimple output of the vc8 config set ... sorted on the keys \n" ); foreach $ckey (sort keys %config_set) { prt( "$ckey -> ".$config_set{$ckey}."\n" ); } } # the set of keys, and some values, should be something like ... # Debug|IntermediateDirectory|IntermediateDirectory|library -> FGDebug # Debug|IntermediateDirectory|IntermediateDirectory|main -> Debug # Debug|VCCLCompilerTool|AdditionalIncludeDirectories|library -> ../../../|../../../Simgear|... # Debug|VCCLCompilerTool|AdditionalIncludeDirectories|main -> ../../../|../../../Simgear|... # Debug|VCCLCompilerTool|PreprocessorDefinitions|library -> WIN32|_DEBUG|_WINDOWS|ENABLE_THREADS|... # Debug|VCCLCompilerTool|PreprocessorDefinitions|main -> WIN32|_DEBUG|_WINDOWS|ENABLE_THREADS|... # Debug|VCLinkerTool|AdditionalDependencies|main -> FlightgearLib.lib|Simgear.lib|fnt_d.lib|... # Debug|VCLinkerTool|AdditionalLibraryDirectories|main -> "FG$(IntDir)"|../../../plib/|... # Release|IntermediateDirectory|IntermediateDirectory|library -> FGRelease # Release|IntermediateDirectory|IntermediateDirectory|main -> Release # Release|VCCLCompilerTool|AdditionalIncludeDirectories|library -> ../../../|../../../Simgear|... # Release|VCCLCompilerTool|AdditionalIncludeDirectories|main -> ../../../|../../../Simgear|... # Release|VCCLCompilerTool|PreprocessorDefinitions|library -> WIN32|NDEBUG|_WINDOWS|PTW32_STATIC_LIB|... # Release|VCCLCompilerTool|PreprocessorDefinitions|main -> WIN32|NDEBUG|_CONSOLE|ENABLE_THREADS|... # Release|VCLinkerTool|AdditionalDependencies|main -> FlightgearLib.lib|Simgear.lib|fnt.lib|... # Release|VCLinkerTool|AdditionalLibraryDirectories|main -> "FG$(IntDir)"|../../../plib/|... my @def_w32_defines = qw( WIN32 NDEBUG|_DEBUG _WINDOWS _CRT_SECURE_NO_DEPRECATE _CONST_CORRECT_OVERLOADS _USE_MATH_DEFINES NOMINMAX PTW32_STATIC_LIB|_CONSOLE ); my @def_w32_libs = qw( wsock32.lib|ws2_32.lib advapi32.lib comdlg32.lib shell32.lib user32.lib ); if ($debug_on5) { foreach $ckey (@def_w32_defines) { prt( "$ckey\n" ); } foreach $ckey (@def_w32_libs) { prt( "$ckey\n" ); } } } # eof - am2dsp6.pl