#!/perl -w # NAME: dswlist.pl # AIM: Given a MSVC6 DSW files, show the LIST of DSP files it references # or given a FOLDER, search for ALL .DSW files, and show .DSP list. # 01/06/2012 - Fixfor 'SUB' should be 'SUBTRACT' # 29/05/2012 - Output a cmake list of sources found # 20090913 - add command line parsing, and make it more conform to scan of vcproj # substitution variables # -NEW_PROJECT_NAME-" = name of the project # -NEW_OUTD_(REL|DBG)- = PROP Output_Dir ???? # -NEW_INTER_(REL|DBG)- = PROP Intermediate_Dir ???? # ADD CPP with # -NEW_RT_(REL|DBG)- = RUNTIME, like /MT /MD, /MTd, etc # -NEW_INCS_(REL|DBG)- = INCLUDE DIRECTORIES, like /I ".." # -NEW_DEFS_(REL|DBG)- = DEFINES, like /D "FGFS" # ADD LINK32 (for console, app, DLL) with # -NEW_LIBS_(REL|DBG)- = Additional libraries for the link # -NEW_OUT_(REL|DBG)- = link output, like /out:"StaticRelease\libpng.lib # -NEW_POST_(REL|DBG)- = POST build - description and commands, TAB separated # ADD LIB32 (for static library) with # -NEW_OUT_(REL|DBG)- = OUTPUT static library # 22/04/2007 - geoff mclane - http://geoffmclane.com/mperl/samples/index.htm use strict; use warnings; use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] ) use File::Spec; # File::Spec->rel2abs($rel); # we are IN the SLN directory, get ABSOLUTE from #use Cwd qw(chdir abs_path); use Cwd; my $os = $^O; my $perl_dir = '/home/geoff/bin'; my $PATH_SEP = '/'; my $temp_dir = '/tmp'; if ($os =~ /win/i) { $perl_dir = 'C:\GTools\perl'; $temp_dir = $perl_dir; $PATH_SEP = "\\"; } unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n"; require 'lib_cmake.pl' or die "Unable to load 'lib_cmake.pl'! Check location and \@INC content.\n"; # log file stuff our ($LF); my $pgmname = $0; if ($pgmname =~ /(\\|\/)/) { my @tmpsp = split(/(\\|\/)/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt"; open_log($outfile); # user variables my $VERS = "0.0.3 2012/05/29"; #my $VERS = "0.0.2 2012/05/21"; #my $VERS = "0.0.1 22/09/2009"; my $load_log = 0; # load log file at END my $in_file = ''; my $verbosity = 0; my $debug_on = 0; my $def_file = 'def_file'; my $recursive = 1; my $show_rel = 0; my $fix_rela = 1; my $show_srcs = 1; # read the DSP, and show the SOURCES contained my $curr_dbg =0; my $spl_exclude_unix = 0; my $output_cmake_sources = 1; my $lib_type = 'OFF'; my $drop_dsp_rel = 1; # debug items my $dbg1 = 0; # show Project line during collection my $dbg2 = 0; # show during collection my $dbg3 = 0; # show during folder collection my $dbg4 = 0; # show Processing my $dbg05 = 0; # show fix_rel details... my $base_name = ''; # base name of source DSP file my $base_dir = "C:\\Projects\\hb\\a52dec\\vc++"; # base directory my $def_input = $base_dir."\\a52dec.dsw"; ##my $base_dir = "C:\\FG\\FGCOM"; ##my $base_dir = "C:\\FG\\10\\freeglut"; #\\progs\\demos\\"; ##my $base_dir = "C:\\Projects\\UltraVNC-102-Src\\UltraVNC"; #my $def_input = $base_dir."demos.dsw"; # adjust this to the file you want parsed ##my $def_input = $base_dir; #."\\freeglut.dsw"; # adjust this to the file you want parsed # program global variables my @files = (); my @file_list = (); my $pcnt = 0; my $wmsg = ''; my $dswcnt = 0; #-- get current directory my $pwd = cwd(); my $targ_dir = ''; my $cmake_all = ''; my ($proj_title,$proj_dir,$proj_ext); my $done_cmake_head = 0; my $appt_console_stg = 'Console Application'; my $appt_windows_stg = 'Application'; my $appt_dynalib_stg = 'Dynamic-Link Library'; my $appt_statlib_stg = 'Static Library'; my $appt_utility_stg = 'Utility'; my %master_hash = (); ### program variables my @warnings = (); my $cwd = cwd(); my $out_file = ''; sub VERB1() { return $verbosity >= 1; } sub VERB2() { return $verbosity >= 2; } sub VERB5() { return $verbosity >= 5; } sub VERB9() { return $verbosity >= 9; } sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { prt( "\nNo warnings issued.\n\n" ) if (VERB9()); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_log($outfile,$load_log); exit($val); } sub prtw($) { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } # "Win32 (x86) Dynamic-Link Library" 0x0102 # TARGTYPE "Win32 (x86) Application" 0x0101 sub get_app_type_stg_local($) { my ($stg) = shift; if ($stg =~ /Static\s+Library/) { return $appt_statlib_stg; } elsif ($stg =~ /Console\s+Application/) { return $appt_console_stg; } elsif ($stg =~ /Dynamic-Link\s+Library/) { return $appt_dynalib_stg; } elsif ($stg =~ /Application/) { return $appt_windows_stg; } elsif ($stg =~ /External\s+Target/) { return $appt_utility_stg; # FIX20120521 = 'Utility'; } return "Unresolved [$stg] FIXME in $pgmname!!!"; } sub strip_quotes2($) { my ($ln) = shift; if ($ln =~ /^".*"$/) { $ln = substr($ln,1,length($ln)-2); } return $ln; } # split_space - space_split - # like split(/\s/,$txt), but honour double inverted commas # also accept and split '"something"/>', but ONLY if in the tail sub space_split2($) { my ($txt) = shift; my $len = length($txt); my ($k, $ch, $tag, $incomm, $k2, $nch); my @arr = (); $tag = ''; $incomm = 0; for ($k = 0; $k < $len; $k++) { $ch = substr($txt,$k,1); $k2 = $k + 1; $nch = ($k2 < $len) ? substr($txt,$k2,1) : ""; if ($incomm) { $incomm = 0 if ($ch eq '"'); $tag .= $ch; } elsif ($ch =~ /\s/) { # any spacey char push(@arr, $tag) if (length($tag)); $tag = ''; } elsif (($ch =~ /\//)&&($nch eq '>')) { # 04/10/2008, but only if before '>' 24/09/2008 add this as well push(@arr, $tag) if (length($tag)); $tag = $ch; # restart tag with this character } else { $tag .= $ch; $incomm = 1 if ($ch eq '"'); } } push(@arr, $tag) if (length($tag)); return \@arr; } sub is_c_source_local($) { my $f = shift; if ( ($f =~ /\.c$/i) || ($f =~ /\.cpp$/i) || ($f =~ /\.cxx$/i) ) { return 1; } return 0; } sub get_cmake_header() { my $cmake_root = "\n# root CMakeLists.txt, generated by $pgmname, on "; $cmake_root .= lu_get_YYYYMMDD_hhmmss(time())."\n\n"; $cmake_root .= "cmake_minimum_required( VERSION 2.8.8 )\n\n"; $cmake_root .= "project( $proj_title )\n\n"; $cmake_root .= "# The version number.\n"; # TODO ***TBD*** This VERSION stuff MUST BE FIXED ONE DAY # ======================================================= $cmake_root .= "set( ${proj_title}_MAJOR 3 )\n"; $cmake_root .= "set( ${proj_title}_MINOR 0 )\n"; $cmake_root .= "set( ${proj_title}_POINT 0 )\n\n"; $cmake_root .= add_options_block($lib_type); $cmake_root .= get_definitions_block(); return $cmake_root; } sub show_hash_results2($$) { my ($dbg, $rh) = @_; my ($key, $val, $arr, $itm, $icnt, $i, $msg, $len, $src, $grp, $nm, $dir, $ext); my ($iia, $wmsg, $tmp, $ics, $mlen, $slen); my ($captyp,$cname,$dsp,$rf,$gotsdsp,$dsp_name,$dsp_dir,$ff,$ffp); my ($rel_path,$sn,$sd); my %srcs = (); my @fsrcs = (); my @results = (); $gotsdsp = 0; $key = '-NEW_PROJECT_NAME-'; if (defined ${$rh}{$key}) { $cname = ${$rh}{$key}; } else { $cname = "Unknown - [$key] NOT SET!"; } $msg = " name: $cname"; $msg .= " [key=$key]" if ($dbg & 8); $key = 'SOURCE_FILE'; if (defined ${$rh}{$key}) { $dsp = ${$rh}{$key}; # path to DSP file, with source $rf = remove_base_path($dsp, $base_dir); $gotsdsp = 1; ($dsp_name,$dsp_dir) = fileparse($dsp); } else { $dsp = "Unknown - [$key] NOT SET!"; $rf = $dsp; } #$msg .= " DSP [$dsp]"; $msg .= " DSP [$dsp_name] in [$dsp_dir]"; prt("$msg\n"); $key = 'APP_TYPE'; if (defined ${$rh}{$key}) { $captyp = ${$rh}{$key}; } else { $captyp = "Unknown - [$key] NOT SET!"; } $msg = " type: $captyp"; $msg .= " [key=$key]" if ($dbg & 8); prt( "$msg\n" ); if (length($targ_dir) && $gotsdsp) { $rel_path = get_relative_path4($targ_dir,$dsp_dir); prt("Got relative path [$rel_path]\n"); } else { $gotsdsp = 0; } # some rough cmake stuff my $var1 = "${cname}_SOURCES"; my $var2 = "${cname}_HEADERS"; my $cmake = ''; my @arr = (); my $tot_srcs = 0; my $tot_ok = 0; my $tot_hdrs = 0; my $tot_hok = 0; my $indent = 3; my $def_max_line1 = 70; my $def_max_line2 = 85; my $max_line = $def_max_line1; my $src_cnt = 0; my $hdr_cnt = 0; if ($output_cmake_sources) { if (defined ${$rh}{'C_SOURCES'}) { $val = ${$rh}{'C_SOURCES'}; $icnt = scalar @{$val}; @arr = (); $tot_srcs += $icnt; $src_cnt = $icnt; if ($icnt) { for ($i = 0; $i < $icnt; $i++) { # $src = path_d2u(${$val}[$i][0]); $src = ${$val}[$i][0]; next if ($spl_exclude_unix && ($src =~ /(\\|\/)unix(\\|\/)/)); if ($gotsdsp) { $ff = $dsp_dir.$src; $ffp = fix_rel_path3($ff,'show_hash_results2'); ($sn,$sd) = fileparse($ffp); $rel_path = get_relative_path4($sd,$targ_dir); $src = path_d2u($rel_path.$sn); } push(@arr,$src); } } $icnt = scalar @arr; $tot_ok = $icnt; if ($icnt) { ###$cmake .= "\n"; $cmake .= "set( $var1 "; $msg = ''; $max_line = $def_max_line1; foreach $src (sort @arr) { # TODO ***TBD*** need to get the actual source path correct, but for the moment # assume it is from a DSP in msvc, so drop the leading '..\' $src =~ s/^\.\.(\\|\/)// if ($drop_dsp_rel); $msg .= "$src "; if (length($msg) > $max_line) { $cmake .= "$msg\n"; $msg = " " x $indent; $max_line = $def_max_line2; } } if (length($msg) > $indent) { $cmake .= $msg; } else { $cmake =~ s/\n$//; # remove trailing new line } $cmake .= ")\n\n"; } } if (defined ${$rh}{'H_SOURCES'}) { $val = ${$rh}{'H_SOURCES'}; $icnt = scalar @{$val}; $tot_hdrs = $icnt; $hdr_cnt = $icnt; @arr = (); if ($icnt) { for ($i = 0; $i < $icnt; $i++) { $src = path_d2u(${$val}[$i][0]); next if ($spl_exclude_unix && ($src =~ /(\\|\/)unix(\\|\/)/)); if ($gotsdsp) { $ff = $dsp_dir.$src; $ffp = fix_rel_path3($ff,'show_hash_results2'); ($sn,$sd) = fileparse($ffp); $rel_path = get_relative_path4($sd,$targ_dir); $src = path_d2u($rel_path.$sn); } push(@arr,$src); } } $icnt = scalar @arr; $tot_hok = $icnt; if ($icnt) { $cmake .= "set( $var2 "; $msg = ''; $max_line = $def_max_line1; foreach $src (sort @arr) { # TODO ***TBD*** need to get the actual source path correct, but for the moment # assume it is from a DSP in msvc, so drop the leading '..\' $src =~ s/^\.\.(\\|\/)// if ($drop_dsp_rel); $msg .= "$src "; if (length($msg) > $max_line) { $cmake .= "$msg\n"; $msg = " " x $indent; $max_line = $def_max_line2; } } if (length($msg) > $indent) { $cmake .= $msg; } else { $cmake =~ s/\n$//; # remove trailing new line } $cmake .= ")\n\n"; } } if (length($cmake)) { prt("\n# Adding $tot_ok of $tot_srcs sources for $cname ($tot_hok of $tot_hdrs hdrs)\n"); prt($cmake); # my $appt_console_stg = 'Console Application'; # my $appt_windows_stg = 'Application'; # my $appt_dynalib_stg = 'Dynamic-Link Library'; # my $appt_statlib_stg = 'Static Library'; $cmake_all = get_cmake_header() if (!$done_cmake_head); $done_cmake_head = 1; if (($captyp eq $appt_console_stg) || ($captyp eq $appt_windows_stg)) { $msg = "\nadd_executable( $cname "; $msg .= "WIN32 " if ($captyp eq $appt_windows_stg); $msg .= "\${$var1} " if ($src_cnt); $msg .= "\${$var2} " if ($hdr_cnt); $msg .= ")\n"; $cmake .= "$msg"; $cmake .= "set_target_properties( $cname PROPERTIES DEBUG_POSTFIX d )\n"; $cmake .= "install(TARGETS $cname DESTINATION bin )\n"; $cmake .= "install(FILES \${$var2} DESTINATION include )\n" if ($hdr_cnt); $cmake .= "# May need to add library dependence\n"; $cmake .= "# target_link_libraries( $cname \${some_lib_LIST} )\n"; } elsif (($captyp eq $appt_dynalib_stg) || ($captyp eq $appt_statlib_stg)) { $msg = "\nadd_library( $cname \${LIB_TYPE} "; $msg .= "\${$var1} " if ($src_cnt); $msg .= "\${$var2} " if ($hdr_cnt); $msg .= ")\n"; $cmake .= "$msg\n"; # # add the install targets # ============================================== # DEAL WITH LIBRARY INSTALL # ============================================== # install (TARGETS Hello DESTINATION lib) # install (FILES ${HELLO_HDRS} DESTINATION include) # $msg = "install(TARGETS $pname DESTINATION $ilibp)\n"; $msg = "\n# deal with install \n"; $msg .= "install( TARGETS $cname\n"; $msg .= " RUNTIME DESTINATION bin\n"; $msg .= " LIBRARY DESTINATION lib\n"; $msg .= " ARCHIVE DESTINATION lib )\n"; $cmake .= $msg; $cmake .= "install(FILES \${$var2} DESTINATION include )\n" if ($hdr_cnt); $cmake .= "# If a SHARED library, may need to add library dependence\n"; $cmake .= "# target_link_libraries( $cname \${some_lib_LIST} )\n"; } $cmake_all .= "# Project $cname, type $captyp\n"; $cmake_all .= "# Adding $tot_ok of $tot_srcs sources ($tot_hok of $tot_hdrs hdrs)\n"; $cmake_all .= "$cmake\n"; } else { prt("UGH! NO sources for $cname\n"); } } # ======================================== push(@results, [$cname, $captyp, 0, 0]); foreach $key (sort keys(%{$rh}) ) { $val = $$rh{$key}; $len = length($val); if (($key eq 'C_SOURCES')||($key eq 'H_SOURCES')) { # SHOW of sources and headers in DSP/VCPROJ file $icnt = scalar @{$val}; $msg = "$key count $icnt sources ..."; prt( "$msg ($icnt)\n" ); $msg = ''; if ($key eq 'C_SOURCES') { $results[0][3] = $icnt; } elsif ($key eq 'H_SOURCES') { $results[0][4] = $icnt; } # push(@vc_c_sources,[$adddefs, $fname, $flist]); $mlen = 0; # get MINIMUM length for ($i = 0; $i < $icnt; $i++) { $src = $$val[$i][0]; $slen = length($src); $mlen = $slen if ($slen > $mlen); } for ($i = 0; $i < $icnt; $i++) { $src = $$val[$i][0]; ($nm,$dir,$ext) = fileparse( $src, qr/\.[^.]*/ ); $nm = lc($nm); $iia = defined $srcs{$nm}; $ics = is_c_source_local($src); if ($iia) { if ($ics) { $wmsg = "WARNING: Duplicate [$src]! "; prtw( "$wmsg\n" ); } } else { $srcs{$nm} = 1 if ($ics); push(@fsrcs,$src); } $grp = $$val[$i][1]; $msg .= "\n" if length($msg); $tmp = $src; $tmp .= ' ' while (length($tmp) < $mlen); $msg .= $tmp; $msg .= " [$grp]"; ###$msg .= ' '.$$val[$i][2]; } prt( "$msg\n" ) if ($dbg & 4); } elsif (($key eq 'APP_TYPE')||($key eq '-NEW_PROJECT_NAME-')) { # now shown at the beginning # prt( "Application Type [$val]\n" ); } elsif ($key eq 'SOURCE_FILE') { # extracted and shown } else { # SHOW of other things extracted from the PROJECT file (vcproj or dsp) $arr = space_split2($val); $icnt = scalar @{$arr}; $msg = "$key = ["; $msg .= "$val]"; $msg .= " $icnt items..."; prt( "$msg\n" ) if !($dbg & 1); # will show ALL if dbg & 1 $msg = ''; if ($dbg & 1) { prt( "[dbg1]: Show of $icnt items ...\n" ); for ($i = 0; $i < $icnt; $i++) { $itm = ${$arr}[$i]; if ($itm =~ /^\/(D|I)/) { # /I or /D $i++; if ($i < $icnt) { $src = ${$arr}[$i]; } else { $src = 'OUT OF ITEMS - CHECK ME!'; } prt( "$itm $src\n" ); } else { # other ... prt( "$itm\n" ); } } } } } return \@results; } sub show_master_hash($) { my ($mhr) = @_; my ($key,$hr,$cnt,$ra); $cnt = scalar keys(%{$mhr}); prt( "Show of $cnt items...\n" ); my %h = (); foreach $key (keys %{$mhr}) { prt( "Project [$key]\n" ); $hr = ${$mhr}{$key}; # extract hash for project $ra = show_hash_results2($curr_dbg,$hr); # ret a results hash $h{$key} = $ra; } return \%h; } # ##################################################### sub process_directory { ## $in_folder my ($inf, $lev) = @_; my $rcnt = 0; my ($DH); if ( !opendir($DH, $inf) ) { prt( "ERROR: Unable to OPEN FOLDER [$inf] ... $! ... \n" ); return $rcnt; } my @files = readdir($DH); closedir $DH; my $fcnt = scalar @files; prt( "Have $fcnt to process from $inf ...\n" ) if ($dbg3); foreach my $file (@files) { if (($file eq '.') || ($file eq '..')) { next; } my $ff = $inf . "\\" . $file; if (-d $ff) { if ($recursive) { ###if (in_excl_list($file)) { ### push(@folders, sub_main($ff)); ###} $rcnt += process_directory( $ff, $lev + 1 ); } } else { # is a FILE if ( is_my_file($file) ) { push(@file_list, $ff); $rcnt++; } } } return $rcnt; } sub is_my_file { my ($f) = shift; my ($nm,$dir,$ext) = fileparse( $f, qr/\.[^.]*/ ); if (lc($ext) eq '.dsw') { return 1; } return 0; } # ENSURE '/' is used throughout string. sub dos_to_unix { my ($du) = shift; $du =~ s/\\/\//g; return $du; } sub remove_base_dir($) { my $ff = shift; my $len1 = length($ff); my $bd = $base_dir; my $len2 = length($bd); if ($len1 > $len2) { return substr($ff,$len2); } else { return $ff; } } sub scan_dsp_lines($$) { my ($ra,$dsp) = @_; ##my @dsplines = @_; ##my $lncnt = scalar @dsplines; my $lncnt = scalar @{$ra}; my @dspsrcs = (); my $projname = ''; my $projtype = ''; my $group = ''; my $filter = ''; my ($tmp, $key, $line, $tline, $lnn, $len, $i, $ff); my %dsp_hash = (); my $hr = \%dsp_hash; my $mhr = \%master_hash; my @c_sources = (); my @h_sources = (); my @o_sources = (); # others my ($dsp_name,$dsp_dir) = fileparse($dsp); ###prt( "File contains $lncnt lines ...\n" ); # push(@c_sources,[$src, $group, $filter, 0]); $lnn = 0; for ($i = 0; $i < $lncnt; $i++) { #$line = $dsplines[$i]; $line = ${$ra}[$i]; chomp $line; $lnn++; $tline = trim_all($line); $len = length($tline); next if ($len == 0); if ($line =~ /^#\s+Microsoft\s+Developer\s+Studio\s+.+Name="(\w+)".+$/) { $projname = $1; prt( "Project Name [$projname]\n" ); # -NEW_PROJECT_NAME-" = name of the project $key = '-NEW_PROJECT_NAME-'; ${$hr}{$key} = $projname; } elsif ($line =~ /^#\s+TARGTYPE\s+(.*)/) { $tmp = $1; #prt( "# TARGTYPE $1\n" ); $projtype = get_app_type_stg_local($tmp); prt( "Project Type [$projtype]\n" ); $key = 'APP_TYPE'; ${$hr}{$key} = $projtype; } elsif ( $line =~ /^#\s+Begin\s+Group\s+(.*)/ ) { $group = strip_quotes2($1); prt( "Begin Group [$group]\n" ) if (VERB9()); } elsif ( $line =~ /^#\s+PROP\s+Default_Filter\s+"(.*)".*$/ ) { $filter = $1; prt( "Filter [$filter]\n" ) if (VERB9()); } elsif ( $line =~ /^SOURCE=/ ) { $line =~ s/^SOURCE=//o; while ($line =~ /\W$/) { # ending in NON-alphanumic ####prt( "Discarding [".substr($line,-1,1)."]!\n" ); $line = substr($line,0,length($line)-1); } ##while (( substr($line,-1,1) eq ' ' )||( substr($line,-1,1) eq "\t")|| ## ( substr($line,-1,1) eq "\r")||( substr($line,-1,1) eq "\n")) { ## $line = substr($line,0,length($line)-1); ##} $line =~ s/^\"//; # remove leading inverted commas $line =~ s/\"$//; # remove trailing inverted commas $line = dos_to_unix($line); $line =~ s/^\.\///; # remove any leading './'; $ff = remove_base_dir($dsp_dir.$line); $ff = path_d2u($ff); if (($line =~ /\.cxx$/i) || ($line =~ /\.c$/i) || ($line =~ /\.cpp$/i)) { #push(@dspsrcs, $line); #push(@c_sources, [$line, $group, $filter]); push(@dspsrcs, $ff); push(@c_sources, [$ff, $group, $filter]); } elsif ( ($line =~ /\.hxx$/i) || ($line =~ /\.h$/i) || ($line =~ /\.hpp$/i) ) { #push(@dspsrcs, $line); #push(@h_sources, [$line, $group, $filter]); push(@dspsrcs, $ff); push(@h_sources, [$ff, $group, $filter]); } else { if ( $line =~ /^\$\(/ ) { # need maco expansion prt("$lnn: CHECK 'MACRO' SOURCE [$line]\n"); # if (VERB9()); } else { #push(@o_sources, [$line, $group, $filter]); push(@o_sources, [$ff, $group, $filter]); prt("$lnn: CHECK 'other' SOURCE [$line]\n") if (VERB9()); } } } elsif ($line =~ /^!MESSAGE/) { # ignore MESSAGE lines } elsif ($line =~ /^!IF\s+/) { } elsif ($line =~ /^!ELSEIF\s+/) { } elsif ($line =~ /^!ENDIF/) { } elsif ($line =~ /^\#/) { $line =~ s/^\#\s+//; # hash line if ($line =~ /^Microsoft Developer Studio Generated Build File, Format Version 6.00/) { # ignore } elsif ($line =~ /^\*\*\s+DO\s+NOT\s+EDIT\s+\*\*/) { # ignore } elsif ($line =~ /^Begin Project/) { # ignore } elsif ($line =~ /^PROP\s+/) { # deal with various PROPERTIES } elsif ($line =~ /^ADD\s+/) { } elsif ($line =~ /^SUB\s+/) { } elsif ($line =~ /^SUBTRACT\s+/) { # FIX20120601 } elsif ($line =~ /^Name\s+/) { } elsif ($line =~ /^Begin\s+/) { # # Begin Custom Build - Creating apr.h from apr.hw # InputPath=.\include\apr.hw # ".\include\apr.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" # type .\include\apr.hw > .\include\apr.h # # End Custom Build if ($line =~ /Begin\s+Custom\s+Build/) { # stay and EAT until END $i++; for (; $i < $lncnt; $i++) { #$line = $dsplines[$i]; $line = ${$ra}[$i]; chomp $line; $lnn++; $tline = trim_all($line); $len = length($tline); next if ($len == 0); last if ($line =~ /^\#\s+End\s+Custom\s+Build/); } } elsif ($line =~ /^Begin\s+Special\s+Build\s+Tool/) { # TargetPath=Release\libapr-2.dll # SOURCE="$(InputPath)" # PostBuild_Desc=Embed .manifest # PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2 # # End Special Build Tool # stay and EAT until END $i++; for (; $i < $lncnt; $i++) { #$line = $dsplines[$i]; $line = ${$ra}[$i]; chomp $line; $lnn++; $tline = trim_all($line); $len = length($tline); next if ($len == 0); last if ($line =~ /^\#\s+End\s+Special\s+Build/); } } } elsif ($line =~ /^End\s+/) { } else { prt("CHECK UNdecoded HASH line [$line]\n"); } } elsif ($line =~ /^\w+=/) { # macro } else { prt("CHECK UNdecoded line [$line]\n"); } } $key = 'C_SOURCES'; ${$hr}{$key} = [@c_sources]; $key = 'H_SOURCES'; ${$hr}{$key} = [@h_sources]; $key = 'SOURCE_FILE'; ${$hr}{$key} = $dsp; $key = $projname; ${$mhr}{$key} = $hr; $lncnt = scalar @dspsrcs; prt( "File contains $lncnt SOURCES ...\n" ); return \@dspsrcs; } sub remove_base_path($$) { my ($ln, $bs) = @_; my $len1 = length($ln); my $len2 = length($bs); if ($len1 < $len2) { return $ln; } my ($i,$c1,$c2); for ($i = 0; $i < $len2; $i++) { $c1 = lc(substr($ln,$i,1)); $c2 = lc(substr($bs,$i,1)); if ($c1 ne $c2) { return $ln; } } return substr($ln,$len2); } sub show_files { my (@fils) = @_; my $cnt = 0; my ($line,$ff); foreach $line (@fils) { $cnt++; $ff = File::Spec->rel2abs($line); ###my $rp = substr($line, length($base_dir)); my $rp = remove_base_path($line, $base_dir); if ($show_rel) { if ($fix_rela) { $rp = fix_rel($rp); } prt( "$cnt: [$rp]\n" ); } else { #prt( "$cnt: [$line]\n" ); prt( "$cnt: [$ff]\n" ); } if ($show_srcs) { # read the DSP, and enumerate the SOURCES if (open(INF, "<$line")) { my @lns = ; close INF; my $lncnt = scalar @lns; prt( "$line contains $lncnt lines to process ...\n" ) if (VERB9()); my $srcs = scan_dsp_lines(\@lns,$ff); if (VERB5()) { foreach my $src (@{$srcs}) { prt( " $src\n" ); } } } else { prt( "WARNING: Failed to open [$line] ...\n" ); } } } } sub process_dsw { my ($fl) = shift; my @fls = load_in_file( $fl ); prt( "\nFrom $fl got ".scalar @fls." DSP files...\n" ); show_files( @fls ); } sub load_in_file { my ($inf) = shift; my @infs = (); my ($cnt,$nm,$dir,$proj,@arr,$dsp,$ok,$line); ###prt( "Processing $inf ...\n" ); if ( !open INF, "<$inf" ) { $wmsg = "WARNING: Can not OPEN [$inf] ... $! ..."; prt( "$wmsg\n" ); push(@warnings, $wmsg); return @infs; } my @lines = ; close INF; $cnt = scalar @lines; ($nm,$dir) = fileparse($inf); prt( "\nProcessing $cnt lines from [$nm] in [$dir] ...\n" ) if ($dbg4); $cnt = 0; foreach $line (@lines) { $line = trim_all($line); ###if ($line =~ /Project:\s+\"{1}(.+)\"{1}/) { if ($line =~ /Project:\s+(.+)\s+-\s+Package\s+Owner=/) { $cnt++; prt( "$cnt Project [$1] ...\n" ) if ($dbg1); $proj = $1; $proj =~ s/\"//g; @arr = split(/=/, $proj); if (scalar @arr >= 2) { $pcnt++; $dsp = $dir . $arr[1]; $ok = 'NOT FOUND'; if ( -f $dsp) { $ok = 'ok'; } prt( "$pcnt name=[".$arr[0]."], file=[".$arr[1]."] ...$ok \n" ) if ($dbg2); push(@infs, $dsp); } } } $cnt = scalar @infs; prt( "Got $cnt files from $inf ...\n" ) if ($dbg4); return @infs; } sub unix_2_dos { my ($f) = shift; $f =~ s/\//\\/g; return $f; } sub fix_rel { my ($path) = shift; # my @a = split(/\\/, $path); $path = unix_2_dos($path); my @a = split(/\\/, $path); my $npath = ''; my $max = scalar @a; my @na = (); my ($i,$p,$pt); prt( "[dbg05] fix_rel:[$path], split to $max parts...\n" ) if ($dbg05); for ($i = 0; $i < $max; $i++) { $p = $a[$i]; if ($p eq '.') { # ignore this } elsif ($p eq '..') { if (@na) { pop @na; # discard previous } else { prt( "WARNING: Got relative .. without previous!!!\n" ); } } else { prt( "[dbg05] adding [$p]\n" ) if ($dbg05); push(@na,$p); } } foreach $pt (@na) { $npath .= "\\" if length($npath); $npath .= $pt; } prt( "[dbg05] returning [$npath]\n" ) if ($dbg05); return $npath; } sub die_if_no_file { my ($fil) = shift; if ((length($fil) == 0) || !( -f $fil )) { if (length($fil)) { mydie( "ERROR: Can NOT locate [$fil] ... $! ...\n" ); } else { mydie( "ERROR: Must give a DSW input file ...\n" ); } } } sub process_build_file($) { my $file = shift; if ($file =~ /\.dsp/i) { my @fl = (); push(@fl,$file); show_files(@fl); } else { process_dsw($file); # assume it is a DSW } } sub process_in_file($) { my ($inf) = @_; my $ok = 0; if ( -f $inf ) { my $ff = File::Spec->rel2abs($inf); ($base_name,$base_dir) = fileparse($ff); process_build_file($inf); $ok = 1; # } elsif ( -d $inf ) { # process_directory( $inf, 0 ); # $dswcnt = scalar @file_list; # prt( "Found $dswcnt DSW files to process ...\n" ); # foreach $line (@file_list) { # process_dsw( $line ); # } # $ok = 1; } else { prtw("WARNING: [$in_file] is NOT a file!\n"); } if ($ok) { prt( "\nShow of MASTER HASH\n" ); my $rr = show_master_hash(\%master_hash); my ($nm,$tp,$ln,$min,$ct); $min = 0; foreach my $k (keys %{$rr}) { my $v = ${$rr}{$k}; $nm = ${$v}[0][0]; $tp = ${$v}[0][1]; $ln = length($nm); $min = $ln if ($ln > $min); } $ct = 0; foreach my $k (keys %{$rr}) { my $v = ${$rr}{$k}; $nm = ${$v}[0][0]; $tp = ${$v}[0][1]; $nm .= ' ' while (length($nm) < $min); $ct++; # The $k is the same as the name prt( "$ct: Project: $nm Type: $tp\n" ); } } } ### MAIN ### parse_args(@ARGV); process_in_file($in_file); if (length($cmake_all)) { if (length($out_file)) { $cmake_all .= "\n# end of generated root CMakeLists.txt file for $proj_title, by $pgmname\n\n"; write2file($cmake_all,$out_file); prt("Bare cmake written to [$out_file]\n"); } else { prt("No output file so bare cmake not written. User -o file-name\n"); } } pgm_exit(0,""); ############ sub need_arg { my ($arg,@av) = @_; pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av); } sub parse_args { my (@av) = @_; my ($arg,$sarg); while (@av) { $arg = $av[0]; if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if (($sarg =~ /^h/i)||($sarg eq '?')) { give_help(); pgm_exit(0,"Help exit(0)"); } elsif ($sarg =~ /^v/) { if ($sarg =~ /^v.*(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/) { $verbosity++; $sarg = substr($sarg,1); } } prt("Verbosity = $verbosity\n") if (VERB1()); } elsif ($sarg =~ /^l/) { $load_log = 1; prt("Set to load log at end.\n") if (VERB1()); } elsif ($sarg =~ /^o/) { need_arg(@av); shift @av; $sarg = $av[0]; $out_file = $sarg; prt("Set out file to [$out_file].\n") if (VERB1()); } elsif ($sarg =~ /^t/) { need_arg(@av); shift @av; $sarg = $av[0]; $targ_dir = File::Spec->rel2abs($sarg); prt("Set target directory to [$targ_dir].\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n"); } } else { $in_file = File::Spec->rel2abs($arg); ($proj_title,$proj_dir,$proj_ext) = fileparse($in_file , qr/\.[^.]*/ ); prt("Set input to [$in_file]\n") if (VERB1()); } shift @av; } if ((length($in_file) == 0) && $debug_on) { $in_file = $def_file; prt("Set DEFAULT input to [$in_file]\n"); } if (length($in_file) == 0) { pgm_exit(1,"ERROR: No input files found in command!\n"); } if (! -f $in_file) { pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n"); } } sub give_help { prt("$pgmname: version $VERS\n"); prt("Usage: $pgmname [options] in-file\n"); prt("Options:\n"); prt(" --help (-h or -?) = This help, and exit 0.\n"); prt(" --verb[n] (-v) = Bump [or set] verbosity. def=$verbosity\n"); prt(" --load (-l) = Load LOG at end. ($outfile)\n"); prt(" --targ dir (-t) = Target directory for CMakeLists.txt. Implies fix source el to this.\n"); prt(" --out (-o) = Write output to this file.\n"); } # eof - dswlist.pl