Fix the annoying base-files autorebuild bug.
[openwrt/svn-archive/archive.git] / scripts / config.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
9 use warnings;
10 use strict;
11
12 my @arg = @ARGV;
13
14 sub load_config($) {
15 my $file = shift;
16 my %config;
17
18 open FILE, "$file" or die "can't open file";
19 while (<FILE>) {
20 chomp;
21 /^CONFIG_(.+)=(.+)/ and do {
22 $config{$1} = $2;
23 next;
24 };
25 /^# CONFIG_(.+) is not set/ and do {
26 $config{$1} = -1;
27 next;
28 };
29 /^#/ and next;
30 /^(.+)$/ and print "WARNING: can't parse line: $1\n";
31 }
32 return \%config;
33 }
34
35
36 sub config_and($$) {
37 my $cfg1 = shift;
38 my $cfg2 = shift;
39 my %config;
40
41 foreach my $config (keys %$cfg1) {
42 my $val1 = $cfg1->{$config};
43 my $val2 = $cfg2->{$config};
44 $val2 and ($val1 eq $val2) and do {
45 $config{$config} = $val1;
46 };
47 }
48 return \%config;
49 }
50
51
52 sub config_add($$) {
53 my $cfg1 = shift;
54 my $cfg2 = shift;
55 my %config;
56
57 for ($cfg1, $cfg2) {
58 my %cfg = %$_;
59
60 foreach my $config (keys %cfg) {
61 $config{$config} = $cfg{$config};
62 }
63 }
64 return \%config;
65 }
66
67 sub config_diff($$) {
68 my $cfg1 = shift;
69 my $cfg2 = shift;
70 my %config;
71
72 foreach my $config (keys %$cfg2) {
73 if (!$cfg1->{$config} or $cfg1->{$config} ne $cfg2->{$config}) {
74 $config{$config} = $cfg2->{$config};
75 }
76 }
77 return \%config
78 }
79
80 sub config_sub($$) {
81 my $cfg1 = shift;
82 my $cfg2 = shift;
83 my %config = %{$cfg1};
84
85 foreach my $config (keys %$cfg2) {
86 delete $config{$config};
87 }
88 return \%config;
89 }
90
91 sub print_cfgline($$) {
92 my $name = shift;
93 my $val = shift;
94 if ($val eq '-1') {
95 print "# CONFIG_$name is not set\n";
96 } else {
97 print "CONFIG_$name=$val\n";
98 }
99 }
100
101
102 sub dump_config($) {
103 my $cfg = shift;
104 die "argument error in dump_config" unless ($cfg);
105 my %config = %$cfg;
106 foreach my $config (sort keys %config) {
107 print_cfgline($config, $config{$config});
108 }
109 }
110
111 sub parse_expr($);
112
113 sub parse_expr($) {
114 my $pos = shift;
115 my $arg = $arg[$$pos++];
116
117 die "Parse error" if (!$arg);
118
119 if ($arg eq '&') {
120 my $arg1 = parse_expr($pos);
121 my $arg2 = parse_expr($pos);
122 return config_and($arg1, $arg2);
123 } elsif ($arg =~ /^\+/) {
124 my $arg1 = parse_expr($pos);
125 my $arg2 = parse_expr($pos);
126 return config_add($arg1, $arg2);
127 } elsif ($arg eq '>') {
128 my $arg1 = parse_expr($pos);
129 my $arg2 = parse_expr($pos);
130 return config_diff($arg1, $arg2);
131 } elsif ($arg eq '-') {
132 my $arg1 = parse_expr($pos);
133 my $arg2 = parse_expr($pos);
134 return config_sub($arg1, $arg2);
135 } else {
136 return load_config($arg);
137 }
138 }
139
140 my $pos = 0;
141 dump_config(parse_expr(\$pos));
142 die "Parse error" if ($arg[$pos]);