]> mj.ucw.cz Git - libucw.git/blobdiff - build/genconf
hashtables: fixed combination of HASH_GIVE_ALLOC and HASH_TABLE_ALLOC
[libucw.git] / build / genconf
index 2c3147861b67ef792eb8dbd7e8fbca98106057e1..ac9755f4aaa7b28b2495b82baf111cc3d06a30dc 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 #!/usr/bin/perl
-# Configuration file preprocessor
-# (c) 2003 Martin Mares <mj@ucw.cz>
+# Configuration file and script preprocessor
+# (c) 2004--2007 Martin Mares <mj@ucw.cz>
 
 use strict;
 use warnings;
 
 use strict;
 use warnings;
@@ -9,34 +9,64 @@ use warnings;
 
 open CF, $ARGV[2] or die "Unable to open $ARGV[2]";
 my %options = ();
 
 open CF, $ARGV[2] or die "Unable to open $ARGV[2]";
 my %options = ();
+my %vars = ();
 while (<CF>) {
 while (<CF>) {
-       /^(CONFIG_\w+)=1/ || next;
-       $options{$1} = 1;
+       chomp;
+       if (my ($k,$v) = /^(\w+)=(.*)/) {
+               $v =~ s/\s+$//;
+               $vars{$k} = $v;
+               $options{$k} = 1 if ($k =~ /^CONFIG_/);
+       }
 }
 close CF;
 
 }
 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]";
 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
+my @ifs = ();  # stack of conditions, 1=satisfied, -1=unsatisfied, 0=shadowed
 my $empty = 0; # last line was empty
 while (<IN>) {
 my $empty = 0; # last line was empty
 while (<IN>) {
-       if (/^#?ifdef\s+(\w+)/) {
-               push @ifs, !defined $options{$1};
+       if (/^#ifdef\s+(\w+)/) {
+               push @ifs, (@ifs && $ifs[$#ifs] <= 0) ? 0 : (defined $options{$1}) ? 1 : -1;
        } elsif (/^#ifndef\s+(\w+)/) {
        } elsif (/^#ifndef\s+(\w+)/) {
-               push @ifs, defined $options{$1};
-       } elsif (/^#?endif/) {
+               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";
                defined pop @ifs || die "Improper nesting of conditionals";
-       } elsif (/^#?else/) {
+       } 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";
                my $x = pop @ifs;
                defined $x || die "Improper nesting of conditionals";
-               push @ifs, !$x;
+               push @ifs, $x >= 0 ? 0 : (eval_expr $1) ? 1 : -1;
        } else {
        } else {
-               @ifs && $ifs[$#ifs] && next;
+               @ifs && $ifs[$#ifs] <= 0 && next;
                if (/^$/) {
                        $empty && next;
                        $empty = 1;
                } else { $empty = 0; }
                if (/^$/) {
                        $empty && next;
                        $empty = 1;
                } else { $empty = 0; }
-               print OUT;
+               if (/^#pipe\s+(.+)/) {
+                       my $cmd = $1;
+                       my $val = `$cmd`;
+                       die "Piped command '$cmd' failed" if $?;
+                       print OUT `$1`;
+               } else {
+                       sub repl ($) {
+                               my $v = shift @_;
+                               exists $vars{$v} or die "Cannot substitute $v: variable not set";
+                               return $vars{$v};
+                       }
+                       s/@(\w+)@/repl($1)/ge;
+                       print OUT;
+               }
        }
 }
 @ifs && die "Unterminated #ifdef";
        }
 }
 @ifs && die "Unterminated #ifdef";