aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kernel-doc
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kernel-doc')
-rwxr-xr-xscripts/kernel-doc457
1 files changed, 306 insertions, 151 deletions
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 2fc8fad5195e..4f2e9049e8fa 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -59,6 +59,12 @@ Output format selection (mutually exclusive):
59 -text Output plain text format. 59 -text Output plain text format.
60 60
61Output selection (mutually exclusive): 61Output selection (mutually exclusive):
62 -export Only output documentation for symbols that have been
63 exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()
64 in any input FILE or -export-file FILE.
65 -internal Only output documentation for symbols that have NOT been
66 exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()
67 in any input FILE or -export-file FILE.
62 -function NAME Only output documentation for the given function(s) 68 -function NAME Only output documentation for the given function(s)
63 or DOC: section title(s). All other functions and DOC: 69 or DOC: section title(s). All other functions and DOC:
64 sections are ignored. May be specified multiple times. 70 sections are ignored. May be specified multiple times.
@@ -68,6 +74,11 @@ Output selection (mutually exclusive):
68 74
69Output selection modifiers: 75Output selection modifiers:
70 -no-doc-sections Do not output DOC: sections. 76 -no-doc-sections Do not output DOC: sections.
77 -enable-lineno Enable output of #define LINENO lines. Only works with
78 reStructuredText format.
79 -export-file FILE Specify an additional FILE in which to look for
80 EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with
81 -export or -internal. May be specified multiple times.
71 82
72Other parameters: 83Other parameters:
73 -v Verbose output, more warnings and other information. 84 -v Verbose output, more warnings and other information.
@@ -206,6 +217,10 @@ my $type_struct_xml = '\\&((struct\s*)*[_\w]+)';
206my $type_env = '(\$\w+)'; 217my $type_env = '(\$\w+)';
207my $type_enum_full = '\&(enum)\s*([_\w]+)'; 218my $type_enum_full = '\&(enum)\s*([_\w]+)';
208my $type_struct_full = '\&(struct)\s*([_\w]+)'; 219my $type_struct_full = '\&(struct)\s*([_\w]+)';
220my $type_typedef_full = '\&(typedef)\s*([_\w]+)';
221my $type_union_full = '\&(union)\s*([_\w]+)';
222my $type_member = '\&([_\w]+)((\.|->)[_\w]+)';
223my $type_member_func = $type_member . '\(\)';
209 224
210# Output conversion substitutions. 225# Output conversion substitutions.
211# One for each output format 226# One for each output format
@@ -274,10 +289,16 @@ my $blankline_text = "";
274# rst-mode 289# rst-mode
275my @highlights_rst = ( 290my @highlights_rst = (
276 [$type_constant, "``\$1``"], 291 [$type_constant, "``\$1``"],
277 [$type_func, "\\:c\\:func\\:`\$1`"], 292 # Note: need to escape () to avoid func matching later
293 [$type_member_func, "\\:c\\:type\\:`\$1\$2\\\\(\\\\) <\$1>`"],
294 [$type_member, "\\:c\\:type\\:`\$1\$2 <\$1>`"],
295 [$type_func, "\\:c\\:func\\:`\$1()`"],
278 [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 296 [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
279 [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 297 [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
280 [$type_struct, "\\:c\\:type\\:`struct \$1 <\$1>`"], 298 [$type_typedef_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
299 [$type_union_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
300 # in rst this can refer to any type
301 [$type_struct, "\\:c\\:type\\:`\$1`"],
281 [$type_param, "**\$1**"] 302 [$type_param, "**\$1**"]
282 ); 303 );
283my $blankline_rst = "\n"; 304my $blankline_rst = "\n";
@@ -303,12 +324,23 @@ my $verbose = 0;
303my $output_mode = "man"; 324my $output_mode = "man";
304my $output_preformatted = 0; 325my $output_preformatted = 0;
305my $no_doc_sections = 0; 326my $no_doc_sections = 0;
327my $enable_lineno = 0;
306my @highlights = @highlights_man; 328my @highlights = @highlights_man;
307my $blankline = $blankline_man; 329my $blankline = $blankline_man;
308my $modulename = "Kernel API"; 330my $modulename = "Kernel API";
309my $function_only = 0; 331
332use constant {
333 OUTPUT_ALL => 0, # output all symbols and doc sections
334 OUTPUT_INCLUDE => 1, # output only specified symbols
335 OUTPUT_EXCLUDE => 2, # output everything except specified symbols
336 OUTPUT_EXPORTED => 3, # output exported symbols
337 OUTPUT_INTERNAL => 4, # output non-exported symbols
338};
339my $output_selection = OUTPUT_ALL;
310my $show_not_found = 0; 340my $show_not_found = 0;
311 341
342my @export_file_list;
343
312my @build_time; 344my @build_time;
313if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && 345if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) &&
314 (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') { 346 (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') {
@@ -327,6 +359,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
327# CAVEAT EMPTOR! Some of the others I localised may not want to be, which 359# CAVEAT EMPTOR! Some of the others I localised may not want to be, which
328# could cause "use of undefined value" or other bugs. 360# could cause "use of undefined value" or other bugs.
329my ($function, %function_table, %parametertypes, $declaration_purpose); 361my ($function, %function_table, %parametertypes, $declaration_purpose);
362my $declaration_start_line;
330my ($type, $declaration_name, $return_type); 363my ($type, $declaration_name, $return_type);
331my ($newsection, $newcontents, $prototype, $brcount, %source_map); 364my ($newsection, $newcontents, $prototype, $brcount, %source_map);
332 365
@@ -344,52 +377,62 @@ my $section_counter = 0;
344 377
345my $lineprefix=""; 378my $lineprefix="";
346 379
347# states 380# Parser states
348# 0 - normal code 381use constant {
349# 1 - looking for function name 382 STATE_NORMAL => 0, # normal code
350# 2 - scanning field start. 383 STATE_NAME => 1, # looking for function name
351# 3 - scanning prototype. 384 STATE_FIELD => 2, # scanning field start
352# 4 - documentation block 385 STATE_PROTO => 3, # scanning prototype
353# 5 - gathering documentation outside main block 386 STATE_DOCBLOCK => 4, # documentation block
387 STATE_INLINE => 5, # gathering documentation outside main block
388};
354my $state; 389my $state;
355my $in_doc_sect; 390my $in_doc_sect;
356 391
357# Split Doc State 392# Inline documentation state
358# 0 - Invalid (Before start or after finish) 393use constant {
359# 1 - Is started (the /** was found inside a struct) 394 STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE)
360# 2 - The @parameter header was found, start accepting multi paragraph text. 395 STATE_INLINE_NAME => 1, # looking for member name (@foo:)
361# 3 - Finished (the */ was found) 396 STATE_INLINE_TEXT => 2, # looking for member documentation
362# 4 - Error - Comment without header was found. Spit a warning as it's not 397 STATE_INLINE_END => 3, # done
363# proper kernel-doc and ignore the rest. 398 STATE_INLINE_ERROR => 4, # error - Comment without header was found.
364my $split_doc_state; 399 # Spit a warning as it's not
400 # proper kernel-doc and ignore the rest.
401};
402my $inline_doc_state;
365 403
366#declaration types: can be 404#declaration types: can be
367# 'function', 'struct', 'union', 'enum', 'typedef' 405# 'function', 'struct', 'union', 'enum', 'typedef'
368my $decl_type; 406my $decl_type;
369 407
370my $doc_special = "\@\%\$\&";
371
372my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. 408my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
373my $doc_end = '\*/'; 409my $doc_end = '\*/';
374my $doc_com = '\s*\*\s*'; 410my $doc_com = '\s*\*\s*';
375my $doc_com_body = '\s*\* ?'; 411my $doc_com_body = '\s*\* ?';
376my $doc_decl = $doc_com . '(\w+)'; 412my $doc_decl = $doc_com . '(\w+)';
377my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)'; 413# @params and a strictly limited set of supported section names
414my $doc_sect = $doc_com .
415 '\s*(\@\w+|description|context|returns?|notes?|examples?)\s*:(.*)';
378my $doc_content = $doc_com_body . '(.*)'; 416my $doc_content = $doc_com_body . '(.*)';
379my $doc_block = $doc_com . 'DOC:\s*(.*)?'; 417my $doc_block = $doc_com . 'DOC:\s*(.*)?';
380my $doc_split_start = '^\s*/\*\*\s*$'; 418my $doc_inline_start = '^\s*/\*\*\s*$';
381my $doc_split_sect = '\s*\*\s*(@[\w\s]+):(.*)'; 419my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)';
382my $doc_split_end = '^\s*\*/\s*$'; 420my $doc_inline_end = '^\s*\*/\s*$';
421my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;';
383 422
384my %constants;
385my %parameterdescs; 423my %parameterdescs;
424my %parameterdesc_start_lines;
386my @parameterlist; 425my @parameterlist;
387my %sections; 426my %sections;
388my @sectionlist; 427my @sectionlist;
428my %section_start_lines;
389my $sectcheck; 429my $sectcheck;
390my $struct_actual; 430my $struct_actual;
391 431
392my $contents = ""; 432my $contents = "";
433my $new_start_line = 0;
434
435# the canonical section names. see also $doc_sect above.
393my $section_default = "Description"; # default section 436my $section_default = "Description"; # default section
394my $section_intro = "Introduction"; 437my $section_intro = "Introduction";
395my $section = $section_default; 438my $section = $section_default;
@@ -437,19 +480,30 @@ while ($ARGV[0] =~ m/^-(.*)/) {
437 } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document 480 } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
438 $modulename = shift @ARGV; 481 $modulename = shift @ARGV;
439 } elsif ($cmd eq "-function") { # to only output specific functions 482 } elsif ($cmd eq "-function") { # to only output specific functions
440 $function_only = 1; 483 $output_selection = OUTPUT_INCLUDE;
441 $function = shift @ARGV; 484 $function = shift @ARGV;
442 $function_table{$function} = 1; 485 $function_table{$function} = 1;
443 } elsif ($cmd eq "-nofunction") { # to only output specific functions 486 } elsif ($cmd eq "-nofunction") { # output all except specific functions
444 $function_only = 2; 487 $output_selection = OUTPUT_EXCLUDE;
445 $function = shift @ARGV; 488 $function = shift @ARGV;
446 $function_table{$function} = 1; 489 $function_table{$function} = 1;
490 } elsif ($cmd eq "-export") { # only exported symbols
491 $output_selection = OUTPUT_EXPORTED;
492 %function_table = ();
493 } elsif ($cmd eq "-internal") { # only non-exported symbols
494 $output_selection = OUTPUT_INTERNAL;
495 %function_table = ();
496 } elsif ($cmd eq "-export-file") {
497 my $file = shift @ARGV;
498 push(@export_file_list, $file);
447 } elsif ($cmd eq "-v") { 499 } elsif ($cmd eq "-v") {
448 $verbose = 1; 500 $verbose = 1;
449 } elsif (($cmd eq "-h") || ($cmd eq "--help")) { 501 } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
450 usage(); 502 usage();
451 } elsif ($cmd eq '-no-doc-sections') { 503 } elsif ($cmd eq '-no-doc-sections') {
452 $no_doc_sections = 1; 504 $no_doc_sections = 1;
505 } elsif ($cmd eq '-enable-lineno') {
506 $enable_lineno = 1;
453 } elsif ($cmd eq '-show-not-found') { 507 } elsif ($cmd eq '-show-not-found') {
454 $show_not_found = 1; 508 $show_not_found = 1;
455 } 509 }
@@ -467,6 +521,13 @@ sub get_kernel_version() {
467 return $version; 521 return $version;
468} 522}
469 523
524#
525sub print_lineno {
526 my $lineno = shift;
527 if ($enable_lineno && defined($lineno)) {
528 print "#define LINENO " . $lineno . "\n";
529 }
530}
470## 531##
471# dumps section contents to arrays/hashes intended for that purpose. 532# dumps section contents to arrays/hashes intended for that purpose.
472# 533#
@@ -475,28 +536,32 @@ sub dump_section {
475 my $name = shift; 536 my $name = shift;
476 my $contents = join "\n", @_; 537 my $contents = join "\n", @_;
477 538
478 if ($name =~ m/$type_constant/) { 539 if ($name =~ m/$type_param/) {
479 $name = $1;
480# print STDERR "constant section '$1' = '$contents'\n";
481 $constants{$name} = $contents;
482 } elsif ($name =~ m/$type_param/) {
483# print STDERR "parameter def '$1' = '$contents'\n";
484 $name = $1; 540 $name = $1;
485 $parameterdescs{$name} = $contents; 541 $parameterdescs{$name} = $contents;
486 $sectcheck = $sectcheck . $name . " "; 542 $sectcheck = $sectcheck . $name . " ";
543 $parameterdesc_start_lines{$name} = $new_start_line;
544 $new_start_line = 0;
487 } elsif ($name eq "@\.\.\.") { 545 } elsif ($name eq "@\.\.\.") {
488# print STDERR "parameter def '...' = '$contents'\n";
489 $name = "..."; 546 $name = "...";
490 $parameterdescs{$name} = $contents; 547 $parameterdescs{$name} = $contents;
491 $sectcheck = $sectcheck . $name . " "; 548 $sectcheck = $sectcheck . $name . " ";
549 $parameterdesc_start_lines{$name} = $new_start_line;
550 $new_start_line = 0;
492 } else { 551 } else {
493# print STDERR "other section '$name' = '$contents'\n";
494 if (defined($sections{$name}) && ($sections{$name} ne "")) { 552 if (defined($sections{$name}) && ($sections{$name} ne "")) {
495 print STDERR "${file}:$.: error: duplicate section name '$name'\n"; 553 # Only warn on user specified duplicate section names.
496 ++$errors; 554 if ($name ne $section_default) {
555 print STDERR "${file}:$.: warning: duplicate section name '$name'\n";
556 ++$warnings;
557 }
558 $sections{$name} .= $contents;
559 } else {
560 $sections{$name} = $contents;
561 push @sectionlist, $name;
562 $section_start_lines{$name} = $new_start_line;
563 $new_start_line = 0;
497 } 564 }
498 $sections{$name} = $contents;
499 push @sectionlist, $name;
500 } 565 }
501} 566}
502 567
@@ -512,15 +577,17 @@ sub dump_doc_section {
512 return; 577 return;
513 } 578 }
514 579
515 if (($function_only == 0) || 580 if (($output_selection == OUTPUT_ALL) ||
516 ( $function_only == 1 && defined($function_table{$name})) || 581 ($output_selection == OUTPUT_INCLUDE &&
517 ( $function_only == 2 && !defined($function_table{$name}))) 582 defined($function_table{$name})) ||
583 ($output_selection == OUTPUT_EXCLUDE &&
584 !defined($function_table{$name})))
518 { 585 {
519 dump_section($file, $name, $contents); 586 dump_section($file, $name, $contents);
520 output_blockhead({'sectionlist' => \@sectionlist, 587 output_blockhead({'sectionlist' => \@sectionlist,
521 'sections' => \%sections, 588 'sections' => \%sections,
522 'module' => $modulename, 589 'module' => $modulename,
523 'content-only' => ($function_only != 0), }); 590 'content-only' => ($output_selection != OUTPUT_ALL), });
524 } 591 }
525} 592}
526 593
@@ -1736,7 +1803,10 @@ sub output_blockhead_rst(%) {
1736 my ($parameter, $section); 1803 my ($parameter, $section);
1737 1804
1738 foreach $section (@{$args{'sectionlist'}}) { 1805 foreach $section (@{$args{'sectionlist'}}) {
1739 print "**$section**\n\n"; 1806 if ($output_selection != OUTPUT_INCLUDE) {
1807 print "**$section**\n\n";
1808 }
1809 print_lineno($section_start_lines{$section});
1740 output_highlight_rst($args{'sections'}{$section}); 1810 output_highlight_rst($args{'sections'}{$section});
1741 print "\n"; 1811 print "\n";
1742 } 1812 }
@@ -1753,19 +1823,14 @@ sub output_highlight_rst {
1753 die $@ if $@; 1823 die $@ if $@;
1754 1824
1755 foreach $line (split "\n", $contents) { 1825 foreach $line (split "\n", $contents) {
1756 if ($line eq "") { 1826 print $lineprefix . $line . "\n";
1757 print $lineprefix, $blankline;
1758 } else {
1759 $line =~ s/\\\\\\/\&/g;
1760 print $lineprefix, $line;
1761 }
1762 print "\n";
1763 } 1827 }
1764} 1828}
1765 1829
1766sub output_function_rst(%) { 1830sub output_function_rst(%) {
1767 my %args = %{$_[0]}; 1831 my %args = %{$_[0]};
1768 my ($parameter, $section); 1832 my ($parameter, $section);
1833 my $oldprefix = $lineprefix;
1769 my $start; 1834 my $start;
1770 1835
1771 print ".. c:function:: "; 1836 print ".. c:function:: ";
@@ -1783,6 +1848,10 @@ sub output_function_rst(%) {
1783 } 1848 }
1784 $count++; 1849 $count++;
1785 $type = $args{'parametertypes'}{$parameter}; 1850 $type = $args{'parametertypes'}{$parameter};
1851
1852 # RST doesn't like address_space tags at function prototypes
1853 $type =~ s/__(user|kernel|iomem|percpu|pmem|rcu)\s*//;
1854
1786 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { 1855 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1787 # pointer-to-function 1856 # pointer-to-function
1788 print $1 . $parameter . ") (" . $2; 1857 print $1 . $parameter . ") (" . $2;
@@ -1790,29 +1859,37 @@ sub output_function_rst(%) {
1790 print $type . " " . $parameter; 1859 print $type . " " . $parameter;
1791 } 1860 }
1792 } 1861 }
1793 print ")\n\n " . $args{'purpose'} . "\n\n"; 1862 print ")\n\n";
1863 print_lineno($declaration_start_line);
1864 $lineprefix = " ";
1865 output_highlight_rst($args{'purpose'});
1866 print "\n";
1794 1867
1795 print ":Parameters:\n\n"; 1868 print "**Parameters**\n\n";
1869 $lineprefix = " ";
1796 foreach $parameter (@{$args{'parameterlist'}}) { 1870 foreach $parameter (@{$args{'parameterlist'}}) {
1797 my $parameter_name = $parameter; 1871 my $parameter_name = $parameter;
1798 #$parameter_name =~ s/\[.*//; 1872 #$parameter_name =~ s/\[.*//;
1799 $type = $args{'parametertypes'}{$parameter}; 1873 $type = $args{'parametertypes'}{$parameter};
1800 1874
1801 if ($type ne "") { 1875 if ($type ne "") {
1802 print " ``$type $parameter``\n"; 1876 print "``$type $parameter``\n";
1803 } else { 1877 } else {
1804 print " ``$parameter``\n"; 1878 print "``$parameter``\n";
1805 } 1879 }
1806 if ($args{'parameterdescs'}{$parameter_name} ne $undescribed) { 1880
1807 my $oldprefix = $lineprefix; 1881 print_lineno($parameterdesc_start_lines{$parameter_name});
1808 $lineprefix = " "; 1882
1883 if (defined($args{'parameterdescs'}{$parameter_name}) &&
1884 $args{'parameterdescs'}{$parameter_name} ne $undescribed) {
1809 output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 1885 output_highlight_rst($args{'parameterdescs'}{$parameter_name});
1810 $lineprefix = $oldprefix;
1811 } else { 1886 } else {
1812 print "\n _undescribed_\n"; 1887 print " *undescribed*\n";
1813 } 1888 }
1814 print "\n"; 1889 print "\n";
1815 } 1890 }
1891
1892 $lineprefix = $oldprefix;
1816 output_section_rst(@_); 1893 output_section_rst(@_);
1817} 1894}
1818 1895
@@ -1820,10 +1897,11 @@ sub output_section_rst(%) {
1820 my %args = %{$_[0]}; 1897 my %args = %{$_[0]};
1821 my $section; 1898 my $section;
1822 my $oldprefix = $lineprefix; 1899 my $oldprefix = $lineprefix;
1823 $lineprefix = " "; 1900 $lineprefix = "";
1824 1901
1825 foreach $section (@{$args{'sectionlist'}}) { 1902 foreach $section (@{$args{'sectionlist'}}) {
1826 print ":$section:\n\n"; 1903 print "**$section**\n\n";
1904 print_lineno($section_start_lines{$section});
1827 output_highlight_rst($args{'sections'}{$section}); 1905 output_highlight_rst($args{'sections'}{$section});
1828 print "\n"; 1906 print "\n";
1829 } 1907 }
@@ -1834,24 +1912,28 @@ sub output_section_rst(%) {
1834sub output_enum_rst(%) { 1912sub output_enum_rst(%) {
1835 my %args = %{$_[0]}; 1913 my %args = %{$_[0]};
1836 my ($parameter); 1914 my ($parameter);
1915 my $oldprefix = $lineprefix;
1837 my $count; 1916 my $count;
1838 my $name = "enum " . $args{'enum'}; 1917 my $name = "enum " . $args{'enum'};
1839 1918
1840 print "\n\n.. c:type:: " . $name . "\n\n"; 1919 print "\n\n.. c:type:: " . $name . "\n\n";
1841 print " " . $args{'purpose'} . "\n\n"; 1920 print_lineno($declaration_start_line);
1921 $lineprefix = " ";
1922 output_highlight_rst($args{'purpose'});
1923 print "\n";
1842 1924
1843 print "..\n\n:Constants:\n\n"; 1925 print "**Constants**\n\n";
1844 my $oldprefix = $lineprefix; 1926 $lineprefix = " ";
1845 $lineprefix = " ";
1846 foreach $parameter (@{$args{'parameterlist'}}) { 1927 foreach $parameter (@{$args{'parameterlist'}}) {
1847 print " `$parameter`\n"; 1928 print "``$parameter``\n";
1848 if ($args{'parameterdescs'}{$parameter} ne $undescribed) { 1929 if ($args{'parameterdescs'}{$parameter} ne $undescribed) {
1849 output_highlight_rst($args{'parameterdescs'}{$parameter}); 1930 output_highlight_rst($args{'parameterdescs'}{$parameter});
1850 } else { 1931 } else {
1851 print " undescribed\n"; 1932 print " *undescribed*\n";
1852 } 1933 }
1853 print "\n"; 1934 print "\n";
1854 } 1935 }
1936
1855 $lineprefix = $oldprefix; 1937 $lineprefix = $oldprefix;
1856 output_section_rst(@_); 1938 output_section_rst(@_);
1857} 1939}
@@ -1859,30 +1941,37 @@ sub output_enum_rst(%) {
1859sub output_typedef_rst(%) { 1941sub output_typedef_rst(%) {
1860 my %args = %{$_[0]}; 1942 my %args = %{$_[0]};
1861 my ($parameter); 1943 my ($parameter);
1862 my $count; 1944 my $oldprefix = $lineprefix;
1863 my $name = "typedef " . $args{'typedef'}; 1945 my $name = "typedef " . $args{'typedef'};
1864 1946
1865 ### FIXME: should the name below contain "typedef" or not?
1866 print "\n\n.. c:type:: " . $name . "\n\n"; 1947 print "\n\n.. c:type:: " . $name . "\n\n";
1867 print " " . $args{'purpose'} . "\n\n"; 1948 print_lineno($declaration_start_line);
1949 $lineprefix = " ";
1950 output_highlight_rst($args{'purpose'});
1951 print "\n";
1868 1952
1953 $lineprefix = $oldprefix;
1869 output_section_rst(@_); 1954 output_section_rst(@_);
1870} 1955}
1871 1956
1872sub output_struct_rst(%) { 1957sub output_struct_rst(%) {
1873 my %args = %{$_[0]}; 1958 my %args = %{$_[0]};
1874 my ($parameter); 1959 my ($parameter);
1960 my $oldprefix = $lineprefix;
1875 my $name = $args{'type'} . " " . $args{'struct'}; 1961 my $name = $args{'type'} . " " . $args{'struct'};
1876 1962
1877 print "\n\n.. c:type:: " . $name . "\n\n"; 1963 print "\n\n.. c:type:: " . $name . "\n\n";
1878 print " " . $args{'purpose'} . "\n\n"; 1964 print_lineno($declaration_start_line);
1965 $lineprefix = " ";
1966 output_highlight_rst($args{'purpose'});
1967 print "\n";
1879 1968
1880 print ":Definition:\n\n"; 1969 print "**Definition**\n\n";
1881 print " ::\n\n"; 1970 print "::\n\n";
1882 print " " . $args{'type'} . " " . $args{'struct'} . " {\n"; 1971 print " " . $args{'type'} . " " . $args{'struct'} . " {\n";
1883 foreach $parameter (@{$args{'parameterlist'}}) { 1972 foreach $parameter (@{$args{'parameterlist'}}) {
1884 if ($parameter =~ /^#/) { 1973 if ($parameter =~ /^#/) {
1885 print " " . "$parameter\n"; 1974 print " " . "$parameter\n";
1886 next; 1975 next;
1887 } 1976 }
1888 1977
@@ -1903,7 +1992,8 @@ sub output_struct_rst(%) {
1903 } 1992 }
1904 print " };\n\n"; 1993 print " };\n\n";
1905 1994
1906 print ":Members:\n\n"; 1995 print "**Members**\n\n";
1996 $lineprefix = " ";
1907 foreach $parameter (@{$args{'parameterlist'}}) { 1997 foreach $parameter (@{$args{'parameterlist'}}) {
1908 ($parameter =~ /^#/) && next; 1998 ($parameter =~ /^#/) && next;
1909 1999
@@ -1912,14 +2002,14 @@ sub output_struct_rst(%) {
1912 2002
1913 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 2003 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1914 $type = $args{'parametertypes'}{$parameter}; 2004 $type = $args{'parametertypes'}{$parameter};
1915 print " `$type $parameter`" . "\n"; 2005 print_lineno($parameterdesc_start_lines{$parameter_name});
1916 my $oldprefix = $lineprefix; 2006 print "``$type $parameter``\n";
1917 $lineprefix = " ";
1918 output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 2007 output_highlight_rst($args{'parameterdescs'}{$parameter_name});
1919 $lineprefix = $oldprefix;
1920 print "\n"; 2008 print "\n";
1921 } 2009 }
1922 print "\n"; 2010 print "\n";
2011
2012 $lineprefix = $oldprefix;
1923 output_section_rst(@_); 2013 output_section_rst(@_);
1924} 2014}
1925 2015
@@ -1969,9 +2059,13 @@ sub output_declaration {
1969 my $name = shift; 2059 my $name = shift;
1970 my $functype = shift; 2060 my $functype = shift;
1971 my $func = "output_${functype}_$output_mode"; 2061 my $func = "output_${functype}_$output_mode";
1972 if (($function_only==0) || 2062 if (($output_selection == OUTPUT_ALL) ||
1973 ( $function_only == 1 && defined($function_table{$name})) || 2063 (($output_selection == OUTPUT_INCLUDE ||
1974 ( $function_only == 2 && !($functype eq "function" && defined($function_table{$name})))) 2064 $output_selection == OUTPUT_EXPORTED) &&
2065 defined($function_table{$name})) ||
2066 (($output_selection == OUTPUT_EXCLUDE ||
2067 $output_selection == OUTPUT_INTERNAL) &&
2068 !($functype eq "function" && defined($function_table{$name}))))
1975 { 2069 {
1976 &$func(@_); 2070 &$func(@_);
1977 $section_counter++; 2071 $section_counter++;
@@ -2471,7 +2565,6 @@ sub dump_function($$) {
2471 2565
2472sub reset_state { 2566sub reset_state {
2473 $function = ""; 2567 $function = "";
2474 %constants = ();
2475 %parameterdescs = (); 2568 %parameterdescs = ();
2476 %parametertypes = (); 2569 %parametertypes = ();
2477 @parameterlist = (); 2570 @parameterlist = ();
@@ -2481,8 +2574,8 @@ sub reset_state {
2481 $struct_actual = ""; 2574 $struct_actual = "";
2482 $prototype = ""; 2575 $prototype = "";
2483 2576
2484 $state = 0; 2577 $state = STATE_NORMAL;
2485 $split_doc_state = 0; 2578 $inline_doc_state = STATE_INLINE_NA;
2486} 2579}
2487 2580
2488sub tracepoint_munge($) { 2581sub tracepoint_munge($) {
@@ -2545,7 +2638,7 @@ sub syscall_munge() {
2545 } 2638 }
2546} 2639}
2547 2640
2548sub process_state3_function($$) { 2641sub process_proto_function($$) {
2549 my $x = shift; 2642 my $x = shift;
2550 my $file = shift; 2643 my $file = shift;
2551 2644
@@ -2575,7 +2668,7 @@ sub process_state3_function($$) {
2575 } 2668 }
2576} 2669}
2577 2670
2578sub process_state3_type($$) { 2671sub process_proto_type($$) {
2579 my $x = shift; 2672 my $x = shift;
2580 my $file = shift; 2673 my $file = shift;
2581 2674
@@ -2649,25 +2742,54 @@ sub local_unescape($) {
2649 return $text; 2742 return $text;
2650} 2743}
2651 2744
2652sub process_file($) { 2745sub map_filename($) {
2653 my $file; 2746 my $file;
2654 my $identifier;
2655 my $func;
2656 my $descr;
2657 my $in_purpose = 0;
2658 my $initial_section_counter = $section_counter;
2659 my ($orig_file) = @_; 2747 my ($orig_file) = @_;
2660 2748
2661 if (defined($ENV{'SRCTREE'})) { 2749 if (defined($ENV{'SRCTREE'})) {
2662 $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; 2750 $file = "$ENV{'SRCTREE'}" . "/" . $orig_file;
2663 } 2751 } else {
2664 else {
2665 $file = $orig_file; 2752 $file = $orig_file;
2666 } 2753 }
2754
2667 if (defined($source_map{$file})) { 2755 if (defined($source_map{$file})) {
2668 $file = $source_map{$file}; 2756 $file = $source_map{$file};
2669 } 2757 }
2670 2758
2759 return $file;
2760}
2761
2762sub process_export_file($) {
2763 my ($orig_file) = @_;
2764 my $file = map_filename($orig_file);
2765
2766 if (!open(IN,"<$file")) {
2767 print STDERR "Error: Cannot open file $file\n";
2768 ++$errors;
2769 return;
2770 }
2771
2772 while (<IN>) {
2773 if (/$export_symbol/) {
2774 $function_table{$2} = 1;
2775 }
2776 }
2777
2778 close(IN);
2779}
2780
2781sub process_file($) {
2782 my $file;
2783 my $identifier;
2784 my $func;
2785 my $descr;
2786 my $in_purpose = 0;
2787 my $initial_section_counter = $section_counter;
2788 my ($orig_file) = @_;
2789 my $leading_space;
2790
2791 $file = map_filename($orig_file);
2792
2671 if (!open(IN,"<$file")) { 2793 if (!open(IN,"<$file")) {
2672 print STDERR "Error: Cannot open file $file\n"; 2794 print STDERR "Error: Cannot open file $file\n";
2673 ++$errors; 2795 ++$errors;
@@ -2681,15 +2803,18 @@ sub process_file($) {
2681 while (s/\\\s*$//) { 2803 while (s/\\\s*$//) {
2682 $_ .= <IN>; 2804 $_ .= <IN>;
2683 } 2805 }
2684 if ($state == 0) { 2806 if ($state == STATE_NORMAL) {
2685 if (/$doc_start/o) { 2807 if (/$doc_start/o) {
2686 $state = 1; # next line is always the function name 2808 $state = STATE_NAME; # next line is always the function name
2687 $in_doc_sect = 0; 2809 $in_doc_sect = 0;
2810 $declaration_start_line = $. + 1;
2688 } 2811 }
2689 } elsif ($state == 1) { # this line is the function name (always) 2812 } elsif ($state == STATE_NAME) {# this line is the function name (always)
2690 if (/$doc_block/o) { 2813 if (/$doc_block/o) {
2691 $state = 4; 2814 $state = STATE_DOCBLOCK;
2692 $contents = ""; 2815 $contents = "";
2816 $new_start_line = $. + 1;
2817
2693 if ( $1 eq "" ) { 2818 if ( $1 eq "" ) {
2694 $section = $section_intro; 2819 $section = $section_intro;
2695 } else { 2820 } else {
@@ -2702,7 +2827,12 @@ sub process_file($) {
2702 $identifier = $1; 2827 $identifier = $1;
2703 } 2828 }
2704 2829
2705 $state = 2; 2830 $state = STATE_FIELD;
2831 # if there's no @param blocks need to set up default section
2832 # here
2833 $contents = "";
2834 $section = $section_default;
2835 $new_start_line = $. + 1;
2706 if (/-(.*)/) { 2836 if (/-(.*)/) {
2707 # strip leading/trailing/multiple spaces 2837 # strip leading/trailing/multiple spaces
2708 $descr= $1; 2838 $descr= $1;
@@ -2740,13 +2870,25 @@ sub process_file($) {
2740 print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", 2870 print STDERR "${file}:$.: warning: Cannot understand $_ on line $.",
2741 " - I thought it was a doc line\n"; 2871 " - I thought it was a doc line\n";
2742 ++$warnings; 2872 ++$warnings;
2743 $state = 0; 2873 $state = STATE_NORMAL;
2744 } 2874 }
2745 } elsif ($state == 2) { # look for head: lines, and include content 2875 } elsif ($state == STATE_FIELD) { # look for head: lines, and include content
2746 if (/$doc_sect/o) { 2876 if (/$doc_sect/i) { # case insensitive for supported section names
2747 $newsection = $1; 2877 $newsection = $1;
2748 $newcontents = $2; 2878 $newcontents = $2;
2749 2879
2880 # map the supported section names to the canonical names
2881 if ($newsection =~ m/^description$/i) {
2882 $newsection = $section_default;
2883 } elsif ($newsection =~ m/^context$/i) {
2884 $newsection = $section_context;
2885 } elsif ($newsection =~ m/^returns?$/i) {
2886 $newsection = $section_return;
2887 } elsif ($newsection =~ m/^\@return$/) {
2888 # special: @return is a section, not a param description
2889 $newsection = $section_return;
2890 }
2891
2750 if (($contents ne "") && ($contents ne "\n")) { 2892 if (($contents ne "") && ($contents ne "\n")) {
2751 if (!$in_doc_sect && $verbose) { 2893 if (!$in_doc_sect && $verbose) {
2752 print STDERR "${file}:$.: warning: contents before sections\n"; 2894 print STDERR "${file}:$.: warning: contents before sections\n";
@@ -2759,14 +2901,16 @@ sub process_file($) {
2759 $in_doc_sect = 1; 2901 $in_doc_sect = 1;
2760 $in_purpose = 0; 2902 $in_purpose = 0;
2761 $contents = $newcontents; 2903 $contents = $newcontents;
2904 $new_start_line = $.;
2905 while ((substr($contents, 0, 1) eq " ") ||
2906 substr($contents, 0, 1) eq "\t") {
2907 $contents = substr($contents, 1);
2908 }
2762 if ($contents ne "") { 2909 if ($contents ne "") {
2763 while ((substr($contents, 0, 1) eq " ") ||
2764 substr($contents, 0, 1) eq "\t") {
2765 $contents = substr($contents, 1);
2766 }
2767 $contents .= "\n"; 2910 $contents .= "\n";
2768 } 2911 }
2769 $section = $newsection; 2912 $section = $newsection;
2913 $leading_space = undef;
2770 } elsif (/$doc_end/) { 2914 } elsif (/$doc_end/) {
2771 if (($contents ne "") && ($contents ne "\n")) { 2915 if (($contents ne "") && ($contents ne "\n")) {
2772 dump_section($file, $section, xml_escape($contents)); 2916 dump_section($file, $section, xml_escape($contents));
@@ -2780,7 +2924,7 @@ sub process_file($) {
2780 } 2924 }
2781 2925
2782 $prototype = ""; 2926 $prototype = "";
2783 $state = 3; 2927 $state = STATE_PROTO;
2784 $brcount = 0; 2928 $brcount = 0;
2785# print STDERR "end of doc comment, looking for prototype\n"; 2929# print STDERR "end of doc comment, looking for prototype\n";
2786 } elsif (/$doc_content/) { 2930 } elsif (/$doc_content/) {
@@ -2791,6 +2935,7 @@ sub process_file($) {
2791 dump_section($file, $section, xml_escape($contents)); 2935 dump_section($file, $section, xml_escape($contents));
2792 $section = $section_default; 2936 $section = $section_default;
2793 $contents = ""; 2937 $contents = "";
2938 $new_start_line = $.;
2794 } else { 2939 } else {
2795 $contents .= "\n"; 2940 $contents .= "\n";
2796 } 2941 }
@@ -2801,87 +2946,86 @@ sub process_file($) {
2801 $declaration_purpose .= " " . xml_escape($1); 2946 $declaration_purpose .= " " . xml_escape($1);
2802 $declaration_purpose =~ s/\s+/ /g; 2947 $declaration_purpose =~ s/\s+/ /g;
2803 } else { 2948 } else {
2804 $contents .= $1 . "\n"; 2949 my $cont = $1;
2950 if ($section =~ m/^@/ || $section eq $section_context) {
2951 if (!defined $leading_space) {
2952 if ($cont =~ m/^(\s+)/) {
2953 $leading_space = $1;
2954 } else {
2955 $leading_space = "";
2956 }
2957 }
2958
2959 $cont =~ s/^$leading_space//;
2960 }
2961 $contents .= $cont . "\n";
2805 } 2962 }
2806 } else { 2963 } else {
2807 # i dont know - bad line? ignore. 2964 # i dont know - bad line? ignore.
2808 print STDERR "${file}:$.: warning: bad line: $_"; 2965 print STDERR "${file}:$.: warning: bad line: $_";
2809 ++$warnings; 2966 ++$warnings;
2810 } 2967 }
2811 } elsif ($state == 5) { # scanning for split parameters 2968 } elsif ($state == STATE_INLINE) { # scanning for inline parameters
2812 # First line (state 1) needs to be a @parameter 2969 # First line (state 1) needs to be a @parameter
2813 if ($split_doc_state == 1 && /$doc_split_sect/o) { 2970 if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) {
2814 $section = $1; 2971 $section = $1;
2815 $contents = $2; 2972 $contents = $2;
2973 $new_start_line = $.;
2816 if ($contents ne "") { 2974 if ($contents ne "") {
2817 while ((substr($contents, 0, 1) eq " ") || 2975 while ((substr($contents, 0, 1) eq " ") ||
2818 substr($contents, 0, 1) eq "\t") { 2976 substr($contents, 0, 1) eq "\t") {
2819 $contents = substr($contents, 1); 2977 $contents = substr($contents, 1);
2820 } 2978 }
2821 $contents .= "\n"; 2979 $contents .= "\n";
2822 } 2980 }
2823 $split_doc_state = 2; 2981 $inline_doc_state = STATE_INLINE_TEXT;
2824 # Documentation block end */ 2982 # Documentation block end */
2825 } elsif (/$doc_split_end/) { 2983 } elsif (/$doc_inline_end/) {
2826 if (($contents ne "") && ($contents ne "\n")) { 2984 if (($contents ne "") && ($contents ne "\n")) {
2827 dump_section($file, $section, xml_escape($contents)); 2985 dump_section($file, $section, xml_escape($contents));
2828 $section = $section_default; 2986 $section = $section_default;
2829 $contents = ""; 2987 $contents = "";
2830 } 2988 }
2831 $state = 3; 2989 $state = STATE_PROTO;
2832 $split_doc_state = 0; 2990 $inline_doc_state = STATE_INLINE_NA;
2833 # Regular text 2991 # Regular text
2834 } elsif (/$doc_content/) { 2992 } elsif (/$doc_content/) {
2835 if ($split_doc_state == 2) { 2993 if ($inline_doc_state == STATE_INLINE_TEXT) {
2836 $contents .= $1 . "\n"; 2994 $contents .= $1 . "\n";
2837 } elsif ($split_doc_state == 1) { 2995 # nuke leading blank lines
2838 $split_doc_state = 4; 2996 if ($contents =~ /^\s*$/) {
2839 print STDERR "Warning(${file}:$.): "; 2997 $contents = "";
2998 }
2999 } elsif ($inline_doc_state == STATE_INLINE_NAME) {
3000 $inline_doc_state = STATE_INLINE_ERROR;
3001 print STDERR "${file}:$.: warning: ";
2840 print STDERR "Incorrect use of kernel-doc format: $_"; 3002 print STDERR "Incorrect use of kernel-doc format: $_";
2841 ++$warnings; 3003 ++$warnings;
2842 } 3004 }
2843 } 3005 }
2844 } elsif ($state == 3) { # scanning for function '{' (end of prototype) 3006 } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype)
2845 if (/$doc_split_start/) { 3007 if (/$doc_inline_start/) {
2846 $state = 5; 3008 $state = STATE_INLINE;
2847 $split_doc_state = 1; 3009 $inline_doc_state = STATE_INLINE_NAME;
2848 } elsif ($decl_type eq 'function') { 3010 } elsif ($decl_type eq 'function') {
2849 process_state3_function($_, $file); 3011 process_proto_function($_, $file);
2850 } else { 3012 } else {
2851 process_state3_type($_, $file); 3013 process_proto_type($_, $file);
2852 } 3014 }
2853 } elsif ($state == 4) { 3015 } elsif ($state == STATE_DOCBLOCK) {
2854 # Documentation block 3016 if (/$doc_end/)
2855 if (/$doc_block/) {
2856 dump_doc_section($file, $section, xml_escape($contents));
2857 $contents = "";
2858 $function = "";
2859 %constants = ();
2860 %parameterdescs = ();
2861 %parametertypes = ();
2862 @parameterlist = ();
2863 %sections = ();
2864 @sectionlist = ();
2865 $prototype = "";
2866 if ( $1 eq "" ) {
2867 $section = $section_intro;
2868 } else {
2869 $section = $1;
2870 }
2871 }
2872 elsif (/$doc_end/)
2873 { 3017 {
2874 dump_doc_section($file, $section, xml_escape($contents)); 3018 dump_doc_section($file, $section, xml_escape($contents));
3019 $section = $section_default;
2875 $contents = ""; 3020 $contents = "";
2876 $function = ""; 3021 $function = "";
2877 %constants = ();
2878 %parameterdescs = (); 3022 %parameterdescs = ();
2879 %parametertypes = (); 3023 %parametertypes = ();
2880 @parameterlist = (); 3024 @parameterlist = ();
2881 %sections = (); 3025 %sections = ();
2882 @sectionlist = (); 3026 @sectionlist = ();
2883 $prototype = ""; 3027 $prototype = "";
2884 $state = 0; 3028 $state = STATE_NORMAL;
2885 } 3029 }
2886 elsif (/$doc_content/) 3030 elsif (/$doc_content/)
2887 { 3031 {
@@ -2898,7 +3042,7 @@ sub process_file($) {
2898 } 3042 }
2899 if ($initial_section_counter == $section_counter) { 3043 if ($initial_section_counter == $section_counter) {
2900 print STDERR "${file}:1: warning: no structured comments found\n"; 3044 print STDERR "${file}:1: warning: no structured comments found\n";
2901 if (($function_only == 1) && ($show_not_found == 1)) { 3045 if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) {
2902 print STDERR " Was looking for '$_'.\n" for keys %function_table; 3046 print STDERR " Was looking for '$_'.\n" for keys %function_table;
2903 } 3047 }
2904 if ($output_mode eq "xml") { 3048 if ($output_mode eq "xml") {
@@ -2957,6 +3101,17 @@ if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
2957 close(SOURCE_MAP); 3101 close(SOURCE_MAP);
2958} 3102}
2959 3103
3104if ($output_selection == OUTPUT_EXPORTED ||
3105 $output_selection == OUTPUT_INTERNAL) {
3106
3107 push(@export_file_list, @ARGV);
3108
3109 foreach (@export_file_list) {
3110 chomp;
3111 process_export_file($_);
3112 }
3113}
3114
2960foreach (@ARGV) { 3115foreach (@ARGV) {
2961 chomp; 3116 chomp;
2962 process_file($_); 3117 process_file($_);