xref: /linux-6.15/scripts/kernel-doc (revision 089e06c3)
1#!/usr/bin/env perl
2# SPDX-License-Identifier: GPL-2.0
3# vim: softtabstop=4
4
5use warnings;
6use strict;
7
8## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
9## Copyright (C) 2000, 1  Tim Waugh <[email protected]>          ##
10## Copyright (C) 2001  Simon Huggins                             ##
11## Copyright (C) 2005-2012  Randy Dunlap                         ##
12## Copyright (C) 2012  Dan Luedtke                               ##
13## 								 ##
14## #define enhancements by Armin Kuster <[email protected]>	 ##
15## Copyright (c) 2000 MontaVista Software, Inc.			 ##
16#
17# Copyright (C) 2022 Tomasz Warniełło (POD)
18
19use Pod::Usage qw/pod2usage/;
20
21=head1 NAME
22
23kernel-doc - Print formatted kernel documentation to stdout
24
25=head1 SYNOPSIS
26
27 kernel-doc [-h] [-v] [-Werror] [-Wall] [-Wreturn] [-Wshort-desc[ription]] [-Wcontents-before-sections]
28   [ -man |
29     -rst [-enable-lineno] |
30     -none
31   ]
32   [
33     -export |
34     -internal |
35     [-function NAME] ... |
36     [-nosymbol NAME] ...
37   ]
38   [-no-doc-sections]
39   [-export-file FILE] ...
40   FILE ...
41
42Run `kernel-doc -h` for details.
43
44=head1 DESCRIPTION
45
46Read C language source or header FILEs, extract embedded documentation comments,
47and print formatted documentation to standard output.
48
49The documentation comments are identified by the "/**" opening comment mark.
50
51See Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax.
52
53=cut
54
55# more perldoc at the end of the file
56
57## init lots of data
58
59my $errors = 0;
60my $warnings = 0;
61my $anon_struct_union = 0;
62
63# match expressions used to find embedded type information
64my $type_constant = '\b``([^\`]+)``\b';
65my $type_constant2 = '\%([-_*\w]+)';
66my $type_func = '(\w+)\(\)';
67my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
68my $type_param_ref = '([\!~\*]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
69my $type_fp_param = '\@(\w+)\(\)';  # Special RST handling for func ptr params
70my $type_fp_param2 = '\@(\w+->\S+)\(\)';  # Special RST handling for structs with func ptr params
71my $type_env = '(\$\w+)';
72my $type_enum = '\&(enum\s*([_\w]+))';
73my $type_struct = '\&(struct\s*([_\w]+))';
74my $type_typedef = '\&(typedef\s*([_\w]+))';
75my $type_union = '\&(union\s*([_\w]+))';
76my $type_member = '\&([_\w]+)(\.|->)([_\w]+)';
77my $type_fallback = '\&([_\w]+)';
78my $type_member_func = $type_member . '\(\)';
79
80# Output conversion substitutions.
81#  One for each output format
82
83# these are pretty rough
84my @highlights_man = (
85    [$type_constant, "\$1"],
86    [$type_constant2, "\$1"],
87    [$type_func, "\\\\fB\$1\\\\fP"],
88    [$type_enum, "\\\\fI\$1\\\\fP"],
89    [$type_struct, "\\\\fI\$1\\\\fP"],
90    [$type_typedef, "\\\\fI\$1\\\\fP"],
91    [$type_union, "\\\\fI\$1\\\\fP"],
92    [$type_param, "\\\\fI\$1\\\\fP"],
93    [$type_param_ref, "\\\\fI\$1\$2\\\\fP"],
94    [$type_member, "\\\\fI\$1\$2\$3\\\\fP"],
95    [$type_fallback, "\\\\fI\$1\\\\fP"]
96  );
97my $blankline_man = "";
98
99# rst-mode
100my @highlights_rst = (
101    [$type_constant, "``\$1``"],
102    [$type_constant2, "``\$1``"],
103
104    # Note: need to escape () to avoid func matching later
105    [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"],
106    [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"],
107    [$type_fp_param, "**\$1\\\\(\\\\)**"],
108    [$type_fp_param2, "**\$1\\\\(\\\\)**"],
109    [$type_func, "\$1()"],
110    [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"],
111    [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"],
112    [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"],
113    [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"],
114
115    # in rst this can refer to any type
116    [$type_fallback, "\\:c\\:type\\:`\$1`"],
117    [$type_param_ref, "**\$1\$2**"]
118  );
119my $blankline_rst = "\n";
120
121# read arguments
122if ($#ARGV == -1) {
123    pod2usage(
124        -message => "No arguments!\n",
125        -exitval => 1,
126        -verbose => 99,
127        -sections => 'SYNOPSIS',
128        -output => \*STDERR,
129      );
130}
131
132my $kernelversion;
133
134my $dohighlight = "";
135
136my $verbose = 0;
137my $Werror = 0;
138my $Wreturn = 0;
139my $Wshort_desc = 0;
140my $Wcontents_before_sections = 0;
141my $output_mode = "rst";
142my $output_preformatted = 0;
143my $no_doc_sections = 0;
144my $enable_lineno = 0;
145my @highlights = @highlights_rst;
146my $blankline = $blankline_rst;
147my $modulename = "Kernel API";
148
149use constant {
150    OUTPUT_ALL          => 0, # output all symbols and doc sections
151    OUTPUT_INCLUDE      => 1, # output only specified symbols
152    OUTPUT_EXPORTED     => 2, # output exported symbols
153    OUTPUT_INTERNAL     => 3, # output non-exported symbols
154};
155my $output_selection = OUTPUT_ALL;
156my $show_not_found = 0;	# No longer used
157
158my @export_file_list;
159
160my @build_time;
161if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) &&
162    (my $seconds = `date -d "${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') {
163    @build_time = gmtime($seconds);
164} else {
165    @build_time = localtime;
166}
167
168my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
169                'July', 'August', 'September', 'October',
170                'November', 'December')[$build_time[4]] .
171    " " . ($build_time[5]+1900);
172
173# Essentially these are globals.
174# They probably want to be tidied up, made more localised or something.
175# CAVEAT EMPTOR!  Some of the others I localised may not want to be, which
176# could cause "use of undefined value" or other bugs.
177my ($function, %function_table, %parametertypes, $declaration_purpose);
178my %nosymbol_table = ();
179my $declaration_start_line;
180my ($type, $declaration_name, $return_type);
181my ($newsection, $newcontents, $prototype, $brcount);
182
183if (defined($ENV{'KBUILD_VERBOSE'}) && $ENV{'KBUILD_VERBOSE'} =~ '1') {
184    $verbose = 1;
185}
186
187if (defined($ENV{'KCFLAGS'})) {
188    my $kcflags = "$ENV{'KCFLAGS'}";
189
190    if ($kcflags =~ /(\s|^)-Werror(\s|$)/) {
191        $Werror = 1;
192    }
193}
194
195# reading this variable is for backwards compat just in case
196# someone was calling it with the variable from outside the
197# kernel's build system
198if (defined($ENV{'KDOC_WERROR'})) {
199    $Werror = "$ENV{'KDOC_WERROR'}";
200}
201# other environment variables are converted to command-line
202# arguments in cmd_checkdoc in the build system
203
204# Generated docbook code is inserted in a template at a point where
205# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
206# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
207# We keep track of number of generated entries and generate a dummy
208# if needs be to ensure the expanded template can be postprocessed
209# into html.
210my $section_counter = 0;
211
212my $lineprefix="";
213
214# Parser states
215use constant {
216    STATE_NORMAL        => 0,        # normal code
217    STATE_NAME          => 1,        # looking for function name
218    STATE_BODY_MAYBE    => 2,        # body - or maybe more description
219    STATE_BODY          => 3,        # the body of the comment
220    STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line
221    STATE_PROTO         => 5,        # scanning prototype
222    STATE_DOCBLOCK      => 6,        # documentation block
223    STATE_INLINE        => 7,        # gathering doc outside main block
224};
225my $state;
226my $in_doc_sect;
227my $leading_space;
228
229# Inline documentation state
230use constant {
231    STATE_INLINE_NA     => 0, # not applicable ($state != STATE_INLINE)
232    STATE_INLINE_NAME   => 1, # looking for member name (@foo:)
233    STATE_INLINE_TEXT   => 2, # looking for member documentation
234    STATE_INLINE_END    => 3, # done
235    STATE_INLINE_ERROR  => 4, # error - Comment without header was found.
236                              # Spit a warning as it's not
237                              # proper kernel-doc and ignore the rest.
238};
239my $inline_doc_state;
240
241#declaration types: can be
242# 'function', 'struct', 'union', 'enum', 'typedef'
243my $decl_type;
244
245# Name of the kernel-doc identifier for non-DOC markups
246my $identifier;
247
248my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
249my $doc_end = '\*/';
250my $doc_com = '\s*\*\s*';
251my $doc_com_body = '\s*\* ?';
252my $doc_decl = $doc_com . '(\w+)';
253# @params and a strictly limited set of supported section names
254# Specifically:
255#   Match @word:
256#	  @...:
257#         @{section-name}:
258# while trying to not match literal block starts like "example::"
259#
260my $doc_sect = $doc_com .
261    '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$';
262my $doc_content = $doc_com_body . '(.*)';
263my $doc_block = $doc_com . 'DOC:\s*(.*)?';
264my $doc_inline_start = '^\s*/\*\*\s*$';
265my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)';
266my $doc_inline_end = '^\s*\*/\s*$';
267my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$';
268my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;';
269my $export_symbol_ns = '^\s*EXPORT_SYMBOL_NS(_GPL)?\s*\(\s*(\w+)\s*,\s*"\S+"\)\s*;';
270my $function_pointer = qr{([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)};
271my $attribute = qr{__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)}i;
272
273my %parameterdescs;
274my %parameterdesc_start_lines;
275my @parameterlist;
276my %sections;
277my @sectionlist;
278my %section_start_lines;
279my $sectcheck;
280my $struct_actual;
281
282my $contents = "";
283my $new_start_line = 0;
284
285# the canonical section names. see also $doc_sect above.
286my $section_default = "Description";	# default section
287my $section_intro = "Introduction";
288my $section = $section_default;
289my $section_context = "Context";
290my $section_return = "Return";
291
292my $undescribed = "-- undescribed --";
293
294reset_state();
295
296while ($ARGV[0] =~ m/^--?(.*)/) {
297    my $cmd = $1;
298    shift @ARGV;
299    if ($cmd eq "man") {
300        $output_mode = "man";
301        @highlights = @highlights_man;
302        $blankline = $blankline_man;
303    } elsif ($cmd eq "rst") {
304        $output_mode = "rst";
305        @highlights = @highlights_rst;
306        $blankline = $blankline_rst;
307    } elsif ($cmd eq "none") {
308        $output_mode = "none";
309    } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document
310        $modulename = shift @ARGV;
311    } elsif ($cmd eq "function") { # to only output specific functions
312        $output_selection = OUTPUT_INCLUDE;
313        $function = shift @ARGV;
314        $function_table{$function} = 1;
315    } elsif ($cmd eq "nosymbol") { # Exclude specific symbols
316        my $symbol = shift @ARGV;
317        $nosymbol_table{$symbol} = 1;
318    } elsif ($cmd eq "export") { # only exported symbols
319        $output_selection = OUTPUT_EXPORTED;
320        %function_table = ();
321    } elsif ($cmd eq "internal") { # only non-exported symbols
322        $output_selection = OUTPUT_INTERNAL;
323        %function_table = ();
324    } elsif ($cmd eq "export-file") {
325        my $file = shift @ARGV;
326        push(@export_file_list, $file);
327    } elsif ($cmd eq "v") {
328        $verbose = 1;
329    } elsif ($cmd eq "Werror") {
330        $Werror = 1;
331    } elsif ($cmd eq "Wreturn") {
332        $Wreturn = 1;
333    } elsif ($cmd eq "Wshort-desc" or $cmd eq "Wshort-description") {
334        $Wshort_desc = 1;
335    } elsif ($cmd eq "Wcontents-before-sections") {
336        $Wcontents_before_sections = 1;
337    } elsif ($cmd eq "Wall") {
338        $Wreturn = 1;
339        $Wshort_desc = 1;
340        $Wcontents_before_sections = 1;
341    } elsif (($cmd eq "h") || ($cmd eq "help")) {
342        pod2usage(-exitval => 0, -verbose => 2);
343    } elsif ($cmd eq 'no-doc-sections') {
344        $no_doc_sections = 1;
345    } elsif ($cmd eq 'enable-lineno') {
346        $enable_lineno = 1;
347    } elsif ($cmd eq 'show-not-found') {
348        $show_not_found = 1;  # A no-op but don't fail
349    } else {
350        # Unknown argument
351        pod2usage(
352            -message => "Argument unknown!\n",
353            -exitval => 1,
354            -verbose => 99,
355            -sections => 'SYNOPSIS',
356            -output => \*STDERR,
357            );
358    }
359    if ($#ARGV < 0){
360        pod2usage(
361            -message => "FILE argument missing\n",
362            -exitval => 1,
363            -verbose => 99,
364            -sections => 'SYNOPSIS',
365            -output => \*STDERR,
366            );
367    }
368}
369
370# continue execution near EOF;
371
372sub findprog($)
373{
374    foreach(split(/:/, $ENV{PATH})) {
375        return "$_/$_[0]" if(-x "$_/$_[0]");
376    }
377}
378
379# get kernel version from env
380sub get_kernel_version() {
381    my $version = 'unknown kernel version';
382
383    if (defined($ENV{'KERNELVERSION'})) {
384        $version = $ENV{'KERNELVERSION'};
385    }
386    return $version;
387}
388
389#
390sub print_lineno {
391    my $lineno = shift;
392    if ($enable_lineno && defined($lineno)) {
393        print ".. LINENO " . $lineno . "\n";
394    }
395}
396
397sub emit_warning {
398    my $location = shift;
399    my $msg = shift;
400    print STDERR "$location: warning: $msg";
401    ++$warnings;
402}
403##
404# dumps section contents to arrays/hashes intended for that purpose.
405#
406sub dump_section {
407    my $file = shift;
408    my $name = shift;
409    my $contents = join "\n", @_;
410
411    if ($name =~ m/$type_param/) {
412        $name = $1;
413        $parameterdescs{$name} = $contents;
414        $sectcheck = $sectcheck . $name . " ";
415        $parameterdesc_start_lines{$name} = $new_start_line;
416        $new_start_line = 0;
417    } elsif ($name eq "@\.\.\.") {
418        $name = "...";
419        $parameterdescs{$name} = $contents;
420        $sectcheck = $sectcheck . $name . " ";
421        $parameterdesc_start_lines{$name} = $new_start_line;
422        $new_start_line = 0;
423    } else {
424        if (defined($sections{$name}) && ($sections{$name} ne "")) {
425            # Only warn on user specified duplicate section names.
426            if ($name ne $section_default) {
427                emit_warning("${file}:$.", "duplicate section name '$name'\n");
428            }
429            $sections{$name} .= $contents;
430        } else {
431            $sections{$name} = $contents;
432            push @sectionlist, $name;
433            $section_start_lines{$name} = $new_start_line;
434            $new_start_line = 0;
435        }
436    }
437}
438
439##
440# dump DOC: section after checking that it should go out
441#
442sub dump_doc_section {
443    my $file = shift;
444    my $name = shift;
445    my $contents = join "\n", @_;
446
447    if ($no_doc_sections) {
448        return;
449    }
450
451    return if (defined($nosymbol_table{$name}));
452
453    if (($output_selection == OUTPUT_ALL) ||
454        (($output_selection == OUTPUT_INCLUDE) &&
455         defined($function_table{$name})))
456    {
457        dump_section($file, $name, $contents);
458        output_blockhead({'sectionlist' => \@sectionlist,
459                          'sections' => \%sections,
460                          'module' => $modulename,
461                          'content-only' => ($output_selection != OUTPUT_ALL), });
462    }
463}
464
465##
466# output function
467#
468# parameterdescs, a hash.
469#  function => "function name"
470#  parameterlist => @list of parameters
471#  parameterdescs => %parameter descriptions
472#  sectionlist => @list of sections
473#  sections => %section descriptions
474#
475
476sub output_highlight {
477    my $contents = join "\n",@_;
478    my $line;
479
480#   DEBUG
481#   if (!defined $contents) {
482#	use Carp;
483#	confess "output_highlight got called with no args?\n";
484#   }
485
486#   print STDERR "contents b4:$contents\n";
487    eval $dohighlight;
488    die $@ if $@;
489#   print STDERR "contents af:$contents\n";
490
491    foreach $line (split "\n", $contents) {
492        if (! $output_preformatted) {
493            $line =~ s/^\s*//;
494        }
495        if ($line eq ""){
496            if (! $output_preformatted) {
497                print $lineprefix, $blankline;
498            }
499        } else {
500            if ($output_mode eq "man" && substr($line, 0, 1) eq ".") {
501                print "\\&$line";
502            } else {
503                print $lineprefix, $line;
504            }
505        }
506        print "\n";
507    }
508}
509
510##
511# output function in man
512sub output_function_man(%) {
513    my %args = %{$_[0]};
514    my ($parameter, $section);
515    my $count;
516    my $func_macro = $args{'func_macro'};
517    my $paramcount = $#{$args{'parameterlist'}}; # -1 is empty
518
519    print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
520
521    print ".SH NAME\n";
522    print $args{'function'} . " \\- " . $args{'purpose'} . "\n";
523
524    print ".SH SYNOPSIS\n";
525    if ($args{'functiontype'} ne "") {
526        print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n";
527    } else {
528        print ".B \"" . $args{'function'} . "\n";
529    }
530    $count = 0;
531    my $parenth = "(";
532    my $post = ",";
533    foreach my $parameter (@{$args{'parameterlist'}}) {
534        if ($count == $#{$args{'parameterlist'}}) {
535            $post = ");";
536        }
537        $type = $args{'parametertypes'}{$parameter};
538        if ($type =~ m/$function_pointer/) {
539            # pointer-to-function
540            print ".BI \"" . $parenth . $1 . "\" " . " \") (" . $2 . ")" . $post . "\"\n";
541        } else {
542            $type =~ s/([^\*])$/$1 /;
543            print ".BI \"" . $parenth . $type . "\" " . " \"" . $post . "\"\n";
544        }
545        $count++;
546        $parenth = "";
547    }
548
549    $paramcount = $#{$args{'parameterlist'}}; # -1 is empty
550    if ($paramcount >= 0) {
551    	print ".SH ARGUMENTS\n";
552	}
553    foreach $parameter (@{$args{'parameterlist'}}) {
554        my $parameter_name = $parameter;
555        $parameter_name =~ s/\[.*//;
556
557        print ".IP \"" . $parameter . "\" 12\n";
558        output_highlight($args{'parameterdescs'}{$parameter_name});
559    }
560    foreach $section (@{$args{'sectionlist'}}) {
561        print ".SH \"", uc $section, "\"\n";
562        output_highlight($args{'sections'}{$section});
563    }
564}
565
566##
567# output enum in man
568sub output_enum_man(%) {
569    my %args = %{$_[0]};
570    my ($parameter, $section);
571    my $count;
572
573    print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
574
575    print ".SH NAME\n";
576    print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n";
577
578    print ".SH SYNOPSIS\n";
579    print "enum " . $args{'enum'} . " {\n";
580    $count = 0;
581    foreach my $parameter (@{$args{'parameterlist'}}) {
582        print ".br\n.BI \"    $parameter\"\n";
583        if ($count == $#{$args{'parameterlist'}}) {
584            print "\n};\n";
585            last;
586        } else {
587            print ", \n.br\n";
588        }
589        $count++;
590    }
591
592    print ".SH Constants\n";
593    foreach $parameter (@{$args{'parameterlist'}}) {
594        my $parameter_name = $parameter;
595        $parameter_name =~ s/\[.*//;
596
597        print ".IP \"" . $parameter . "\" 12\n";
598        output_highlight($args{'parameterdescs'}{$parameter_name});
599    }
600    foreach $section (@{$args{'sectionlist'}}) {
601        print ".SH \"$section\"\n";
602        output_highlight($args{'sections'}{$section});
603    }
604}
605
606##
607# output struct in man
608sub output_struct_man(%) {
609    my %args = %{$_[0]};
610    my ($parameter, $section);
611
612    print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n";
613
614    print ".SH NAME\n";
615    print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n";
616
617    my $declaration = $args{'definition'};
618    $declaration =~ s/\t/  /g;
619    $declaration =~ s/\n/"\n.br\n.BI \"/g;
620    print ".SH SYNOPSIS\n";
621    print $args{'type'} . " " . $args{'struct'} . " {\n.br\n";
622    print ".BI \"$declaration\n};\n.br\n\n";
623
624    print ".SH Members\n";
625    foreach $parameter (@{$args{'parameterlist'}}) {
626        ($parameter =~ /^#/) && next;
627
628        my $parameter_name = $parameter;
629        $parameter_name =~ s/\[.*//;
630
631        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
632        print ".IP \"" . $parameter . "\" 12\n";
633        output_highlight($args{'parameterdescs'}{$parameter_name});
634    }
635    foreach $section (@{$args{'sectionlist'}}) {
636        print ".SH \"$section\"\n";
637        output_highlight($args{'sections'}{$section});
638    }
639}
640
641##
642# output typedef in man
643sub output_typedef_man(%) {
644    my %args = %{$_[0]};
645    my ($parameter, $section);
646
647    print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
648
649    print ".SH NAME\n";
650    print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n";
651
652    foreach $section (@{$args{'sectionlist'}}) {
653        print ".SH \"$section\"\n";
654        output_highlight($args{'sections'}{$section});
655    }
656}
657
658sub output_blockhead_man(%) {
659    my %args = %{$_[0]};
660    my ($parameter, $section);
661    my $count;
662
663    print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
664
665    foreach $section (@{$args{'sectionlist'}}) {
666        print ".SH \"$section\"\n";
667        output_highlight($args{'sections'}{$section});
668    }
669}
670
671##
672# output in restructured text
673#
674
675#
676# This could use some work; it's used to output the DOC: sections, and
677# starts by putting out the name of the doc section itself, but that tends
678# to duplicate a header already in the template file.
679#
680sub output_blockhead_rst(%) {
681    my %args = %{$_[0]};
682    my ($parameter, $section);
683
684    foreach $section (@{$args{'sectionlist'}}) {
685        next if (defined($nosymbol_table{$section}));
686
687        if ($output_selection != OUTPUT_INCLUDE) {
688            print ".. _$section:\n\n";
689            print "**$section**\n\n";
690        }
691        print_lineno($section_start_lines{$section});
692        output_highlight_rst($args{'sections'}{$section});
693        print "\n";
694    }
695}
696
697#
698# Apply the RST highlights to a sub-block of text.
699#
700sub highlight_block($) {
701    # The dohighlight kludge requires the text be called $contents
702    my $contents = shift;
703    eval $dohighlight;
704    die $@ if $@;
705    return $contents;
706}
707
708#
709# Regexes used only here.
710#
711my $sphinx_literal = '^[^.].*::$';
712my $sphinx_cblock = '^\.\.\ +code-block::';
713
714sub output_highlight_rst {
715    my $input = join "\n",@_;
716    my $output = "";
717    my $line;
718    my $in_literal = 0;
719    my $litprefix;
720    my $block = "";
721
722    foreach $line (split "\n",$input) {
723        #
724        # If we're in a literal block, see if we should drop out
725        # of it.  Otherwise pass the line straight through unmunged.
726        #
727        if ($in_literal) {
728            if (! ($line =~ /^\s*$/)) {
729                #
730                # If this is the first non-blank line in a literal
731                # block we need to figure out what the proper indent is.
732                #
733                if ($litprefix eq "") {
734                    $line =~ /^(\s*)/;
735                    $litprefix = '^' . $1;
736                    $output .= $line . "\n";
737                } elsif (! ($line =~ /$litprefix/)) {
738                    $in_literal = 0;
739                } else {
740                    $output .= $line . "\n";
741                }
742            } else {
743                $output .= $line . "\n";
744            }
745        }
746        #
747        # Not in a literal block (or just dropped out)
748        #
749        if (! $in_literal) {
750            $block .= $line . "\n";
751            if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) {
752                $in_literal = 1;
753                $litprefix = "";
754                $output .= highlight_block($block);
755                $block = ""
756            }
757        }
758    }
759
760    if ($block) {
761        $output .= highlight_block($block);
762    }
763    foreach $line (split "\n", $output) {
764        print $lineprefix . $line . "\n";
765    }
766}
767
768sub output_function_rst(%) {
769    my %args = %{$_[0]};
770    my ($parameter, $section);
771    my $oldprefix = $lineprefix;
772
773    my $signature = "";
774    my $func_macro = $args{'func_macro'};
775    my $paramcount = $#{$args{'parameterlist'}}; # -1 is empty
776
777	if ($func_macro) {
778        $signature = $args{'function'};
779	} else {
780		if ($args{'functiontype'}) {
781        	$signature = $args{'functiontype'} . " ";
782		}
783		$signature .= $args{'function'} . " (";
784    }
785
786    my $count = 0;
787    foreach my $parameter (@{$args{'parameterlist'}}) {
788        if ($count ne 0) {
789            $signature .= ", ";
790        }
791        $count++;
792        $type = $args{'parametertypes'}{$parameter};
793
794        if ($type =~ m/$function_pointer/) {
795            # pointer-to-function
796            $signature .= $1 . $parameter . ") (" . $2 . ")";
797        } else {
798            $signature .= $type;
799        }
800    }
801
802    if (!$func_macro) {
803    	$signature .= ")";
804    }
805
806    if ($args{'typedef'} || $args{'functiontype'} eq "") {
807        print ".. c:macro:: ". $args{'function'} . "\n\n";
808
809        if ($args{'typedef'}) {
810            print_lineno($declaration_start_line);
811            print "   **Typedef**: ";
812            $lineprefix = "";
813            output_highlight_rst($args{'purpose'});
814            print "\n\n**Syntax**\n\n";
815            print "  ``$signature``\n\n";
816        } else {
817            print "``$signature``\n\n";
818        }
819    } else {
820        print ".. c:function:: $signature\n\n";
821    }
822
823    if (!$args{'typedef'}) {
824        print_lineno($declaration_start_line);
825        $lineprefix = "   ";
826        output_highlight_rst($args{'purpose'});
827        print "\n";
828    }
829
830    #
831    # Put our descriptive text into a container (thus an HTML <div>) to help
832    # set the function prototypes apart.
833    #
834    $lineprefix = "  ";
835	if ($paramcount >= 0) {
836    	print ".. container:: kernelindent\n\n";
837   		print $lineprefix . "**Parameters**\n\n";
838    }
839    foreach $parameter (@{$args{'parameterlist'}}) {
840        my $parameter_name = $parameter;
841        $parameter_name =~ s/\[.*//;
842        $type = $args{'parametertypes'}{$parameter};
843
844        if ($type ne "") {
845            print $lineprefix . "``$type``\n";
846        } else {
847            print $lineprefix . "``$parameter``\n";
848        }
849
850        print_lineno($parameterdesc_start_lines{$parameter_name});
851
852        $lineprefix = "    ";
853        if (defined($args{'parameterdescs'}{$parameter_name}) &&
854            $args{'parameterdescs'}{$parameter_name} ne $undescribed) {
855            output_highlight_rst($args{'parameterdescs'}{$parameter_name});
856        } else {
857            print $lineprefix . "*undescribed*\n";
858        }
859        $lineprefix = "  ";
860        print "\n";
861    }
862
863    output_section_rst(@_);
864    $lineprefix = $oldprefix;
865}
866
867sub output_section_rst(%) {
868    my %args = %{$_[0]};
869    my $section;
870    my $oldprefix = $lineprefix;
871
872    foreach $section (@{$args{'sectionlist'}}) {
873        print $lineprefix . "**$section**\n\n";
874        print_lineno($section_start_lines{$section});
875        output_highlight_rst($args{'sections'}{$section});
876        print "\n";
877    }
878    print "\n";
879}
880
881sub output_enum_rst(%) {
882    my %args = %{$_[0]};
883    my ($parameter);
884    my $oldprefix = $lineprefix;
885    my $count;
886    my $outer;
887
888    my $name = $args{'enum'};
889    print "\n\n.. c:enum:: " . $name . "\n\n";
890
891    print_lineno($declaration_start_line);
892    $lineprefix = "  ";
893    output_highlight_rst($args{'purpose'});
894    print "\n";
895
896    print ".. container:: kernelindent\n\n";
897    $outer = $lineprefix . "  ";
898    $lineprefix = $outer . "  ";
899    print $outer . "**Constants**\n\n";
900    foreach $parameter (@{$args{'parameterlist'}}) {
901        print $outer . "``$parameter``\n";
902
903        if ($args{'parameterdescs'}{$parameter} ne $undescribed) {
904            output_highlight_rst($args{'parameterdescs'}{$parameter});
905        } else {
906            print $lineprefix . "*undescribed*\n";
907        }
908        print "\n";
909    }
910    print "\n";
911    $lineprefix = $oldprefix;
912    output_section_rst(@_);
913}
914
915sub output_typedef_rst(%) {
916    my %args = %{$_[0]};
917    my ($parameter);
918    my $oldprefix = $lineprefix;
919    my $name;
920
921    $name = $args{'typedef'};
922
923    print "\n\n.. c:type:: " . $name . "\n\n";
924    print_lineno($declaration_start_line);
925    $lineprefix = "   ";
926    output_highlight_rst($args{'purpose'});
927    print "\n";
928
929    $lineprefix = $oldprefix;
930    output_section_rst(@_);
931}
932
933sub output_struct_rst(%) {
934    my %args = %{$_[0]};
935    my ($parameter);
936    my $oldprefix = $lineprefix;
937
938    my $name = $args{'struct'};
939    if ($args{'type'} eq 'union') {
940        print "\n\n.. c:union:: " . $name . "\n\n";
941    } else {
942        print "\n\n.. c:struct:: " . $name . "\n\n";
943    }
944
945    print_lineno($declaration_start_line);
946    $lineprefix = "  ";
947    output_highlight_rst($args{'purpose'});
948    print "\n";
949
950    print ".. container:: kernelindent\n\n";
951    print $lineprefix . "**Definition**::\n\n";
952    my $declaration = $args{'definition'};
953    $lineprefix = $lineprefix . "  ";
954    $declaration =~ s/\t/$lineprefix/g;
955    print $lineprefix . $args{'type'} . " " . $args{'struct'} . " {\n$declaration" . $lineprefix . "};\n\n";
956
957    $lineprefix = "  ";
958    print $lineprefix . "**Members**\n\n";
959    foreach $parameter (@{$args{'parameterlist'}}) {
960        ($parameter =~ /^#/) && next;
961
962        my $parameter_name = $parameter;
963        $parameter_name =~ s/\[.*//;
964
965        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
966        $type = $args{'parametertypes'}{$parameter};
967        print_lineno($parameterdesc_start_lines{$parameter_name});
968        print $lineprefix . "``" . $parameter . "``\n";
969        $lineprefix = "    ";
970        output_highlight_rst($args{'parameterdescs'}{$parameter_name});
971        $lineprefix = "  ";
972        print "\n";
973    }
974    print "\n";
975
976    $lineprefix = $oldprefix;
977    output_section_rst(@_);
978}
979
980## none mode output functions
981
982sub output_function_none(%) {
983}
984
985sub output_enum_none(%) {
986}
987
988sub output_typedef_none(%) {
989}
990
991sub output_struct_none(%) {
992}
993
994sub output_blockhead_none(%) {
995}
996
997##
998# generic output function for all types (function, struct/union, typedef, enum);
999# calls the generated, variable output_ function name based on
1000# functype and output_mode
1001sub output_declaration {
1002    no strict 'refs';
1003    my $name = shift;
1004    my $functype = shift;
1005    my $func = "output_${functype}_$output_mode";
1006
1007    return if (defined($nosymbol_table{$name}));
1008
1009    if (($output_selection == OUTPUT_ALL) ||
1010        (($output_selection == OUTPUT_INCLUDE ||
1011          $output_selection == OUTPUT_EXPORTED) &&
1012         defined($function_table{$name})) ||
1013        ($output_selection == OUTPUT_INTERNAL &&
1014         !($functype eq "function" && defined($function_table{$name}))))
1015    {
1016        &$func(@_);
1017        $section_counter++;
1018    }
1019}
1020
1021##
1022# generic output function - calls the right one based on current output mode.
1023sub output_blockhead {
1024    no strict 'refs';
1025    my $func = "output_blockhead_" . $output_mode;
1026    &$func(@_);
1027    $section_counter++;
1028}
1029
1030##
1031# takes a declaration (struct, union, enum, typedef) and
1032# invokes the right handler. NOT called for functions.
1033sub dump_declaration($$) {
1034    no strict 'refs';
1035    my ($prototype, $file) = @_;
1036    my $func = "dump_" . $decl_type;
1037    &$func(@_);
1038}
1039
1040sub dump_union($$) {
1041    dump_struct(@_);
1042}
1043
1044sub dump_struct($$) {
1045    my $x = shift;
1046    my $file = shift;
1047    my $decl_type;
1048    my $members;
1049    my $type = qr{struct|union};
1050    # For capturing struct/union definition body, i.e. "{members*}qualifiers*"
1051    my $qualifiers = qr{$attribute|__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned};
1052    my $definition_body = qr{\{(.*)\}\s*$qualifiers*};
1053    my $struct_members = qr{($type)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;};
1054
1055    if ($x =~ /($type)\s+(\w+)\s*$definition_body/) {
1056        $decl_type = $1;
1057        $declaration_name = $2;
1058        $members = $3;
1059    } elsif ($x =~ /typedef\s+($type)\s*$definition_body\s*(\w+)\s*;/) {
1060        $decl_type = $1;
1061        $declaration_name = $3;
1062        $members = $2;
1063    }
1064
1065    if ($members) {
1066        if ($identifier ne $declaration_name) {
1067            emit_warning("${file}:$.", "expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n");
1068            return;
1069        }
1070
1071        # ignore members marked private:
1072        $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi;
1073        $members =~ s/\/\*\s*private:.*//gosi;
1074        # strip comments:
1075        $members =~ s/\/\*.*?\*\///gos;
1076        # strip attributes
1077        $members =~ s/\s*$attribute/ /gi;
1078        $members =~ s/\s*__aligned\s*\([^;]*\)/ /gos;
1079        $members =~ s/\s*__counted_by\s*\([^;]*\)/ /gos;
1080        $members =~ s/\s*__counted_by_(le|be)\s*\([^;]*\)/ /gos;
1081        $members =~ s/\s*__packed\s*/ /gos;
1082        $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos;
1083        $members =~ s/\s*____cacheline_aligned_in_smp/ /gos;
1084        $members =~ s/\s*____cacheline_aligned/ /gos;
1085        # unwrap struct_group():
1086        # - first eat non-declaration parameters and rewrite for final match
1087        # - then remove macro, outer parens, and trailing semicolon
1088        $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos;
1089        $members =~ s/\bstruct_group_attr\s*\(([^,]*,){2}/STRUCT_GROUP(/gos;
1090        $members =~ s/\bstruct_group_tagged\s*\(([^,]*),([^,]*),/struct $1 $2; STRUCT_GROUP(/gos;
1091        $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos;
1092        $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos;
1093
1094        my $args = qr{([^,)]+)};
1095        # replace DECLARE_BITMAP
1096        $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos;
1097        $members =~ s/DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, PHY_INTERFACE_MODE_MAX)/gos;
1098        $members =~ s/DECLARE_BITMAP\s*\($args,\s*$args\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos;
1099        # replace DECLARE_HASHTABLE
1100        $members =~ s/DECLARE_HASHTABLE\s*\($args,\s*$args\)/unsigned long $1\[1 << (($2) - 1)\]/gos;
1101        # replace DECLARE_KFIFO
1102        $members =~ s/DECLARE_KFIFO\s*\($args,\s*$args,\s*$args\)/$2 \*$1/gos;
1103        # replace DECLARE_KFIFO_PTR
1104        $members =~ s/DECLARE_KFIFO_PTR\s*\($args,\s*$args\)/$2 \*$1/gos;
1105        # replace DECLARE_FLEX_ARRAY
1106        $members =~ s/(?:__)?DECLARE_FLEX_ARRAY\s*\($args,\s*$args\)/$1 $2\[\]/gos;
1107        #replace DEFINE_DMA_UNMAP_ADDR
1108        $members =~ s/DEFINE_DMA_UNMAP_ADDR\s*\($args\)/dma_addr_t $1/gos;
1109        #replace DEFINE_DMA_UNMAP_LEN
1110        $members =~ s/DEFINE_DMA_UNMAP_LEN\s*\($args\)/__u32 $1/gos;
1111        my $declaration = $members;
1112
1113        # Split nested struct/union elements as newer ones
1114        while ($members =~ m/$struct_members/) {
1115            my $newmember;
1116            my $maintype = $1;
1117            my $ids = $4;
1118            my $content = $3;
1119            foreach my $id(split /,/, $ids) {
1120                $newmember .= "$maintype $id; ";
1121
1122                $id =~ s/[:\[].*//;
1123                $id =~ s/^\s*\**(\S+)\s*/$1/;
1124                foreach my $arg (split /;/, $content) {
1125                    next if ($arg =~ m/^\s*$/);
1126                    if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) {
1127                        # pointer-to-function
1128                        my $type = $1;
1129                        my $name = $2;
1130                        my $extra = $3;
1131                        next if (!$name);
1132                        if ($id =~ m/^\s*$/) {
1133                            # anonymous struct/union
1134                            $newmember .= "$type$name$extra; ";
1135                        } else {
1136                            $newmember .= "$type$id.$name$extra; ";
1137                        }
1138                    } else {
1139                        my $type;
1140                        my $names;
1141                        $arg =~ s/^\s+//;
1142                        $arg =~ s/\s+$//;
1143                        # Handle bitmaps
1144                        $arg =~ s/:\s*\d+\s*//g;
1145                        # Handle arrays
1146                        $arg =~ s/\[.*\]//g;
1147                        # The type may have multiple words,
1148                        # and multiple IDs can be defined, like:
1149                        #    const struct foo, *bar, foobar
1150                        # So, we remove spaces when parsing the
1151                        # names, in order to match just names
1152                        # and commas for the names
1153                        $arg =~ s/\s*,\s*/,/g;
1154                        if ($arg =~ m/(.*)\s+([\S+,]+)/) {
1155                            $type = $1;
1156                            $names = $2;
1157                        } else {
1158                            $newmember .= "$arg; ";
1159                            next;
1160                        }
1161                        foreach my $name (split /,/, $names) {
1162                            $name =~ s/^\s*\**(\S+)\s*/$1/;
1163                            next if (($name =~ m/^\s*$/));
1164                            if ($id =~ m/^\s*$/) {
1165                                # anonymous struct/union
1166                                $newmember .= "$type $name; ";
1167                            } else {
1168                                $newmember .= "$type $id.$name; ";
1169                            }
1170                        }
1171                    }
1172                }
1173            }
1174            $members =~ s/$struct_members/$newmember/;
1175        }
1176
1177        # Ignore other nested elements, like enums
1178        $members =~ s/(\{[^\{\}]*\})//g;
1179
1180        create_parameterlist($members, ';', $file, $declaration_name);
1181        check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual);
1182
1183        # Adjust declaration for better display
1184        $declaration =~ s/([\{;])/$1\n/g;
1185        $declaration =~ s/\}\s+;/};/g;
1186        # Better handle inlined enums
1187        do {} while ($declaration =~ s/(enum\s+\{[^\}]+),([^\n])/$1,\n$2/);
1188
1189        my @def_args = split /\n/, $declaration;
1190        my $level = 1;
1191        $declaration = "";
1192        foreach my $clause (@def_args) {
1193            $clause =~ s/^\s+//;
1194            $clause =~ s/\s+$//;
1195            $clause =~ s/\s+/ /;
1196            next if (!$clause);
1197            $level-- if ($clause =~ m/(\})/ && $level > 1);
1198            if (!($clause =~ m/^\s*#/)) {
1199                $declaration .= "\t" x $level;
1200            }
1201            $declaration .= "\t" . $clause . "\n";
1202            $level++ if ($clause =~ m/(\{)/ && !($clause =~m/\}/));
1203        }
1204        output_declaration($declaration_name,
1205                   'struct',
1206                   {'struct' => $declaration_name,
1207                    'module' => $modulename,
1208                    'definition' => $declaration,
1209                    'parameterlist' => \@parameterlist,
1210                    'parameterdescs' => \%parameterdescs,
1211                    'parametertypes' => \%parametertypes,
1212                    'sectionlist' => \@sectionlist,
1213                    'sections' => \%sections,
1214                    'purpose' => $declaration_purpose,
1215                    'type' => $decl_type
1216                   });
1217    } else {
1218        print STDERR "${file}:$.: error: Cannot parse struct or union!\n";
1219        ++$errors;
1220    }
1221}
1222
1223
1224sub show_warnings($$) {
1225    my $functype = shift;
1226    my $name = shift;
1227
1228    return 0 if (defined($nosymbol_table{$name}));
1229
1230    return 1 if ($output_selection == OUTPUT_ALL);
1231
1232    if ($output_selection == OUTPUT_EXPORTED) {
1233        if (defined($function_table{$name})) {
1234            return 1;
1235        } else {
1236            return 0;
1237        }
1238    }
1239    if ($output_selection == OUTPUT_INTERNAL) {
1240        if (!($functype eq "function" && defined($function_table{$name}))) {
1241            return 1;
1242        } else {
1243            return 0;
1244        }
1245    }
1246    if ($output_selection == OUTPUT_INCLUDE) {
1247        if (defined($function_table{$name})) {
1248            return 1;
1249        } else {
1250            return 0;
1251        }
1252    }
1253    die("Please add the new output type at show_warnings()");
1254}
1255
1256sub dump_enum($$) {
1257    my $x = shift;
1258    my $file = shift;
1259    my $members;
1260
1261    # ignore members marked private:
1262    $x =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi;
1263    $x =~ s/\/\*\s*private:.*}/}/gosi;
1264
1265    $x =~ s@/\*.*?\*/@@gos;	# strip comments.
1266    # strip #define macros inside enums
1267    $x =~ s@#\s*((define|ifdef|if)\s+|endif)[^;]*;@@gos;
1268
1269    if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;/) {
1270        $declaration_name = $2;
1271        $members = $1;
1272    } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) {
1273        $declaration_name = $1;
1274        $members = $2;
1275    }
1276
1277    if ($members) {
1278        if ($identifier ne $declaration_name) {
1279            if ($identifier eq "") {
1280                emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n");
1281            } else {
1282                emit_warning("${file}:$.", "expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n");
1283            }
1284            return;
1285        }
1286        $declaration_name = "(anonymous)" if ($declaration_name eq "");
1287
1288        my %_members;
1289
1290        $members =~ s/\s+$//;
1291        $members =~ s/\([^;]*?[\)]//g;
1292
1293        foreach my $arg (split ',', $members) {
1294            $arg =~ s/^\s*(\w+).*/$1/;
1295            push @parameterlist, $arg;
1296            if (!$parameterdescs{$arg}) {
1297                $parameterdescs{$arg} = $undescribed;
1298                if (show_warnings("enum", $declaration_name)) {
1299                    emit_warning("${file}:$.", "Enum value '$arg' not described in enum '$declaration_name'\n");
1300                }
1301            }
1302            $_members{$arg} = 1;
1303        }
1304
1305        while (my ($k, $v) = each %parameterdescs) {
1306            if (!exists($_members{$k})) {
1307                if (show_warnings("enum", $declaration_name)) {
1308                    emit_warning("${file}:$.", "Excess enum value '$k' description in '$declaration_name'\n");
1309                }
1310            }
1311        }
1312
1313        output_declaration($declaration_name,
1314                           'enum',
1315                           {'enum' => $declaration_name,
1316                            'module' => $modulename,
1317                            'parameterlist' => \@parameterlist,
1318                            'parameterdescs' => \%parameterdescs,
1319                            'sectionlist' => \@sectionlist,
1320                            'sections' => \%sections,
1321                            'purpose' => $declaration_purpose
1322                           });
1323    } else {
1324        print STDERR "${file}:$.: error: Cannot parse enum!\n";
1325        ++$errors;
1326    }
1327}
1328
1329my $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8})\s* }x;
1330my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x;
1331my $typedef_args = qr { \s*\((.*)\); }x;
1332
1333my $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x;
1334my $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x;
1335
1336sub dump_typedef($$) {
1337    my $x = shift;
1338    my $file = shift;
1339
1340    $x =~ s@/\*.*?\*/@@gos;	# strip comments.
1341
1342    # Parse function typedef prototypes
1343    if ($x =~ $typedef1 || $x =~ $typedef2) {
1344        $return_type = $1;
1345        $declaration_name = $2;
1346        my $args = $3;
1347        $return_type =~ s/^\s+//;
1348
1349        if ($identifier ne $declaration_name) {
1350            emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n");
1351            return;
1352        }
1353
1354        create_parameterlist($args, ',', $file, $declaration_name);
1355
1356        output_declaration($declaration_name,
1357                           'function',
1358                           {'function' => $declaration_name,
1359                            'typedef' => 1,
1360                            'module' => $modulename,
1361                            'functiontype' => $return_type,
1362                            'parameterlist' => \@parameterlist,
1363                            'parameterdescs' => \%parameterdescs,
1364                            'parametertypes' => \%parametertypes,
1365                            'sectionlist' => \@sectionlist,
1366                            'sections' => \%sections,
1367                            'purpose' => $declaration_purpose
1368                           });
1369        return;
1370    }
1371
1372    while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
1373        $x =~ s/\(*.\)\s*;$/;/;
1374        $x =~ s/\[*.\]\s*;$/;/;
1375    }
1376
1377    if ($x =~ /typedef.*\s+(\w+)\s*;/) {
1378        $declaration_name = $1;
1379
1380        if ($identifier ne $declaration_name) {
1381            emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n");
1382            return;
1383        }
1384
1385        output_declaration($declaration_name,
1386                           'typedef',
1387                           {'typedef' => $declaration_name,
1388                            'module' => $modulename,
1389                            'sectionlist' => \@sectionlist,
1390                            'sections' => \%sections,
1391                            'purpose' => $declaration_purpose
1392                           });
1393    } else {
1394        print STDERR "${file}:$.: error: Cannot parse typedef!\n";
1395        ++$errors;
1396    }
1397}
1398
1399sub save_struct_actual($) {
1400    my $actual = shift;
1401
1402    # strip all spaces from the actual param so that it looks like one string item
1403    $actual =~ s/\s*//g;
1404    $struct_actual = $struct_actual . $actual . " ";
1405}
1406
1407sub create_parameterlist($$$$) {
1408    my $args = shift;
1409    my $splitter = shift;
1410    my $file = shift;
1411    my $declaration_name = shift;
1412    my $type;
1413    my $param;
1414
1415    # temporarily replace commas inside function pointer definition
1416    my $arg_expr = qr{\([^\),]+};
1417    while ($args =~ /$arg_expr,/) {
1418        $args =~ s/($arg_expr),/$1#/g;
1419    }
1420
1421    foreach my $arg (split($splitter, $args)) {
1422        # strip comments
1423        $arg =~ s/\/\*.*\*\///;
1424        # ignore argument attributes
1425        $arg =~ s/\sPOS0?\s/ /;
1426        # strip leading/trailing spaces
1427        $arg =~ s/^\s*//;
1428        $arg =~ s/\s*$//;
1429        $arg =~ s/\s+/ /;
1430
1431        if ($arg =~ /^#/) {
1432            # Treat preprocessor directive as a typeless variable just to fill
1433            # corresponding data structures "correctly". Catch it later in
1434            # output_* subs.
1435            push_parameter($arg, "", "", $file);
1436        } elsif ($arg =~ m/\(.+\)\s*\(/) {
1437            # pointer-to-function
1438            $arg =~ tr/#/,/;
1439            $arg =~ m/[^\(]+\(\*?\s*([\w\[\]\.]*)\s*\)/;
1440            $param = $1;
1441            $type = $arg;
1442            $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
1443            save_struct_actual($param);
1444            push_parameter($param, $type, $arg, $file, $declaration_name);
1445        } elsif ($arg =~ m/\(.+\)\s*\[/) {
1446            # array-of-pointers
1447            $arg =~ tr/#/,/;
1448            $arg =~ m/[^\(]+\(\s*\*\s*([\w\[\]\.]*?)\s*(\s*\[\s*[\w]+\s*\]\s*)*\)/;
1449            $param = $1;
1450            $type = $arg;
1451            $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
1452            save_struct_actual($param);
1453            push_parameter($param, $type, $arg, $file, $declaration_name);
1454        } elsif ($arg) {
1455            $arg =~ s/\s*:\s*/:/g;
1456            $arg =~ s/\s*\[/\[/g;
1457
1458            my @args = split('\s*,\s*', $arg);
1459            if ($args[0] =~ m/\*/) {
1460                $args[0] =~ s/(\*+)\s*/ $1/;
1461            }
1462
1463            my @first_arg;
1464            if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) {
1465                shift @args;
1466                push(@first_arg, split('\s+', $1));
1467                push(@first_arg, $2);
1468            } else {
1469                @first_arg = split('\s+', shift @args);
1470            }
1471
1472            unshift(@args, pop @first_arg);
1473            $type = join " ", @first_arg;
1474
1475            foreach $param (@args) {
1476                if ($param =~ m/^(\*+)\s*(.*)/) {
1477                    save_struct_actual($2);
1478
1479                    push_parameter($2, "$type $1", $arg, $file, $declaration_name);
1480                } elsif ($param =~ m/(.*?):(\w+)/) {
1481                    if ($type ne "") { # skip unnamed bit-fields
1482                        save_struct_actual($1);
1483                        push_parameter($1, "$type:$2", $arg, $file, $declaration_name)
1484                    }
1485                } else {
1486                    save_struct_actual($param);
1487                    push_parameter($param, $type, $arg, $file, $declaration_name);
1488                }
1489            }
1490        }
1491    }
1492}
1493
1494sub push_parameter($$$$$) {
1495    my $param = shift;
1496    my $type = shift;
1497    my $org_arg = shift;
1498    my $file = shift;
1499    my $declaration_name = shift;
1500
1501    if (($anon_struct_union == 1) && ($type eq "") &&
1502        ($param eq "}")) {
1503        return;        # ignore the ending }; from anon. struct/union
1504    }
1505
1506    $anon_struct_union = 0;
1507    $param =~ s/[\[\)].*//;
1508
1509    if ($type eq "" && $param =~ /\.\.\.$/)
1510    {
1511        if (!$param =~ /\w\.\.\.$/) {
1512            # handles unnamed variable parameters
1513            $param = "...";
1514        } elsif ($param =~ /\w\.\.\.$/) {
1515            # for named variable parameters of the form `x...`, remove the dots
1516            $param =~ s/\.\.\.$//;
1517        }
1518        if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
1519            $parameterdescs{$param} = "variable arguments";
1520        }
1521    }
1522    elsif ($type eq "" && ($param eq "" or $param eq "void"))
1523    {
1524        $param="void";
1525        $parameterdescs{void} = "no arguments";
1526    }
1527    elsif ($type eq "" && ($param eq "struct" or $param eq "union"))
1528    # handle unnamed (anonymous) union or struct:
1529    {
1530        $type = $param;
1531        $param = "{unnamed_" . $param . "}";
1532        $parameterdescs{$param} = "anonymous\n";
1533        $anon_struct_union = 1;
1534    }
1535    elsif ($param =~ "__cacheline_group" )
1536    # handle cache group enforcing variables: they do not need be described in header files
1537    {
1538        return; # ignore __cacheline_group_begin and __cacheline_group_end
1539    }
1540
1541    # warn if parameter has no description
1542    # (but ignore ones starting with # as these are not parameters
1543    # but inline preprocessor statements);
1544    # Note: It will also ignore void params and unnamed structs/unions
1545    if (!defined $parameterdescs{$param} && $param !~ /^#/) {
1546        $parameterdescs{$param} = $undescribed;
1547
1548        if (show_warnings($type, $declaration_name) && $param !~ /\./) {
1549            emit_warning("${file}:$.", "Function parameter or struct member '$param' not described in '$declaration_name'\n");
1550        }
1551    }
1552
1553    # strip spaces from $param so that it is one continuous string
1554    # on @parameterlist;
1555    # this fixes a problem where check_sections() cannot find
1556    # a parameter like "addr[6 + 2]" because it actually appears
1557    # as "addr[6", "+", "2]" on the parameter list;
1558    # but it's better to maintain the param string unchanged for output,
1559    # so just weaken the string compare in check_sections() to ignore
1560    # "[blah" in a parameter string;
1561    ###$param =~ s/\s*//g;
1562    push @parameterlist, $param;
1563    $org_arg =~ s/\s\s+/ /g;
1564    $parametertypes{$param} = $org_arg;
1565}
1566
1567sub check_sections($$$$$) {
1568    my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_;
1569    my @sects = split ' ', $sectcheck;
1570    my @prms = split ' ', $prmscheck;
1571    my $err;
1572    my ($px, $sx);
1573    my $prm_clean;        # strip trailing "[array size]" and/or beginning "*"
1574
1575    foreach $sx (0 .. $#sects) {
1576        $err = 1;
1577        foreach $px (0 .. $#prms) {
1578            $prm_clean = $prms[$px];
1579            $prm_clean =~ s/\[.*\]//;
1580            $prm_clean =~ s/$attribute//i;
1581            # ignore array size in a parameter string;
1582            # however, the original param string may contain
1583            # spaces, e.g.:  addr[6 + 2]
1584            # and this appears in @prms as "addr[6" since the
1585            # parameter list is split at spaces;
1586            # hence just ignore "[..." for the sections check;
1587            $prm_clean =~ s/\[.*//;
1588
1589            ##$prm_clean =~ s/^\**//;
1590            if ($prm_clean eq $sects[$sx]) {
1591                $err = 0;
1592                last;
1593            }
1594        }
1595        if ($err) {
1596            if ($decl_type eq "function") {
1597                emit_warning("${file}:$.",
1598                    "Excess function parameter " .
1599                    "'$sects[$sx]' " .
1600                    "description in '$decl_name'\n");
1601            } elsif (($decl_type eq "struct") or
1602                          ($decl_type eq "union")) {
1603                emit_warning("${file}:$.",
1604                    "Excess $decl_type member " .
1605                    "'$sects[$sx]' " .
1606                    "description in '$decl_name'\n");
1607            }
1608        }
1609    }
1610}
1611
1612##
1613# Checks the section describing the return value of a function.
1614sub check_return_section {
1615    my $file = shift;
1616    my $declaration_name = shift;
1617    my $return_type = shift;
1618
1619    # Ignore an empty return type (It's a macro)
1620    # Ignore functions with a "void" return type. (But don't ignore "void *")
1621    if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) {
1622        return;
1623    }
1624
1625    if (!defined($sections{$section_return}) ||
1626        $sections{$section_return} eq "")
1627    {
1628        emit_warning("${file}:$.",
1629                     "No description found for return value of " .
1630                     "'$declaration_name'\n");
1631    }
1632}
1633
1634##
1635# takes a function prototype and the name of the current file being
1636# processed and spits out all the details stored in the global
1637# arrays/hashes.
1638sub dump_function($$) {
1639    my $prototype = shift;
1640    my $file = shift;
1641    my $func_macro = 0;
1642
1643    print_lineno($new_start_line);
1644
1645    $prototype =~ s/^static +//;
1646    $prototype =~ s/^extern +//;
1647    $prototype =~ s/^asmlinkage +//;
1648    $prototype =~ s/^inline +//;
1649    $prototype =~ s/^__inline__ +//;
1650    $prototype =~ s/^__inline +//;
1651    $prototype =~ s/^__always_inline +//;
1652    $prototype =~ s/^noinline +//;
1653    $prototype =~ s/^__FORTIFY_INLINE +//;
1654    $prototype =~ s/__init +//;
1655    $prototype =~ s/__init_or_module +//;
1656    $prototype =~ s/__deprecated +//;
1657    $prototype =~ s/__flatten +//;
1658    $prototype =~ s/__meminit +//;
1659    $prototype =~ s/__must_check +//;
1660    $prototype =~ s/__weak +//;
1661    $prototype =~ s/__sched +//;
1662    $prototype =~ s/_noprof//;
1663    $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//;
1664    $prototype =~ s/__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//;
1665    $prototype =~ s/__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +//;
1666    $prototype =~ s/DECL_BUCKET_PARAMS\s*\(\s*(\S+)\s*,\s*(\S+)\s*\)/$1, $2/;
1667    my $define = $prototype =~ s/^#\s*define\s+//; #ak added
1668    $prototype =~ s/__attribute_const__ +//;
1669    $prototype =~ s/__attribute__\s*\(\(
1670            (?:
1671                 [\w\s]++          # attribute name
1672                 (?:\([^)]*+\))?   # attribute arguments
1673                 \s*+,?            # optional comma at the end
1674            )+
1675          \)\)\s+//x;
1676
1677    # Yes, this truly is vile.  We are looking for:
1678    # 1. Return type (may be nothing if we're looking at a macro)
1679    # 2. Function name
1680    # 3. Function parameters.
1681    #
1682    # All the while we have to watch out for function pointer parameters
1683    # (which IIRC is what the two sections are for), C types (these
1684    # regexps don't even start to express all the possibilities), and
1685    # so on.
1686    #
1687    # If you mess with these regexps, it's a good idea to check that
1688    # the following functions' documentation still comes out right:
1689    # - parport_register_device (function pointer parameters)
1690    # - atomic_set (macro)
1691    # - pci_match_device, __copy_to_user (long return type)
1692    my $name = qr{[a-zA-Z0-9_~:]+};
1693    my $prototype_end1 = qr{[^\(]*};
1694    my $prototype_end2 = qr{[^\{]*};
1695    my $prototype_end = qr{\(($prototype_end1|$prototype_end2)\)};
1696    my $type1 = qr{[\w\s]+};
1697    my $type2 = qr{$type1\*+};
1698
1699    if ($define && $prototype =~ m/^()($name)\s+/) {
1700        # This is an object-like macro, it has no return type and no parameter
1701        # list.
1702        # Function-like macros are not allowed to have spaces between
1703        # declaration_name and opening parenthesis (notice the \s+).
1704        $return_type = $1;
1705        $declaration_name = $2;
1706        $func_macro = 1;
1707    } elsif ($prototype =~ m/^()($name)\s*$prototype_end/ ||
1708        $prototype =~ m/^($type1)\s+($name)\s*$prototype_end/ ||
1709        $prototype =~ m/^($type2+)\s*($name)\s*$prototype_end/)  {
1710        $return_type = $1;
1711        $declaration_name = $2;
1712        my $args = $3;
1713
1714        create_parameterlist($args, ',', $file, $declaration_name);
1715    } else {
1716        emit_warning("${file}:$.", "cannot understand function prototype: '$prototype'\n");
1717        return;
1718    }
1719
1720    if ($identifier ne $declaration_name) {
1721        emit_warning("${file}:$.", "expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n");
1722        return;
1723    }
1724
1725    my $prms = join " ", @parameterlist;
1726    check_sections($file, $declaration_name, "function", $sectcheck, $prms);
1727
1728    # This check emits a lot of warnings at the moment, because many
1729    # functions don't have a 'Return' doc section. So until the number
1730    # of warnings goes sufficiently down, the check is only performed in
1731    # -Wreturn mode.
1732    # TODO: always perform the check.
1733    if ($Wreturn && !$func_macro) {
1734        check_return_section($file, $declaration_name, $return_type);
1735    }
1736
1737    # The function parser can be called with a typedef parameter.
1738    # Handle it.
1739    if ($return_type =~ /typedef/) {
1740        output_declaration($declaration_name,
1741                           'function',
1742                           {'function' => $declaration_name,
1743                            'typedef' => 1,
1744                            'module' => $modulename,
1745                            'functiontype' => $return_type,
1746                            'parameterlist' => \@parameterlist,
1747                            'parameterdescs' => \%parameterdescs,
1748                            'parametertypes' => \%parametertypes,
1749                            'sectionlist' => \@sectionlist,
1750                            'sections' => \%sections,
1751                            'purpose' => $declaration_purpose,
1752							'func_macro' => $func_macro
1753                           });
1754    } else {
1755        output_declaration($declaration_name,
1756                           'function',
1757                           {'function' => $declaration_name,
1758                            'module' => $modulename,
1759                            'functiontype' => $return_type,
1760                            'parameterlist' => \@parameterlist,
1761                            'parameterdescs' => \%parameterdescs,
1762                            'parametertypes' => \%parametertypes,
1763                            'sectionlist' => \@sectionlist,
1764                            'sections' => \%sections,
1765                            'purpose' => $declaration_purpose,
1766							'func_macro' => $func_macro
1767                           });
1768    }
1769}
1770
1771sub reset_state {
1772    $function = "";
1773    %parameterdescs = ();
1774    %parametertypes = ();
1775    @parameterlist = ();
1776    %sections = ();
1777    @sectionlist = ();
1778    $sectcheck = "";
1779    $struct_actual = "";
1780    $prototype = "";
1781
1782    $state = STATE_NORMAL;
1783    $inline_doc_state = STATE_INLINE_NA;
1784}
1785
1786sub tracepoint_munge($) {
1787    my $file = shift;
1788    my $tracepointname = 0;
1789    my $tracepointargs = 0;
1790
1791    if ($prototype =~ m/TRACE_EVENT\((.*?),/) {
1792        $tracepointname = $1;
1793    }
1794    if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) {
1795        $tracepointname = $1;
1796    }
1797    if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) {
1798        $tracepointname = $2;
1799    }
1800    $tracepointname =~ s/^\s+//; #strip leading whitespace
1801    if ($prototype =~ m/TP_PROTO\((.*?)\)/) {
1802        $tracepointargs = $1;
1803    }
1804    if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
1805        emit_warning("${file}:$.", "Unrecognized tracepoint format: \n".
1806                 "$prototype\n");
1807    } else {
1808        $prototype = "static inline void trace_$tracepointname($tracepointargs)";
1809        $identifier = "trace_$identifier";
1810    }
1811}
1812
1813sub syscall_munge() {
1814    my $void = 0;
1815
1816    $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's
1817##    if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) {
1818    if ($prototype =~ m/SYSCALL_DEFINE0/) {
1819        $void = 1;
1820##        $prototype = "long sys_$1(void)";
1821    }
1822
1823    $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name
1824    if ($prototype =~ m/long (sys_.*?),/) {
1825        $prototype =~ s/,/\(/;
1826    } elsif ($void) {
1827        $prototype =~ s/\)/\(void\)/;
1828    }
1829
1830    # now delete all of the odd-number commas in $prototype
1831    # so that arg types & arg names don't have a comma between them
1832    my $count = 0;
1833    my $len = length($prototype);
1834    if ($void) {
1835        $len = 0;    # skip the for-loop
1836    }
1837    for (my $ix = 0; $ix < $len; $ix++) {
1838        if (substr($prototype, $ix, 1) eq ',') {
1839            $count++;
1840            if ($count % 2 == 1) {
1841                substr($prototype, $ix, 1) = ' ';
1842            }
1843        }
1844    }
1845}
1846
1847sub process_proto_function($$) {
1848    my $x = shift;
1849    my $file = shift;
1850
1851    $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
1852
1853    if ($x =~ /^#/ && $x !~ /^#\s*define/) {
1854        # do nothing
1855    } elsif ($x =~ /([^\{]*)/) {
1856        $prototype .= $1;
1857    }
1858
1859    if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) {
1860        $prototype =~ s@/\*.*?\*/@@gos;        # strip comments.
1861        $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1862        $prototype =~ s@^\s+@@gos; # strip leading spaces
1863
1864        # Handle prototypes for function pointers like:
1865        # int (*pcs_config)(struct foo)
1866        $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos;
1867
1868        if ($prototype =~ /SYSCALL_DEFINE/) {
1869            syscall_munge();
1870        }
1871        if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ ||
1872            $prototype =~ /DEFINE_SINGLE_EVENT/)
1873        {
1874            tracepoint_munge($file);
1875        }
1876        dump_function($prototype, $file);
1877        reset_state();
1878    }
1879}
1880
1881sub process_proto_type($$) {
1882    my $x = shift;
1883    my $file = shift;
1884
1885    $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1886    $x =~ s@^\s+@@gos; # strip leading spaces
1887    $x =~ s@\s+$@@gos; # strip trailing spaces
1888    $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
1889
1890    if ($x =~ /^#/) {
1891        # To distinguish preprocessor directive from regular declaration later.
1892        $x .= ";";
1893    }
1894
1895    while (1) {
1896        if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ ) {
1897            if( length $prototype ) {
1898                $prototype .= " "
1899            }
1900            $prototype .= $1 . $2;
1901            ($2 eq '{') && $brcount++;
1902            ($2 eq '}') && $brcount--;
1903            if (($2 eq ';') && ($brcount == 0)) {
1904                dump_declaration($prototype, $file);
1905                reset_state();
1906                last;
1907            }
1908            $x = $3;
1909        } else {
1910            $prototype .= $x;
1911            last;
1912        }
1913    }
1914}
1915
1916
1917sub map_filename($) {
1918    my $file;
1919    my ($orig_file) = @_;
1920
1921    if (defined($ENV{'SRCTREE'})) {
1922        $file = "$ENV{'SRCTREE'}" . "/" . $orig_file;
1923    } else {
1924        $file = $orig_file;
1925    }
1926
1927    return $file;
1928}
1929
1930sub process_export_file($) {
1931    my ($orig_file) = @_;
1932    my $file = map_filename($orig_file);
1933
1934    if (!open(IN,"<$file")) {
1935        print STDERR "Error: Cannot open file $file\n";
1936        ++$errors;
1937        return;
1938    }
1939
1940    while (<IN>) {
1941        if (/$export_symbol/) {
1942            next if (defined($nosymbol_table{$2}));
1943            $function_table{$2} = 1;
1944        }
1945        if (/$export_symbol_ns/) {
1946            next if (defined($nosymbol_table{$2}));
1947            $function_table{$2} = 1;
1948        }
1949    }
1950
1951    close(IN);
1952}
1953
1954#
1955# Parsers for the various processing states.
1956#
1957# STATE_NORMAL: looking for the /** to begin everything.
1958#
1959sub process_normal() {
1960    if (/$doc_start/o) {
1961        $state = STATE_NAME;        # next line is always the function name
1962        $in_doc_sect = 0;
1963        $declaration_start_line = $. + 1;
1964    }
1965}
1966
1967#
1968# STATE_NAME: Looking for the "name - description" line
1969#
1970sub process_name($$) {
1971    my $file = shift;
1972    my $descr;
1973
1974    if (/$doc_block/o) {
1975        $state = STATE_DOCBLOCK;
1976        $contents = "";
1977        $new_start_line = $.;
1978
1979        if ( $1 eq "" ) {
1980            $section = $section_intro;
1981        } else {
1982            $section = $1;
1983        }
1984    } elsif (/$doc_decl/o) {
1985        $identifier = $1;
1986        my $is_kernel_comment = 0;
1987        my $decl_start = qr{$doc_com};
1988        # test for pointer declaration type, foo * bar() - desc
1989        my $fn_type = qr{\w+\s*\*\s*};
1990        my $parenthesis = qr{\(\w*\)};
1991        my $decl_end = qr{[-:].*};
1992        if (/^$decl_start([\w\s]+?)$parenthesis?\s*$decl_end?$/) {
1993            $identifier = $1;
1994        }
1995        if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) {
1996            $decl_type = $1;
1997            $identifier = $2;
1998            $is_kernel_comment = 1;
1999        }
2000        # Look for foo() or static void foo() - description; or misspelt
2001        # identifier
2002        elsif (/^$decl_start$fn_type?(\w+)\s*$parenthesis?\s*$decl_end?$/ ||
2003            /^$decl_start$fn_type?(\w+[^-:]*)$parenthesis?\s*$decl_end$/) {
2004            $identifier = $1;
2005            $decl_type = 'function';
2006            $identifier =~ s/^define\s+//;
2007            $is_kernel_comment = 1;
2008        }
2009        $identifier =~ s/\s+$//;
2010
2011        $state = STATE_BODY;
2012        # if there's no @param blocks need to set up default section
2013        # here
2014        $contents = "";
2015        $section = $section_default;
2016        $new_start_line = $. + 1;
2017        if (/[-:](.*)/) {
2018            # strip leading/trailing/multiple spaces
2019            $descr= $1;
2020            $descr =~ s/^\s*//;
2021            $descr =~ s/\s*$//;
2022            $descr =~ s/\s+/ /g;
2023            $declaration_purpose = $descr;
2024            $state = STATE_BODY_MAYBE;
2025        } else {
2026            $declaration_purpose = "";
2027        }
2028
2029        if (!$is_kernel_comment) {
2030            emit_warning("${file}:$.", "This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n$_");
2031            $state = STATE_NORMAL;
2032        }
2033
2034        if (($declaration_purpose eq "") && $Wshort_desc) {
2035            emit_warning("${file}:$.", "missing initial short description on line:\n$_");
2036        }
2037
2038        if ($identifier eq "" && $decl_type ne "enum") {
2039            emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n$_");
2040            $state = STATE_NORMAL;
2041        }
2042
2043        if ($verbose) {
2044            print STDERR "${file}:$.: info: Scanning doc for $decl_type $identifier\n";
2045        }
2046    } else {
2047        emit_warning("${file}:$.", "Cannot understand $_ on line $. - I thought it was a doc line\n");
2048        $state = STATE_NORMAL;
2049    }
2050}
2051
2052
2053#
2054# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment.
2055#
2056sub process_body($$) {
2057    my $file = shift;
2058
2059    if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) {
2060        dump_section($file, $section, $contents);
2061        $section = $section_default;
2062        $new_start_line = $.;
2063        $contents = "";
2064    }
2065
2066    if (/$doc_sect/i) { # case insensitive for supported section names
2067        $in_doc_sect = 1;
2068        $newsection = $1;
2069        $newcontents = $2;
2070
2071        # map the supported section names to the canonical names
2072        if ($newsection =~ m/^description$/i) {
2073            $newsection = $section_default;
2074        } elsif ($newsection =~ m/^context$/i) {
2075            $newsection = $section_context;
2076        } elsif ($newsection =~ m/^returns?$/i) {
2077            $newsection = $section_return;
2078        } elsif ($newsection =~ m/^\@return$/) {
2079            # special: @return is a section, not a param description
2080            $newsection = $section_return;
2081        }
2082
2083        if (($contents ne "") && ($contents ne "\n")) {
2084            if (!$in_doc_sect && $Wcontents_before_sections) {
2085                emit_warning("${file}:$.", "contents before sections\n");
2086            }
2087            dump_section($file, $section, $contents);
2088            $section = $section_default;
2089        }
2090
2091        $in_doc_sect = 1;
2092        $state = STATE_BODY;
2093        $contents = $newcontents;
2094        $new_start_line = $.;
2095        while (substr($contents, 0, 1) eq " ") {
2096            $contents = substr($contents, 1);
2097        }
2098        if ($contents ne "") {
2099            $contents .= "\n";
2100        }
2101        $section = $newsection;
2102        $leading_space = undef;
2103    } elsif (/$doc_end/) {
2104        if (($contents ne "") && ($contents ne "\n")) {
2105            dump_section($file, $section, $contents);
2106            $section = $section_default;
2107            $contents = "";
2108        }
2109        # look for doc_com + <text> + doc_end:
2110        if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
2111            emit_warning("${file}:$.", "suspicious ending line: $_");
2112        }
2113
2114        $prototype = "";
2115        $state = STATE_PROTO;
2116        $brcount = 0;
2117        $new_start_line = $. + 1;
2118    } elsif (/$doc_content/) {
2119        if ($1 eq "") {
2120            if ($section eq $section_context) {
2121                dump_section($file, $section, $contents);
2122                $section = $section_default;
2123                $contents = "";
2124                $new_start_line = $.;
2125                $state = STATE_BODY;
2126            } else {
2127                if ($section ne $section_default) {
2128                    $state = STATE_BODY_WITH_BLANK_LINE;
2129                } else {
2130                    $state = STATE_BODY;
2131                }
2132                $contents .= "\n";
2133            }
2134        } elsif ($state == STATE_BODY_MAYBE) {
2135            # Continued declaration purpose
2136            chomp($declaration_purpose);
2137            $declaration_purpose .= " " . $1;
2138            $declaration_purpose =~ s/\s+/ /g;
2139        } else {
2140            my $cont = $1;
2141            if ($section =~ m/^@/ || $section eq $section_context) {
2142                if (!defined $leading_space) {
2143                    if ($cont =~ m/^(\s+)/) {
2144                        $leading_space = $1;
2145                    } else {
2146                        $leading_space = "";
2147                    }
2148                }
2149                $cont =~ s/^$leading_space//;
2150            }
2151            $contents .= $cont . "\n";
2152        }
2153    } else {
2154        # i dont know - bad line?  ignore.
2155        emit_warning("${file}:$.", "bad line: $_");
2156    }
2157}
2158
2159
2160#
2161# STATE_PROTO: reading a function/whatever prototype.
2162#
2163sub process_proto($$) {
2164    my $file = shift;
2165
2166    if (/$doc_inline_oneline/) {
2167        $section = $1;
2168        $contents = $2;
2169        if ($contents ne "") {
2170            $contents .= "\n";
2171            dump_section($file, $section, $contents);
2172            $section = $section_default;
2173            $contents = "";
2174        }
2175    } elsif (/$doc_inline_start/) {
2176        $state = STATE_INLINE;
2177        $inline_doc_state = STATE_INLINE_NAME;
2178    } elsif ($decl_type eq 'function') {
2179        process_proto_function($_, $file);
2180    } else {
2181        process_proto_type($_, $file);
2182    }
2183}
2184
2185#
2186# STATE_DOCBLOCK: within a DOC: block.
2187#
2188sub process_docblock($$) {
2189    my $file = shift;
2190
2191    if (/$doc_end/) {
2192        dump_doc_section($file, $section, $contents);
2193        $section = $section_default;
2194        $contents = "";
2195        $function = "";
2196        %parameterdescs = ();
2197        %parametertypes = ();
2198        @parameterlist = ();
2199        %sections = ();
2200        @sectionlist = ();
2201        $prototype = "";
2202        $state = STATE_NORMAL;
2203    } elsif (/$doc_content/) {
2204        if ( $1 eq "" )        {
2205            $contents .= $blankline;
2206        } else {
2207            $contents .= $1 . "\n";
2208        }
2209    }
2210}
2211
2212#
2213# STATE_INLINE: docbook comments within a prototype.
2214#
2215sub process_inline($$) {
2216    my $file = shift;
2217
2218    # First line (state 1) needs to be a @parameter
2219    if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) {
2220        $section = $1;
2221        $contents = $2;
2222        $new_start_line = $.;
2223        if ($contents ne "") {
2224            while (substr($contents, 0, 1) eq " ") {
2225                $contents = substr($contents, 1);
2226            }
2227            $contents .= "\n";
2228        }
2229        $inline_doc_state = STATE_INLINE_TEXT;
2230        # Documentation block end */
2231    } elsif (/$doc_inline_end/) {
2232        if (($contents ne "") && ($contents ne "\n")) {
2233            dump_section($file, $section, $contents);
2234            $section = $section_default;
2235            $contents = "";
2236        }
2237        $state = STATE_PROTO;
2238        $inline_doc_state = STATE_INLINE_NA;
2239        # Regular text
2240    } elsif (/$doc_content/) {
2241        if ($inline_doc_state == STATE_INLINE_TEXT) {
2242            $contents .= $1 . "\n";
2243            # nuke leading blank lines
2244            if ($contents =~ /^\s*$/) {
2245                $contents = "";
2246            }
2247        } elsif ($inline_doc_state == STATE_INLINE_NAME) {
2248            $inline_doc_state = STATE_INLINE_ERROR;
2249            emit_warning("${file}:$.", "Incorrect use of kernel-doc format: $_");
2250        }
2251    }
2252}
2253
2254
2255sub process_file($) {
2256    my $file;
2257    my ($orig_file) = @_;
2258
2259    $file = map_filename($orig_file);
2260
2261    if (!open(IN_FILE,"<$file")) {
2262        print STDERR "Error: Cannot open file $file\n";
2263        ++$errors;
2264        return;
2265    }
2266
2267    $. = 1;
2268
2269    $section_counter = 0;
2270    while (<IN_FILE>) {
2271        while (!/^ \*/ && s/\\\s*$//) {
2272            $_ .= <IN_FILE>;
2273        }
2274        # Replace tabs by spaces
2275        while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {};
2276        # Hand this line to the appropriate state handler
2277        if ($state == STATE_NORMAL) {
2278            process_normal();
2279        } elsif ($state == STATE_NAME) {
2280            process_name($file, $_);
2281        } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE ||
2282                 $state == STATE_BODY_WITH_BLANK_LINE) {
2283            process_body($file, $_);
2284        } elsif ($state == STATE_INLINE) { # scanning for inline parameters
2285            process_inline($file, $_);
2286        } elsif ($state == STATE_PROTO) {
2287            process_proto($file, $_);
2288        } elsif ($state == STATE_DOCBLOCK) {
2289            process_docblock($file, $_);
2290        }
2291    }
2292
2293    # Make sure we got something interesting.
2294    if (!$section_counter && $output_mode ne "none") {
2295        if ($output_selection == OUTPUT_INCLUDE) {
2296            emit_warning("${file}:1", "'$_' not found\n")
2297                for keys %function_table;
2298        } else {
2299            emit_warning("${file}:1", "no structured comments found\n");
2300        }
2301    }
2302    close IN_FILE;
2303}
2304
2305$kernelversion = get_kernel_version();
2306
2307# generate a sequence of code that will splice in highlighting information
2308# using the s// operator.
2309for (my $k = 0; $k < @highlights; $k++) {
2310    my $pattern = $highlights[$k][0];
2311    my $result = $highlights[$k][1];
2312#   print STDERR "scanning pattern:$pattern, highlight:($result)\n";
2313    $dohighlight .=  "\$contents =~ s:$pattern:$result:gs;\n";
2314}
2315
2316if ($output_selection == OUTPUT_EXPORTED ||
2317    $output_selection == OUTPUT_INTERNAL) {
2318
2319    push(@export_file_list, @ARGV);
2320
2321    foreach (@export_file_list) {
2322        chomp;
2323        process_export_file($_);
2324    }
2325}
2326
2327foreach (@ARGV) {
2328    chomp;
2329    process_file($_);
2330}
2331if ($verbose && $errors) {
2332    print STDERR "$errors errors\n";
2333}
2334if ($verbose && $warnings) {
2335    print STDERR "$warnings warnings\n";
2336}
2337
2338if ($Werror && $warnings) {
2339    print STDERR "$warnings warnings as Errors\n";
2340    exit($warnings);
2341} else {
2342    exit($output_mode eq "none" ? 0 : $errors)
2343}
2344
2345__END__
2346
2347=head1 OPTIONS
2348
2349=head2 Output format selection (mutually exclusive):
2350
2351=over 8
2352
2353=item -man
2354
2355Output troff manual page format.
2356
2357=item -rst
2358
2359Output reStructuredText format. This is the default.
2360
2361=item -none
2362
2363Do not output documentation, only warnings.
2364
2365=back
2366
2367=head2 Output format modifiers
2368
2369=head3 reStructuredText only
2370
2371=head2 Output selection (mutually exclusive):
2372
2373=over 8
2374
2375=item -export
2376
2377Only output documentation for the symbols that have been exported using
2378EXPORT_SYMBOL() and related macros in any input FILE or -export-file FILE.
2379
2380=item -internal
2381
2382Only output documentation for the symbols that have NOT been exported using
2383EXPORT_SYMBOL() and related macros in any input FILE or -export-file FILE.
2384
2385=item -function NAME
2386
2387Only output documentation for the given function or DOC: section title.
2388All other functions and DOC: sections are ignored.
2389
2390May be specified multiple times.
2391
2392=item -nosymbol NAME
2393
2394Exclude the specified symbol from the output documentation.
2395
2396May be specified multiple times.
2397
2398=back
2399
2400=head2 Output selection modifiers:
2401
2402=over 8
2403
2404=item -no-doc-sections
2405
2406Do not output DOC: sections.
2407
2408=item -export-file FILE
2409
2410Specify an additional FILE in which to look for EXPORT_SYMBOL information.
2411
2412To be used with -export or -internal.
2413
2414May be specified multiple times.
2415
2416=back
2417
2418=head3 reStructuredText only
2419
2420=over 8
2421
2422=item -enable-lineno
2423
2424Enable output of .. LINENO lines.
2425
2426=back
2427
2428=head2 Other parameters:
2429
2430=over 8
2431
2432=item -h, -help
2433
2434Print this help.
2435
2436=item -v
2437
2438Verbose output, more warnings and other information.
2439
2440=item -Werror
2441
2442Treat warnings as errors.
2443
2444=back
2445
2446=cut
2447