blob: 531c710fc73f9a3446c51f48948cb25dd2f9e6d1 [file] [log] [blame]
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -03001#!/usr/bin/perl
2use strict;
3use Text::Tabs;
4
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -03005my $debug = 0;
6
Mauro Carvalho Chehabbcec7c22016-08-31 06:41:40 -03007while ($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
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030017if (scalar @ARGV < 2 || scalar @ARGV > 3) {
18 die "Usage:\n\t$0 <file in> <file out> [<exceptions file>]\n";
19}
20
21my ($file_in, $file_out, $file_exceptions) = @ARGV;
22
23my $data;
24my %ioctls;
25my %defines;
26my %typedefs;
27my %enums;
28my %enum_symbols;
29my %structs;
30
31#
32# read the file and get identifiers
33#
34
35my $is_enum = 0;
Mauro Carvalho Chehab034e6c82016-07-07 14:13:12 -030036my $is_comment = 0;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030037open IN, $file_in or die "Can't open $file_in";
38while (<IN>) {
39 $data .= $_;
40
Mauro Carvalho Chehab034e6c82016-07-07 14:13:12 -030041 my $ln = $_;
42 if (!$is_comment) {
43 $ln =~ s,/\*.*(\*/),,g;
44
45 $is_comment = 1 if ($ln =~ s,/\*.*,,);
46 } else {
47 if ($ln =~ s,^(.*\*/),,) {
48 $is_comment = 0;
49 } else {
50 next;
51 }
52 }
53
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030054 if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030055 my $s = $1;
56 my $n = $1;
57 $n =~ tr/A-Z/a-z/;
58 $n =~ tr/_/-/;
59
60 $enum_symbols{$s} = $n;
61
62 $is_enum = 0 if ($is_enum && m/\}/);
63 next;
64 }
65 $is_enum = 0 if ($is_enum && m/\}/);
66
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030067 if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030068 my $s = $1;
69 my $n = $1;
70 $n =~ tr/A-Z/a-z/;
71
72 $ioctls{$s} = $n;
73 next;
74 }
75
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030076 if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030077 my $s = $1;
78 my $n = $1;
79 $n =~ tr/A-Z/a-z/;
80 $n =~ tr/_/-/;
81
82 $defines{$s} = $n;
83 next;
84 }
85
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030086 if ($ln =~ m/^\s*typedef\s+.*\s+([_\w][\w\d_]+);/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030087 my $s = $1;
88 my $n = $1;
89 $n =~ tr/A-Z/a-z/;
90 $n =~ tr/_/-/;
91
92 $typedefs{$s} = $n;
93 next;
94 }
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030095 if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/
Mauro Carvalho Chehab6c4c7da2016-07-07 07:20:27 -030096 || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/
97 || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/
98 || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030099 my $s = $1;
100 my $n = $1;
101 $n =~ tr/A-Z/a-z/;
102 $n =~ tr/_/-/;
103
104 $enums{$s} = $n;
105
106 $is_enum = $1;
107 next;
108 }
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -0300109 if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/
Mauro Carvalho Chehab6c4c7da2016-07-07 07:20:27 -0300110 || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/
111 || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/
112 || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/
113 ) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300114 my $s = $1;
115 my $n = $1;
116 $n =~ tr/A-Z/a-z/;
117 $n =~ tr/_/-/;
118
119 $structs{$s} = $n;
120 next;
121 }
122}
123close IN;
124
125#
126# Handle multi-line typedefs
127#
128
Mauro Carvalho Chehab4ff916a2016-07-07 08:09:37 -0300129my @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,
130 $data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,);
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300131foreach my $m (@matches) {
Mauro Carvalho Chehab4ff916a2016-07-07 08:09:37 -0300132 my $s = $m;
133 my $n = $m;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300134 $n =~ tr/A-Z/a-z/;
135 $n =~ tr/_/-/;
136
137 $typedefs{$s} = $n;
138 next;
139}
140
141#
142# Handle exceptions, if any
143#
144
145if ($file_exceptions) {
146 open IN, $file_exceptions or die "Can't read $file_exceptions";
147 while (<IN>) {
148 next if (m/^\s*$/ || m/^\s*#/);
149
150 # Parsers to ignore a symbol
151
152 if (m/^ignore\s+ioctl\s+(\S+)/) {
153 delete $ioctls{$1} if (exists($ioctls{$1}));
154 next;
155 }
156 if (m/^ignore\s+define\s+(\S+)/) {
157 delete $defines{$1} if (exists($defines{$1}));
158 next;
159 }
160 if (m/^ignore\s+typedef\s+(\S+)/) {
161 delete $typedefs{$1} if (exists($typedefs{$1}));
162 next;
163 }
164 if (m/^ignore\s+enum\s+(\S+)/) {
165 delete $enums{$1} if (exists($enums{$1}));
166 next;
167 }
168 if (m/^ignore\s+struct\s+(\S+)/) {
169 delete $structs{$1} if (exists($structs{$1}));
170 next;
171 }
Mauro Carvalho Chehab526b8842016-07-07 14:26:51 -0300172 if (m/^ignore\s+symbol\s+(\S+)/) {
173 delete $enum_symbols{$1} if (exists($enum_symbols{$1}));
174 next;
175 }
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300176
177 # Parsers to replace a symbol
178
179 if (m/^replace\s+ioctl\s+(\S+)\s+(\S+)/) {
180 $ioctls{$1} = $2 if (exists($ioctls{$1}));
181 next;
182 }
183 if (m/^replace\s+define\s+(\S+)\s+(\S+)/) {
184 $defines{$1} = $2 if (exists($defines{$1}));
185 next;
186 }
187 if (m/^replace\s+typedef\s+(\S+)\s+(\S+)/) {
188 $typedefs{$1} = $2 if (exists($typedefs{$1}));
189 next;
190 }
191 if (m/^replace\s+enum\s+(\S+)\s+(\S+)/) {
192 $enums{$1} = $2 if (exists($enums{$1}));
193 next;
194 }
195 if (m/^replace\s+symbol\s+(\S+)\s+(\S+)/) {
196 $enum_symbols{$1} = $2 if (exists($enum_symbols{$1}));
197 next;
198 }
199 if (m/^replace\s+struct\s+(\S+)\s+(\S+)/) {
200 $structs{$1} = $2 if (exists($structs{$1}));
201 next;
202 }
203
204 die "Can't parse $file_exceptions: $_";
205 }
206}
207
208if ($debug) {
209 print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls);
210 print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs);
211 print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums);
212 print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs);
213 print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines);
214 print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols);
215}
216
217#
218# Align block
219#
220$data = expand($data);
221$data = " " . $data;
222$data =~ s/\n/\n /g;
223$data =~ s/\n\s+$/\n/g;
224$data =~ s/\n\s+\n/\n\n/g;
225
226#
227# Add escape codes for special characters
228#
Mauro Carvalho Chehab999d9982016-08-16 13:25:41 -0300229$data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300230
Mauro Carvalho Chehab7d95fa82016-07-07 06:31:21 -0300231$data =~ s,DEPRECATED,**DEPRECATED**,g;
232
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300233#
234# Add references
235#
236
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300237my $start_delim = "[ \n\t\(\=\*\@]";
238my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300239
240foreach my $r (keys %ioctls) {
241 my $n = $ioctls{$r};
242
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300243 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300244
245 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
246
247 print "$r -> $s\n" if ($debug);
248
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300249 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300250}
251
252foreach my $r (keys %defines) {
253 my $n = $defines{$r};
254
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300255 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300256
257 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
258
259 print "$r -> $s\n" if ($debug);
260
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300261 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300262}
263
264foreach my $r (keys %enum_symbols) {
265 my $n = $enum_symbols{$r};
266
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300267 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300268
269 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
270
271 print "$r -> $s\n" if ($debug);
272
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300273 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300274}
275
276foreach my $r (keys %enums) {
277 my $n = $enums{$r};
278
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300279 my $s = "\\ :ref:`enum $r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300280
281 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
282
283 print "$r -> $s\n" if ($debug);
284
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300285 $data =~ s/enum\s+($r)$end_delim/$s$2/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300286}
287
288foreach my $r (keys %structs) {
289 my $n = $structs{$r};
290
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300291 my $s = "\\ :ref:`struct $r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300292
293 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
294
295 print "$r -> $s\n" if ($debug);
296
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300297 $data =~ s/struct\s+($r)$end_delim/$s$2/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300298}
299
300foreach my $r (keys %typedefs) {
301 my $n = $typedefs{$r};
302
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300303 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300304
305 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
306
307 print "$r -> $s\n" if ($debug);
308
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300309 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300310}
311
Mauro Carvalho Chehabfb6fc6c2016-07-09 09:35:34 -0300312$data =~ s/\\ \n/\n/g;
313
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300314#
315# Generate output file
316#
317
318my $title = $file_in;
319$title =~ s,.*/,,;
320
321open OUT, "> $file_out" or die "Can't open $file_out";
322print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n";
323print OUT "$title\n";
324print OUT "=" x length($title);
325print OUT "\n\n.. parsed-literal::\n\n";
326print OUT $data;
327close OUT;