#!/usr/bin/perl use Getopt::Std; my $debug = 0; getopts('dc:p:o:') || die "foo"; if ($opt_d) { $debug = 1; } die "missing arg" if (!defined $opt_c || !defined $opt_p || !defined $opt_o); my %defines; my $IN; my $OUT; print "parse config.h\n" if ($debug); open IN, $opt_c || die "failed open ${opt_c}"; my @nesting; push @nesting, 1; while () { if (m/\s*#ifdef\s+(.*)/) { my $var = $1; if (defined $defines{$var}) { push @nesting, 1; } else { push @nesting, 0; } next; } elsif (m/\s*#ifndef\s+(.*)/) { my $var = $1; if (defined $defines{$var}) { push @nesting, 0; } else { push @nesting, 1; } next; } elsif (m/\s*#else/) { my $var = pop @nesting; $var = !$var; push @nesting, $var; next; } elsif ($nesting[$#nesting] and m/\s*#define\s+(\w+)\s+(\S+)/) { my $res = $2; $res = 1 if (!defined $res); $defines{$1} = $res; } } close IN; if ($debug) { foreach my $i (keys %defines) { print "k: $i v: $defines{$i}\n"; } } open IN, "$opt_p" || die "failed open ${opt_p}"; open OUT, ">$opt_o" || die "failed open ${opt_o}"; print "parse roken.h.in\n" if ($debug); print OUT "/* This is an OS dependent, generated file */\n"; print OUT "\n"; print OUT "\n"; print OUT "#ifndef __ROKEN_H__\n"; print OUT "#define __ROKEN_H__\n"; print OUT "\n"; @nesting = (1); while () { if (m/\s*#ifdef\s+(.*)/) { my $var = $1; if (defined $defines{$var}) { push @nesting, 1; } else { push @nesting, 0; } next; } elsif (m/\s*#ifndef\s+(.*)/) { my $var = $1; if (defined $defines{$var}) { push @nesting, 0; } else { push @nesting, 1; } next; } elsif (m/\s*#if\s+(.*)/) { my $res = parse_if($1); print "line = $res: $1\n" if ($debug); push @nesting, $res; next; } elsif (m/\s*#elif\s+(.*)/) { my $res = pop @nesting; if ($res gt 0) { $res = -1; } else { my $res = parse_if($1); } push @nesting, $res; next; } elsif (m/\s*#else/) { my $var = pop @nesting; $var = !$var; push @nesting, $var; next; } elsif (m/\s*#endif/) { pop @nesting; next; } print "line: $_\n" if ($debug); print "nesting dep $#{nesting}\n" if ($debug); my $i = 0, $t = 1; while ($i le $#nesting) { $t = 0 if ($nesting[$i] le 0); print "nesting $i val $nesting[$i] -> $t\n" if ($debug); $i++; } if ($t) { print OUT; } } print OUT "\n"; print OUT "#endif /* __ROKEN_H__ */\n"; close IN; exit 0; sub parse_if { my ($neg, $var); $_ = shift; if (m/^\s*$/) { print "end $_\n" if ($debug); return 1; } elsif (m/^\(([^&]+)\&\&(.*)\)\s*\|\|\s*\(([^&]+)\&\&(.*)\)$/) { print "($1 and $2) or ($3 and $4)\n" if ($debug); return ((parse_if($1) and parse_if($2)) or (parse_if($3) and parse_if($4))); } elsif (m/^([^&]+)\&\&(.*)$/) { print "$1 and $2\n" if ($debug); return parse_if($1) and parse_if($2); } elsif (m/^([^\|]+)\|\|(.*)$/) { print "$1 or $2\n" if ($debug); return (parse_if($1) or parse_if($2)); } elsif (m/^\s*(\!)?\s*defined\((\w+)\)/) { ($neg, $var) = ($1, $2); print "def: ${neg}-defined(${var})\n" if ($debug); my $res = defined $defines{$var}; if ($neg eq "!") { if ($res) { $res = 0; } else { $res = 1; } } print "res: $res\n" if ($debug); return $res; } elsif (m/^\s*(\!)?(\w+)/) { ($neg, $var) = ($1, $2); print "var: $neg $var\n" if ($debug); my $res; if (defined $defines{$var}) { $res = $defines{$var}; } else { $res = 0; } $res = ! $res if ($neg =~ m/!/); print "res: $res\n" if ($debug); return $res; } die "failed parse: $_\n"; }