]>
Commit | Line | Data |
---|---|---|
dabf8be3 MCC |
1 | #!/usr/bin/perl |
2 | use strict; | |
3 | use Text::Tabs; | |
4 | ||
dabf8be3 MCC |
5 | my $debug = 0; |
6 | ||
bcec7c21 MCC |
7 | while ($ARGV[0] =~ m/^-(.*)/) { |
8 | my $cmd = shift @ARGV; | |
9 | if ($cmd eq "--debug") { | |
10 | require Data::Dumper; | |
11 | $debug = 1; | |
12 | next; | |
13 | } | |
14 | die "argument $cmd unknown"; | |
15 | } | |
16 | ||
dabf8be3 MCC |
17 | if (scalar @ARGV < 2 || scalar @ARGV > 3) { |
18 | die "Usage:\n\t$0 <file in> <file out> [<exceptions file>]\n"; | |
19 | } | |
20 | ||
21 | my ($file_in, $file_out, $file_exceptions) = @ARGV; | |
22 | ||
23 | my $data; | |
24 | my %ioctls; | |
25 | my %defines; | |
26 | my %typedefs; | |
27 | my %enums; | |
28 | my %enum_symbols; | |
29 | my %structs; | |
30 | ||
31 | # | |
32 | # read the file and get identifiers | |
33 | # | |
34 | ||
35 | my $is_enum = 0; | |
034e6c8e | 36 | my $is_comment = 0; |
dabf8be3 MCC |
37 | open IN, $file_in or die "Can't open $file_in"; |
38 | while (<IN>) { | |
034e6c8e MCC |
39 | $data .= $_; |
40 | ||
9afe5112 | 41 | my $ln = $_; |
034e6c8e MCC |
42 | if (!$is_comment) { |
43 | $ln =~ s,/\*.*(\*/),,g; | |
9afe5112 | 44 | |
034e6c8e MCC |
45 | $is_comment = 1 if ($ln =~ s,/\*.*,,); |
46 | } else { | |
47 | if ($ln =~ s,^(.*\*/),,) { | |
48 | $is_comment = 0; | |
49 | } else { | |
50 | next; | |
51 | } | |
52 | } | |
dabf8be3 | 53 | |
9c80c745 | 54 | if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) { |
dabf8be3 MCC |
55 | my $s = $1; |
56 | my $n = $1; | |
57 | $n =~ tr/A-Z/a-z/; | |
58 | $n =~ tr/_/-/; | |
59 | ||
22c40033 | 60 | $enum_symbols{$s} = "\\ :ref:`$s <$n>`\\ "; |
dabf8be3 MCC |
61 | |
62 | $is_enum = 0 if ($is_enum && m/\}/); | |
63 | next; | |
64 | } | |
65 | $is_enum = 0 if ($is_enum && m/\}/); | |
66 | ||
9c80c745 | 67 | if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) { |
dabf8be3 MCC |
68 | my $s = $1; |
69 | my $n = $1; | |
70 | $n =~ tr/A-Z/a-z/; | |
71 | ||
22c40033 | 72 | $ioctls{$s} = "\\ :ref:`$s <$n>`\\ "; |
dabf8be3 MCC |
73 | next; |
74 | } | |
75 | ||
9c80c745 | 76 | if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) { |
dabf8be3 MCC |
77 | my $s = $1; |
78 | my $n = $1; | |
79 | $n =~ tr/A-Z/a-z/; | |
80 | $n =~ tr/_/-/; | |
81 | ||
22c40033 | 82 | $defines{$s} = "\\ :ref:`$s <$n>`\\ "; |
dabf8be3 MCC |
83 | next; |
84 | } | |
85 | ||
22c40033 MCC |
86 | if ($ln =~ m/^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);/) { |
87 | my $s = $2; | |
88 | my $n = $3; | |
dabf8be3 | 89 | |
22c40033 | 90 | $typedefs{$n} = "\\ :c:type:`$n <$s>`\\ "; |
dabf8be3 MCC |
91 | next; |
92 | } | |
9c80c745 | 93 | if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/ |
6c4c7dad MCC |
94 | || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/ |
95 | || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/ | |
96 | || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) { | |
dabf8be3 | 97 | my $s = $1; |
dabf8be3 | 98 | |
22c40033 | 99 | $enums{$s} = "enum :c:type:`$s`\\ "; |
dabf8be3 MCC |
100 | |
101 | $is_enum = $1; | |
102 | next; | |
103 | } | |
9c80c745 | 104 | if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/ |
6c4c7dad MCC |
105 | || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/ |
106 | || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/ | |
107 | || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/ | |
108 | ) { | |
dabf8be3 | 109 | my $s = $1; |
dabf8be3 | 110 | |
22c40033 | 111 | $structs{$s} = "struct :c:type:`$s`\\ "; |
dabf8be3 MCC |
112 | next; |
113 | } | |
114 | } | |
115 | close IN; | |
116 | ||
117 | # | |
118 | # Handle multi-line typedefs | |
119 | # | |
120 | ||
4ff916a0 MCC |
121 | my @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g, |
122 | $data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,); | |
dabf8be3 | 123 | foreach my $m (@matches) { |
22c40033 | 124 | my $s = $m; |
dabf8be3 | 125 | |
22c40033 | 126 | $typedefs{$s} = "\\ :c:type:`$s`\\ "; |
dabf8be3 MCC |
127 | next; |
128 | } | |
129 | ||
130 | # | |
131 | # Handle exceptions, if any | |
132 | # | |
133 | ||
22c40033 MCC |
134 | my %def_reftype = ( |
135 | "ioctl" => ":ref", | |
136 | "define" => ":ref", | |
137 | "symbol" => ":ref", | |
138 | "typedef" => ":c:type", | |
139 | "enum" => ":c:type", | |
140 | "struct" => ":c:type", | |
141 | ); | |
142 | ||
dabf8be3 MCC |
143 | if ($file_exceptions) { |
144 | open IN, $file_exceptions or die "Can't read $file_exceptions"; | |
145 | while (<IN>) { | |
146 | next if (m/^\s*$/ || m/^\s*#/); | |
147 | ||
148 | # Parsers to ignore a symbol | |
149 | ||
150 | if (m/^ignore\s+ioctl\s+(\S+)/) { | |
151 | delete $ioctls{$1} if (exists($ioctls{$1})); | |
152 | next; | |
153 | } | |
154 | if (m/^ignore\s+define\s+(\S+)/) { | |
155 | delete $defines{$1} if (exists($defines{$1})); | |
156 | next; | |
157 | } | |
158 | if (m/^ignore\s+typedef\s+(\S+)/) { | |
159 | delete $typedefs{$1} if (exists($typedefs{$1})); | |
160 | next; | |
161 | } | |
162 | if (m/^ignore\s+enum\s+(\S+)/) { | |
163 | delete $enums{$1} if (exists($enums{$1})); | |
164 | next; | |
165 | } | |
166 | if (m/^ignore\s+struct\s+(\S+)/) { | |
167 | delete $structs{$1} if (exists($structs{$1})); | |
168 | next; | |
169 | } | |
526b8848 MCC |
170 | if (m/^ignore\s+symbol\s+(\S+)/) { |
171 | delete $enum_symbols{$1} if (exists($enum_symbols{$1})); | |
172 | next; | |
173 | } | |
dabf8be3 MCC |
174 | |
175 | # Parsers to replace a symbol | |
22c40033 | 176 | my ($type, $old, $new, $reftype); |
dabf8be3 | 177 | |
22c40033 MCC |
178 | if (m/^replace\s+(\S+)\s+(\S+)\s+(\S+)/) { |
179 | $type = $1; | |
180 | $old = $2; | |
181 | $new = $3; | |
182 | } else { | |
183 | die "Can't parse $file_exceptions: $_"; | |
184 | } | |
185 | ||
186 | if ($new =~ m/^\:c\:(data|func|macro|type)\:\`(.+)\`/) { | |
187 | $reftype = ":c:$1"; | |
188 | $new = $2; | |
189 | } elsif ($new =~ m/\:ref\:\`(.+)\`/) { | |
190 | $reftype = ":ref"; | |
191 | $new = $1; | |
192 | } else { | |
193 | $reftype = $def_reftype{$type}; | |
194 | } | |
195 | $new = "$reftype:`$old <$new>`"; | |
196 | ||
197 | if ($type eq "ioctl") { | |
198 | $ioctls{$old} = $new if (exists($ioctls{$old})); | |
dabf8be3 MCC |
199 | next; |
200 | } | |
22c40033 MCC |
201 | if ($type eq "define") { |
202 | $defines{$old} = $new if (exists($defines{$old})); | |
dabf8be3 MCC |
203 | next; |
204 | } | |
22c40033 MCC |
205 | if ($type eq "symbol") { |
206 | $enum_symbols{$old} = $new if (exists($enum_symbols{$old})); | |
dabf8be3 MCC |
207 | next; |
208 | } | |
22c40033 MCC |
209 | if ($type eq "typedef") { |
210 | $typedefs{$old} = $new if (exists($typedefs{$old})); | |
dabf8be3 MCC |
211 | next; |
212 | } | |
22c40033 MCC |
213 | if ($type eq "enum") { |
214 | $enums{$old} = $new if (exists($enums{$old})); | |
dabf8be3 MCC |
215 | next; |
216 | } | |
22c40033 MCC |
217 | if ($type eq "struct") { |
218 | $structs{$old} = $new if (exists($structs{$old})); | |
dabf8be3 MCC |
219 | next; |
220 | } | |
221 | ||
222 | die "Can't parse $file_exceptions: $_"; | |
223 | } | |
224 | } | |
225 | ||
226 | if ($debug) { | |
227 | print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls); | |
228 | print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs); | |
229 | print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums); | |
230 | print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs); | |
231 | print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines); | |
232 | print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols); | |
233 | } | |
234 | ||
235 | # | |
236 | # Align block | |
237 | # | |
238 | $data = expand($data); | |
239 | $data = " " . $data; | |
240 | $data =~ s/\n/\n /g; | |
241 | $data =~ s/\n\s+$/\n/g; | |
242 | $data =~ s/\n\s+\n/\n\n/g; | |
243 | ||
244 | # | |
245 | # Add escape codes for special characters | |
246 | # | |
999d998e | 247 | $data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g; |
dabf8be3 | 248 | |
7d95fa8d MCC |
249 | $data =~ s,DEPRECATED,**DEPRECATED**,g; |
250 | ||
dabf8be3 MCC |
251 | # |
252 | # Add references | |
253 | # | |
254 | ||
6fe79d1e MCC |
255 | my $start_delim = "[ \n\t\(\=\*\@]"; |
256 | my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)"; | |
dabf8be3 MCC |
257 | |
258 | foreach my $r (keys %ioctls) { | |
22c40033 | 259 | my $s = $ioctls{$r}; |
dabf8be3 MCC |
260 | |
261 | $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; | |
262 | ||
263 | print "$r -> $s\n" if ($debug); | |
264 | ||
6fe79d1e | 265 | $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
dabf8be3 MCC |
266 | } |
267 | ||
268 | foreach my $r (keys %defines) { | |
22c40033 | 269 | my $s = $defines{$r}; |
dabf8be3 MCC |
270 | |
271 | $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; | |
272 | ||
273 | print "$r -> $s\n" if ($debug); | |
274 | ||
6fe79d1e | 275 | $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
dabf8be3 MCC |
276 | } |
277 | ||
278 | foreach my $r (keys %enum_symbols) { | |
22c40033 | 279 | my $s = $enum_symbols{$r}; |
dabf8be3 MCC |
280 | |
281 | $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; | |
282 | ||
283 | print "$r -> $s\n" if ($debug); | |
284 | ||
6fe79d1e | 285 | $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
dabf8be3 MCC |
286 | } |
287 | ||
288 | foreach my $r (keys %enums) { | |
22c40033 | 289 | my $s = $enums{$r}; |
dabf8be3 MCC |
290 | |
291 | $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; | |
292 | ||
293 | print "$r -> $s\n" if ($debug); | |
294 | ||
6fe79d1e | 295 | $data =~ s/enum\s+($r)$end_delim/$s$2/g; |
dabf8be3 MCC |
296 | } |
297 | ||
298 | foreach my $r (keys %structs) { | |
22c40033 | 299 | my $s = $structs{$r}; |
dabf8be3 MCC |
300 | |
301 | $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; | |
302 | ||
303 | print "$r -> $s\n" if ($debug); | |
304 | ||
6fe79d1e | 305 | $data =~ s/struct\s+($r)$end_delim/$s$2/g; |
dabf8be3 MCC |
306 | } |
307 | ||
308 | foreach my $r (keys %typedefs) { | |
22c40033 | 309 | my $s = $typedefs{$r}; |
dabf8be3 MCC |
310 | |
311 | $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; | |
312 | ||
313 | print "$r -> $s\n" if ($debug); | |
6fe79d1e | 314 | $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; |
dabf8be3 MCC |
315 | } |
316 | ||
22c40033 | 317 | $data =~ s/\\ ([\n\s])/\1/g; |
fb6fc6c9 | 318 | |
dabf8be3 MCC |
319 | # |
320 | # Generate output file | |
321 | # | |
322 | ||
323 | my $title = $file_in; | |
324 | $title =~ s,.*/,,; | |
325 | ||
326 | open OUT, "> $file_out" or die "Can't open $file_out"; | |
327 | print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n"; | |
328 | print OUT "$title\n"; | |
329 | print OUT "=" x length($title); | |
330 | print OUT "\n\n.. parsed-literal::\n\n"; | |
331 | print OUT $data; | |
332 | close OUT; |