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            next if $mod_plus and $config{$config} and $config{$config} eq "y";
77            $config{$config} = $cfg{$config};
78        }
79    }
80    return \%config;
81}
82
83sub config_diff($$$) {
84    my $cfg1 = shift;
85    my $cfg2 = shift;
86    my $new_only = shift;
87    my %config;
88    
89    foreach my $config (keys %$cfg2) {
90        if (!defined($cfg1->{$config}) or $cfg1->{$config} ne $cfg2->{$config}) {
91            next if $new_only and !defined($cfg1->{$config}) and $cfg2->{$config} eq '#undef';
92            $config{$config} = $cfg2->{$config};
93        }
94    }
95    return \%config
96}
97
98sub config_sub($$) {
99    my $cfg1 = shift;
100    my $cfg2 = shift;
101    my %config = %{$cfg1};
102    
103    foreach my $config (keys %$cfg2) {
104        delete $config{$config};
105    }
106    return \%config;
107}
108
109sub print_cfgline($$) {
110    my $name = shift;
111    my $val = shift;
112    if ($val eq '#undef' or $val eq 'n') {
113        print "# $PREFIX$name is not set\n";
114    } else {
115        print "$PREFIX$name=$val\n";
116    }
117}
118
119
120sub dump_config($) {
121    my $cfg = shift;
122    die "argument error in dump_config" unless ($cfg);
123    my %config = %$cfg;
124    foreach my $config (sort keys %config) {
125        print_cfgline($config, $config{$config});
126    }
127}
128
129sub parse_expr {
130    my $pos = shift;
131    my $mod_plus = shift;
132    my $arg = $arg[$$pos++];
133
134    die "Parse error" if (!$arg);
135
136    if ($arg eq '&') {
137        my $arg1 = parse_expr($pos);
138        my $arg2 = parse_expr($pos);
139        return config_and($arg1, $arg2);
140    } elsif ($arg =~ /^\+/) {
141        my $arg1 = parse_expr($pos);
142        my $arg2 = parse_expr($pos);
143        return config_add($arg1, $arg2, 0);
144    } elsif ($arg =~ /^m\+/) {
145        my $arg1 = parse_expr($pos);
146        my $arg2 = parse_expr($pos, 1);
147        return config_add($arg1, $arg2, 1);
148    } elsif ($arg eq '>') {
149        my $arg1 = parse_expr($pos);
150        my $arg2 = parse_expr($pos);
151        return config_diff($arg1, $arg2, 0);
152    } elsif ($arg eq '>+') {
153        my $arg1 = parse_expr($pos);
154        my $arg2 = parse_expr($pos);
155        return config_diff($arg1, $arg2, 1);
156    } elsif ($arg eq '-') {
157        my $arg1 = parse_expr($pos);
158        my $arg2 = parse_expr($pos);
159        return config_sub($arg1, $arg2);
160    } else {
161        return load_config($arg, $mod_plus);
162    }
163}
164
165while (@ARGV > 0 and $ARGV[0] =~ /^-\w+$/) {
166    my $cmd = shift @ARGV;
167    if ($cmd =~ /^-n$/) {
168        $PREFIX = "";
169    } elsif ($cmd =~ /^-p$/) {
170        $PREFIX = shift @ARGV;
171    } else {
172        die "Invalid option: $cmd\n";
173    }
174}
175@arg = @ARGV;
176
177my $pos = 0;
178dump_config(parse_expr(\$pos));
179die "Parse error" if ($arg[$pos]);
180

Archive Download this file



interactive