]>
Commit | Line | Data |
---|---|---|
6f248ce1 TL |
1 | #!/usr/bin/perl -w |
2 | ||
3 | use strict; | |
4 | ||
5 | my $DEB_HOST_ARCH_OS = `dpkg-architecture -qDEB_HOST_ARCH_OS`; | |
6 | ||
7 | $DEB_HOST_ARCH_OS =~ s/\n//; | |
8 | ||
9 | # declarations | |
10 | my $address_family = ""; | |
11 | my %methods = (); | |
12 | my %ourmethods = (); | |
13 | my $line = ""; | |
14 | my $arch = ""; | |
15 | my $match = ""; | |
16 | ||
17 | # subroutines | |
18 | sub nextline { | |
19 | $line = <>; | |
20 | while($line and ($line =~ /^#/ or $line =~ /^\s*$/)) { | |
21 | $line = <>; | |
22 | } | |
23 | if (!$line) { return 0; } | |
24 | chomp $line; | |
25 | while ($line =~ m/^(.*)\\$/s) { | |
26 | my $addon = <>; | |
27 | chomp $addon; | |
28 | $line = $1 . "\n". $addon; | |
29 | } | |
30 | return 1; | |
31 | } | |
32 | sub our_arch { | |
33 | return ($arch eq $DEB_HOST_ARCH_OS) || ($arch eq "any") | |
34 | } | |
35 | sub match { | |
36 | my $line = $_[0]; | |
37 | my $cmd = "$_[1]" ? "$_[1]\\b\\s*" : "";; | |
38 | my $indentexp = (@_ == 3) ? "$_[2]\\s+" : ""; | |
39 | ||
40 | if ($line =~ /^${indentexp}${cmd}(([^\s](.*[^\s])?)?)\s*$/s) { | |
41 | $match = $1; | |
42 | return 1; | |
43 | } else { | |
44 | return 0; | |
45 | } | |
46 | } | |
47 | sub get_address_family { | |
48 | $address_family = $_[0] if ($address_family eq ""); | |
49 | nextline; | |
50 | } | |
51 | sub get_architecture { | |
52 | %ourmethods = %methods if (our_arch()); | |
53 | $arch = $_[0]; | |
54 | if (!our_arch) { | |
55 | %methods = (); | |
56 | } else { | |
57 | print "#include \"archcommon.h\"\n"; | |
58 | print "#include \"arch${DEB_HOST_ARCH_OS}.h\"\n\n\n"; | |
59 | } | |
60 | nextline; | |
61 | } | |
62 | sub get_method { | |
63 | my $method = $_[0]; | |
64 | my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : ""; | |
65 | my @options = (); | |
66 | my @variables = (); | |
67 | ||
68 | die "Duplicate method $method\n" if ($methods{$method}++); | |
69 | ||
70 | nextline; | |
71 | if (match($line, "description", $indent)) { | |
72 | skip_section(); | |
73 | } | |
74 | if (match($line, "options", $indent)) { | |
75 | @options = get_options(); | |
76 | } | |
77 | print "static option_default _${method}_default[] = {\n"; | |
78 | if (@options) { | |
79 | foreach my $o (@options) { | |
80 | if ($o =~ m/^\s*(\S*)\s*(.*)\s+--\s+(\S[^[]*)(\s+\[([^]]*)\]\s*)?$/) { | |
81 | my $opt = $1; | |
82 | my $optargs = $2; | |
83 | my $dsc = $3; | |
84 | push @variables, $opt; | |
85 | if ($4) { | |
86 | print "\t{ \"$opt\", \"$5\" },\n"; | |
87 | } | |
88 | } | |
89 | } | |
90 | } | |
91 | print "\t{ NULL, NULL }\n"; | |
92 | print "};\n"; | |
93 | print "static conversion _${method}_conv[] = {\n"; | |
94 | if (match($line, "conversion", $indent)) { | |
95 | while (nextline && match($line, "", "$indent ")) { | |
96 | my $foo = $line; | |
97 | $foo =~ s/^\s+//; | |
98 | $foo =~ m/^\s*(\S+)\s+(\([^)]+\)|\S+)\s*(\S+)?\s*$/; | |
99 | my $option = $1; | |
100 | my $fn = $2; | |
101 | my $newoption = $3; | |
102 | if ($fn =~ m/^\((.*)\)$/) { | |
103 | my @params = split(/ /, $1); | |
104 | $fn = shift(@params); | |
105 | foreach (@params) { | |
106 | if ($_ =~ m/^"(.*)"$/) { | |
107 | $_ = $1; | |
108 | } | |
109 | } | |
110 | $fn .= (", ".scalar(@params).", (char * []){\"".join("\", \"", @params)."\"}"); | |
111 | } else { | |
112 | $fn .= ", 0, NULL"; | |
113 | } | |
114 | if ($newoption) { | |
115 | $newoption =~ s/^=//; | |
116 | die "Duplicate option use: $newoption (from $method/$option)" if (grep $_ eq $newoption, @variables); | |
117 | push @variables, $newoption; | |
118 | print "\t{ \"$option\", \"$newoption\", $fn },\n"; | |
119 | } else { | |
120 | print "\t{ \"$option\", NULL, $fn },\n"; | |
121 | } | |
122 | } | |
123 | } | |
124 | print "\t\{ NULL, NULL, NULL, 0, NULL }\n"; | |
125 | print "};\n"; | |
126 | if (match($line, "up", $indent)) { | |
127 | get_commands(${method}, "up"); | |
128 | } else { | |
129 | print "static int _${method}_up(interface_defn *ifd, execfn *exec) { return 0; }\n" | |
130 | } | |
131 | if (match($line, "down", $indent)) { | |
132 | get_commands(${method}, "down"); | |
133 | } else { | |
134 | print "static int _${method}_down(interface_defn *ifd, execfn *exec) { return 0; }\n" | |
135 | } | |
136 | if (match($line, "rename", $indent)) { | |
137 | get_commands(${method}, "rename"); | |
138 | } else { | |
139 | print "static int _${method}_rename(interface_defn *ifd, execfn *exec) { return 0; }\n" | |
140 | } | |
141 | } | |
142 | sub skip_section { | |
143 | my $struct = $_[0]; | |
144 | my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : ""; | |
145 | ||
146 | 1 while (nextline && match($line, "", $indent)); | |
147 | } | |
148 | ||
149 | sub quote_chars { | |
150 | my $string = $_[0]; | |
151 | $string =~ s/\\/\\\\/g; | |
152 | $string =~ s/"/\\"/g; | |
153 | $string =~ s/\n/\\\n/g; | |
154 | return $string; | |
155 | } | |
156 | sub get_commands { | |
157 | my $method = $_[0]; | |
158 | my $mode = $_[1]; | |
159 | my $function = "_${method}_${mode}"; | |
160 | my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : ""; | |
161 | ||
162 | print "static int ${function}(interface_defn *ifd, execfn *exec) {\n"; | |
163 | ||
164 | while (nextline && match($line, "", $indent)) { | |
165 | if ( $match =~ /^(.*[^\s])\s+if\s*\((.*)\)\s*$/s ) { | |
166 | print "if ( $2 ) {\n"; | |
167 | print " if (!execute(\"".quote_chars($1)."\", ifd, exec) && !ignore_failures) return 0;\n"; | |
168 | print "}\n"; | |
169 | } elsif ( $match =~ /^(.*[^\s])\s+elsif\s*\((.*)\)\s*$/s ) { | |
170 | print "else if ( $2 ) {\n"; | |
171 | print " if (!execute(\"".quote_chars($1)."\", ifd, exec) && !ignore_failures) return 0;\n"; | |
172 | print "}\n"; | |
173 | } elsif ( $match =~ /^(.*[^\s])\s*$/s ) { | |
174 | print "{\n"; | |
175 | print " if (!execute(\"".quote_chars($1)."\", ifd, exec) && !ignore_failures) return 0;\n"; | |
176 | print "}\n"; | |
177 | } | |
178 | } | |
179 | ||
180 | print "return 1;\n"; | |
181 | print "}\n"; | |
182 | } | |
183 | sub get_options { | |
184 | my @opts = (); | |
185 | my $indent = ($line =~ /(\s*)\S/) ? $1 : ""; | |
186 | while(nextline && match($line, "", $indent)) { | |
187 | push @opts, $match; | |
188 | } | |
189 | return @opts; | |
190 | } | |
191 | ||
192 | # main code | |
193 | print "#include <stddef.h>\n"; | |
194 | print "#include \"header.h\"\n\n\n"; | |
195 | nextline; | |
196 | while($line) { | |
197 | if (match($line, "address_family")) { | |
198 | get_address_family $match; | |
199 | next; | |
200 | } | |
201 | if (match($line, "architecture")) { | |
202 | get_architecture $match; | |
203 | next; | |
204 | } | |
205 | if (match($line, "method")) { | |
206 | if (our_arch()) { | |
207 | get_method $match; | |
208 | } else { | |
209 | skip_section; | |
210 | } | |
211 | next; | |
212 | } | |
213 | ||
214 | # ...otherwise | |
215 | die("Unknown command \"$line\""); | |
216 | } | |
217 | print "static method methods[] = {\n"; | |
218 | %ourmethods = %methods if (our_arch()); | |
219 | my $method; | |
220 | foreach $method (sort keys %ourmethods) { | |
221 | print <<EOF; | |
222 | { | |
223 | "$method", | |
224 | _${method}_up, _${method}_down, _${method}_rename, | |
225 | _${method}_conv, _${method}_default, | |
226 | }, | |
227 | EOF | |
228 | } | |
229 | print "};\n\n"; | |
230 | ||
231 | print <<EOF; | |
232 | address_family addr_${address_family} = { | |
233 | "$address_family", | |
234 | sizeof(methods)/sizeof(struct method), | |
235 | methods | |
236 | }; | |
237 | EOF |