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