Root/scripts/kconfig.pl

1#!/usr/bin/env perl
2#
3# Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
4#
5# This is free software, licensed under the GNU General Public License v2.
6# See /LICENSE for more information.
7#
8
9use warnings;
10use strict;
11
12my @arg;
13my $PREFIX = "CONFIG_";
14
15sub set_config($$$$) {
16    my $config = shift;
17    my $idx = shift;
18    my $newval = shift;
19    my $mod_plus = shift;
20
21    if (!defined($config->{$idx}) or !$mod_plus or
22        $config->{$idx} eq '#undef' or $newval eq 'y') {
23        $config->{$idx} = $newval;
24    }
25}
26
27sub load_config($$) {
28    my $file = shift;
29    my $mod_plus = shift;
30    my %config;
31
32    open FILE, "$file" or die "can't open file";
33    while (<FILE>) {
34        chomp;
35        /^$PREFIX(.+?)=(.+)/ and do {
36            set_config(\%config, $1, $2, $mod_plus);
37            next;
38        };
39        /^# $PREFIX(.+?) is not set/ and do {
40            set_config(\%config, $1, "#undef", $mod_plus);
41            next;
42        };
43        /^#/ and next;
44        /^(.+)$/ and warn "WARNING: can't parse line: $1\n";
45    }
46    return \%config;
47}
48
49
50sub config_and($$) {
51    my $cfg1 = shift;
52    my $cfg2 = shift;
53    my %config;
54
55    foreach my $config (keys %$cfg1) {
56        my $val1 = $cfg1->{$config};
57        my $val2 = $cfg2->{$config};
58        $val2 and ($val1 eq $val2) and do {
59            $config{$config} = $val1;
60        };
61    }
62    return \%config;
63}
64
65
66sub config_add($$$) {
67    my $cfg1 = shift;
68    my $cfg2 = shift;
69    my $mod_plus = shift;
70    my %config;
71    
72    for ($cfg1, $cfg2) {
73        my %cfg = %$_;
74        
75        foreach my $config (keys %cfg) {
76            if ($mod_plus and $config{$config}) {
77                next if $config{$config} eq "y";
78                next if $cfg{$config} eq '#undef';
79            }
80            $config{$config} = $cfg{$config};
81        }
82    }
83    return \%config;
84}
85
86sub config_diff($$$) {
87    my $cfg1 = shift;
88    my $cfg2 = shift;
89    my $new_only = shift;
90    my %config;
91    
92    foreach my $config (keys %$cfg2) {
93        if (!defined($cfg1->{$config}) or $cfg1->{$config} ne $cfg2->{$config}) {
94            next if $new_only and !defined($cfg1->{$config}) and $cfg2->{$config} eq '#undef';
95            $config{$config} = $cfg2->{$config};
96        }
97    }
98    return \%config
99}
100
101sub config_sub($$) {
102    my $cfg1 = shift;
103    my $cfg2 = shift;
104    my %config = %{$cfg1};
105    
106    foreach my $config (keys %$cfg2) {
107        delete $config{$config};
108    }
109    return \%config;
110}
111
112sub print_cfgline($$) {
113    my $name = shift;
114    my $val = shift;
115    if ($val eq '#undef' or $val eq 'n') {
116        print "# $PREFIX$name is not set\n";
117    } else {
118        print "$PREFIX$name=$val\n";
119    }
120}
121
122
123sub dump_config($) {
124    my $cfg = shift;
125    die "argument error in dump_config" unless ($cfg);
126    my %config = %$cfg;
127    foreach my $config (sort keys %config) {
128        print_cfgline($config, $config{$config});
129    }
130}
131
132sub parse_expr {
133    my $pos = shift;
134    my $mod_plus = shift;
135    my $arg = $arg[$$pos++];
136
137    die "Parse error" if (!$arg);
138
139    if ($arg eq '&') {
140        my $arg1 = parse_expr($pos);
141        my $arg2 = parse_expr($pos);
142        return config_and($arg1, $arg2);
143    } elsif ($arg =~ /^\+/) {
144        my $arg1 = parse_expr($pos);
145        my $arg2 = parse_expr($pos);
146        return config_add($arg1, $arg2, 0);
147    } elsif ($arg =~ /^m\+/) {
148        my $arg1 = parse_expr($pos);
149        my $arg2 = parse_expr($pos, 1);
150        return config_add($arg1, $arg2, 1);
151    } elsif ($arg eq '>') {
152        my $arg1 = parse_expr($pos);
153        my $arg2 = parse_expr($pos);
154        return config_diff($arg1, $arg2, 0);
155    } elsif ($arg eq '>+') {
156        my $arg1 = parse_expr($pos);
157        my $arg2 = parse_expr($pos);
158        return config_diff($arg1, $arg2, 1);
159    } elsif ($arg eq '-') {
160        my $arg1 = parse_expr($pos);
161        my $arg2 = parse_expr($pos);
162        return config_sub($arg1, $arg2);
163    } else {
164        return load_config($arg, $mod_plus);
165    }
166}
167
168while (@ARGV > 0 and $ARGV[0] =~ /^-\w+$/) {
169    my $cmd = shift @ARGV;
170    if ($cmd =~ /^-n$/) {
171        $PREFIX = "";
172    } elsif ($cmd =~ /^-p$/) {
173        $PREFIX = shift @ARGV;
174    } else {
175        die "Invalid option: $cmd\n";
176    }
177}
178@arg = @ARGV;
179
180my $pos = 0;
181dump_config(parse_expr(\$pos));
182die "Parse error" if ($arg[$pos]);
183

Archive Download this file



interactive