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