#!/usr/bin/perl -w # Copyright (c) 2000, 2002 Stephen Montgomery-Smith # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of Stephen Montgomery-Smith nor the names of his # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. sub setatom { $atom = $atomlist[$atomcount]; $previousatom = $atomlist[$atomcount-1]; $nextatom = $atomlist[$atomcount+1]; $atom =~ s/^\d+: // if defined $atom; $previousatom =~ s/^\d+: // if defined $previousatom; $nextatom =~ s/^\d+: // if defined $nextatom; } sub getatom { $atomcount++; setatom; } sub pushatom { $atomcount--; setatom; } sub fetchatoms { @atomlist = (); open(CONFIG,"config_getargs"); while ($line = ) { if ($line !~ /^\#/) { while (1) { next if ($line =~ s/^\s+//); if ($line =~ s/^\"([^\"]*)\"//) {} elsif ($line =~ s/^([a-zA-Z\_][a-zA-Z\_0-9]*)//) {} elsif ($line =~ s/^(\%\d*[a-zA-Z])//) {} elsif ($line =~ s/^(\S)//) {} else { last } push(@atomlist,$1); } } } close(CONFIG); push(@atomlist,"end"); $atomcount = 0; setatom; } sub enum_value { my $enum = ''; getatom; $enum = $atom; getatom; die if $atom ne '='; getatom; $enum .= '=' . $atom; getatom; return $enum; } sub sub_title_item { my $item; if ($atom =~ /^[a-zA-Z0-9]/) { $item = "strcmp(ARG,\"$atom\")==0" } elsif ($atom eq '%d') { $item = "get_number(ARG,LOW,HIGH,&VAL)" } elsif ($atom eq '%64x') { $item = "get_64_hex(ARG,char_array_32)" } elsif ($atom eq '%e') { getatom; die "'{' expected at beginning of enum list\n" if $atom ne '{'; $item = "ENUM(ARG," . enum_value; while ($atom eq ';') { $item .= "," . enum_value; } die "'}' expected at end of enum list - got $atom\n" if $atom ne '}'; $item .= ')'; } getatom if defined($item); return $item; } sub title_item { my $title_item = sub_title_item; my $next_item; my $n = 1; die "syntax error in title\n" if !defined($title_item); $title_item =~ s/ARG/argv[i]/; while(defined($next_item = sub_title_item)) { $next_item =~ s/ARG/argv\[i+$n\]/; $title_item = "$title_item && $next_item"; $n++; } return "(i+$n<=argc && $title_item && (inc=$n))"; } sub substitute { @t=(); foreach $t (split /\|\|/,$_[0]) { $t =~ s/LOW/$_[1]/; $t =~ s/HIGH/$_[2]/; $t =~ s/VAL/val$_[3]/; push(@t,$t); } return join '||',@t; } $n_max = 0; sub process_item { my $title_item; $title_item = title_item; while ($atom eq '|') { getatom; $title_item .= " ||\n " . title_item; } die "expected ':'\n" if $atom ne ':'; my $execute = ''; my %maskhash = (); my $n = 1; while ($atom =~ /^(\:|\,)$/) { getatom; my $type = $atom; last if $atom eq '{'; getatom; my $field = $atom; getatom; my $mask = $atom; getatom; die "expected three fields\n" if !defined($atom); #$execute .= "printf(\"executing for $type $field $mask\\n\");\n"; $maskhash{$mask} = 1; if ($type =~ /^MASK\_(.*)$/) { $execute .= "if (argv[i][0] == '-') ctrls->$field &= ~$1;\n" . "else ctrls->$field |= $1;\n"; } elsif ($type eq 'USHORT') { $title_item = substitute($title_item,0,65535,$n); $execute .= "ctrls->$field = val$n;\n"; $n++; } elsif ($type eq 'SHORT') { $title_item = substitute($title_item,-32767,32767,$n); $execute .= "ctrls->$field = val$n;\n"; $n++; } elsif ($type eq 'UCHAR') { $title_item = substitute($title_item,0,255,$n); $execute .= "ctrls->$field = val$n;\n"; $n++; } elsif ($type eq 'LOW_NIBBLE') { $title_item = substitute($title_item,0,255,$n); $execute .= "ctrls->$field &= 0xF0;\n" . "ctrls->$field |= 0x0F & val$n;\n"; $n++; } elsif ($type eq 'BIT32') { $title_item = substitute($title_item,0,255,$n); $execute .= "if (argv[i][0] == '-') ctrls->$field\[val$n>>3] &= ~(1<<(val$n&7));\n" . "else ctrls->$field\[val$n>>3] |= (1<<(val$n&7));\n"; $n++; } elsif ($type eq 'CHAR_ARRAY32') { $execute .= "memcpy(ctrls->$field,char_array_32,32);\n"; } elsif ($type eq 'HIGH_NIBBLE_ENUM') { $title_item =~ s/ENUM\(([^\)]*)\)/1/; @enum_list = split ',',$1; $arg = shift(@enum_list); $first = 1; foreach $enum (@enum_list) { ($code,$value) = split '=',$enum; $execute .= (!$first?"else ":"") . "if (strcmp($arg,\"$code\")==0) {\n" . " ctrls->$field &= 0x0F;\n" . " ctrls->$field |= $value;\n" . "}\n"; $first = 0; } $execute .= "else return 0;\n"; } else { die "Unknown type $type"; } if ($type eq 'BIT32' || $type =~ /^MASK\_/) { $temp = $title_item; $temp =~ s/strcmp\(([^\,]+)\,\"([^\"]+)\"\)/strcmp\($1,\"-$2\"\)/g; $title_item .= " ||\n $temp"; } } $n_max = $n-1 if $n-1>$n_max; foreach $i (@_) { $maskhash{$i} = 0; } $masklist = join '|',grep $maskhash{$_}==1, keys %maskhash; $execute .= "*mask |= $masklist;\n" if $masklist; $execute .= "i += inc;\n"; my $inner; my $inner_count = 0; if ($atom eq '{') { getatom; $inner = process_item(keys %maskhash); $inner_count++ if $inner; while ($atom ne '}') { $t = process_item(keys %maskhash); if ($t) { $inner .= "else " . $t; $inner_count++; } } } else { die "expected ';' or '{' got $atom" if $atom ne ';'; } if ($inner_count==1) { $execute .= $inner; } elsif ($inner_count>=2) { $inner .= "else break;\n"; $inner =~ s/^/ /gm; $execute .= "while (1) {\n$inner}\n"; } getatom; $execute =~ s/^/ /gm; #$t=$title_item; #$t =~ s/\n/\\n/sg; #$t =~ s/\"/\\\"/g; #$title_item = "(printf(\"checking $t i = %d (%s)\\n\",i,argv[i])||1) && ($title_item)"; $execute = "if ($title_item) {\n$execute}\n"; return $execute; } sub process_expire { my $title_item; $title_item = title_item; while ($atom eq '|') { getatom; $title_item .= " ||\n " . title_item; } die "expected ':'\n" if $atom ne ':'; my $type; my $execute = ''; while ($atom =~ /^(\:|\,)$/) { getatom; $type = $atom; last if $atom eq '{'; getatom; my $field = $atom; getatom; my $mask = $atom; getatom; die "expected three fields\n" if !defined($atom); #$execute .= "printf(\"executing for $type $field $mask\\n\");\n"; if ($type =~ /^MASK\_(.*)$/) { if ($field eq 'enabled_ctrls') { ($axmask,$axvalues) = ('axt_ctrls_mask','axt_ctrls_values'); } elsif ($field eq 'ax_options') { ($axmask,$axvalues) = ('axt_opts_mask','axt_opts_values'); } else { ($axmask,$axvalues) = ('',''); } if ($axmask) { $execute .= "if (argv[i][0] == '-') {\n" . " ctrls->$axmask |= $1;\n" . " ctrls->$axvalues &= ~$1;\n" . "}\n" . "else if (argv[i][0] == '=') {\n" . " ctrls->$axmask &= ~$1;\n" . " ctrls->$axvalues &= ~$1;\n" . "}\n" . "else {\n" . " ctrls->$axmask |= $1;\n" . " ctrls->$axvalues |= $1;\n" . "}\n"; $temp1 = $title_item; $temp1 =~ s/strcmp\(([^\,]+)\,\"([^\"]+)\"\)/strcmp\($1,\"-$2\"\)/g; $temp2 = $title_item; $temp2 =~ s/strcmp\(([^\,]+)\,\"([^\"]+)\"\)/strcmp\($1,\"\=$2\"\)/g; $title_item .= " ||\n $temp1 ||\n $temp2"; } } } $execute .= "i += inc;\n"; my $inner; my $inner_count = 0; if ($atom eq '{') { getatom; $inner = process_expire(); $inner_count++ if $inner; while ($atom ne '}') { $t = process_expire(); if ($t) { $inner .= "else " . $t; $inner_count++; } } } else { die "expected ';' or '{'" if $atom ne ';'; } if ($inner_count==1) { $execute .= $inner; } elsif ($inner_count>=2) { $inner .= "else break;\n"; $inner =~ s/^/ /gm; $execute .= "while (1) {\n$inner}\n"; } getatom; $execute =~ s/^/ /gm; #$t=$title_item; #$t =~ s/\n/\\n/sg; #$t =~ s/\"/\\\"/g; #$title_item = "(printf(\"checking $t i = %d (%s)\\n\",i,argv[i])||1) && ($title_item)"; $execute = "if ($title_item) {\n$execute}\n"; return $type =~ /^MASK\_/ ? $execute : ""; } ############ main fetchatoms; $output .= process_item; while ($atom ne 'end') { $output .= "else " . process_item; } $output .= "else return 0;"; $output =~ s/^/ /gm; $vallist = join(', ', map "val$_",(1..$n_max)); fetchatoms; $output_expire = process_expire; while ($atom ne 'end') { $t = process_expire; $output_expire .= "else " . $t if $t; } $output_expire .= "else if ((i+1<=argc && get_number(argv[i],0,65535,&val1) && (inc=1))) {\n" . " ctrls->ax_timeout = val1;\n" . " i += inc;\n" . "}\n" . "else return 0;"; $output_expire =~ s/^/ /gm; open(GETC,">getargs.c"); open(COPY,"COPYRIGHT"); $copy = join '',; print GETC <