0001
0002 use strict;
0003 use Text::Tabs;
0004 use Getopt::Long;
0005 use Pod::Usage;
0006
0007 my $debug;
0008 my $help;
0009 my $man;
0010
0011 GetOptions(
0012 "debug" => \$debug,
0013 'usage|?' => \$help,
0014 'help' => \$man
0015 ) or pod2usage(2);
0016
0017 pod2usage(1) if $help;
0018 pod2usage(-exitstatus => 0, -verbose => 2) if $man;
0019 pod2usage(2) if (scalar @ARGV < 2 || scalar @ARGV > 3);
0020
0021 my ($file_in, $file_out, $file_exceptions) = @ARGV;
0022
0023 my $data;
0024 my %ioctls;
0025 my %defines;
0026 my %typedefs;
0027 my %enums;
0028 my %enum_symbols;
0029 my %structs;
0030
0031 require Data::Dumper if ($debug);
0032
0033
0034
0035
0036
0037 my $is_enum = 0;
0038 my $is_comment = 0;
0039 open IN, $file_in or die "Can't open $file_in";
0040 while (<IN>) {
0041 $data .= $_;
0042
0043 my $ln = $_;
0044 if (!$is_comment) {
0045 $ln =~ s,/\*.*(\*/),,g;
0046
0047 $is_comment = 1 if ($ln =~ s,/\*.*,,);
0048 } else {
0049 if ($ln =~ s,^(.*\*/),,) {
0050 $is_comment = 0;
0051 } else {
0052 next;
0053 }
0054 }
0055
0056 if ($is_enum && $ln =~ ) {
0057 my $s = $1;
0058 my $n = $1;
0059 $n =~ tr/A-Z/a-z/;
0060 $n =~ tr/_/-/;
0061
0062 $enum_symbols{$s} = "\\ :ref:`$s <$n>`\\ ";
0063
0064 $is_enum = 0 if ($is_enum && );
0065 next;
0066 }
0067 $is_enum = 0 if ($is_enum && );
0068
0069 if ($ln =~ ) {
0070 my $s = $1;
0071 my $n = $1;
0072 $n =~ tr/A-Z/a-z/;
0073
0074 $ioctls{$s} = "\\ :ref:`$s <$n>`\\ ";
0075 next;
0076 }
0077
0078 if ($ln =~ ) {
0079 my $s = $1;
0080 my $n = $1;
0081 $n =~ tr/A-Z/a-z/;
0082 $n =~ tr/_/-/;
0083
0084 $defines{$s} = "\\ :ref:`$s <$n>`\\ ";
0085 next;
0086 }
0087
0088 if ($ln =~ ) {
0089 my $s = $2;
0090 my $n = $3;
0091
0092 $typedefs{$n} = "\\ :c:type:`$n <$s>`\\ ";
0093 next;
0094 }
0095 if ($ln =~
0096 || $ln =~
0097 || $ln =~
0098 || $ln =~ ) {
0099 my $s = $1;
0100
0101 $enums{$s} = "enum :c:type:`$s`\\ ";
0102
0103 $is_enum = $1;
0104 next;
0105 }
0106 if ($ln =~
0107 || $ln =~
0108 || $ln =~
0109 || $ln =~
0110 ) {
0111 my $s = $1;
0112
0113 $structs{$s} = "struct $s\\ ";
0114 next;
0115 }
0116 }
0117 close IN;
0118
0119
0120
0121
0122
0123 my @matches = ($data =~ ,
0124 $data =~ ,);
0125 foreach my $m (@matches) {
0126 my $s = $m;
0127
0128 $typedefs{$s} = "\\ :c:type:`$s`\\ ";
0129 next;
0130 }
0131
0132
0133
0134
0135
0136 my %def_reftype = (
0137 "ioctl" => ":ref",
0138 "define" => ":ref",
0139 "symbol" => ":ref",
0140 "typedef" => ":c:type",
0141 "enum" => ":c:type",
0142 "struct" => ":c:type",
0143 );
0144
0145 if ($file_exceptions) {
0146 open IN, $file_exceptions or die "Can't read $file_exceptions";
0147 while (<IN>) {
0148 next if ( || );
0149
0150
0151
0152 if () {
0153 delete $ioctls{$1} if (exists($ioctls{$1}));
0154 next;
0155 }
0156 if () {
0157 delete $defines{$1} if (exists($defines{$1}));
0158 next;
0159 }
0160 if () {
0161 delete $typedefs{$1} if (exists($typedefs{$1}));
0162 next;
0163 }
0164 if () {
0165 delete $enums{$1} if (exists($enums{$1}));
0166 next;
0167 }
0168 if () {
0169 delete $structs{$1} if (exists($structs{$1}));
0170 next;
0171 }
0172 if () {
0173 delete $enum_symbols{$1} if (exists($enum_symbols{$1}));
0174 next;
0175 }
0176
0177
0178 my ($type, $old, $new, $reftype);
0179
0180 if () {
0181 $type = $1;
0182 $old = $2;
0183 $new = $3;
0184 } else {
0185 die "Can't parse $file_exceptions: $_";
0186 }
0187
0188 if ($new =~ ) {
0189 $reftype = ":c:$1";
0190 $new = $2;
0191 } elsif ($new =~ ) {
0192 $reftype = ":ref";
0193 $new = $1;
0194 } else {
0195 $reftype = $def_reftype{$type};
0196 }
0197 $new = "$reftype:`$old <$new>`";
0198
0199 if ($type eq "ioctl") {
0200 $ioctls{$old} = $new if (exists($ioctls{$old}));
0201 next;
0202 }
0203 if ($type eq "define") {
0204 $defines{$old} = $new if (exists($defines{$old}));
0205 next;
0206 }
0207 if ($type eq "symbol") {
0208 $enum_symbols{$old} = $new if (exists($enum_symbols{$old}));
0209 next;
0210 }
0211 if ($type eq "typedef") {
0212 $typedefs{$old} = $new if (exists($typedefs{$old}));
0213 next;
0214 }
0215 if ($type eq "enum") {
0216 $enums{$old} = $new if (exists($enums{$old}));
0217 next;
0218 }
0219 if ($type eq "struct") {
0220 $structs{$old} = $new if (exists($structs{$old}));
0221 next;
0222 }
0223
0224 die "Can't parse $file_exceptions: $_";
0225 }
0226 }
0227
0228 if ($debug) {
0229 print Data::Dumper->Dump([\%ioctls], []) if (%ioctls);
0230 print Data::Dumper->Dump([\%typedefs], []) if (%typedefs);
0231 print Data::Dumper->Dump([\%enums], []) if (%enums);
0232 print Data::Dumper->Dump([\%structs], []) if (%structs);
0233 print Data::Dumper->Dump([\%defines], []) if (%defines);
0234 print Data::Dumper->Dump([\%enum_symbols], []) if (%enum_symbols);
0235 }
0236
0237
0238
0239
0240 $data = expand($data);
0241 $data = " " . $data;
0242 $data =~ s/\n/\n /g;
0243 $data =~ s/\n\s+$/\n/g;
0244 $data =~ s/\n\s+\n/\n\n/g;
0245
0246
0247
0248
0249 $data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g;
0250
0251 $data =~ s,DEPRECATED,**DEPRECATED**,g;
0252
0253
0254
0255
0256
0257 my $start_delim = "[ \n\t\(\=\*\@]";
0258 my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)";
0259
0260 foreach my $r (keys %ioctls) {
0261 my $s = $ioctls{$r};
0262
0263 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
0264
0265 print "$r -> $s\n" if ($debug);
0266
0267 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
0268 }
0269
0270 foreach my $r (keys %defines) {
0271 my $s = $defines{$r};
0272
0273 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
0274
0275 print "$r -> $s\n" if ($debug);
0276
0277 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
0278 }
0279
0280 foreach my $r (keys %enum_symbols) {
0281 my $s = $enum_symbols{$r};
0282
0283 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
0284
0285 print "$r -> $s\n" if ($debug);
0286
0287 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
0288 }
0289
0290 foreach my $r (keys %enums) {
0291 my $s = $enums{$r};
0292
0293 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
0294
0295 print "$r -> $s\n" if ($debug);
0296
0297 $data =~ s/enum\s+($r)$end_delim/$s$2/g;
0298 }
0299
0300 foreach my $r (keys %structs) {
0301 my $s = $structs{$r};
0302
0303 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
0304
0305 print "$r -> $s\n" if ($debug);
0306
0307 $data =~ s/struct\s+($r)$end_delim/$s$2/g;
0308 }
0309
0310 foreach my $r (keys %typedefs) {
0311 my $s = $typedefs{$r};
0312
0313 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
0314
0315 print "$r -> $s\n" if ($debug);
0316 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
0317 }
0318
0319 $data =~ s/\\ ([\n\s])/\1/g;
0320
0321
0322
0323
0324
0325 my $title = $file_in;
0326 $title =~ s,.*/,,;
0327
0328 open OUT, "> $file_out" or die "Can't open $file_out";
0329 print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n";
0330 print OUT "$title\n";
0331 print OUT "=" x length($title);
0332 print OUT "\n\n.. parsed-literal::\n\n";
0333 print OUT $data;
0334 close OUT;
0335
0336 __END__
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401