1#!/usr/bin/perl 2 3require 'getopts.pl'; 4 5my $debug = 0; 6 7Getopts('dc:p:o:') || die "foo"; 8 9if ($opt_d) { 10 $debug = 1; 11} 12 13die "missing arg" if (!defined $opt_c || !defined $opt_p || !defined $opt_o); 14 15my %defines; 16my $IN; 17my $OUT; 18 19print "parse config.h\n" if ($debug); 20 21open IN, $opt_c || die "failed open ${opt_c}"; 22 23my @nesting; 24 25push @nesting, 1; 26 27while (<IN>) { 28 if (m/\s*#ifdef\s+(.*)/) { 29 my $var = $1; 30 if (defined $defines{$var}) { 31 push @nesting, 1; 32 } else { 33 push @nesting, 0; 34 } 35 next; 36 } elsif (m/\s*#ifndef\s+(.*)/) { 37 my $var = $1; 38 if (defined $defines{$var}) { 39 push @nesting, 0; 40 } else { 41 push @nesting, 1; 42 } 43 next; 44 } elsif (m/\s*#else/) { 45 my $var = pop @nesting; 46 $var = !$var; 47 push @nesting, $var; 48 next; 49 } elsif ($nesting[$#nesting] and m/\s*#define\s+(\w+)\s+(\S+)/) { 50 my $res = $2; 51 $res = 1 if (!defined $res); 52 $defines{$1} = $res; 53 } 54} 55 56close IN; 57 58if ($debug) { 59 foreach my $i (keys %defines) { 60 print "k: $i v: $defines{$i}\n"; 61 } 62} 63 64open IN, "$opt_p" || die "failed open ${opt_p}"; 65open OUT, ">$opt_o" || die "failed open ${opt_o}"; 66 67print "parse roken.h.in\n" if ($debug); 68 69print OUT "/* This is an OS dependent, generated file */\n"; 70print OUT "\n"; 71print OUT "\n"; 72print OUT "#ifndef __ROKEN_H__\n"; 73print OUT "#define __ROKEN_H__\n"; 74print OUT "\n"; 75 76@nesting = (1); 77 78while (<IN>) { 79 if (m/\s*#ifdef\s+(.*)/) { 80 my $var = $1; 81 if (defined $defines{$var}) { 82 push @nesting, 1; 83 } else { 84 push @nesting, 0; 85 } 86 next; 87 } elsif (m/\s*#ifndef\s+(.*)/) { 88 my $var = $1; 89 if (defined $defines{$var}) { 90 push @nesting, 0; 91 } else { 92 push @nesting, 1; 93 } 94 next; 95 } elsif (m/\s*#if\s+(.*)/) { 96 my $res = parse_if($1); 97 print "line = $res: $1\n" if ($debug); 98 push @nesting, $res; 99 next; 100 } elsif (m/\s*#elif\s+(.*)/) { 101 my $res = pop @nesting; 102 if ($res gt 0) { 103 $res = -1; 104 } else { 105 my $res = parse_if($1); 106 } 107 push @nesting, $res; 108 next; 109 } elsif (m/\s*#else/) { 110 my $var = pop @nesting; 111 $var = !$var; 112 push @nesting, $var; 113 next; 114 } elsif (m/\s*#endif/) { 115 pop @nesting; 116 next; 117 } 118 print "line: $_\n" if ($debug); 119 print "nesting dep $#{nesting}\n" if ($debug); 120 my $i = 0, $t = 1; 121 while ($i le $#nesting) { 122 $t = 0 if ($nesting[$i] le 0); 123 print "nesting $i val $nesting[$i] -> $t\n" if ($debug); 124 $i++; 125 } 126 if ($t) { 127 print OUT; 128 } 129} 130 131print OUT "\n"; 132print OUT "#endif /* __ROKEN_H__ */\n"; 133 134 135close IN; 136 137exit 0; 138 139sub parse_if 140{ 141 my ($neg, $var); 142 143 $_ = shift; 144 145 if (m/^\s*$/) { 146 print "end $_\n" if ($debug); 147 return 1; 148 } elsif (m/^([^&]+)\&\&(.*)$/) { 149 print "$1 and $2\n" if ($debug); 150 return parse_if($1) and parse_if($2); 151 } elsif (m/^([^\|]+)\|\|(.*)$/) { 152 print "$1 or $2\n" if ($debug); 153 return parse_if($1) or parse_if($2); 154 } elsif (m/^\s*(\!)?\s*defined\((\w+)\)/) { 155 ($neg, $var) = ($1, $2); 156 print "def: ${neg}-defined(${var})\n" if ($debug); 157 my $res = defined $defines{$var}; 158 if ($neg eq "!") { 159 if ($res) { 160 $res = 0; 161 } else { 162 $res = 1; 163 } 164 } 165 print "res: $res\n" if ($debug); 166 return $res; 167 } elsif (m/^\s*(\!)?(\w+)/) { 168 ($neg, $var) = ($1, $2); 169 print "var: $neg $var\n" if ($debug); 170 my $res; 171 if (defined $defines{$var}) { 172 $res = $defines{$var}; 173 } else { 174 $res = 0; 175 } 176 $res = ! $res if ($neg =~ m/!/); 177 print "res: $res\n" if ($debug); 178 return $res; 179 } 180 die "failed parse: $_\n"; 181} 182