diff options
Diffstat (limited to 'local/minimalist/removeifdefcode.pl')
-rwxr-xr-x | local/minimalist/removeifdefcode.pl | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/local/minimalist/removeifdefcode.pl b/local/minimalist/removeifdefcode.pl new file mode 100755 index 0000000..5a64c05 --- /dev/null +++ b/local/minimalist/removeifdefcode.pl @@ -0,0 +1,333 @@ +#! /usr/bin/perl + +use strict; +use File::Copy; +use File::Basename; +use IO::File; +use Getopt::Std; + +my $ID_NOREAD = "NETSNMP_NO_READ_SUPPORT"; +my $ID_NOWRITE = "NETSNMP_NO_WRITE_SUPPORT"; +# my $ID_MIN = "NETSNMP_MINIMAL_CODE"; + +my($ST_OFF, $ST_IF, $ST_ELSE, $ST_IFN, $ST_ELSEN) = + ("off", "if", "else", "ifnot", "elsenot"); + +my %opts = (); +my %thash = (); +my $canwrite = 1; # current write state + +my($appname,$apppath) = fileparse($0); + +my $minimal_include_path = "include/net-snmp/net-snmp-features.h"; + + +if ( (!getopts("rwmi:v",\%opts)) || (1 != $#ARGV) ) { + print "$appname [options] from-directory to-direpctory\n"; + print "-r parse out code unneeded by $ID_NOREAD ifdef\n"; + print "-w parse out code unneeded by $ID_NOWRITE ifdef (DEFAULT)\n"; + print "-m parse out code unneeded according minimalist ifdefs\n"; + print " requires from-directory to be the top of the net-snmp tree\n"; + print " (This is multiple ifdefs auto selected depending\n"; + print " on the net-snmp source configuration)\n\n"; + print "-i 'ignore-file' file of files to ignore (not copy)\n"; + print "-v print verbose info to standard out\n"; + die "Error: two command line arguments required\n"; +} + +#default to everything +if ( (!exists $opts{r}) && (!exists $opts{w}) && (!exists $opts{m}) ) { + $thash{"$ID_NOWRITE"} = "$ST_OFF"; +} +else { + $thash{"$ID_NOREAD"} = "$ST_OFF" if ( exists $opts{r} ); + $thash{"$ID_NOWRITE"} = "$ST_OFF" if ( exists $opts{w} ); +} + +my $fromdir = $ARGV[0]; +my $todir = $ARGV[1]; + +if ( !(-e $fromdir) ) { + die "Error: $appname: from directory does not exist: '$fromdir'\n"; +} +if ( !(-d $fromdir) ) { + die "Error: $appname: from directory, '$fromdir', must be a directory\n"; +} + +if ( exists $opts{m} ) { + load_minamal_ifdefs(); +} + +# create search string from tags +# minimal must be done before this +my $search = join "|", (keys %thash); + + +# check for and load ignore file +my $igstring = ""; +if ( exists $opts{i} ) { + open my($IH), "< $opts{i}" or + die "Could not open ignore-file '$opts{i}': $!"; + my @iglist = <$IH>; + $IH->close(); + chomp @iglist; + $igstring = join "|", @iglist; + $igstring = "(" . $igstring . ")"; + print "ignore string: \'$igstring\'\n" if (exists $opts{v}); +} + + + +if ( -e $todir ) { + if ( ((-d $fromdir) && !(-d $todir)) || + (!(-d $fromdir) && (-d $todir)) ) { + die "Error: $appname: from-directory and to-directory must both either be a file or both be a directory\n"; + } +} +else { + if (-d $fromdir) { + print "Warning: $appname: '$todir' does not exist, creating\n"; + mkdir "$todir" or + die "Error: $appname: Unable to create to-directory '$todir': $!\n"; + } +} + +if (-d $fromdir) { + parsedirectory($fromdir, $todir); +} +else { + parsefile($fromdir, $todir); +} + + + +exit(0); + + +# PROCEDURES PROCEDURES PROCEDURES PROCEDURES PROCEDURES + + +sub parsedirectory { + my($fdir, $tdir) = @_; + + my @ldirs = (); + my $DH; + opendir my($DH), $fdir or die "Could not open directory '$fdir': $!"; + if ( !(-e $tdir) || !(-d $tdir) ) { + mkdir $tdir or die "Could not create directory '$tdir': $!"; + } + my @flist = readdir $DH; + closedir $DH; + # remove . and .. + @flist = grep (! /(^\.$|^\.\.$)/ , @flist); + + while (my $name = shift @flist) { + if (-d "$fdir/$name") { + push @ldirs, "$name"; + } + else { + parsefile("$fdir/$name", "$tdir/$name"); + } + } + + while (my $name = shift @ldirs) { + parsedirectory("$fdir/$name", "$tdir/$name") + } + +} # parsedirectory + + +# returns 1 if current state for tag is write, 0 otherwise +sub iswritestate { + my $tag = ""; + + foreach $tag (keys %thash) { + if ( ($thash{$tag} eq "$ST_ELSE") || + ($thash{$tag} eq "$ST_IFN") ) { + return(0); + } + } + + return(1); +} # iswritestate + + +# Check $line for ifdef state changes for all of the tags and change +# state. +# If there is a state change error return 0, otherwise return 1; + +sub checkifdef { + my($TF, $line, $fromfilename) = @_; + + if ( $line =~ /(#ifdef|#ifndef|#else|#endif).*($search)(\s|$|\*)/ ) { + my $copt = $1; + my $tag = $2; + + if ( $copt eq "#ifdef" ) { + if ($thash{"$tag"} eq "$ST_OFF") { + $thash{"$tag"} = "$ST_IF"; + print "state change $tag: $ST_OFF -> $ST_IF\n" if (exists $opts{v}); + $canwrite = iswritestate(); + } + else { + print "Error: $fromfilename: Found '#ifdef $tag' with state $thash{$tag}\n"; + return 0; + } + } + elsif ( $copt eq "#ifndef" ) { + if ($thash{"$tag"} eq "$ST_OFF") { + # before changing to a non-write state (ifn) print #IFNDEF + # line, if current state is a write state. + print $TF "$line" if ( $canwrite ); + $thash{"$tag"} = "$ST_IFN"; + print "state change $tag: $ST_OFF -> $ST_IFN\n" if (exists $opts{v}); + $canwrite = iswritestate(); + } + else { + print "Error: $fromfilename: Found '#ifndef $tag' with state $thash{$tag}\n"; + return 0; + } + } + elsif ( $copt eq "#else" ) { + if ($thash{"$tag"} eq "$ST_IF") { + # before changing to a non-write state (else) print #else + # line, if current state is a write state. + print $TF "$line" if ( $canwrite ); + $thash{"$tag"} = "$ST_ELSE"; + print "state change $tag: $ST_IF -> $ST_ELSE\n" if (exists $opts{v}); + $canwrite = iswritestate(); + } + elsif ($thash{"$tag"} eq "$ST_IFN") { + $thash{"$tag"} = "$ST_ELSEN"; + print "state change $tag: $ST_IFN -> $ST_ELSEN\n" if (exists $opts{v}); + $canwrite = iswritestate(); + } + else { + print "Error: $fromfilename: Found '#else (...) $tag' with state $thash{$tag}\n"; + return 0; + } + } + elsif ( $copt eq "#endif" ) { + if (($thash{"$tag"} eq "$ST_ELSE") || ($thash{"$tag"} eq "$ST_IF") || + ($thash{"$tag"} eq "$ST_ELSEN") || ($thash{"$tag"} eq "$ST_IFN")) + { + print "state change $tag: $thash{$tag} -> $ST_OFF\n" + if (exists $opts{v}); + $thash{"$tag"} = "$ST_OFF"; + $canwrite = iswritestate(); + } + else { + print "Error: Found '#endif (...) $tag' with state $thash{$tag}\n"; + return 0; + } + } + + } # foreach tag + + return 1; +} # checkifdef + + +sub parsefile { + my($fname, $tname) = @_; + my $FF; my $TF; + my @fromfile = (); + $canwrite = 1; + + # ignore file for file names + if ( (exists $opts{i}) && ("$fname" =~ /$igstring/) ) { + print "IGNORING $fname\n" if ( exists $opts{v} ); + return 1; + } + + print "Info: Opening '$fname'\n" if ( exists $opts{v} ); + if ( !(open($FF, "< $fname")) ) { + print "Warning: unable to open input file, skipping: '$fname': $!\n"; + return 0; + } + + my @fromfile = <$FF>; + $FF->close(); + + if ( !(open($TF, "> $tname")) ) { + print "Warning: unable to open output file, skipping: '$tname': $!\n"; + return 0; + } + my $mode = (stat("$fname"))[2]; + if ($mode) { my $resp = chmod $mode, "$tname"; } + + my $line = ""; + my @tout = (); + my $retval = 1; + + while ( $line = shift @fromfile ) { + # check for any ifdef state changes + if ( ! checkifdef($TF, $line, $fname) ) { + $FF->close(); + $TF->close(); + die "Error: tag error in file \'$fname\', exiting\n"; + } + + if ( $canwrite ) { + print $TF "$line"; + } + else { + print "Info: not copying: $fname: $line" if ( exists $opts{v} ); + } + + } + + if (! $canwrite) { + print "End of $fname reached and we're not reset into 'canwrite' state\n"; + } + $TF->close(); + + return $retval; +} # parsefile + + +# note, fromdir should have already been checked to exist and be a +# directory +sub load_minamal_ifdefs { + my @filelist = (); + my $MF; + + if ( !(open($MF, "< $fromdir/$minimal_include_path")) ) { + die "Unable to open main minimal feature file: '$fromdir/$minimal_include_path'\n"; + } + my $line; + # skip preceding lines + while ( ($line = <$MF>) && + ($line !~ /^#else.*NETSNMP_FEATURE_CHECKING/ ) ) { + } + # grab the fetaure .h files + while ( ($line = <$MF>) && + ($line !~ /^#endif.*NET_SNMP_FEATURE_CHECKING/) ) { + if ($line =~ /include.*<(.*.h)>/) { + push @filelist, $1; + } + } + + close($MF); + + while (my $fname = shift @filelist) { + if ( !( -e "$fromdir/include/$fname" ) ) { + print "Warn: feature file does not exist, skipping: '$fromdir/include/$fname'"; + next; + } + if ( !(open($MF, "< $fromdir/include/$fname")) ) { + die "Unable to open minimal feature file: '$fromdir/include/$fname'\n"; + } + while ( ($line = <$MF>) ) { + if ( $line =~ /^#define.*(NETSNMP_FEATURE_REMOVE[^ ]+) / ) { + $thash{"$1"} = $ST_OFF; + } + } + close($MF); + } + +} # load_minamal_ifdefs + + + + |