diff --git a/doc/scripts/kernel-doc b/doc/scripts/kernel-doc index 8bcf90407..8f0f508a7 100755 --- a/doc/scripts/kernel-doc +++ b/doc/scripts/kernel-doc @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 use warnings; use strict; @@ -48,16 +49,12 @@ Read C language source or header FILEs, extract embedded documentation comments, and print formatted documentation to standard output. The documentation comments are identified by "/**" opening comment mark. See -Documentation/kernel-doc-nano-HOWTO.txt for the documentation comment syntax. +Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. Output format selection (mutually exclusive): - -docbook Output DocBook format. - -html Output HTML format. - -html5 Output HTML5 format. - -list Output symbol list format. This is for use by docproc. -man Output troff manual page format. This is the default. -rst Output reStructuredText format. - -text Output plain text format. + -none Do not output documentation, only warnings. Output selection (mutually exclusive): -export Only output documentation for symbols that have been @@ -215,7 +212,7 @@ my $anon_struct_union = 0; my $type_constant = '\b``([^\`]+)``\b'; my $type_constant2 = '\%([-_\w]+)'; my $type_func = '(\w+)\(\)'; -my $type_param = '\@(\w+(\.\.\.)?)'; +my $type_param = '\@(\w*(\.\w+)*(\.\.\.)?)'; my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params my $type_env = '(\$\w+)'; my $type_enum = '\&(enum\s*([_\w]+))'; @@ -224,84 +221,11 @@ my $type_typedef = '\&(typedef\s*([_\w]+))'; my $type_union = '\&(union\s*([_\w]+))'; my $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; my $type_fallback = '\&([_\w]+)'; -my $type_enum_xml = '\&(enum\s*([_\w]+))'; -my $type_struct_xml = '\&(struct\s*([_\w]+))'; -my $type_typedef_xml = '\&(typedef\s*([_\w]+))'; -my $type_union_xml = '\&(union\s*([_\w]+))'; -my $type_member_xml = '\&([_\w]+)(\.|-\>)([_\w]+)'; -my $type_fallback_xml = '\&([_\w]+)'; my $type_member_func = $type_member . '\(\)'; # Output conversion substitutions. # One for each output format -# these work fairly well -my @highlights_html = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum_xml, "\$1"], - [$type_struct_xml, "\$1"], - [$type_typedef_xml, "\$1"], - [$type_union_xml, "\$1"], - [$type_env, "\$1"], - [$type_param, "\$1"], - [$type_member_xml, "\$1\$2\$3"], - [$type_fallback_xml, "\$1"] - ); -my $local_lt = "\\\\\\\\lt:"; -my $local_gt = "\\\\\\\\gt:"; -my $blankline_html = $local_lt . "p" . $local_gt; # was "

" - -# html version 5 -my @highlights_html5 = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum_xml, "\$1"], - [$type_struct_xml, "\$1"], - [$type_typedef_xml, "\$1"], - [$type_union_xml, "\$1"], - [$type_env, "\$1"], - [$type_param, "\$1]"], - [$type_member_xml, "\$1\$2\$3"], - [$type_fallback_xml, "\$1"] - ); -my $blankline_html5 = $local_lt . "br /" . $local_gt; - -# XML, docbook format -my @highlights_xml = ( - ["([^=])\\\"([^\\\"<]+)\\\"", "\$1\$2"], - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_enum_xml, "\$1"], - [$type_struct_xml, "\$1"], - [$type_typedef_xml, "\$1"], - [$type_union_xml, "\$1"], - [$type_param, "\$1"], - [$type_func, "\$1"], - [$type_env, "\$1"], - [$type_member_xml, "\$1\$2\$3"], - [$type_fallback_xml, "\$1"] - ); -my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n"; - -# gnome, docbook format -my @highlights_gnome = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_env, "\$1"], - [$type_param, "\$1" ], - [$type_member, "\$1\$2\$3"], - [$type_fallback, "\$1"] - ); -my $blankline_gnome = "\n"; - # these are pretty rough my @highlights_man = ( [$type_constant, "\$1"], @@ -317,21 +241,6 @@ my @highlights_man = ( ); my $blankline_man = ""; -# text-mode -my @highlights_text = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_param, "\$1"], - [$type_member, "\$1\$2\$3"], - [$type_fallback, "\$1"] - ); -my $blankline_text = ""; - # rst-mode my @highlights_rst = ( [$type_constant, "``\$1``"], @@ -351,21 +260,6 @@ my @highlights_rst = ( ); my $blankline_rst = "\n"; -# list mode -my @highlights_list = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_param, "\$1"], - [$type_member, "\$1"], - [$type_fallback, "\$1"] - ); -my $blankline_list = ""; - # read arguments if ($#ARGV == -1) { usage(); @@ -375,12 +269,12 @@ my $kernelversion; my $dohighlight = ""; my $verbose = 0; -my $output_mode = "man"; +my $output_mode = "rst"; my $output_preformatted = 0; my $no_doc_sections = 0; my $enable_lineno = 0; -my @highlights = @highlights_man; -my $blankline = $blankline_man; +my @highlights = @highlights_rst; +my $blankline = $blankline_rst; my $modulename = "Kernel API"; use constant { @@ -435,13 +329,15 @@ my $lineprefix=""; use constant { STATE_NORMAL => 0, # normal code STATE_NAME => 1, # looking for function name - STATE_FIELD => 2, # scanning field start - STATE_PROTO => 3, # scanning prototype - STATE_DOCBLOCK => 4, # documentation block - STATE_INLINE => 5, # gathering documentation outside main block + STATE_BODY_MAYBE => 2, # body - or maybe more description + STATE_BODY => 3, # the body of the comment + STATE_PROTO => 4, # scanning prototype + STATE_DOCBLOCK => 5, # documentation block + STATE_INLINE => 6, # gathering documentation outside main block }; my $state; my $in_doc_sect; +my $leading_space; # Inline documentation state use constant { @@ -470,7 +366,7 @@ my $doc_sect = $doc_com . my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; -my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; +my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)'; my $doc_inline_end = '^\s*\*/\s*$'; my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; @@ -498,69 +394,51 @@ my $undescribed = "-- undescribed --"; reset_state(); -while ($ARGV[0] =~ m/^-(.*)/) { - my $cmd = shift @ARGV; - if ($cmd eq "-html") { - $output_mode = "html"; - @highlights = @highlights_html; - $blankline = $blankline_html; - } elsif ($cmd eq "-html5") { - $output_mode = "html5"; - @highlights = @highlights_html5; - $blankline = $blankline_html5; - } elsif ($cmd eq "-man") { +while ($ARGV[0] =~ m/^--?(.*)/) { + my $cmd = $1; + shift @ARGV; + if ($cmd eq "man") { $output_mode = "man"; @highlights = @highlights_man; $blankline = $blankline_man; - } elsif ($cmd eq "-text") { - $output_mode = "text"; - @highlights = @highlights_text; - $blankline = $blankline_text; - } elsif ($cmd eq "-rst") { + } elsif ($cmd eq "rst") { $output_mode = "rst"; @highlights = @highlights_rst; $blankline = $blankline_rst; - } elsif ($cmd eq "-docbook") { - $output_mode = "xml"; - @highlights = @highlights_xml; - $blankline = $blankline_xml; - } elsif ($cmd eq "-list") { - $output_mode = "list"; - @highlights = @highlights_list; - $blankline = $blankline_list; - } elsif ($cmd eq "-gnome") { - $output_mode = "gnome"; - @highlights = @highlights_gnome; - $blankline = $blankline_gnome; - } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document + } elsif ($cmd eq "none") { + $output_mode = "none"; + } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document $modulename = shift @ARGV; - } elsif ($cmd eq "-function") { # to only output specific functions + } elsif ($cmd eq "function") { # to only output specific functions $output_selection = OUTPUT_INCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "-nofunction") { # output all except specific functions + } elsif ($cmd eq "nofunction") { # output all except specific functions $output_selection = OUTPUT_EXCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "-export") { # only exported symbols + } elsif ($cmd eq "export") { # only exported symbols $output_selection = OUTPUT_EXPORTED; %function_table = (); - } elsif ($cmd eq "-internal") { # only non-exported symbols + } elsif ($cmd eq "internal") { # only non-exported symbols $output_selection = OUTPUT_INTERNAL; %function_table = (); - } elsif ($cmd eq "-export-file") { + } elsif ($cmd eq "export-file") { my $file = shift @ARGV; push(@export_file_list, $file); - } elsif ($cmd eq "-v") { + } elsif ($cmd eq "v") { $verbose = 1; - } elsif (($cmd eq "-h") || ($cmd eq "--help")) { + } elsif (($cmd eq "h") || ($cmd eq "help")) { usage(); - } elsif ($cmd eq '-no-doc-sections') { + } elsif ($cmd eq 'no-doc-sections') { $no_doc_sections = 1; - } elsif ($cmd eq '-enable-lineno') { + } elsif ($cmd eq 'enable-lineno') { $enable_lineno = 1; - } elsif ($cmd eq '-show-not-found') { + } elsif ($cmd eq 'show-not-found') { $show_not_found = 1; + } else { + # Unknown argument + usage(); } } @@ -667,32 +545,20 @@ sub output_highlight { # confess "output_highlight got called with no args?\n"; # } - if ($output_mode eq "html" || $output_mode eq "html5" || - $output_mode eq "xml") { - $contents = local_unescape($contents); - # convert data read & converted thru xml_escape() into &xyz; format: - $contents =~ s/\\\\\\/\&/g; - } # print STDERR "contents b4:$contents\n"; eval $dohighlight; die $@ if $@; # print STDERR "contents af:$contents\n"; -# strip whitespaces when generating html5 - if ($output_mode eq "html5") { - $contents =~ s/^\s+//; - $contents =~ s/\s+$//; - } foreach $line (split "\n", $contents) { if (! $output_preformatted) { $line =~ s/^\s*//; } if ($line eq ""){ if (! $output_preformatted) { - print $lineprefix, local_unescape($blankline); + print $lineprefix, $blankline; } } else { - $line =~ s/\\\\\\/\&/g; if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { print "\\&$line"; } else { @@ -703,817 +569,6 @@ sub output_highlight { } } -# output sections in html -sub output_section_html(%) { - my %args = %{$_[0]}; - my $section; - - foreach $section (@{$args{'sectionlist'}}) { - print "

$section

\n"; - print "
\n"; - output_highlight($args{'sections'}{$section}); - print "
\n"; - } -} - -# output enum in html -sub output_enum_html(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "

enum " . $args{'enum'} . "

\n"; - - print "enum " . $args{'enum'} . " {
\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print " " . $parameter . ""; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - } - print "
"; - } - print "};
\n"; - - print "

Constants

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
" . $parameter . "\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter}); - } - print "
\n"; - output_section_html(@_); - print "
\n"; -} - -# output typedef in html -sub output_typedef_html(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "

typedef " . $args{'typedef'} . "

\n"; - - print "typedef " . $args{'typedef'} . "\n"; - output_section_html(@_); - print "
\n"; -} - -# output struct in html -sub output_struct_html(%) { - my %args = %{$_[0]}; - my ($parameter); - - print "

" . $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "

\n"; - print "" . $args{'type'} . " " . $args{'struct'} . " {
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print "$parameter
\n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "    $1$parameter) ($2);
\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "    $1 $parameter$2;
\n"; - } else { - print "    $type $parameter;
\n"; - } - } - print "};
\n"; - - print "

Members

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - } - print "
\n"; - output_section_html(@_); - print "
\n"; -} - -# output function in html -sub output_function_html(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - print "

" . $args{'function'} . " - " . $args{'purpose'} . "

\n"; - print "" . $args{'functiontype'} . "\n"; - print "" . $args{'function'} . "\n"; - print "("; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "$1$parameter) ($2)"; - } else { - print "" . $type . " " . $parameter . ""; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - } - } - print ")\n"; - - print "

Arguments

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - } - print "
\n"; - output_section_html(@_); - print "
\n"; -} - -# output DOC: block header in html -sub output_blockhead_html(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - foreach $section (@{$args{'sectionlist'}}) { - print "

$section

\n"; - print "\n"; - } - print "
\n"; -} - -# output sections in html5 -sub output_section_html5(%) { - my %args = %{$_[0]}; - my $section; - - foreach $section (@{$args{'sectionlist'}}) { - print "
\n"; - print "

$section

\n"; - print "

\n"; - output_highlight($args{'sections'}{$section}); - print "

\n"; - print "
\n"; - } -} - -# output enum in html5 -sub output_enum_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - my $html5id; - - $html5id = $args{'enum'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
"; - print "

enum " . $args{'enum'} . "

\n"; - print "
    \n"; - print "
  1. "; - print "enum "; - print "" . $args{'enum'} . " {"; - print "
  2. \n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
  3. "; - print "" . $parameter . ""; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "
  4. \n"; - } - print "
  5. };
  6. \n"; - print "
\n"; - - print "
\n"; - print "

Constants

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
" . $parameter . "
\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter}); - print "
\n"; - } - print "
\n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output typedef in html5 -sub output_typedef_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - my $html5id; - - $html5id = $args{'typedef'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "

typedef " . $args{'typedef'} . "

\n"; - - print "
    \n"; - print "
  1. "; - print "typedef "; - print "" . $args{'typedef'} . ""; - print "
  2. \n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output struct in html5 -sub output_struct_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $html5id; - - $html5id = $args{'struct'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "
\n"; - print "

" . $args{'type'} . " " . $args{'struct'} . "

"; - print "

". $args{'purpose'} . "

\n"; - print "
\n"; - print "
    \n"; - print "
  1. "; - print "" . $args{'type'} . " "; - print "" . $args{'struct'} . " {"; - print "
  2. \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
  3. "; - if ($parameter =~ /^#/) { - print "" . $parameter ."\n"; - print "
  4. \n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "$1 "; - print "$parameter"; - print ") "; - print "($2);"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "$1 "; - print "$parameter"; - print "$2;"; - } else { - print "$type "; - print "$parameter;"; - } - print "\n"; - } - print "
  5. };
  6. \n"; - print "
\n"; - - print "
\n"; - print "

Members

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "
\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print "
\n"; - } - print "
\n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output function in html5 -sub output_function_html5(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $html5id; - - $html5id = $args{'function'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "
\n"; - print "

" . $args{'function'} . "

"; - print "

" . $args{'purpose'} . "

\n"; - print "
\n"; - print "
    \n"; - print "
  1. "; - print "" . $args{'functiontype'} . " "; - print "" . $args{'function'} . " ("; - print "
  2. "; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
  3. "; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "$1 "; - print "$parameter"; - print ") "; - print "($2)"; - } else { - print "$type "; - print "$parameter"; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "
  4. \n"; - } - print "
  5. )
  6. \n"; - print "
\n"; - - print "
\n"; - print "

Arguments

\n"; - print "

\n"; - print "

\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "
\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print "
\n"; - } - print "
\n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output DOC: block header in html5 -sub output_blockhead_html5(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $html5id; - - foreach $section (@{$args{'sectionlist'}}) { - $html5id = $section; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "

$section

\n"; - print "

\n"; - output_highlight($args{'sections'}{$section}); - print "

\n"; - } - print "
\n"; -} - -sub output_section_xml(%) { - my %args = %{$_[0]}; - my $section; - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - print "\n"; - print "$section\n"; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - $output_preformatted = 1; - } else { - print "\n"; - } - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - } else { - print "\n"; - } - print "\n"; - } -} - -# output function in XML DocBook -sub output_function_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = "API-" . $args{'function'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " " . $args{'function'} . "\n"; - print " 9\n"; - print " " . $kernelversion . "\n"; - print "\n"; - print "\n"; - print " " . $args{'function'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " \n"; - print " " . $args{'functiontype'} . " "; - print "" . $args{'function'} . " \n"; - - $count = 0; - if ($#{$args{'parameterlist'}} >= 0) { - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1$parameter)\n"; - print " $2\n"; - } else { - print " " . $type; - print " $parameter\n"; - } - } - } else { - print " \n"; - } - print " \n"; - print "\n"; - - # print parameters - print "\n Arguments\n"; - if ($#{$args{'parameterlist'}} >= 0) { - print " \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - $type = $args{'parametertypes'}{$parameter}; - - print " \n $type $parameter\n"; - print " \n \n"; - $lineprefix=" "; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n \n \n"; - } - print " \n"; - } else { - print " \n None\n \n"; - } - print "\n"; - - output_section_xml(@_); - print "\n\n"; -} - -# output struct in XML DocBook -sub output_struct_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $id; - - $id = "API-struct-" . $args{'struct'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " " . $args{'type'} . " " . $args{'struct'} . "\n"; - print " 9\n"; - print " " . $kernelversion . "\n"; - print "\n"; - print "\n"; - print " " . $args{'type'} . " " . $args{'struct'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " \n"; - print $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - my $prm = $parameter; - # convert data read & converted thru xml_escape() into &xyz; format: - # This allows us to have #define macros interspersed in a struct. - $prm =~ s/\\\\\\/\&/g; - print "$prm\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - defined($args{'parameterdescs'}{$parameter_name}) || next; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print " $1 $parameter$2;\n"; - } else { - print " " . $type . " " . $parameter . ";\n"; - } - } - print "};"; - print " \n"; - print "\n"; - - print " \n"; - print " Members\n"; - - if ($#{$args{'parameterlist'}} >= 0) { - print " \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - defined($args{'parameterdescs'}{$parameter_name}) || next; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - print " "; - print " $type $parameter\n"; - print " \n"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n"; - print " \n"; - } - print " \n"; - } else { - print " \n None\n \n"; - } - print " \n"; - - output_section_xml(@_); - - print "\n\n"; -} - -# output enum in XML DocBook -sub output_enum_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = "API-enum-" . $args{'enum'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " enum " . $args{'enum'} . "\n"; - print " 9\n"; - print " " . $kernelversion . "\n"; - print "\n"; - print "\n"; - print " enum " . $args{'enum'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " \n"; - print "enum " . $args{'enum'} . " {\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print " $parameter"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "\n"; - } - print "};"; - print " \n"; - print "\n"; - - print "\n"; - print " Constants\n"; - print " \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print " "; - print " $parameter\n"; - print " \n"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n"; - print " \n"; - } - print " \n"; - print "\n"; - - output_section_xml(@_); - - print "\n\n"; -} - -# output typedef in XML DocBook -sub output_typedef_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $id; - - $id = "API-typedef-" . $args{'typedef'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " typedef " . $args{'typedef'} . "\n"; - print " 9\n"; - print "\n"; - print "\n"; - print " typedef " . $args{'typedef'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " typedef " . $args{'typedef'} . ";\n"; - print "\n"; - - output_section_xml(@_); - - print "\n\n"; -} - -# output in XML DocBook -sub output_blockhead_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - my $id = $args{'module'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - if (!$args{'content-only'}) { - print "\n $section\n"; - } - if ($section =~ m/EXAMPLE/i) { - print "\n"; - $output_preformatted = 1; - } else { - print "\n"; - } - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - } else { - print ""; - } - if (!$args{'content-only'}) { - print "\n\n"; - } - } - - print "\n\n"; -} - -# output in XML DocBook -sub output_function_gnome { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = $args{'module'} . "-" . $args{'function'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print " " . $args{'function'} . "\n"; - - print " \n"; - print " " . $args{'functiontype'} . " "; - print "" . $args{'function'} . " "; - print "\n"; - - $count = 0; - if ($#{$args{'parameterlist'}} >= 0) { - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter)\n"; - print " $2\n"; - } else { - print " " . $type; - print " $parameter\n"; - } - } - } else { - print " \n"; - } - print " \n"; - if ($#{$args{'parameterlist'}} >= 0) { - print " \n"; - print "\n"; - print "\n"; - print "\n"; - print "\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print " $parameter\n"; - print " \n"; - $lineprefix=" "; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n"; - } - print " \n"; - } else { - print " \n None\n \n"; - } - - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - print "\n $section\n"; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - $output_preformatted = 1; - } else { - } - print "\n"; - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - print "\n"; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - } else { - } - print " \n"; - } - - print "\n\n"; -} - ## # output function in man sub output_function_man(%) { @@ -1617,32 +672,12 @@ sub output_struct_man(%) { print ".SH NAME\n"; print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + $declaration =~ s/\n/"\n.br\n.BI \"/g; print ".SH SYNOPSIS\n"; print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; - - foreach my $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print ".BI \"$parameter\"\n.br\n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print ".BI \" " . $1 . "\" " . $parameter . " \") (" . $2 . ")" . "\"\n;\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print ".BI \" " . $1 . "\ \" " . $parameter . $2 . " \"" . "\"\n;\n"; - } else { - $type =~ s/([^\*])$/$1 /; - print ".BI \" " . $type . "\" " . $parameter . " \"" . "\"\n;\n"; - } - print "\n.br\n"; - } - print "};\n.br\n"; + print ".BI \"$declaration\n};\n.br\n\n"; print ".SH Members\n"; foreach $parameter (@{$args{'parameterlist'}}) { @@ -1691,161 +726,6 @@ sub output_blockhead_man(%) { } } -## -# output in text -sub output_function_text(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $start; - - print "Name:\n\n"; - print $args{'function'} . " - " . $args{'purpose'} . "\n"; - - print "\nSynopsis:\n\n"; - if ($args{'functiontype'} ne "") { - $start = $args{'functiontype'} . " " . $args{'function'} . " ("; - } else { - $start = $args{'function'} . " ("; - } - print $start; - - my $count = 0; - foreach my $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print $1 . $parameter . ") (" . $2; - } else { - print $type . " " . $parameter; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - print " " x length($start); - } else { - print ");\n\n"; - } - } - - print "Arguments:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print $parameter . "\n\t" . $args{'parameterdescs'}{$parameter_name} . "\n"; - } - output_section_text(@_); -} - -#output sections in text -sub output_section_text(%) { - my %args = %{$_[0]}; - my $section; - - print "\n"; - foreach $section (@{$args{'sectionlist'}}) { - print "$section:\n\n"; - output_highlight($args{'sections'}{$section}); - } - print "\n\n"; -} - -# output enum in text -sub output_enum_text(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "Enum:\n\n"; - - print "enum " . $args{'enum'} . " - " . $args{'purpose'} . "\n\n"; - print "enum " . $args{'enum'} . " {\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "\t$parameter"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "\n"; - } - print "};\n\n"; - - print "Constants:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "$parameter\n\t"; - print $args{'parameterdescs'}{$parameter} . "\n"; - } - - output_section_text(@_); -} - -# output typedef in text -sub output_typedef_text(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "Typedef:\n\n"; - - print "typedef " . $args{'typedef'} . " - " . $args{'purpose'} . "\n"; - output_section_text(@_); -} - -# output struct as text -sub output_struct_text(%) { - my %args = %{$_[0]}; - my ($parameter); - - print $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "\n\n"; - print $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print "$parameter\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "\t$1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "\t$1 $parameter$2;\n"; - } else { - print "\t" . $type . " " . $parameter . ";\n"; - } - } - print "};\n\n"; - - print "Members:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "$parameter\n\t"; - print $args{'parameterdescs'}{$parameter_name} . "\n"; - } - print "\n"; - output_section_text(@_); -} - -sub output_blockhead_text(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - - foreach $section (@{$args{'sectionlist'}}) { - print " $section:\n"; - print " -> "; - output_highlight($args{'sections'}{$section}); - } -} - ## # output in restructured text # @@ -1869,17 +749,73 @@ sub output_blockhead_rst(%) { } } -sub output_highlight_rst { - my $contents = join "\n",@_; - my $line; - - # undo the evil effects of xml_escape() earlier - $contents = xml_unescape($contents); - +# +# Apply the RST highlights to a sub-block of text. +# +sub highlight_block($) { + # The dohighlight kludge requires the text be called $contents + my $contents = shift; eval $dohighlight; die $@ if $@; + return $contents; +} - foreach $line (split "\n", $contents) { +# +# Regexes used only here. +# +my $sphinx_literal = '^[^.].*::$'; +my $sphinx_cblock = '^\.\.\ +code-block::'; + +sub output_highlight_rst { + my $input = join "\n",@_; + my $output = ""; + my $line; + my $in_literal = 0; + my $litprefix; + my $block = ""; + + foreach $line (split "\n",$input) { + # + # If we're in a literal block, see if we should drop out + # of it. Otherwise pass the line straight through unmunged. + # + if ($in_literal) { + if (! ($line =~ /^\s*$/)) { + # + # If this is the first non-blank line in a literal + # block we need to figure out what the proper indent is. + # + if ($litprefix eq "") { + $line =~ /^(\s*)/; + $litprefix = '^' . $1; + $output .= $line . "\n"; + } elsif (! ($line =~ /$litprefix/)) { + $in_literal = 0; + } else { + $output .= $line . "\n"; + } + } else { + $output .= $line . "\n"; + } + } + # + # Not in a literal block (or just dropped out) + # + if (! $in_literal) { + $block .= $line . "\n"; + if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { + $in_literal = 1; + $litprefix = ""; + $output .= highlight_block($block); + $block = "" + } + } + } + + if ($block) { + $output .= highlight_block($block); + } + foreach $line (split "\n", $output) { print $lineprefix . $line . "\n"; } } @@ -2035,29 +971,9 @@ sub output_struct_rst(%) { print "**Definition**\n\n"; print "::\n\n"; - print " " . $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print " " . "$parameter\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print " $1 $parameter$2;\n"; - } else { - print " " . $type . " " . $parameter . ";\n"; - } - } - print " };\n\n"; + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + print " " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration };\n\n"; print "**Members**\n\n"; $lineprefix = " "; @@ -2080,41 +996,21 @@ sub output_struct_rst(%) { output_section_rst(@_); } +## none mode output functions -## list mode output functions - -sub output_function_list(%) { - my %args = %{$_[0]}; - - print $args{'function'} . "\n"; +sub output_function_none(%) { } -# output enum in list -sub output_enum_list(%) { - my %args = %{$_[0]}; - print $args{'enum'} . "\n"; +sub output_enum_none(%) { } -# output typedef in list -sub output_typedef_list(%) { - my %args = %{$_[0]}; - print $args{'typedef'} . "\n"; +sub output_typedef_none(%) { } -# output struct as list -sub output_struct_list(%) { - my %args = %{$_[0]}; - - print $args{'struct'} . "\n"; +sub output_struct_none(%) { } -sub output_blockhead_list(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - - foreach $section (@{$args{'sectionlist'}}) { - print "DOC: $section\n"; - } +sub output_blockhead_none(%) { } ## @@ -2165,39 +1061,128 @@ sub dump_union($$) { sub dump_struct($$) { my $x = shift; my $file = shift; - my $nested; - if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) { - #my $decl_type = $1; + if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}/) { + my $decl_type = $1; $declaration_name = $2; my $members = $3; - # ignore embedded structs or unions - $members =~ s/({.*})//g; - $nested = $1; - # ignore members marked private: $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; $members =~ s/\/\*\s*private:.*//gosi; # strip comments: $members =~ s/\/\*.*?\*\///gos; - $nested =~ s/\/\*.*?\*\///gos; # strip attributes $members =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; $members =~ s/__aligned\s*\([^;]*\)//gos; $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos; # replace DECLARE_BITMAP - $members =~ s/DECLARE_BITMAP\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; + $members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; # replace DECLARE_HASHTABLE - $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; + $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; + # replace DECLARE_KFIFO + $members =~ s/DECLARE_KFIFO\s*\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; + # replace DECLARE_KFIFO_PTR + $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; - create_parameterlist($members, ';', $file); - check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested); + my $declaration = $members; + # Split nested struct/union elements as newer ones + while ($members =~ m/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/) { + my $newmember; + my $maintype = $1; + my $ids = $4; + my $content = $3; + foreach my $id(split /,/, $ids) { + $newmember .= "$maintype $id; "; + + $id =~ s/[:\[].*//; + $id =~ s/^\s*\**(\S+)\s*/$1/; + foreach my $arg (split /;/, $content) { + next if ($arg =~ m/^\s*$/); + if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { + # pointer-to-function + my $type = $1; + my $name = $2; + my $extra = $3; + next if (!$name); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type$name$extra; "; + } else { + $newmember .= "$type$id.$name$extra; "; + } + } else { + my $type; + my $names; + $arg =~ s/^\s+//; + $arg =~ s/\s+$//; + # Handle bitmaps + $arg =~ s/:\s*\d+\s*//g; + # Handle arrays + $arg =~ s/\[.*\]//g; + # The type may have multiple words, + # and multiple IDs can be defined, like: + # const struct foo, *bar, foobar + # So, we remove spaces when parsing the + # names, in order to match just names + # and commas for the names + $arg =~ s/\s*,\s*/,/g; + if ($arg =~ m/(.*)\s+([\S+,]+)/) { + $type = $1; + $names = $2; + } else { + $newmember .= "$arg; "; + next; + } + foreach my $name (split /,/, $names) { + $name =~ s/^\s*\**(\S+)\s*/$1/; + next if (($name =~ m/^\s*$/)); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type $name; "; + } else { + $newmember .= "$type $id.$name; "; + } + } + } + } + } + $members =~ s/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/$newmember/; + } + + # Ignore other nested elements, like enums + $members =~ s/(\{[^\{\}]*\})//g; + + create_parameterlist($members, ';', $file, $declaration_name); + check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); + + # Adjust declaration for better display + $declaration =~ s/([\{;])/$1\n/g; + $declaration =~ s/\}\s+;/};/g; + # Better handle inlined enums + do {} while ($declaration =~ s/(enum\s+\{[^\}]+),([^\n])/$1,\n$2/); + + my @def_args = split /\n/, $declaration; + my $level = 1; + $declaration = ""; + foreach my $clause (@def_args) { + $clause =~ s/^\s+//; + $clause =~ s/\s+$//; + $clause =~ s/\s+/ /; + next if (!$clause); + $level-- if ($clause =~ m/(\})/ && $level > 1); + if (!($clause =~ m/^\s*#/)) { + $declaration .= "\t" x $level; + } + $declaration .= "\t" . $clause . "\n"; + $level++ if ($clause =~ m/(\{)/ && !($clause =~m/\}/)); + } output_declaration($declaration_name, 'struct', {'struct' => $declaration_name, 'module' => $modulename, + 'definition' => $declaration, 'parameterlist' => \@parameterlist, 'parameterdescs' => \%parameterdescs, 'parametertypes' => \%parametertypes, @@ -2213,6 +1198,44 @@ sub dump_struct($$) { } } + +sub show_warnings($$) { + my $functype = shift; + my $name = shift; + + return 1 if ($output_selection == OUTPUT_ALL); + + if ($output_selection == OUTPUT_EXPORTED) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INTERNAL) { + if (!($functype eq "function" && defined($function_table{$name}))) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INCLUDE) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_EXCLUDE) { + if (!defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + die("Please add the new output type at show_warnings()"); +} + sub dump_enum($$) { my $x = shift; my $file = shift; @@ -2221,9 +1244,11 @@ sub dump_enum($$) { # strip #define macros inside enums $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; - if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { + if ($x =~ /enum\s+(\w+)\s*\{(.*)\}/) { $declaration_name = $1; my $members = $2; + my %_members; + $members =~ s/\s+$//; foreach my $arg (split ',', $members) { @@ -2231,12 +1256,21 @@ sub dump_enum($$) { push @parameterlist, $arg; if (!$parameterdescs{$arg}) { $parameterdescs{$arg} = $undescribed; - print STDERR "${file}:$.: warning: Enum value '$arg' ". - "not described in enum '$declaration_name'\n"; + if (show_warnings("enum", $declaration_name)) { + print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; + } } - + $_members{$arg} = 1; } + while (my ($k, $v) = each %parameterdescs) { + if (!exists($_members{$k})) { + if (show_warnings("enum", $declaration_name)) { + print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; + } + } + } + output_declaration($declaration_name, 'enum', {'enum' => $declaration_name, @@ -2269,7 +1303,7 @@ sub dump_typedef($$) { $declaration_name = $2; my $args = $3; - create_parameterlist($args, ',', $file); + create_parameterlist($args, ',', $file, $declaration_name); output_declaration($declaration_name, 'function', @@ -2318,10 +1352,11 @@ sub save_struct_actual($) { $struct_actual = $struct_actual . $actual . " "; } -sub create_parameterlist($$$) { +sub create_parameterlist($$$$) { my $args = shift; my $splitter = shift; my $file = shift; + my $declaration_name = shift; my $type; my $param; @@ -2346,12 +1381,12 @@ sub create_parameterlist($$$) { } elsif ($arg =~ m/\(.+\)\s*\(/) { # pointer-to-function $arg =~ tr/#/,/; - $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/; + $arg =~ m/[^\(]+\(\*?\s*([\w\.]*)\s*\)/; $param = $1; $type = $arg; $type =~ s/([^\(]+\(\*?)\s*$param/$1/; save_struct_actual($param); - push_parameter($param, $type, $file); + push_parameter($param, $type, $file, $declaration_name); } elsif ($arg) { $arg =~ s/\s*:\s*/:/g; $arg =~ s/\s*\[/\[/g; @@ -2376,27 +1411,28 @@ sub create_parameterlist($$$) { foreach $param (@args) { if ($param =~ m/^(\*+)\s*(.*)/) { save_struct_actual($2); - push_parameter($2, "$type $1", $file); + push_parameter($2, "$type $1", $file, $declaration_name); } elsif ($param =~ m/(.*?):(\d+)/) { if ($type ne "") { # skip unnamed bit-fields save_struct_actual($1); - push_parameter($1, "$type:$2", $file) + push_parameter($1, "$type:$2", $file, $declaration_name) } } else { save_struct_actual($param); - push_parameter($param, $type, $file); + push_parameter($param, $type, $file, $declaration_name); } } } } } -sub push_parameter($$$) { +sub push_parameter($$$$) { my $param = shift; my $type = shift; my $file = shift; + my $declaration_name = shift; if (($anon_struct_union == 1) && ($type eq "") && ($param eq "}")) { @@ -2433,24 +1469,16 @@ sub push_parameter($$$) { # warn if parameter has no description # (but ignore ones starting with # as these are not parameters # but inline preprocessor statements); - # also ignore unnamed structs/unions; - if (!$anon_struct_union) { + # Note: It will also ignore void params and unnamed structs/unions if (!defined $parameterdescs{$param} && $param !~ /^#/) { + $parameterdescs{$param} = $undescribed; - $parameterdescs{$param} = $undescribed; - - if (($type eq 'function') || ($type eq 'enum')) { - print STDERR "${file}:$.: warning: Function parameter ". - "or member '$param' not " . - "described in '$declaration_name'\n"; - } - print STDERR "${file}:$.: warning:" . - " No description found for parameter '$param'\n"; - ++$warnings; + if (show_warnings($type, $declaration_name)) { + print STDERR + "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; + ++$warnings; + } } - } - - $param = xml_escape($param); # strip spaces from $param so that it is one continuous string # on @parameterlist; @@ -2466,8 +1494,8 @@ sub push_parameter($$$) { $parametertypes{$param} = $type; } -sub check_sections($$$$$$) { - my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_; +sub check_sections($$$$$) { + my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_; my @sects = split ' ', $sectcheck; my @prms = split ' ', $prmscheck; my $err; @@ -2501,14 +1529,6 @@ sub check_sections($$$$$$) { "'$sects[$sx]' " . "description in '$decl_name'\n"; ++$warnings; - } else { - if ($nested !~ m/\Q$sects[$sx]\E/) { - print STDERR "${file}:$.: warning: " . - "Excess struct/union/enum/typedef member " . - "'$sects[$sx]' " . - "description in '$decl_name'\n"; - ++$warnings; - } } } } @@ -2558,6 +1578,7 @@ sub dump_function($$) { $prototype =~ s/__meminit +//; $prototype =~ s/__must_check +//; $prototype =~ s/__weak +//; + $prototype =~ s/__sched +//; my $define = $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\( (?: @@ -2612,14 +1633,14 @@ sub dump_function($$) { $declaration_name = $2; my $args = $3; - create_parameterlist($args, ',', $file); + create_parameterlist($args, ',', $file, $declaration_name); } else { print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; return; } my $prms = join " ", @parameterlist; - check_sections($file, $declaration_name, "function", $sectcheck, $prms, ""); + check_sections($file, $declaration_name, "function", $sectcheck, $prms); # This check emits a lot of warnings at the moment, because many # functions don't have a 'Return' doc section. So until the number @@ -2688,7 +1709,7 @@ sub tracepoint_munge($) { sub syscall_munge() { my $void = 0; - $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's ## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { if ($prototype =~ m/SYSCALL_DEFINE0/) { $void = 1; @@ -2764,7 +1785,7 @@ sub process_proto_type($$) { } while (1) { - if ( $x =~ /([^{};]*)([{};])(.*)/ ) { + if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ ) { if( length $prototype ) { $prototype .= " " } @@ -2784,47 +1805,6 @@ sub process_proto_type($$) { } } -# xml_escape: replace <, >, and & in the text stream; -# -# however, formatting controls that are generated internally/locally in the -# kernel-doc script are not escaped here; instead, they begin life like -# $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings -# are converted to their mnemonic-expected output, without the 4 * '\' & ':', -# just before actual output; (this is done by local_unescape()) -sub xml_escape($) { - my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { - return $text; - } - $text =~ s/\&/\\\\\\amp;/g; - $text =~ s/\/\\\\\\gt;/g; - return $text; -} - -# xml_unescape: reverse the effects of xml_escape -sub xml_unescape($) { - my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { - return $text; - } - $text =~ s/\\\\\\amp;/\&/g; - $text =~ s/\\\\\\lt;//g; - return $text; -} - -# convert local escape strings to html -# local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) -sub local_unescape($) { - my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { - return $text; - } - $text =~ s/\\\\\\\\lt://g; - return $text; -} sub map_filename($) { my $file; @@ -2862,15 +1842,291 @@ sub process_export_file($) { close(IN); } +# +# Parsers for the various processing states. +# +# STATE_NORMAL: looking for the /** to begin everything. +# +sub process_normal() { + if (/$doc_start/o) { + $state = STATE_NAME; # next line is always the function name + $in_doc_sect = 0; + $declaration_start_line = $. + 1; + } +} + +# +# STATE_NAME: Looking for the "name - description" line +# +sub process_name($$) { + my $file = shift; + my $identifier; + my $descr; + + if (/$doc_block/o) { + $state = STATE_DOCBLOCK; + $contents = ""; + $new_start_line = $. + 1; + + if ( $1 eq "" ) { + $section = $section_intro; + } else { + $section = $1; + } + } + elsif (/$doc_decl/o) { + $identifier = $1; + if (/\s*([\w\s]+?)(\(\))?\s*-/) { + $identifier = $1; + } + + $state = STATE_BODY; + # if there's no @param blocks need to set up default section + # here + $contents = ""; + $section = $section_default; + $new_start_line = $. + 1; + if (/-(.*)/) { + # strip leading/trailing/multiple spaces + $descr= $1; + $descr =~ s/^\s*//; + $descr =~ s/\s*$//; + $descr =~ s/\s+/ /g; + $declaration_purpose = $descr; + $state = STATE_BODY_MAYBE; + } else { + $declaration_purpose = ""; + } + + if (($declaration_purpose eq "") && $verbose) { + print STDERR "${file}:$.: warning: missing initial short description on line:\n"; + print STDERR $_; + ++$warnings; + } + + if ($identifier =~ m/^struct/) { + $decl_type = 'struct'; + } elsif ($identifier =~ m/^union/) { + $decl_type = 'union'; + } elsif ($identifier =~ m/^enum/) { + $decl_type = 'enum'; + } elsif ($identifier =~ m/^typedef/) { + $decl_type = 'typedef'; + } else { + $decl_type = 'function'; + } + + if ($verbose) { + print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; + } + } else { + print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", + " - I thought it was a doc line\n"; + ++$warnings; + $state = STATE_NORMAL; + } +} + + +# +# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. +# +sub process_body($$) { + my $file = shift; + + if (/$doc_sect/i) { # case insensitive for supported section names + $newsection = $1; + $newcontents = $2; + + # map the supported section names to the canonical names + if ($newsection =~ m/^description$/i) { + $newsection = $section_default; + } elsif ($newsection =~ m/^context$/i) { + $newsection = $section_context; + } elsif ($newsection =~ m/^returns?$/i) { + $newsection = $section_return; + } elsif ($newsection =~ m/^\@return$/) { + # special: @return is a section, not a param description + $newsection = $section_return; + } + + if (($contents ne "") && ($contents ne "\n")) { + if (!$in_doc_sect && $verbose) { + print STDERR "${file}:$.: warning: contents before sections\n"; + ++$warnings; + } + dump_section($file, $section, $contents); + $section = $section_default; + } + + $in_doc_sect = 1; + $state = STATE_BODY; + $contents = $newcontents; + $new_start_line = $.; + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + if ($contents ne "") { + $contents .= "\n"; + } + $section = $newsection; + $leading_space = undef; + } elsif (/$doc_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + # look for doc_com + + doc_end: + if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { + print STDERR "${file}:$.: warning: suspicious ending line: $_"; + ++$warnings; + } + + $prototype = ""; + $state = STATE_PROTO; + $brcount = 0; + } elsif (/$doc_content/) { + # miguel-style comment kludge, look for blank lines after + # @parameter line to signify start of description + if ($1 eq "") { + if ($section =~ m/^@/ || $section eq $section_context) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $new_start_line = $.; + } else { + $contents .= "\n"; + } + $state = STATE_BODY; + } elsif ($state == STATE_BODY_MAYBE) { + # Continued declaration purpose + chomp($declaration_purpose); + $declaration_purpose .= " " . $1; + $declaration_purpose =~ s/\s+/ /g; + } else { + my $cont = $1; + if ($section =~ m/^@/ || $section eq $section_context) { + if (!defined $leading_space) { + if ($cont =~ m/^(\s+)/) { + $leading_space = $1; + } else { + $leading_space = ""; + } + } + $cont =~ s/^$leading_space//; + } + $contents .= $cont . "\n"; + } + } else { + # i dont know - bad line? ignore. + print STDERR "${file}:$.: warning: bad line: $_"; + ++$warnings; + } +} + + +# +# STATE_PROTO: reading a function/whatever prototype. +# +sub process_proto($$) { + my $file = shift; + + if (/$doc_inline_oneline/) { + $section = $1; + $contents = $2; + if ($contents ne "") { + $contents .= "\n"; + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + } elsif (/$doc_inline_start/) { + $state = STATE_INLINE; + $inline_doc_state = STATE_INLINE_NAME; + } elsif ($decl_type eq 'function') { + process_proto_function($_, $file); + } else { + process_proto_type($_, $file); + } +} + +# +# STATE_DOCBLOCK: within a DOC: block. +# +sub process_docblock($$) { + my $file = shift; + + if (/$doc_end/) { + dump_doc_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $function = ""; + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + $state = STATE_NORMAL; + } elsif (/$doc_content/) { + if ( $1 eq "" ) { + $contents .= $blankline; + } else { + $contents .= $1 . "\n"; + } + } +} + +# +# STATE_INLINE: docbook comments within a prototype. +# +sub process_inline($$) { + my $file = shift; + + # First line (state 1) needs to be a @parameter + if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { + $section = $1; + $contents = $2; + $new_start_line = $.; + if ($contents ne "") { + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + $contents .= "\n"; + } + $inline_doc_state = STATE_INLINE_TEXT; + # Documentation block end */ + } elsif (/$doc_inline_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + $state = STATE_PROTO; + $inline_doc_state = STATE_INLINE_NA; + # Regular text + } elsif (/$doc_content/) { + if ($inline_doc_state == STATE_INLINE_TEXT) { + $contents .= $1 . "\n"; + # nuke leading blank lines + if ($contents =~ /^\s*$/) { + $contents = ""; + } + } elsif ($inline_doc_state == STATE_INLINE_NAME) { + $inline_doc_state = STATE_INLINE_ERROR; + print STDERR "${file}:$.: warning: "; + print STDERR "Incorrect use of kernel-doc format: $_"; + ++$warnings; + } + } +} + + sub process_file($) { my $file; - my $identifier; - my $func; - my $descr; - my $in_purpose = 0; my $initial_section_counter = $section_counter; my ($orig_file) = @_; - my $leading_space; $file = map_filename($orig_file); @@ -2887,285 +2143,32 @@ sub process_file($) { while (s/\\\s*$//) { $_ .= ; } + # Replace tabs by spaces + while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; + # Hand this line to the appropriate state handler if ($state == STATE_NORMAL) { - if (/$doc_start/o) { - $state = STATE_NAME; # next line is always the function name - $in_doc_sect = 0; - $declaration_start_line = $. + 1; - } - } elsif ($state == STATE_NAME) {# this line is the function name (always) - if (/$doc_block/o) { - $state = STATE_DOCBLOCK; - $contents = ""; - $new_start_line = $. + 1; - - if ( $1 eq "" ) { - $section = $section_intro; - } else { - $section = $1; - } - } - elsif (/$doc_decl/o) { - $identifier = $1; - if (/\s*([\w\s]+?)\s*-/) { - $identifier = $1; - } - - $state = STATE_FIELD; - # if there's no @param blocks need to set up default section - # here - $contents = ""; - $section = $section_default; - $new_start_line = $. + 1; - if (/-(.*)/) { - # strip leading/trailing/multiple spaces - $descr= $1; - $descr =~ s/^\s*//; - $descr =~ s/\s*$//; - $descr =~ s/\s+/ /g; - $declaration_purpose = xml_escape($descr); - $in_purpose = 1; - } else { - $declaration_purpose = ""; - } - - if (($declaration_purpose eq "") && $verbose) { - print STDERR "${file}:$.: warning: missing initial short description on line:\n"; - print STDERR $_; - ++$warnings; - } - - if ($identifier =~ m/^struct/) { - $decl_type = 'struct'; - } elsif ($identifier =~ m/^union/) { - $decl_type = 'union'; - } elsif ($identifier =~ m/^enum/) { - $decl_type = 'enum'; - } elsif ($identifier =~ m/^typedef/) { - $decl_type = 'typedef'; - } else { - $decl_type = 'function'; - } - - if ($verbose) { - print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; - } - } else { - print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", - " - I thought it was a doc line\n"; - ++$warnings; - $state = STATE_NORMAL; - } - } elsif ($state == STATE_FIELD) { # look for head: lines, and include content - if (/$doc_sect/i) { # case insensitive for supported section names - $newsection = $1; - $newcontents = $2; - - # map the supported section names to the canonical names - if ($newsection =~ m/^description$/i) { - $newsection = $section_default; - } elsif ($newsection =~ m/^context$/i) { - $newsection = $section_context; - } elsif ($newsection =~ m/^returns?$/i) { - $newsection = $section_return; - } elsif ($newsection =~ m/^\@return$/) { - # special: @return is a section, not a param description - $newsection = $section_return; - } - - if (($contents ne "") && ($contents ne "\n")) { - if (!$in_doc_sect && $verbose) { - print STDERR "${file}:$.: warning: contents before sections\n"; - ++$warnings; - } - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - } - - $in_doc_sect = 1; - $in_purpose = 0; - $contents = $newcontents; - $new_start_line = $.; - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { - $contents = substr($contents, 1); - } - if ($contents ne "") { - $contents .= "\n"; - } - $section = $newsection; - $leading_space = undef; - } elsif (/$doc_end/) { - if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - } - # look for doc_com + + doc_end: - if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { - print STDERR "${file}:$.: warning: suspicious ending line: $_"; - ++$warnings; - } - - $prototype = ""; - $state = STATE_PROTO; - $brcount = 0; -# print STDERR "end of doc comment, looking for prototype\n"; - } elsif (/$doc_content/) { - # miguel-style comment kludge, look for blank lines after - # @parameter line to signify start of description - if ($1 eq "") { - if ($section =~ m/^@/ || $section eq $section_context) { - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - $new_start_line = $.; - } else { - $contents .= "\n"; - } - $in_purpose = 0; - } elsif ($in_purpose == 1) { - # Continued declaration purpose - chomp($declaration_purpose); - $declaration_purpose .= " " . xml_escape($1); - $declaration_purpose =~ s/\s+/ /g; - } else { - my $cont = $1; - if ($section =~ m/^@/ || $section eq $section_context) { - if (!defined $leading_space) { - if ($cont =~ m/^(\s+)/) { - $leading_space = $1; - } else { - $leading_space = ""; - } - } - - $cont =~ s/^$leading_space//; - } - $contents .= $cont . "\n"; - } - } else { - # i dont know - bad line? ignore. - print STDERR "${file}:$.: warning: bad line: $_"; - ++$warnings; - } + process_normal(); + } elsif ($state == STATE_NAME) { + process_name($file, $_); + } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { + process_body($file, $_); } elsif ($state == STATE_INLINE) { # scanning for inline parameters - # First line (state 1) needs to be a @parameter - if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { - $section = $1; - $contents = $2; - $new_start_line = $.; - if ($contents ne "") { - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { - $contents = substr($contents, 1); - } - $contents .= "\n"; - } - $inline_doc_state = STATE_INLINE_TEXT; - # Documentation block end */ - } elsif (/$doc_inline_end/) { - if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - } - $state = STATE_PROTO; - $inline_doc_state = STATE_INLINE_NA; - # Regular text - } elsif (/$doc_content/) { - if ($inline_doc_state == STATE_INLINE_TEXT) { - $contents .= $1 . "\n"; - # nuke leading blank lines - if ($contents =~ /^\s*$/) { - $contents = ""; - } - } elsif ($inline_doc_state == STATE_INLINE_NAME) { - $inline_doc_state = STATE_INLINE_ERROR; - print STDERR "${file}:$.: warning: "; - print STDERR "Incorrect use of kernel-doc format: $_"; - ++$warnings; - } - } - } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) - if (/$doc_inline_oneline/) { - $section = $1; - $contents = $2; - if ($contents ne "") { - $contents .= "\n"; - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - } - } elsif (/$doc_inline_start/) { - $state = STATE_INLINE; - $inline_doc_state = STATE_INLINE_NAME; - } elsif ($decl_type eq 'function') { - process_proto_function($_, $file); - } else { - process_proto_type($_, $file); - } + process_inline($file, $_); + } elsif ($state == STATE_PROTO) { + process_proto($file, $_); } elsif ($state == STATE_DOCBLOCK) { - if (/$doc_end/) - { - dump_doc_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - $function = ""; - %parameterdescs = (); - %parametertypes = (); - @parameterlist = (); - %sections = (); - @sectionlist = (); - $prototype = ""; - $state = STATE_NORMAL; - } - elsif (/$doc_content/) - { - if ( $1 eq "" ) - { - $contents .= $blankline; - } - else - { - $contents .= $1 . "\n"; - } - } + process_docblock($file, $_); } } + + # Make sure we got something interesting. if ($initial_section_counter == $section_counter) { - print STDERR "${file}:1: warning: no structured comments found\n"; + if ($output_mode ne "none") { + print STDERR "${file}:1: warning: no structured comments found\n"; + } if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) { print STDERR " Was looking for '$_'.\n" for keys %function_table; } - if ($output_mode eq "xml") { - # The template wants at least one RefEntry here; make one. - print "\n"; - print " \n"; - print " \n"; - print " ${orig_file}\n"; - print " \n"; - print " \n"; - print " Document generation inconsistency\n"; - print " \n"; - print " \n"; - print " \n"; - print " \n"; - print " Oops\n"; - print " \n"; - print " \n"; - print " \n"; - print " The template for this document tried to insert\n"; - print " the structured comment from the file\n"; - print " ${orig_file} at this point,\n"; - print " but none was found.\n"; - print " This dummy section is inserted to allow\n"; - print " generation to continue.\n"; - print " \n"; - print " \n"; - print " \n"; - print "\n"; - } } }