You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.1 KiB
84 lines
2.1 KiB
#!/usr/bin/perl
|
|
# Configuration file and script preprocessor
|
|
# (c) 2004--2007 Martin Mares <mj@ucw.cz>
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
@ARGV == 3 or die "Usage: genconf <src> <dest> <config.mk>";
|
|
|
|
open CF, $ARGV[2] or die "Unable to open $ARGV[2]";
|
|
my %options = ();
|
|
my %vars = ();
|
|
sub opt {
|
|
my ($k,$v) = @_;
|
|
$vars{$k} = $v;
|
|
$options{$k} = 1 if ($k =~ /^CONFIG_/);
|
|
}
|
|
foreach my $k (keys %ENV) {
|
|
opt($k, $ENV{$k});
|
|
}
|
|
while (<CF>) {
|
|
chomp;
|
|
if (my ($k,$v) = /^(\w+)=(.*)/) {
|
|
$v =~ s/\s+$//;
|
|
opt($k, $v);
|
|
}
|
|
}
|
|
close CF;
|
|
|
|
sub eval_expr {
|
|
$_ = shift @_;
|
|
s/\b(CONFIG_\w+)\b/defined($options{$1}) ? 1 : 0/ge;
|
|
return eval $_;
|
|
}
|
|
|
|
open IN, $ARGV[0] or die "Unable to open $ARGV[0]";
|
|
open OUT, ">$ARGV[1]" or die "Unable to create $ARGV[1]";
|
|
my @ifs = (); # stack of conditions, 1=satisfied, -1=unsatisfied, 0=shadowed
|
|
my $empty = 0; # last line was empty
|
|
while (<IN>) {
|
|
if (/^#ifdef\s+(\w+)/) {
|
|
push @ifs, (@ifs && $ifs[$#ifs] <= 0) ? 0 : (defined $options{$1}) ? 1 : -1;
|
|
} elsif (/^#ifndef\s+(\w+)/) {
|
|
push @ifs, (@ifs && $ifs[$#ifs] <= 0) ? 0 : (defined $options{$1}) ? -1 : 1;
|
|
} elsif (/^#if\s(.*)$/) {
|
|
push @ifs, (@ifs && $ifs[$#ifs] <= 0) ? 0 : (eval_expr $1) ? 1 : -1;
|
|
} elsif (/^#endif/) {
|
|
defined pop @ifs || die "Improper nesting of conditionals";
|
|
} elsif (/^#else/) {
|
|
my $x = pop @ifs;
|
|
defined $x || die "Improper nesting of conditionals";
|
|
push @ifs, $x >= 0 ? 0 : 1;
|
|
} elsif (/^#elsif\s(.*)$/) {
|
|
my $x = pop @ifs;
|
|
defined $x || die "Improper nesting of conditionals";
|
|
push @ifs, $x >= 0 ? 0 : (eval_expr $1) ? 1 : -1;
|
|
} else {
|
|
@ifs && $ifs[$#ifs] <= 0 && next;
|
|
if (/^$/) {
|
|
$empty && next;
|
|
$empty = 1;
|
|
} else { $empty = 0; }
|
|
if (/^#pipe\s+(.+)/) {
|
|
my $cmd = $1;
|
|
my $val = `$cmd`;
|
|
die "Piped command '$cmd' failed" if $?;
|
|
print OUT `$1`;
|
|
} else {
|
|
sub repl($);
|
|
sub repl($) {
|
|
my $v = shift @_;
|
|
exists $vars{$v} or die "Cannot substitute $v: variable not set";
|
|
my $x = $vars{$v};
|
|
while ($x =~ s/\$\((\w+)\)/repl($1)/ge) { }
|
|
return $x;
|
|
}
|
|
s/@(\w+)@/repl($1)/ge;
|
|
print OUT;
|
|
}
|
|
}
|
|
}
|
|
@ifs && die "Unterminated #ifdef";
|
|
close IN;
|
|
close OUT;
|
|
|