Blame view

Documentation/sphinx/parse-headers.pl 8.36 KB
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
1
2
3
  #!/usr/bin/perl
  use strict;
  use Text::Tabs;
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
4
5
  use Getopt::Long;
  use Pod::Usage;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
6

327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
7
8
9
  my $debug;
  my $help;
  my $man;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
10

327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
11
12
  GetOptions(
  	"debug" => \$debug,
c33966566   Mauro Carvalho Chehab   docs-rst: parse-h...
13
14
  	'usage|?' => \$help,
  	'help' => \$man
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
15
  ) or pod2usage(2);
bcec7c218   Mauro Carvalho Chehab   [media] docs-rst:...
16

327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
17
18
19
  pod2usage(1) if $help;
  pod2usage(-exitstatus => 0, -verbose => 2) if $man;
  pod2usage(2) if (scalar @ARGV < 2 || scalar @ARGV > 3);
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
20
21
22
23
24
25
26
27
28
29
  
  my ($file_in, $file_out, $file_exceptions) = @ARGV;
  
  my $data;
  my %ioctls;
  my %defines;
  my %typedefs;
  my %enums;
  my %enum_symbols;
  my %structs;
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
30
  require Data::Dumper if ($debug);
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
31
32
33
34
35
  #
  # read the file and get identifiers
  #
  
  my $is_enum = 0;
034e6c8e7   Mauro Carvalho Chehab   doc-rst: parse-he...
36
  my $is_comment = 0;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
37
38
  open IN, $file_in or die "Can't open $file_in";
  while (<IN>) {
034e6c8e7   Mauro Carvalho Chehab   doc-rst: parse-he...
39
  	$data .= $_;
9afe51129   Mauro Carvalho Chehab   doc-rst: fix pars...
40
  	my $ln = $_;
034e6c8e7   Mauro Carvalho Chehab   doc-rst: parse-he...
41
42
  	if (!$is_comment) {
  		$ln =~ s,/\*.*(\*/),,g;
9afe51129   Mauro Carvalho Chehab   doc-rst: fix pars...
43

034e6c8e7   Mauro Carvalho Chehab   doc-rst: parse-he...
44
45
46
47
48
49
50
51
  		$is_comment = 1 if ($ln =~ s,/\*.*,,);
  	} else {
  		if ($ln =~ s,^(.*\*/),,) {
  			$is_comment = 0;
  		} else {
  			next;
  		}
  	}
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
52

9c80c7456   Mauro Carvalho Chehab   doc-rst: parse-he...
53
  	if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) {
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
54
55
56
57
  		my $s = $1;
  		my $n = $1;
  		$n =~ tr/A-Z/a-z/;
  		$n =~ tr/_/-/;
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
58
  		$enum_symbols{$s} =  "\\ :ref:`$s <$n>`\\ ";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
59
60
61
62
63
  
  		$is_enum = 0 if ($is_enum && m/\}/);
  		next;
  	}
  	$is_enum = 0 if ($is_enum && m/\}/);
9c80c7456   Mauro Carvalho Chehab   doc-rst: parse-he...
64
  	if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) {
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
65
66
67
  		my $s = $1;
  		my $n = $1;
  		$n =~ tr/A-Z/a-z/;
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
68
  		$ioctls{$s} = "\\ :ref:`$s <$n>`\\ ";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
69
70
  		next;
  	}
9c80c7456   Mauro Carvalho Chehab   doc-rst: parse-he...
71
  	if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) {
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
72
73
74
75
  		my $s = $1;
  		my $n = $1;
  		$n =~ tr/A-Z/a-z/;
  		$n =~ tr/_/-/;
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
76
  		$defines{$s} = "\\ :ref:`$s <$n>`\\ ";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
77
78
  		next;
  	}
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
79
80
81
  	if ($ln =~ m/^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);/) {
  		my $s = $2;
  		my $n = $3;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
82

22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
83
  		$typedefs{$n} = "\\ :c:type:`$n <$s>`\\ ";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
84
85
  		next;
  	}
9c80c7456   Mauro Carvalho Chehab   doc-rst: parse-he...
86
  	if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/
6c4c7dadb   Mauro Carvalho Chehab   doc-rst: parse-he...
87
88
89
  	    || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/
  	    || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/
  	    || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) {
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
90
  		my $s = $1;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
91

22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
92
  		$enums{$s} =  "enum :c:type:`$s`\\ ";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
93
94
95
96
  
  		$is_enum = $1;
  		next;
  	}
9c80c7456   Mauro Carvalho Chehab   doc-rst: parse-he...
97
  	if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/
6c4c7dadb   Mauro Carvalho Chehab   doc-rst: parse-he...
98
99
100
101
  	    || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/
  	    || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/
  	    || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/
  	    ) {
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
102
  		my $s = $1;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
103

22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
104
  		$structs{$s} = "struct :c:type:`$s`\\ ";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
105
106
107
108
109
110
111
112
  		next;
  	}
  }
  close IN;
  
  #
  # Handle multi-line typedefs
  #
4ff916a0c   Mauro Carvalho Chehab   doc-rst: parse-he...
113
114
  my @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,
  	       $data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,);
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
115
  foreach my $m (@matches) {
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
116
  	my $s = $m;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
117

22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
118
  	$typedefs{$s} = "\\ :c:type:`$s`\\ ";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
119
120
121
122
123
124
  	next;
  }
  
  #
  # Handle exceptions, if any
  #
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
125
126
127
128
129
130
131
132
  my %def_reftype = (
  	"ioctl"   => ":ref",
  	"define"  => ":ref",
  	"symbol"  => ":ref",
  	"typedef" => ":c:type",
  	"enum"    => ":c:type",
  	"struct"  => ":c:type",
  );
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  if ($file_exceptions) {
  	open IN, $file_exceptions or die "Can't read $file_exceptions";
  	while (<IN>) {
  		next if (m/^\s*$/ || m/^\s*#/);
  
  		# Parsers to ignore a symbol
  
  		if (m/^ignore\s+ioctl\s+(\S+)/) {
  			delete $ioctls{$1} if (exists($ioctls{$1}));
  			next;
  		}
  		if (m/^ignore\s+define\s+(\S+)/) {
  			delete $defines{$1} if (exists($defines{$1}));
  			next;
  		}
  		if (m/^ignore\s+typedef\s+(\S+)/) {
  			delete $typedefs{$1} if (exists($typedefs{$1}));
  			next;
  		}
  		if (m/^ignore\s+enum\s+(\S+)/) {
  			delete $enums{$1} if (exists($enums{$1}));
  			next;
  		}
  		if (m/^ignore\s+struct\s+(\S+)/) {
  			delete $structs{$1} if (exists($structs{$1}));
  			next;
  		}
526b88483   Mauro Carvalho Chehab   doc-rst: parse-he...
160
161
162
163
  		if (m/^ignore\s+symbol\s+(\S+)/) {
  			delete $enum_symbols{$1} if (exists($enum_symbols{$1}));
  			next;
  		}
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
164
165
  
  		# Parsers to replace a symbol
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
166
  		my ($type, $old, $new, $reftype);
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
167

22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  		if (m/^replace\s+(\S+)\s+(\S+)\s+(\S+)/) {
  			$type = $1;
  			$old = $2;
  			$new = $3;
  		} else {
  			die "Can't parse $file_exceptions: $_";
  		}
  
  		if ($new =~ m/^\:c\:(data|func|macro|type)\:\`(.+)\`/) {
  			$reftype = ":c:$1";
  			$new = $2;
  		} elsif ($new =~ m/\:ref\:\`(.+)\`/) {
  			$reftype = ":ref";
  			$new = $1;
  		} else {
  			$reftype = $def_reftype{$type};
  		}
  		$new = "$reftype:`$old <$new>`";
  
  		if ($type eq "ioctl") {
  			$ioctls{$old} = $new if (exists($ioctls{$old}));
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
189
190
  			next;
  		}
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
191
192
  		if ($type eq "define") {
  			$defines{$old} = $new if (exists($defines{$old}));
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
193
194
  			next;
  		}
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
195
196
  		if ($type eq "symbol") {
  			$enum_symbols{$old} = $new if (exists($enum_symbols{$old}));
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
197
198
  			next;
  		}
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
199
200
  		if ($type eq "typedef") {
  			$typedefs{$old} = $new if (exists($typedefs{$old}));
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
201
202
  			next;
  		}
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
203
204
  		if ($type eq "enum") {
  			$enums{$old} = $new if (exists($enums{$old}));
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
205
206
  			next;
  		}
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
207
208
  		if ($type eq "struct") {
  			$structs{$old} = $new if (exists($structs{$old}));
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  			next;
  		}
  
  		die "Can't parse $file_exceptions: $_";
  	}
  }
  
  if ($debug) {
  	print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls);
  	print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs);
  	print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums);
  	print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs);
  	print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines);
  	print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols);
  }
  
  #
  # Align block
  #
  $data = expand($data);
  $data = "    " . $data;
  $data =~ s/
  /
      /g;
  $data =~ s/
  \s+$/
  /g;
  $data =~ s/
  \s+
  /
  
  /g;
  
  #
  # Add escape codes for special characters
  #
999d998ee   Mauro Carvalho Chehab   docs-rst: parse-h...
245
  $data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
246

7d95fa8d6   Mauro Carvalho Chehab   doc-dst: parse-he...
247
  $data =~ s,DEPRECATED,**DEPRECATED**,g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
248
249
250
  #
  # Add references
  #
6fe79d1ed   Mauro Carvalho Chehab   doc-rst: parse-he...
251
252
253
  my $start_delim = "[ 
  \t\(\=\*\@]";
  my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)";
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
254
255
  
  foreach my $r (keys %ioctls) {
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
256
  	my $s = $ioctls{$r};
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
257
258
259
260
261
  
  	$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
  
  	print "$r -> $s
  " if ($debug);
6fe79d1ed   Mauro Carvalho Chehab   doc-rst: parse-he...
262
  	$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
263
264
265
  }
  
  foreach my $r (keys %defines) {
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
266
  	my $s = $defines{$r};
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
267
268
269
270
271
  
  	$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
  
  	print "$r -> $s
  " if ($debug);
6fe79d1ed   Mauro Carvalho Chehab   doc-rst: parse-he...
272
  	$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
273
274
275
  }
  
  foreach my $r (keys %enum_symbols) {
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
276
  	my $s = $enum_symbols{$r};
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
277
278
279
280
281
  
  	$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
  
  	print "$r -> $s
  " if ($debug);
6fe79d1ed   Mauro Carvalho Chehab   doc-rst: parse-he...
282
  	$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
283
284
285
  }
  
  foreach my $r (keys %enums) {
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
286
  	my $s = $enums{$r};
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
287
288
289
290
291
  
  	$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
  
  	print "$r -> $s
  " if ($debug);
6fe79d1ed   Mauro Carvalho Chehab   doc-rst: parse-he...
292
  	$data =~ s/enum\s+($r)$end_delim/$s$2/g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
293
294
295
  }
  
  foreach my $r (keys %structs) {
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
296
  	my $s = $structs{$r};
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
297
298
299
300
301
  
  	$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
  
  	print "$r -> $s
  " if ($debug);
6fe79d1ed   Mauro Carvalho Chehab   doc-rst: parse-he...
302
  	$data =~ s/struct\s+($r)$end_delim/$s$2/g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
303
304
305
  }
  
  foreach my $r (keys %typedefs) {
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
306
  	my $s = $typedefs{$r};
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
307
308
309
310
311
  
  	$r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
  
  	print "$r -> $s
  " if ($debug);
6fe79d1ed   Mauro Carvalho Chehab   doc-rst: parse-he...
312
  	$data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
313
  }
22c400336   Mauro Carvalho Chehab   [media] docs-rst:...
314
315
  $data =~ s/\\ ([
  \s])/\1/g;
fb6fc6c9a   Mauro Carvalho Chehab   doc-rst: parse-he...
316

dabf8be33   Mauro Carvalho Chehab   doc-rst: add pars...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  #
  # Generate output file
  #
  
  my $title = $file_in;
  $title =~ s,.*/,,;
  
  open OUT, "> $file_out" or die "Can't open $file_out";
  print OUT ".. -*- coding: utf-8; mode: rst -*-
  
  ";
  print OUT "$title
  ";
  print OUT "=" x length($title);
  print OUT "
  
  .. parsed-literal::
  
  ";
  print OUT $data;
  close OUT;
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
338
339
340
341
342
343
344
345
346
347
348
  
  __END__
  
  =head1 NAME
  
  parse_headers.pl - parse a C file, in order to identify functions, structs,
  enums and defines and create cross-references to a Sphinx book.
  
  =head1 SYNOPSIS
  
  B<parse_headers.pl> [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
f3821276f   Federico Vaga   doc:sphinx: fix p...
349
  Where <options> can be: --debug, --help or --usage.
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
350
351
352
353
354
355
356
357
  
  =head1 OPTIONS
  
  =over 8
  
  =item B<--debug>
  
  Put the script in verbose mode, useful for debugging.
c33966566   Mauro Carvalho Chehab   docs-rst: parse-h...
358
  =item B<--usage>
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
359
360
  
  Prints a brief help message and exits.
c33966566   Mauro Carvalho Chehab   docs-rst: parse-h...
361
  =item B<--help>
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
362

c33966566   Mauro Carvalho Chehab   docs-rst: parse-h...
363
  Prints a more detailed help message and exits.
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  
  =back
  
  =head1 DESCRIPTION
  
  Convert a C header or source file (C_FILE), into a ReStructured Text
  included via ..parsed-literal block with cross-references for the
  documentation files that describe the API. It accepts an optional
  EXCEPTIONS_FILE with describes what elements will be either ignored or
  be pointed to a non-default reference.
  
  The output is written at the (OUT_FILE).
  
  It is capable of identifying defines, functions, structs, typedefs,
  enums and enum symbols and create cross-references for all of them.
  It is also capable of distinguish #define used for specifying a Linux
  ioctl.
c33966566   Mauro Carvalho Chehab   docs-rst: parse-h...
381
382
  The EXCEPTIONS_FILE contain two rules to allow ignoring a symbol or
  to replace the default references by a custom one.
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
383

c33966566   Mauro Carvalho Chehab   docs-rst: parse-h...
384
385
  Please read Documentation/doc-guide/parse-headers.rst at the Kernel's
  tree for more details.
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
386
387
  
  =head1 BUGS
325908199   Mauro Carvalho Chehab   MAINTAINERS & fil...
388
  Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org>
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
389
390
  
  =head1 COPYRIGHT
325908199   Mauro Carvalho Chehab   MAINTAINERS & fil...
391
  Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>.
327f5a754   Mauro Carvalho Chehab   parse-headers.pl:...
392
393
394
395
396
397
398
  
  License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
  
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.
  
  =cut