162306a36Sopenharmony_ci#!/usr/bin/env perl 262306a36Sopenharmony_ciuse strict; 362306a36Sopenharmony_ciuse Text::Tabs; 462306a36Sopenharmony_ciuse Getopt::Long; 562306a36Sopenharmony_ciuse Pod::Usage; 662306a36Sopenharmony_ci 762306a36Sopenharmony_cimy $debug; 862306a36Sopenharmony_cimy $help; 962306a36Sopenharmony_cimy $man; 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ciGetOptions( 1262306a36Sopenharmony_ci "debug" => \$debug, 1362306a36Sopenharmony_ci 'usage|?' => \$help, 1462306a36Sopenharmony_ci 'help' => \$man 1562306a36Sopenharmony_ci) or pod2usage(2); 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cipod2usage(1) if $help; 1862306a36Sopenharmony_cipod2usage(-exitstatus => 0, -verbose => 2) if $man; 1962306a36Sopenharmony_cipod2usage(2) if (scalar @ARGV < 2 || scalar @ARGV > 3); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cimy ($file_in, $file_out, $file_exceptions) = @ARGV; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cimy $data; 2462306a36Sopenharmony_cimy %ioctls; 2562306a36Sopenharmony_cimy %defines; 2662306a36Sopenharmony_cimy %typedefs; 2762306a36Sopenharmony_cimy %enums; 2862306a36Sopenharmony_cimy %enum_symbols; 2962306a36Sopenharmony_cimy %structs; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cirequire Data::Dumper if ($debug); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci# 3462306a36Sopenharmony_ci# read the file and get identifiers 3562306a36Sopenharmony_ci# 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cimy $is_enum = 0; 3862306a36Sopenharmony_cimy $is_comment = 0; 3962306a36Sopenharmony_ciopen IN, $file_in or die "Can't open $file_in"; 4062306a36Sopenharmony_ciwhile (<IN>) { 4162306a36Sopenharmony_ci $data .= $_; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci my $ln = $_; 4462306a36Sopenharmony_ci if (!$is_comment) { 4562306a36Sopenharmony_ci $ln =~ s,/\*.*(\*/),,g; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci $is_comment = 1 if ($ln =~ s,/\*.*,,); 4862306a36Sopenharmony_ci } else { 4962306a36Sopenharmony_ci if ($ln =~ s,^(.*\*/),,) { 5062306a36Sopenharmony_ci $is_comment = 0; 5162306a36Sopenharmony_ci } else { 5262306a36Sopenharmony_ci next; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci } 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) { 5762306a36Sopenharmony_ci my $s = $1; 5862306a36Sopenharmony_ci my $n = $1; 5962306a36Sopenharmony_ci $n =~ tr/A-Z/a-z/; 6062306a36Sopenharmony_ci $n =~ tr/_/-/; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci $enum_symbols{$s} = "\\ :ref:`$s <$n>`\\ "; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci $is_enum = 0 if ($is_enum && m/\}/); 6562306a36Sopenharmony_ci next; 6662306a36Sopenharmony_ci } 6762306a36Sopenharmony_ci $is_enum = 0 if ($is_enum && m/\}/); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) { 7062306a36Sopenharmony_ci my $s = $1; 7162306a36Sopenharmony_ci my $n = $1; 7262306a36Sopenharmony_ci $n =~ tr/A-Z/a-z/; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci $ioctls{$s} = "\\ :ref:`$s <$n>`\\ "; 7562306a36Sopenharmony_ci next; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) { 7962306a36Sopenharmony_ci my $s = $1; 8062306a36Sopenharmony_ci my $n = $1; 8162306a36Sopenharmony_ci $n =~ tr/A-Z/a-z/; 8262306a36Sopenharmony_ci $n =~ tr/_/-/; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci $defines{$s} = "\\ :ref:`$s <$n>`\\ "; 8562306a36Sopenharmony_ci next; 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci if ($ln =~ m/^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);/) { 8962306a36Sopenharmony_ci my $s = $2; 9062306a36Sopenharmony_ci my $n = $3; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci $typedefs{$n} = "\\ :c:type:`$n <$s>`\\ "; 9362306a36Sopenharmony_ci next; 9462306a36Sopenharmony_ci } 9562306a36Sopenharmony_ci if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/ 9662306a36Sopenharmony_ci || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/ 9762306a36Sopenharmony_ci || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/ 9862306a36Sopenharmony_ci || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) { 9962306a36Sopenharmony_ci my $s = $1; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci $enums{$s} = "enum :c:type:`$s`\\ "; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci $is_enum = $1; 10462306a36Sopenharmony_ci next; 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/ 10762306a36Sopenharmony_ci || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/ 10862306a36Sopenharmony_ci || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/ 10962306a36Sopenharmony_ci || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/ 11062306a36Sopenharmony_ci ) { 11162306a36Sopenharmony_ci my $s = $1; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci $structs{$s} = "struct $s\\ "; 11462306a36Sopenharmony_ci next; 11562306a36Sopenharmony_ci } 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ciclose IN; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci# 12062306a36Sopenharmony_ci# Handle multi-line typedefs 12162306a36Sopenharmony_ci# 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cimy @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g, 12462306a36Sopenharmony_ci $data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,); 12562306a36Sopenharmony_ciforeach my $m (@matches) { 12662306a36Sopenharmony_ci my $s = $m; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci $typedefs{$s} = "\\ :c:type:`$s`\\ "; 12962306a36Sopenharmony_ci next; 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci# 13362306a36Sopenharmony_ci# Handle exceptions, if any 13462306a36Sopenharmony_ci# 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cimy %def_reftype = ( 13762306a36Sopenharmony_ci "ioctl" => ":ref", 13862306a36Sopenharmony_ci "define" => ":ref", 13962306a36Sopenharmony_ci "symbol" => ":ref", 14062306a36Sopenharmony_ci "typedef" => ":c:type", 14162306a36Sopenharmony_ci "enum" => ":c:type", 14262306a36Sopenharmony_ci "struct" => ":c:type", 14362306a36Sopenharmony_ci); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ciif ($file_exceptions) { 14662306a36Sopenharmony_ci open IN, $file_exceptions or die "Can't read $file_exceptions"; 14762306a36Sopenharmony_ci while (<IN>) { 14862306a36Sopenharmony_ci next if (m/^\s*$/ || m/^\s*#/); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci # Parsers to ignore a symbol 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci if (m/^ignore\s+ioctl\s+(\S+)/) { 15362306a36Sopenharmony_ci delete $ioctls{$1} if (exists($ioctls{$1})); 15462306a36Sopenharmony_ci next; 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci if (m/^ignore\s+define\s+(\S+)/) { 15762306a36Sopenharmony_ci delete $defines{$1} if (exists($defines{$1})); 15862306a36Sopenharmony_ci next; 15962306a36Sopenharmony_ci } 16062306a36Sopenharmony_ci if (m/^ignore\s+typedef\s+(\S+)/) { 16162306a36Sopenharmony_ci delete $typedefs{$1} if (exists($typedefs{$1})); 16262306a36Sopenharmony_ci next; 16362306a36Sopenharmony_ci } 16462306a36Sopenharmony_ci if (m/^ignore\s+enum\s+(\S+)/) { 16562306a36Sopenharmony_ci delete $enums{$1} if (exists($enums{$1})); 16662306a36Sopenharmony_ci next; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci if (m/^ignore\s+struct\s+(\S+)/) { 16962306a36Sopenharmony_ci delete $structs{$1} if (exists($structs{$1})); 17062306a36Sopenharmony_ci next; 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci if (m/^ignore\s+symbol\s+(\S+)/) { 17362306a36Sopenharmony_ci delete $enum_symbols{$1} if (exists($enum_symbols{$1})); 17462306a36Sopenharmony_ci next; 17562306a36Sopenharmony_ci } 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci # Parsers to replace a symbol 17862306a36Sopenharmony_ci my ($type, $old, $new, $reftype); 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci if (m/^replace\s+(\S+)\s+(\S+)\s+(\S+)/) { 18162306a36Sopenharmony_ci $type = $1; 18262306a36Sopenharmony_ci $old = $2; 18362306a36Sopenharmony_ci $new = $3; 18462306a36Sopenharmony_ci } else { 18562306a36Sopenharmony_ci die "Can't parse $file_exceptions: $_"; 18662306a36Sopenharmony_ci } 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci if ($new =~ m/^\:c\:(data|func|macro|type)\:\`(.+)\`/) { 18962306a36Sopenharmony_ci $reftype = ":c:$1"; 19062306a36Sopenharmony_ci $new = $2; 19162306a36Sopenharmony_ci } elsif ($new =~ m/\:ref\:\`(.+)\`/) { 19262306a36Sopenharmony_ci $reftype = ":ref"; 19362306a36Sopenharmony_ci $new = $1; 19462306a36Sopenharmony_ci } else { 19562306a36Sopenharmony_ci $reftype = $def_reftype{$type}; 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci $new = "$reftype:`$old <$new>`"; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if ($type eq "ioctl") { 20062306a36Sopenharmony_ci $ioctls{$old} = $new if (exists($ioctls{$old})); 20162306a36Sopenharmony_ci next; 20262306a36Sopenharmony_ci } 20362306a36Sopenharmony_ci if ($type eq "define") { 20462306a36Sopenharmony_ci $defines{$old} = $new if (exists($defines{$old})); 20562306a36Sopenharmony_ci next; 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci if ($type eq "symbol") { 20862306a36Sopenharmony_ci $enum_symbols{$old} = $new if (exists($enum_symbols{$old})); 20962306a36Sopenharmony_ci next; 21062306a36Sopenharmony_ci } 21162306a36Sopenharmony_ci if ($type eq "typedef") { 21262306a36Sopenharmony_ci $typedefs{$old} = $new if (exists($typedefs{$old})); 21362306a36Sopenharmony_ci next; 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci if ($type eq "enum") { 21662306a36Sopenharmony_ci $enums{$old} = $new if (exists($enums{$old})); 21762306a36Sopenharmony_ci next; 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci if ($type eq "struct") { 22062306a36Sopenharmony_ci $structs{$old} = $new if (exists($structs{$old})); 22162306a36Sopenharmony_ci next; 22262306a36Sopenharmony_ci } 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci die "Can't parse $file_exceptions: $_"; 22562306a36Sopenharmony_ci } 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ciif ($debug) { 22962306a36Sopenharmony_ci print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls); 23062306a36Sopenharmony_ci print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs); 23162306a36Sopenharmony_ci print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums); 23262306a36Sopenharmony_ci print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs); 23362306a36Sopenharmony_ci print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines); 23462306a36Sopenharmony_ci print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols); 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci# 23862306a36Sopenharmony_ci# Align block 23962306a36Sopenharmony_ci# 24062306a36Sopenharmony_ci$data = expand($data); 24162306a36Sopenharmony_ci$data = " " . $data; 24262306a36Sopenharmony_ci$data =~ s/\n/\n /g; 24362306a36Sopenharmony_ci$data =~ s/\n\s+$/\n/g; 24462306a36Sopenharmony_ci$data =~ s/\n\s+\n/\n\n/g; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci# 24762306a36Sopenharmony_ci# Add escape codes for special characters 24862306a36Sopenharmony_ci# 24962306a36Sopenharmony_ci$data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci$data =~ s,DEPRECATED,**DEPRECATED**,g; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci# 25462306a36Sopenharmony_ci# Add references 25562306a36Sopenharmony_ci# 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cimy $start_delim = "[ \n\t\(\=\*\@]"; 25862306a36Sopenharmony_cimy $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)"; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ciforeach my $r (keys %ioctls) { 26162306a36Sopenharmony_ci my $s = $ioctls{$r}; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci print "$r -> $s\n" if ($debug); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; 26862306a36Sopenharmony_ci} 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ciforeach my $r (keys %defines) { 27162306a36Sopenharmony_ci my $s = $defines{$r}; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci print "$r -> $s\n" if ($debug); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ciforeach my $r (keys %enum_symbols) { 28162306a36Sopenharmony_ci my $s = $enum_symbols{$r}; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci print "$r -> $s\n" if ($debug); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ciforeach my $r (keys %enums) { 29162306a36Sopenharmony_ci my $s = $enums{$r}; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci print "$r -> $s\n" if ($debug); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci $data =~ s/enum\s+($r)$end_delim/$s$2/g; 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ciforeach my $r (keys %structs) { 30162306a36Sopenharmony_ci my $s = $structs{$r}; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci print "$r -> $s\n" if ($debug); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci $data =~ s/struct\s+($r)$end_delim/$s$2/g; 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ciforeach my $r (keys %typedefs) { 31162306a36Sopenharmony_ci my $s = $typedefs{$r}; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci print "$r -> $s\n" if ($debug); 31662306a36Sopenharmony_ci $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; 31762306a36Sopenharmony_ci} 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci$data =~ s/\\ ([\n\s])/\1/g; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci# 32262306a36Sopenharmony_ci# Generate output file 32362306a36Sopenharmony_ci# 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cimy $title = $file_in; 32662306a36Sopenharmony_ci$title =~ s,.*/,,; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ciopen OUT, "> $file_out" or die "Can't open $file_out"; 32962306a36Sopenharmony_ciprint OUT ".. -*- coding: utf-8; mode: rst -*-\n\n"; 33062306a36Sopenharmony_ciprint OUT "$title\n"; 33162306a36Sopenharmony_ciprint OUT "=" x length($title); 33262306a36Sopenharmony_ciprint OUT "\n\n.. parsed-literal::\n\n"; 33362306a36Sopenharmony_ciprint OUT $data; 33462306a36Sopenharmony_ciclose OUT; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci__END__ 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci=head1 NAME 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ciparse_headers.pl - parse a C file, in order to identify functions, structs, 34162306a36Sopenharmony_cienums and defines and create cross-references to a Sphinx book. 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci=head1 SYNOPSIS 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ciB<parse_headers.pl> [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>] 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ciWhere <options> can be: --debug, --help or --usage. 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci=head1 OPTIONS 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci=over 8 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci=item B<--debug> 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ciPut the script in verbose mode, useful for debugging. 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci=item B<--usage> 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ciPrints a brief help message and exits. 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci=item B<--help> 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ciPrints a more detailed help message and exits. 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci=back 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci=head1 DESCRIPTION 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ciConvert a C header or source file (C_FILE), into a ReStructured Text 37062306a36Sopenharmony_ciincluded via ..parsed-literal block with cross-references for the 37162306a36Sopenharmony_cidocumentation files that describe the API. It accepts an optional 37262306a36Sopenharmony_ciEXCEPTIONS_FILE with describes what elements will be either ignored or 37362306a36Sopenharmony_cibe pointed to a non-default reference. 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ciThe output is written at the (OUT_FILE). 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ciIt is capable of identifying defines, functions, structs, typedefs, 37862306a36Sopenharmony_cienums and enum symbols and create cross-references for all of them. 37962306a36Sopenharmony_ciIt is also capable of distinguish #define used for specifying a Linux 38062306a36Sopenharmony_ciioctl. 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ciThe EXCEPTIONS_FILE contain two rules to allow ignoring a symbol or 38362306a36Sopenharmony_cito replace the default references by a custom one. 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ciPlease read Documentation/doc-guide/parse-headers.rst at the Kernel's 38662306a36Sopenharmony_citree for more details. 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci=head1 BUGS 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ciReport bugs to Mauro Carvalho Chehab <mchehab@kernel.org> 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci=head1 COPYRIGHT 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ciCopyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ciLicense GPLv2: GNU GPL version 2 <https://gnu.org/licenses/gpl.html>. 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ciThis is free software: you are free to change and redistribute it. 39962306a36Sopenharmony_ciThere is NO WARRANTY, to the extent permitted by law. 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci=cut 402