track current line and file name; new find_conf, process_file subs; remove
@skip N@ ability; skip @token@ search if line doesn't begin with @;
add @skipif@, @break@; dont require spaces for @close@; add -ifexists param to
@include@; new @ifconf@ + rework code to make other @ifXXX@ tokens easy; merge
else/elsif in process loop
git-svn-id: file:///home/hardaker/lib/sf-bkups/net-snmp-convert-svnrepo/trunk@8584 06827809-a52a-0410-b366-d66718629ded
diff --git a/local/mib2c b/local/mib2c
index 64324dc..b648612 100755
--- a/local/mib2c
+++ b/local/mib2c
@@ -45,6 +45,8 @@
$quiet=0;
$nostats = 0;
$noindent = 0;
+$currentline = 0;
+$currentlevel = -1;
%assignments;
%outputs;
@@ -137,15 +139,8 @@
# loop through mib nodes, remembering stuff.
setup_data($mibnode);
-my $defaults = "";
-if (-f "default-$configfile") {
- $defaults = "default-$configfile";
-} elsif (-f "$ENV{MIB2C_DIR}/default-$configfile") {
- $defaults = "$ENV{MIB2C_DIR}/default-$configfile";
-} elsif (-f "/usr/local/share/snmp/default-$configfile") {
- $defaults = "/usr/local/share/snmp/default-$configfile";
-}
-if ( "$defaults" ne "" ) {
+my $defaults = find_conf("default-$configfile",1);
+if (-f "$defaults" ) {
$fh = open_conf($defaults);
process();
$fh->close;
@@ -157,7 +152,7 @@
$vars{$var} = $assignments{$var};
}
}
-
+$configfile = find_conf($configfile,0);
$fh = open_conf($configfile);
process();
$fh->close;
@@ -285,23 +280,31 @@
# evaluates expression, and if expression is true processes
# contained part until appropriate @end@ is reached.
sub skippart {
- my $endcount = shift;
- if ( "$endcount" == "" ) {
- $endcount = 1;
- }
- while(<$fh>) {
- print "SHIFT($endcount):$_" if ($debug);
+ my $endcount = 1;
+ my $arg = shift;
+ my $rtnelse = 0;
+ while ($arg =~ s/-(\w+)\s*//) {
+ $rtnelse = 1 if ($1 eq "else");
+ }
+ while(<$fh>) {
+ $currentline++;
+ $_ = process_vars($_) if ($debug);
+ print "$currentfile.$currentline.S$endcount.$rtnelse:$_" if ($debug);
if (/\@\s*end\@/) {
- return if ($endcount == 1);
+ return "end" if ($endcount == 1);
$endcount--;
}
- if (/\@\s*else\@/) {
- return process() if ($endcount == 1);
+ elsif (/\@\s*else\@/) {
+ return "else" if (($endcount == 1) && ($rtnelse == 1));
}
- if (/\@\s*(foreach|if)/) {
+ elsif (/\@\s*elsif\s+([^\@]+)\@/) {
+ return "else" if (($endcount == 1) && ($rtnelse == 1) && (eval(process_vars($1))));
+ }
+ elsif (/\@\s*(foreach|if)/) {
$endcount++;
}
}
+ return "eof"
}
sub close_file {
@@ -339,16 +342,56 @@
$written{$name} = '1';
}
-sub process {
- while(<$fh>) {
+sub process_file {
+ my ($file, $missingok) = (@_);
+ my $oldfh = $fh;
+ my $oldfile = $currentfile;
+ my $oldline = $currentline;
+ # keep old copy of @vars and just build on it.
+ my %oldvars = %vars;
- if (/^\s*\#\#/) {
- # noop, it's a comment
- } elsif (/\@\s*exit\@/) {
- die "exiting at conf file ($currentfile) request\n";
- } elsif (/\@\s*else\@/) {
- return skippart();
- } elsif (/\@\s*open\s+([^\@]+)\@/) {
+ $file = find_conf($file,$missingok);
+ return if (! $file);
+
+ $fh = open_conf($file);
+ $currentline = 0;
+ process();
+ $fh->close();
+
+ $fh = $oldfh;
+ $currentfile = $oldfile;
+ $currentline = $oldline;
+
+ # don't keep values in replaced vars. Revert to ours.
+ %vars = %oldvars;
+}
+
+sub process {
+ my $arg = shift;
+ my $elseok = 0;
+ while ($arg =~ s/-(\w+)\s*//) {
+ $elseok = 1 if ($1 eq "elseok");
+ }
+
+ $currentlevel++;
+ while(<$fh>) {
+ $currentline++;
+ if ($debug) {
+# my $line = process_vars($_);
+# chop $line;
+ print "$currentfile.$currentline.P$currentlevel.$elseok:$_";
+ }
+
+ next if (/^\s*\#\#/); # noop, it's a comment
+ if (! /^\s*\@.*\@/ ) { # output
+ my $line = process_vars($_);
+ foreach $file (values(%outputs)) {
+ print $file "$line";
+ }
+ } ####################################################################
+ elsif (/\@\s*exit\@/) { # EXIT
+ die "exiting at conf file ($currentfile:$currentline) request\n";
+ } elsif (/\@\s*open\s+([^\@]+)\@/) { # OPEN
my $arg = $1;
my ($multiple) = (0);
while ($arg =~ s/-(\w+)\s+//) {
@@ -356,10 +399,10 @@
}
my $spec = process_vars($arg);
open_file($multiple, $spec);
- } elsif (/\@\s+close\s+([^\@]+)\@/) {
+ } elsif (/\@\s*close\s+([^\@]+)\@/) { # CLOSE
my $spec = process_vars($1);
close_file($spec);
- } elsif (/\@\s*append\s+([^\@]+)\@/) {
+ } elsif (/\@\s*append\s+([^\@]+)\@/) { # APPEND
my $arg = $1;
my ($multiple) = (0);
while ($arg =~ s/-(\w+)\s+//) {
@@ -368,7 +411,7 @@
my $spec = process_vars($arg);
$spec=">$spec";
open_file($multiple,$spec);
- } elsif (/\@\s*run (.*)\@/) {
+ } elsif (/\@\s*run (.*)\@/) { # RUN
my $arg = $1;
my ($again) = (0);
while ($arg =~ s/-(\w+)\s+//) {
@@ -379,51 +422,71 @@
}
next if (!$again && $ranalready{$arg});
$ranalready{$arg} = 1;
- my $oldfh = $fh;
my %oldout = %outputs;
my %emptyarray;
%outputs = %emptyoutputs;
- my %oldvars = %vars;
- # keep old copy of @vars and just build on it.
- $fh = open_conf($arg);
-# $out = undef;
- process();
- $fh->close();
- $fh = $oldfh;
+ process_file($arg);
%outputs = %oldout;
- # don't keep values in replaced vars. Revert to ours.
- %vars = %oldvars;
- } elsif (/\@\s*include (.*)\@/) {
- my $oldfh = $fh;
- my %oldvars = %vars;
- # keep old copy of @vars and just build on it.
- $fh = open_conf($1);
- process();
- $fh->close();
- $fh = $oldfh;
- # don't keep values in replaced vars. Revert to ours.
- %vars = %oldvars;
- } elsif (/\@\s*end\@/) {
- return;
- } elsif (/\@\s*if\s+([^@]*)\@/) {
- if (eval(process_vars($1))) {
- process();
- } else {
- skippart();
+ } elsif (/\@\s*include (.*)\@/) { # INCLUDE
+ my $arg = $1;
+ my ($missingok) = (0);
+ while ($arg =~ s/-(\w+)\s+//) {
+ $missingok = 1 if ($1 eq 'ifexists');
}
- } elsif (/\@\s*eval\s+\$(\w+)\s*=\s*([^\@]*)/) {
+ process_file($arg,$missingok);
+ } elsif (/\@\s*if([a-z]*)\s+([^@]+)\@/) { # IF
+ my ($type,$arg,$ok) = ($1,$2,0);
+ # check condition based on type
+ if (! $type) {
+ $ok = eval(process_vars($arg));
+ } elsif ($type eq conf) {
+ my $file = find_conf($arg,1); # missingok
+ $ok = (-f $file);
+ } else {
+ die "unknown if modifier ($type)\n";
+ }
+ my $rtn;
+ # act on condition
+ if ($ok) {
+ $rtn = process("-elseok");
+ } else {
+ $rtn = skippart("-else");
+ $rtn = process("-elseok") if ($rtn eq "else");
+ }
+ if ($rtn eq "break") {
+ skippart();
+ $currentlevel--;
+ return "end";
+ }
+ } elsif (/\@\s*els(e|if).*\@/) { # ELSE/ELSEIF
+ die "unexpected else or elsif\n" if ($elseok != 1);
+ skippart();
+ $currentlevel--;
+ return "else";
+ } elsif (/\@\s+skipif\s+([^@]*)\@/) { # SKIPIF
+ if (eval(process_vars($1))) {
+ skippart();
+ $currentlevel--;
+ return "skipif";
+ }
+ } elsif (/\@\s*break\s*\@/) { # BREAK
+ skippart();
+ $currentlevel--;
+ return "break";
+ } elsif (/\@\s*end\@/) { # END
+ $currentlevel--;
+ return "end";
+ } elsif (/\@\s*eval\s+\$(\w+)\s*=\s*([^\@]*)/) { # EVAL
my ($v, $e) = ($1, $2);
# print STDERR "eval: $e\n";
my $e = process_vars($e);
$vars{$v} = eval($e);
# warn "$@" if (!defined($vars{$v}));
- } elsif (/\@\s*perleval\s*(.*)\@/) {
+ } elsif (/\@\s*perleval\s*(.*)\@/) { # PERLEVAL
print STDERR "perleval: $1\n";
my $res = eval($1);
warn "$@" if ($res);
- } elsif (/\@\s+skip\s*([^@]*)\@/) {
- return skippart($1);
- } elsif (/\@\s*foreach\s+\$([^\@]+)\s+scalars*\s*\@/) {
+ } elsif (/\@\s*foreach\s+\$([^\@]+)\s+scalars*\s*\@/) { # SCALARS
my $var = $1;
my $startpos = $fh->tell();
my $scalar;
@@ -566,7 +629,7 @@
} else {
skippart();
}
- } elsif (/\@\s*prompt\s+\$(\S+)\s*(.*)\@/) {
+ } elsif (/\@\s*prompt\s+\$(\S+)\s*(.*)\@/) { # PROMPT
my ($var, $prompt) = ($1, $2);
if (!$term) {
my $haveit = eval { require Term::ReadLine };
@@ -577,7 +640,7 @@
if ($term) {
$vars{$var} = $term->readline(process_vars($prompt));
}
- } elsif (/\@\s*print\s+([^@]*)\@/) {
+ } elsif (/\@\s*print\s+([^@]*)\@/) { # PRINT
my $line = process_vars($1);
print "$line\n";
} else {
@@ -585,11 +648,12 @@
foreach $file (values(%outputs)) {
print $file "$line";
}
- if (/\@.*\@/) {
- warn "The configuration file contained a line with a @@ pair in it which may be a configuration token line mib2c couldn't recognize ($_).";
- }
+ chop $_;
+ warn "$currentfile:$currentline contained a @@ pair in it which may be a configuration token line mib2c couldn't recognize.\n";
+ warn "$currentfile:$currentline [$_]\n";
}
}
+ $currentlevel--;
}
sub setup_data {
@@ -639,22 +703,30 @@
return $_[1];
}
+sub find_conf {
+ my ($configfile, $missingok) = (@_);
+
+ return $configfile if (-f "$configfile");
+ return "$ENV{MIB2C_DIR}/$configfile" if (-f "$ENV{MIB2C_DIR}/$configfile");
+ return "/usr/local/share/snmp/$configfile" if (-f "/usr/local/share/snmp/$configfile");
+
+ return if ($missingok);
+
+ print STDERR "Can't find a configuration file called $configfile\n";
+ print STDERR "I looked in ., $ENV{MIB2C_DIR} and /usr/local/share/snmp\n";
+ exit;
+}
+
sub open_conf {
my $configfile = shift;
- $currentfile = $configfile;
# process .conf file
- my $fh = new IO::File;
- if (-f "$configfile") {
- $fh->open("$configfile");
- } elsif (-f "$ENV{MIB2C_DIR}/$configfile") {
- $fh->open("$ENV{MIB2C_DIR}/$configfile");
- } elsif (-f "/usr/local/share/snmp/$configfile") {
- $fh->open("/usr/local/share/snmp/$configfile");
- } else {
+ if (! -f "$configfile") {
print STDERR "Can't find a configuration file called $configfile\n";
- print STDERR "I looked in ., $ENV{MIB2C_DIR} and /usr/local/share/snmp\n";
exit;
}
+ $currentfile = $configfile;
+ my $fh = new IO::File;
+ $fh->open("$configfile");
return $fh;
}