## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
## Copyright (C) 2001 Simon Huggins ##
-## Copyright (C) 2005-2007 Randy Dunlap ##
+## Copyright (C) 2005-2008 Randy Dunlap ##
## ##
## #define enhancements by Armin Kuster <akuster@mvista.com> ##
## Copyright (c) 2000 MontaVista Software, Inc. ##
# Note: This only supports 'c'.
# usage:
-# kernel-doc [ -docbook | -html | -text | -man ]
+# kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ]
# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
# or
# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
#
# Set output format using one of -docbook -html -text or -man. Default is man.
#
+# -no-doc-sections
+# Do not output DOC: sections
+#
# -function funcname
-# If set, then only generate documentation for the given function(s). All
-# other functions are ignored.
+# If set, then only generate documentation for the given function(s) or
+# DOC: section titles. All other functions and DOC: sections are ignored.
#
# -nofunction funcname
-# If set, then only generate documentation for the other function(s).
-# Cannot be used together with -function
-# (yes, that's a bug -- perl hackers can fix it 8))
+# If set, then only generate documentation for the other function(s)/DOC:
+# sections. Cannot be used together with -function (yes, that's a bug --
+# perl hackers can fix it 8))
#
# c files - list of 'c' files to process
#
sub usage {
- print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
+ print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ] [ -no-doc-sections ]\n";
print " [ -function funcname [ -function funcname ...] ]\n";
print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
print " c source file(s) > outputfile\n";
+ print " -v : verbose output, more warnings & other info listed\n";
exit 1;
}
my $verbose = 0;
my $output_mode = "man";
+my $no_doc_sections = 0;
my %highlights = %highlights_man;
my $blankline = $blankline_man;
my $modulename = "Kernel API";
my ($type,$declaration_name,$return_type);
my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
+if (defined($ENV{'KBUILD_VERBOSE'})) {
+ $verbose = "$ENV{'KBUILD_VERBOSE'}";
+}
+
# Generated docbook code is inserted in a template at a point where
# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
usage();
} elsif ($cmd eq '-filelist') {
$filelist = shift @ARGV;
+ } elsif ($cmd eq '-no-doc-sections') {
+ $no_doc_sections = 1;
}
}
# dumps section contents to arrays/hashes intended for that purpose.
#
sub dump_section {
+ my $file = shift;
my $name = shift;
my $contents = join "\n", @_;
$parameterdescs{$name} = $contents;
} else {
# print STDERR "other section '$name' = '$contents'\n";
+ if (defined($sections{$name}) && ($sections{$name} ne "")) {
+ print STDERR "Error(${file}:$.): duplicate section name '$name'\n";
+ ++$errors;
+ }
$sections{$name} = $contents;
push @sectionlist, $name;
}
}
##
+# dump DOC: section after checking that it should go out
+#
+sub dump_doc_section {
+ my $file = shift;
+ my $name = shift;
+ my $contents = join "\n", @_;
+
+ if ($no_doc_sections) {
+ return;
+ }
+
+ if (($function_only == 0) ||
+ ( $function_only == 1 && defined($function_table{$name})) ||
+ ( $function_only == 2 && !defined($function_table{$name})))
+ {
+ dump_section($file, $name, $contents);
+ output_blockhead({'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'module' => $modulename,
+ 'content-only' => ($function_only != 0), });
+ }
+}
+
+##
# output function
#
# parameterdescs, a hash.
print "<hr>\n";
}
-# output intro in html
-sub output_intro_html(%) {
+# output DOC: block header in html
+sub output_blockhead_html(%) {
my %args = %{$_[0]};
my ($parameter, $section);
my $count;
print " <refsect1>\n";
print " <title>Members</title>\n";
+ if ($#{$args{'parameterlist'}} >= 0) {
print " <variablelist>\n";
foreach $parameter (@{$args{'parameterlist'}}) {
($parameter =~ /^#/) && next;
print " </varlistentry>\n";
}
print " </variablelist>\n";
+ } else {
+ print " <para>\n None\n </para>\n";
+ }
print " </refsect1>\n";
output_section_xml(@_);
}
# output in XML DocBook
-sub output_intro_xml(%) {
+sub output_blockhead_xml(%) {
my %args = %{$_[0]};
my ($parameter, $section);
my $count;
# print out each section
$lineprefix=" ";
foreach $section (@{$args{'sectionlist'}}) {
- print "<refsect1>\n <title>$section</title>\n <para>\n";
+ if (!$args{'content-only'}) {
+ print "<refsect1>\n <title>$section</title>\n";
+ }
if ($section =~ m/EXAMPLE/i) {
print "<example><para>\n";
+ } else {
+ print "<para>\n";
}
output_highlight($args{'sections'}{$section});
if ($section =~ m/EXAMPLE/i) {
print "</para></example>\n";
+ } else {
+ print "</para>";
+ }
+ if (!$args{'content-only'}) {
+ print "\n</refsect1>\n";
}
- print " </para>\n</refsect1>\n";
}
print "\n\n";
}
}
-sub output_intro_man(%) {
+sub output_blockhead_man(%) {
my %args = %{$_[0]};
my ($parameter, $section);
my $count;
output_section_text(@_);
}
-sub output_intro_text(%) {
+sub output_blockhead_text(%) {
my %args = %{$_[0]};
my ($parameter, $section);
##
# generic output function - calls the right one based on current output mode.
-sub output_intro {
+sub output_blockhead {
no strict 'refs';
- my $func = "output_intro_".$output_mode;
+ my $func = "output_blockhead_".$output_mode;
&$func(@_);
$section_counter++;
}
my $members = $3;
# ignore embedded structs or unions
- $members =~ s/{.*?}//g;
+ $members =~ s/{.*}//g;
# ignore members marked private:
$members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
# corresponding data structures "correctly". Catch it later in
# output_* subs.
push_parameter($arg, "", $file);
- } elsif ($arg =~ m/\(.*\*/) {
+ } elsif ($arg =~ m/\(.+\)\s*\(/) {
# pointer-to-function
$arg =~ tr/#/,/;
- $arg =~ m/[^\(]+\(\*\s*([^\)]+)\)/;
+ $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/;
$param = $1;
$type = $arg;
- $type =~ s/([^\(]+\(\*)$param/$1/;
+ $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
push_parameter($param, $type, $file);
} elsif ($arg) {
$arg =~ s/\s*:\s*/:/g;
push_parameter($2, "$type $1", $file);
}
elsif ($param =~ m/(.*?):(\d+)/) {
- push_parameter($1, "$type:$2", $file)
+ if ($type ne "") { # skip unnamed bit-fields
+ push_parameter($1, "$type:$2", $file)
+ }
}
else {
push_parameter($param, $type, $file);
$prototype =~ s/^static +//;
$prototype =~ s/^extern +//;
- $prototype =~ s/^fastcall +//;
$prototype =~ s/^asmlinkage +//;
$prototype =~ s/^inline +//;
$prototype =~ s/^__inline__ +//;
$prototype =~ s/^__always_inline +//;
$prototype =~ s/^noinline +//;
$prototype =~ s/__devinit +//;
+ $prototype =~ s/__init +//;
$prototype =~ s/^#define\s+//; #ak added
$prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
$prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
$prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
$prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
- $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
$prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
$prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
$prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
} else {
$declaration_purpose = "";
}
+
+ if (($declaration_purpose eq "") && $verbose) {
+ print STDERR "Warning(${file}:$.): missing initial short description on line:\n";
+ print STDERR $_;
+ ++$warnings;
+ }
+
if ($identifier =~ m/^struct/) {
$decl_type = 'struct';
} elsif ($identifier =~ m/^union/) {
$newsection = $1;
$newcontents = $2;
- if ($contents ne "") {
+ if (($contents ne "") && ($contents ne "\n")) {
if (!$in_doc_sect && $verbose) {
print STDERR "Warning(${file}:$.): contents before sections\n";
++$warnings;
}
- dump_section($section, xml_escape($contents));
+ dump_section($file, $section, xml_escape($contents));
$section = $section_default;
}
} elsif (/$doc_end/) {
if ($contents ne "") {
- dump_section($section, xml_escape($contents));
+ dump_section($file, $section, xml_escape($contents));
$section = $section_default;
$contents = "";
}
+ # look for doc_com + <text> + doc_end:
+ if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
+ print STDERR "Warning(${file}:$.): suspicious ending line: $_";
+ ++$warnings;
+ }
$prototype = "";
$state = 3;
# @parameter line to signify start of description
if ($1 eq "" &&
($section =~ m/^@/ || $section eq $section_context)) {
- dump_section($section, xml_escape($contents));
+ dump_section($file, $section, xml_escape($contents));
$section = $section_default;
$contents = "";
} else {
} elsif ($state == 4) {
# Documentation block
if (/$doc_block/) {
- dump_section($section, xml_escape($contents));
- output_intro({'sectionlist' => \@sectionlist,
- 'sections' => \%sections });
+ dump_doc_section($file, $section, xml_escape($contents));
$contents = "";
$function = "";
%constants = ();
}
elsif (/$doc_end/)
{
- dump_section($section, xml_escape($contents));
- output_intro({'sectionlist' => \@sectionlist,
- 'sections' => \%sections });
+ dump_doc_section($file, $section, xml_escape($contents));
$contents = "";
$function = "";
%constants = ();