[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

Going from config.h back to config.sh







Here's my first attempt at turning a config.h file back into a config.sh
file that will produce it. I've needed to do this while hacking around
on miniperl, and I guess it might be useful if other people attack the
config.h file and need to make their changes more permanent/portable.

At the moment, it won't read everything perfectly; there are still a few
variables I've marked as `special' that require a bit more work, and it
gets confused by defines containing brackets. You need to look over the
config.h file once it's produced, but it's been a bit of a lifesaver
so far. Hope it helps someone.

cpp needs to be in your path, by the way. No way I'm parsing .h files by
hand.

Simon
(Comments to simon@brecon.co.uk, as usual.)


#!/usr/bin/perl -w
# config_sh.pl - This dirty hack creates a config.sh from a config.h;
ordinarily you
# don't need to go back that way, but if you're hacking around with your
# config, you might end up having to.
use strict;
my %parser; my %configure;

open (OUT, ">config.sh") or die "Writing to config.sh: $!\n";
print OUT <<EOC;
#!/bin/sh
# This file was produced by running config_sh.pl on an existing config.h
# file; this was done because either Configure doesn't work properly on
# your system and this file was supplied in your Perl distribution, or
# we're doing something wicked.

EOC

open (SH, "config_h.SH") or die "Reading config_h.sh: $!\n";

while (<SH>) {
    next unless /\$/;
    s|/\*.*\*/||; s/\s+/:/g; chop;
    next unless s/^#:?//; s/"//g; # XXX
    my ($a,$b,$c) = split /:/;
    if ($a eq "define") { # `#define foo bar' -> foo="bar"
        $parser{$b} = { type => "defines", value => $c };
    } elsif (defined $c) {
        $parser{$b} = { type => "special", value => [$a, $c] };
    } else { # `#define foo' -> foo="define"
        $parser{$b} = { type => "settings", value => $a };
    }
}

open(IN, "cpp -dM config.h|") or die $!;
while (<IN>) {
    chomp;
    for my $key (keys %parser) {
        if (/\b$key\b/) {
            if ($parser{$key}->{type} eq "defines") {
                s/"//g;
                if (/^#\s*define\s+$key\s*(.*)\s*$/) {
                    $configure{$parser{$key}->{value}}=$1;
                } else {
                    warn "Couldn't parse #define on line $.\n$key -> $_\n"
                }
            } elsif ($parser{$key}->{type} eq "settings") {
                if (/^#\s*(define|undef)\s+$key\s*/) {
                    $configure{$parser{$key}->{value}}=$1;
                } else {
                    die "Bad setting: $key -> $_ \n";
                }
            } else {
                warn "Don't yet know how to process line $.\n$key->$_\n";
            }
            delete $parser{$key}; # Done it now, no need to look further.
            last;
        }
    }
}

for (keys %parser) { # Things we didn't find defined - are undefined!
    my $value=$parser{$_}; my $type = $value->{type};
    if ($type eq "defines" or $type eq "settings") {
        $configure{$value->{value}} = "undef";
    } else { warn "Unprocessed $type $_\n"; }
}

for (keys %configure) {
    my $key = $_; $key=~s/^\$//; print OUT "$key=\'$configure{$_}\'\n"
}



Follow-Ups from:
Andy Dougherty <doughera@lafayette.edu>

[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]