ramips: add alsa support
[openwrt.git] / 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
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 '$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                         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
86 sub 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
101 sub 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
112 sub 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
123 sub 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
132 sub 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
168 while (@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
180 my $pos = 0;
181 dump_config(parse_expr(\$pos));
182 die "Parse error" if ($arg[$pos]);