# Note: This only supports 'c'.
# usage:
-# kerneldoc [ -docbook | -html | -text | -man ]
+# kernel-doc [ -docbook | -html | -text | -man ]
# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
# or
# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
# -nofunction funcname
# If set, then only generate documentation for the other function(s). All
# other functions are ignored. Cannot be used with -function together
-# (yes thats a bug - perl hackers can fix it 8))
+# (yes, that's a bug -- perl hackers can fix it 8))
#
# c files - list of 'c' files to process
#
# * my_function - does my stuff
# * @my_arg: its mine damnit
# *
-# * Does my stuff explained.
+# * Does my stuff explained.
# */
#
# or, could also use:
# /**
# * my_function - does my stuff
# * @my_arg: its mine damnit
-# * Description: Does my stuff explained.
+# * Description: Does my stuff explained.
# */
# etc.
#
-# Beside functions you can also write documentation for structs, unions,
-# enums and typedefs. Instead of the function name you must write the name
-# of the declaration; the struct/union/enum/typedef must always precede
-# the name. Nesting of declarations is not supported.
+# Beside functions you can also write documentation for structs, unions,
+# enums and typedefs. Instead of the function name you must write the name
+# of the declaration; the struct/union/enum/typedef must always precede
+# the name. Nesting of declarations is not supported.
# Use the argument mechanism to document members or constants.
# e.g.
# /**
# * struct my_struct - short description
# * @a: first member
# * @b: second member
-# *
+# *
# * Longer description
# */
# struct my_struct {
# };
#
# All descriptions can be multiline, except the short function description.
-#
-# You can also add additional sections. When documenting kernel functions you
-# should document the "Context:" of the function, e.g. whether the functions
+#
+# You can also add additional sections. When documenting kernel functions you
+# should document the "Context:" of the function, e.g. whether the functions
# can be called form interrupts. Unlike other sections you can end it with an
-# empty line.
-# Example-sections should contain the string EXAMPLE so that they are marked
+# empty line.
+# Example-sections should contain the string EXAMPLE so that they are marked
# appropriately in DocBook.
#
# Example:
# * user_function - function that can only be called in user context
# * @a: some argument
# * Context: !in_interrupt()
-# *
+# *
# * Some description
# * Example:
# * user_function(22);
my $blankline = $blankline_man;
my $modulename = "Kernel API";
my $function_only = 0;
-my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
- 'July', 'August', 'September', 'October',
- 'November', 'December')[(localtime)[4]] .
+my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
+ 'July', 'August', 'September', 'October',
+ 'November', 'December')[(localtime)[4]] .
" " . ((localtime)[5]+1900);
# Essentially these are globals
my ($type,$declaration_name,$return_type);
my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
-# Generated docbook code is inserted in a template at a point where
+# 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
# We keep track of number of generated entries and generate a dummy
# parameterdescs => %parameter descriptions
# sectionlist => @list of sections
# sections => %descriont descriptions
-#
+#
sub output_highlight {
my $contents = join "\n",@_;
print "<blockquote>\n";
output_highlight($args{'sections'}{$section});
print "</blockquote>\n";
- }
+ }
}
# output enum in html
print "<hr>\n";
}
-# output tyepdef in html
+# output typedef in html
sub output_typedef_html(%) {
my %args = %{$_[0]};
my ($parameter);
sub output_section_xml(%) {
my %args = %{$_[0]};
- my $section;
+ my $section;
# print out each section
$lineprefix=" ";
foreach $section (@{$args{'sectionlist'}}) {
print "</refsynopsisdiv>\n";
print "<refsect1>\n";
- print " <title>Constants</title>\n";
+ print " <title>Constants</title>\n";
print " <variablelist>\n";
foreach $parameter (@{$args{'parameterlist'}}) {
my $parameter_name = $parameter;
foreach $section (@{$args{'sectionlist'}}) {
print "$section:\n\n";
output_highlight($args{'sections'}{$section});
- }
+ }
print "\n\n";
}
my $name = shift;
my $functype = shift;
my $func = "output_${functype}_$output_mode";
- if (($function_only==0) ||
- ( $function_only == 1 && defined($function_table{$name})) ||
+ if (($function_only==0) ||
+ ( $function_only == 1 && defined($function_table{$name})) ||
( $function_only == 2 && !defined($function_table{$name})))
{
&$func(@_);
}
##
-# takes a declaration (struct, union, enum, typedef) and
+# takes a declaration (struct, union, enum, typedef) and
# invokes the right handler. NOT called for functions.
sub dump_declaration($$) {
no strict 'refs';
}
}
-
+
output_declaration($declaration_name,
'enum',
{'enum' => $declaration_name,
my $type;
my $param;
+ # temporarily replace commas inside function pointer definition
while ($args =~ /(\([^\),]+),/) {
$args =~ s/(\([^\),]+),/$1#/g;
}
-
+
foreach my $arg (split($splitter, $args)) {
# strip comments
$arg =~ s/\/\*.*\*\///;
my $param_name = $param;
$param_name =~ s/\[.*//;
- if ($type eq "" && $param eq "...")
+ if ($type eq "" && $param =~ /\.\.\.$/)
{
$type="";
- $param="...";
- $parameterdescs{"..."} = "variable arguments";
+ $parameterdescs{$param} = "variable arguments";
}
elsif ($type eq "" && ($param eq "" or $param eq "void"))
{
$param="void";
$parameterdescs{void} = "no arguments";
}
- if (defined $type && $type && !defined $parameterdescs{$param_name}) {
+ # warn if parameter has no description
+ # (but ignore ones starting with # as these are no parameters
+ # but inline preprocessor statements
+ if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
+
$parameterdescs{$param_name} = $undescribed;
if (($type eq 'function') || ($type eq 'enum')) {
# the following functions' documentation still comes out right:
# - parport_register_device (function pointer parameters)
# - atomic_set (macro)
- # - pci_match_device (long return type)
+ # - pci_match_device, __copy_to_user (long return type)
if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
$prototype =~ m/^(\w+)\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+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
- $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) {
+ $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) {
$return_type = $1;
$declaration_name = $2;
my $args = $3;
return;
}
- output_declaration($declaration_name,
+ output_declaration($declaration_name,
'function',
{'function' => $declaration_name,
'module' => $modulename,
%sections = ();
@sectionlist = ();
$prototype = "";
-
+
$state = 0;
}
-sub process_state3_function($$) {
+sub process_state3_function($$) {
my $x = shift;
my $file = shift;
}
}
-sub process_state3_type($$) {
+sub process_state3_type($$) {
my $x = shift;
my $file = shift;
} elsif (/$doc_content/) {
# miguel-style comment kludge, look for blank lines after
# @parameter line to signify start of description
- if ($1 eq "" &&
+ if ($1 eq "" &&
($section =~ m/^@/ || $section eq $section_context)) {
dump_section($section, xml_escape($contents));
$section = $section_default;
}
} else {
# i dont know - bad line? ignore.
- print STDERR "Warning(${file}:$.): bad line: $_";
+ print STDERR "Warning(${file}:$.): bad line: $_";
++$warnings;
}
} elsif ($state == 3) { # scanning for function { (end of prototype)
else
{
$contents .= $1 . "\n";
- }
+ }
}
}
}