blob: b657cadb53aecce47fb936d4f3cf8d677a61ddb7 [file] [log] [blame]
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -03001#!/usr/bin/perl
2use strict;
3use Text::Tabs;
4
5# Uncomment if debug is needed
6#use Data::Dumper;
7
8# change to 1 to generate some debug prints
9my $debug = 0;
10
11if (scalar @ARGV < 2 || scalar @ARGV > 3) {
12 die "Usage:\n\t$0 <file in> <file out> [<exceptions file>]\n";
13}
14
15my ($file_in, $file_out, $file_exceptions) = @ARGV;
16
17my $data;
18my %ioctls;
19my %defines;
20my %typedefs;
21my %enums;
22my %enum_symbols;
23my %structs;
24
25#
26# read the file and get identifiers
27#
28
29my $is_enum = 0;
30open IN, $file_in or die "Can't open $file_in";
31while (<IN>) {
Mauro Carvalho Chehab9afe5112016-07-07 06:52:10 -030032 my $ln = $_;
33 $ln =~ s,/\*.*\*/,,;
34
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030035 $data .= $_;
36
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030037 if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030038 my $s = $1;
39 my $n = $1;
40 $n =~ tr/A-Z/a-z/;
41 $n =~ tr/_/-/;
42
43 $enum_symbols{$s} = $n;
44
45 $is_enum = 0 if ($is_enum && m/\}/);
46 next;
47 }
48 $is_enum = 0 if ($is_enum && m/\}/);
49
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030050 if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030051 my $s = $1;
52 my $n = $1;
53 $n =~ tr/A-Z/a-z/;
54
55 $ioctls{$s} = $n;
56 next;
57 }
58
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030059 if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030060 my $s = $1;
61 my $n = $1;
62 $n =~ tr/A-Z/a-z/;
63 $n =~ tr/_/-/;
64
65 $defines{$s} = $n;
66 next;
67 }
68
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030069 if ($ln =~ m/^\s*typedef\s+.*\s+([_\w][\w\d_]+);/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030070 my $s = $1;
71 my $n = $1;
72 $n =~ tr/A-Z/a-z/;
73 $n =~ tr/_/-/;
74
75 $typedefs{$s} = $n;
76 next;
77 }
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030078 if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/
Mauro Carvalho Chehab6c4c7da2016-07-07 07:20:27 -030079 || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/
80 || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/
81 || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030082 my $s = $1;
83 my $n = $1;
84 $n =~ tr/A-Z/a-z/;
85 $n =~ tr/_/-/;
86
87 $enums{$s} = $n;
88
89 $is_enum = $1;
90 next;
91 }
Mauro Carvalho Chehab9c80c742016-07-07 07:06:05 -030092 if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/
Mauro Carvalho Chehab6c4c7da2016-07-07 07:20:27 -030093 || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/
94 || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/
95 || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/
96 ) {
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -030097 my $s = $1;
98 my $n = $1;
99 $n =~ tr/A-Z/a-z/;
100 $n =~ tr/_/-/;
101
102 $structs{$s} = $n;
103 next;
104 }
105}
106close IN;
107
108#
109# Handle multi-line typedefs
110#
111
112my @matches = $data =~ m/typedef\s+struct\s+\S+\s*\{[^\}]+\}\s*(\S+)\s*\;/g;
113foreach my $m (@matches) {
114 my $s = $1;
115 my $n = $1;
116 $n =~ tr/A-Z/a-z/;
117 $n =~ tr/_/-/;
118
119 $typedefs{$s} = $n;
120 next;
121}
122
123#
124# Handle exceptions, if any
125#
126
127if ($file_exceptions) {
128 open IN, $file_exceptions or die "Can't read $file_exceptions";
129 while (<IN>) {
130 next if (m/^\s*$/ || m/^\s*#/);
131
132 # Parsers to ignore a symbol
133
134 if (m/^ignore\s+ioctl\s+(\S+)/) {
135 delete $ioctls{$1} if (exists($ioctls{$1}));
136 next;
137 }
138 if (m/^ignore\s+define\s+(\S+)/) {
139 delete $defines{$1} if (exists($defines{$1}));
140 next;
141 }
142 if (m/^ignore\s+typedef\s+(\S+)/) {
143 delete $typedefs{$1} if (exists($typedefs{$1}));
144 next;
145 }
146 if (m/^ignore\s+enum\s+(\S+)/) {
147 delete $enums{$1} if (exists($enums{$1}));
148 next;
149 }
150 if (m/^ignore\s+struct\s+(\S+)/) {
151 delete $structs{$1} if (exists($structs{$1}));
152 next;
153 }
154
155 # Parsers to replace a symbol
156
157 if (m/^replace\s+ioctl\s+(\S+)\s+(\S+)/) {
158 $ioctls{$1} = $2 if (exists($ioctls{$1}));
159 next;
160 }
161 if (m/^replace\s+define\s+(\S+)\s+(\S+)/) {
162 $defines{$1} = $2 if (exists($defines{$1}));
163 next;
164 }
165 if (m/^replace\s+typedef\s+(\S+)\s+(\S+)/) {
166 $typedefs{$1} = $2 if (exists($typedefs{$1}));
167 next;
168 }
169 if (m/^replace\s+enum\s+(\S+)\s+(\S+)/) {
170 $enums{$1} = $2 if (exists($enums{$1}));
171 next;
172 }
173 if (m/^replace\s+symbol\s+(\S+)\s+(\S+)/) {
174 $enum_symbols{$1} = $2 if (exists($enum_symbols{$1}));
175 next;
176 }
177 if (m/^replace\s+struct\s+(\S+)\s+(\S+)/) {
178 $structs{$1} = $2 if (exists($structs{$1}));
179 next;
180 }
181
182 die "Can't parse $file_exceptions: $_";
183 }
184}
185
186if ($debug) {
187 print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls);
188 print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs);
189 print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums);
190 print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs);
191 print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines);
192 print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols);
193}
194
195#
196# Align block
197#
198$data = expand($data);
199$data = " " . $data;
200$data =~ s/\n/\n /g;
201$data =~ s/\n\s+$/\n/g;
202$data =~ s/\n\s+\n/\n\n/g;
203
204#
205# Add escape codes for special characters
206#
207$data =~ s,([\_\`\*\<\>\&\\\\:\/]),\\$1,g;
208
Mauro Carvalho Chehab7d95fa82016-07-07 06:31:21 -0300209$data =~ s,DEPRECATED,**DEPRECATED**,g;
210
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300211#
212# Add references
213#
214
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300215my $start_delim = "[ \n\t\(\=\*\@]";
216my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300217
218foreach my $r (keys %ioctls) {
219 my $n = $ioctls{$r};
220
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300221 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300222
223 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
224
225 print "$r -> $s\n" if ($debug);
226
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300227 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300228}
229
230foreach my $r (keys %defines) {
231 my $n = $defines{$r};
232
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300233 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300234
235 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
236
237 print "$r -> $s\n" if ($debug);
238
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300239 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300240}
241
242foreach my $r (keys %enum_symbols) {
243 my $n = $enum_symbols{$r};
244
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300245 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300246
247 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
248
249 print "$r -> $s\n" if ($debug);
250
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300251 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300252}
253
254foreach my $r (keys %enums) {
255 my $n = $enums{$r};
256
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300257 my $s = "\\ :ref:`enum $r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300258
259 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
260
261 print "$r -> $s\n" if ($debug);
262
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300263 $data =~ s/enum\s+($r)$end_delim/$s$2/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300264}
265
266foreach my $r (keys %structs) {
267 my $n = $structs{$r};
268
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300269 my $s = "\\ :ref:`struct $r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300270
271 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
272
273 print "$r -> $s\n" if ($debug);
274
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300275 $data =~ s/struct\s+($r)$end_delim/$s$2/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300276}
277
278foreach my $r (keys %typedefs) {
279 my $n = $typedefs{$r};
280
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300281 my $s = "\\ :ref:`$r <$n>`\\ ";
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300282
283 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
284
285 print "$r -> $s\n" if ($debug);
286
Mauro Carvalho Chehab6fe79d12016-07-07 06:27:54 -0300287 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
Mauro Carvalho Chehabdabf8be2016-07-06 22:58:54 -0300288}
289
290#
291# Generate output file
292#
293
294my $title = $file_in;
295$title =~ s,.*/,,;
296
297open OUT, "> $file_out" or die "Can't open $file_out";
298print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n";
299print OUT "$title\n";
300print OUT "=" x length($title);
301print OUT "\n\n.. parsed-literal::\n\n";
302print OUT $data;
303close OUT;