ia64/linux-2.6.18-xen.hg

view scripts/kernel-doc @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 #!/usr/bin/perl -w
3 use strict;
5 ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
6 ## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
7 ## Copyright (C) 2001 Simon Huggins ##
8 ## ##
9 ## #define enhancements by Armin Kuster <akuster@mvista.com> ##
10 ## Copyright (c) 2000 MontaVista Software, Inc. ##
11 ## ##
12 ## This software falls under the GNU General Public License. ##
13 ## Please read the COPYING file for more information ##
15 # w.o. 03-11-2000: added the '-filelist' option.
17 # 18/01/2001 - Cleanups
18 # Functions prototyped as foo(void) same as foo()
19 # Stop eval'ing where we don't need to.
20 # -- huggie@earth.li
22 # 27/06/2001 - Allowed whitespace after initial "/**" and
23 # allowed comments before function declarations.
24 # -- Christian Kreibich <ck@whoop.org>
26 # Still to do:
27 # - add perldoc documentation
28 # - Look more closely at some of the scarier bits :)
30 # 26/05/2001 - Support for separate source and object trees.
31 # Return error code.
32 # Keith Owens <kaos@ocs.com.au>
34 # 23/09/2001 - Added support for typedefs, structs, enums and unions
35 # Support for Context section; can be terminated using empty line
36 # Small fixes (like spaces vs. \s in regex)
37 # -- Tim Jansen <tim@tjansen.de>
40 #
41 # This will read a 'c' file and scan for embedded comments in the
42 # style of gnome comments (+minor extensions - see below).
43 #
45 # Note: This only supports 'c'.
47 # usage:
48 # kernel-doc [ -docbook | -html | -text | -man ]
49 # [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
50 # or
51 # [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
52 #
53 # Set output format using one of -docbook -html -text or -man. Default is man.
54 #
55 # -function funcname
56 # If set, then only generate documentation for the given function(s). All
57 # other functions are ignored.
58 #
59 # -nofunction funcname
60 # If set, then only generate documentation for the other function(s). All
61 # other functions are ignored. Cannot be used with -function together
62 # (yes, that's a bug -- perl hackers can fix it 8))
63 #
64 # c files - list of 'c' files to process
65 #
66 # All output goes to stdout, with errors to stderr.
68 #
69 # format of comments.
70 # In the following table, (...)? signifies optional structure.
71 # (...)* signifies 0 or more structure elements
72 # /**
73 # * function_name(:)? (- short description)?
74 # (* @parameterx: (description of parameter x)?)*
75 # (* a blank line)?
76 # * (Description:)? (Description of function)?
77 # * (section header: (section description)? )*
78 # (*)?*/
79 #
80 # So .. the trivial example would be:
81 #
82 # /**
83 # * my_function
84 # **/
85 #
86 # If the Description: header tag is ommitted, then there must be a blank line
87 # after the last parameter specification.
88 # e.g.
89 # /**
90 # * my_function - does my stuff
91 # * @my_arg: its mine damnit
92 # *
93 # * Does my stuff explained.
94 # */
95 #
96 # or, could also use:
97 # /**
98 # * my_function - does my stuff
99 # * @my_arg: its mine damnit
100 # * Description: Does my stuff explained.
101 # */
102 # etc.
103 #
104 # Beside functions you can also write documentation for structs, unions,
105 # enums and typedefs. Instead of the function name you must write the name
106 # of the declaration; the struct/union/enum/typedef must always precede
107 # the name. Nesting of declarations is not supported.
108 # Use the argument mechanism to document members or constants.
109 # e.g.
110 # /**
111 # * struct my_struct - short description
112 # * @a: first member
113 # * @b: second member
114 # *
115 # * Longer description
116 # */
117 # struct my_struct {
118 # int a;
119 # int b;
120 # /* private: */
121 # int c;
122 # };
123 #
124 # All descriptions can be multiline, except the short function description.
125 #
126 # You can also add additional sections. When documenting kernel functions you
127 # should document the "Context:" of the function, e.g. whether the functions
128 # can be called form interrupts. Unlike other sections you can end it with an
129 # empty line.
130 # Example-sections should contain the string EXAMPLE so that they are marked
131 # appropriately in DocBook.
132 #
133 # Example:
134 # /**
135 # * user_function - function that can only be called in user context
136 # * @a: some argument
137 # * Context: !in_interrupt()
138 # *
139 # * Some description
140 # * Example:
141 # * user_function(22);
142 # */
143 # ...
144 #
145 #
146 # All descriptive text is further processed, scanning for the following special
147 # patterns, which are highlighted appropriately.
148 #
149 # 'funcname()' - function
150 # '$ENVVAR' - environmental variable
151 # '&struct_name' - name of a structure (up to two words including 'struct')
152 # '@parameter' - name of a parameter
153 # '%CONST' - name of a constant.
155 my $errors = 0;
156 my $warnings = 0;
158 # match expressions used to find embedded type information
159 my $type_constant = '\%([-_\w]+)';
160 my $type_func = '(\w+)\(\)';
161 my $type_param = '\@(\w+)';
162 my $type_struct = '\&((struct\s*)?[_\w]+)';
163 my $type_env = '(\$\w+)';
165 # Output conversion substitutions.
166 # One for each output format
168 # these work fairly well
169 my %highlights_html = ( $type_constant, "<i>\$1</i>",
170 $type_func, "<b>\$1</b>",
171 $type_struct, "<i>\$1</i>",
172 $type_param, "<tt><b>\$1</b></tt>" );
173 my $blankline_html = "<p>";
175 # XML, docbook format
176 my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
177 $type_constant, "<constant>\$1</constant>",
178 $type_func, "<function>\$1</function>",
179 $type_struct, "<structname>\$1</structname>",
180 $type_env, "<envar>\$1</envar>",
181 $type_param, "<parameter>\$1</parameter>" );
182 my $blankline_xml = "</para><para>\n";
184 # gnome, docbook format
185 my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
186 $type_func, "<function>\$1</function>",
187 $type_struct, "<structname>\$1</structname>",
188 $type_env, "<envar>\$1</envar>",
189 $type_param, "<parameter>\$1</parameter>" );
190 my $blankline_gnome = "</para><para>\n";
192 # these are pretty rough
193 my %highlights_man = ( $type_constant, "\$1",
194 $type_func, "\\\\fB\$1\\\\fP",
195 $type_struct, "\\\\fI\$1\\\\fP",
196 $type_param, "\\\\fI\$1\\\\fP" );
197 my $blankline_man = "";
199 # text-mode
200 my %highlights_text = ( $type_constant, "\$1",
201 $type_func, "\$1",
202 $type_struct, "\$1",
203 $type_param, "\$1" );
204 my $blankline_text = "";
207 sub usage {
208 print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
209 print " [ -function funcname [ -function funcname ...] ]\n";
210 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
211 print " c source file(s) > outputfile\n";
212 exit 1;
213 }
215 # read arguments
216 if ($#ARGV==-1) {
217 usage();
218 }
220 my $verbose = 0;
221 my $output_mode = "man";
222 my %highlights = %highlights_man;
223 my $blankline = $blankline_man;
224 my $modulename = "Kernel API";
225 my $function_only = 0;
226 my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
227 'July', 'August', 'September', 'October',
228 'November', 'December')[(localtime)[4]] .
229 " " . ((localtime)[5]+1900);
231 # Essentially these are globals
232 # They probably want to be tidied up made more localised or summat.
233 # CAVEAT EMPTOR! Some of the others I localised may not want to be which
234 # could cause "use of undefined value" or other bugs.
235 my ($function, %function_table,%parametertypes,$declaration_purpose);
236 my ($type,$declaration_name,$return_type);
237 my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
239 # Generated docbook code is inserted in a template at a point where
240 # docbook v3.1 requires a non-zero sequence of RefEntry's; see:
241 # http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
242 # We keep track of number of generated entries and generate a dummy
243 # if needs be to ensure the expanded template can be postprocessed
244 # into html.
245 my $section_counter = 0;
247 my $lineprefix="";
249 # states
250 # 0 - normal code
251 # 1 - looking for function name
252 # 2 - scanning field start.
253 # 3 - scanning prototype.
254 # 4 - documentation block
255 my $state;
256 my $in_doc_sect;
258 #declaration types: can be
259 # 'function', 'struct', 'union', 'enum', 'typedef'
260 my $decl_type;
262 my $doc_special = "\@\%\$\&";
264 my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
265 my $doc_end = '\*/';
266 my $doc_com = '\s*\*\s*';
267 my $doc_decl = $doc_com.'(\w+)';
268 my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)';
269 my $doc_content = $doc_com.'(.*)';
270 my $doc_block = $doc_com.'DOC:\s*(.*)?';
272 my %constants;
273 my %parameterdescs;
274 my @parameterlist;
275 my %sections;
276 my @sectionlist;
278 my $contents = "";
279 my $section_default = "Description"; # default section
280 my $section_intro = "Introduction";
281 my $section = $section_default;
282 my $section_context = "Context";
284 my $undescribed = "-- undescribed --";
286 reset_state();
288 while ($ARGV[0] =~ m/^-(.*)/) {
289 my $cmd = shift @ARGV;
290 if ($cmd eq "-html") {
291 $output_mode = "html";
292 %highlights = %highlights_html;
293 $blankline = $blankline_html;
294 } elsif ($cmd eq "-man") {
295 $output_mode = "man";
296 %highlights = %highlights_man;
297 $blankline = $blankline_man;
298 } elsif ($cmd eq "-text") {
299 $output_mode = "text";
300 %highlights = %highlights_text;
301 $blankline = $blankline_text;
302 } elsif ($cmd eq "-docbook") {
303 $output_mode = "xml";
304 %highlights = %highlights_xml;
305 $blankline = $blankline_xml;
306 } elsif ($cmd eq "-gnome") {
307 $output_mode = "gnome";
308 %highlights = %highlights_gnome;
309 $blankline = $blankline_gnome;
310 } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
311 $modulename = shift @ARGV;
312 } elsif ($cmd eq "-function") { # to only output specific functions
313 $function_only = 1;
314 $function = shift @ARGV;
315 $function_table{$function} = 1;
316 } elsif ($cmd eq "-nofunction") { # to only output specific functions
317 $function_only = 2;
318 $function = shift @ARGV;
319 $function_table{$function} = 1;
320 } elsif ($cmd eq "-v") {
321 $verbose = 1;
322 } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
323 usage();
324 } elsif ($cmd eq '-filelist') {
325 $filelist = shift @ARGV;
326 }
327 }
330 # generate a sequence of code that will splice in highlighting information
331 # using the s// operator.
332 my $dohighlight = "";
333 foreach my $pattern (keys %highlights) {
334 # print "scanning pattern $pattern ($highlights{$pattern})\n";
335 $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
336 }
338 ##
339 # dumps section contents to arrays/hashes intended for that purpose.
340 #
341 sub dump_section {
342 my $name = shift;
343 my $contents = join "\n", @_;
345 if ($name =~ m/$type_constant/) {
346 $name = $1;
347 # print STDERR "constant section '$1' = '$contents'\n";
348 $constants{$name} = $contents;
349 } elsif ($name =~ m/$type_param/) {
350 # print STDERR "parameter def '$1' = '$contents'\n";
351 $name = $1;
352 $parameterdescs{$name} = $contents;
353 } else {
354 # print STDERR "other section '$name' = '$contents'\n";
355 $sections{$name} = $contents;
356 push @sectionlist, $name;
357 }
358 }
360 ##
361 # output function
362 #
363 # parameterdescs, a hash.
364 # function => "function name"
365 # parameterlist => @list of parameters
366 # parameterdescs => %parameter descriptions
367 # sectionlist => @list of sections
368 # sections => %descriont descriptions
369 #
371 sub output_highlight {
372 my $contents = join "\n",@_;
373 my $line;
375 # DEBUG
376 # if (!defined $contents) {
377 # use Carp;
378 # confess "output_highlight got called with no args?\n";
379 # }
381 eval $dohighlight;
382 die $@ if $@;
383 foreach $line (split "\n", $contents) {
384 if ($line eq ""){
385 print $lineprefix, $blankline;
386 } else {
387 $line =~ s/\\\\\\/\&/g;
388 print $lineprefix, $line;
389 }
390 print "\n";
391 }
392 }
394 #output sections in html
395 sub output_section_html(%) {
396 my %args = %{$_[0]};
397 my $section;
399 foreach $section (@{$args{'sectionlist'}}) {
400 print "<h3>$section</h3>\n";
401 print "<blockquote>\n";
402 output_highlight($args{'sections'}{$section});
403 print "</blockquote>\n";
404 }
405 }
407 # output enum in html
408 sub output_enum_html(%) {
409 my %args = %{$_[0]};
410 my ($parameter);
411 my $count;
412 print "<h2>enum ".$args{'enum'}."</h2>\n";
414 print "<b>enum ".$args{'enum'}."</b> {<br>\n";
415 $count = 0;
416 foreach $parameter (@{$args{'parameterlist'}}) {
417 print " <b>".$parameter."</b>";
418 if ($count != $#{$args{'parameterlist'}}) {
419 $count++;
420 print ",\n";
421 }
422 print "<br>";
423 }
424 print "};<br>\n";
426 print "<h3>Constants</h3>\n";
427 print "<dl>\n";
428 foreach $parameter (@{$args{'parameterlist'}}) {
429 print "<dt><b>".$parameter."</b>\n";
430 print "<dd>";
431 output_highlight($args{'parameterdescs'}{$parameter});
432 }
433 print "</dl>\n";
434 output_section_html(@_);
435 print "<hr>\n";
436 }
438 # output typedef in html
439 sub output_typedef_html(%) {
440 my %args = %{$_[0]};
441 my ($parameter);
442 my $count;
443 print "<h2>typedef ".$args{'typedef'}."</h2>\n";
445 print "<b>typedef ".$args{'typedef'}."</b>\n";
446 output_section_html(@_);
447 print "<hr>\n";
448 }
450 # output struct in html
451 sub output_struct_html(%) {
452 my %args = %{$_[0]};
453 my ($parameter);
455 print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n";
456 print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n";
457 foreach $parameter (@{$args{'parameterlist'}}) {
458 if ($parameter =~ /^#/) {
459 print "$parameter<br>\n";
460 next;
461 }
462 my $parameter_name = $parameter;
463 $parameter_name =~ s/\[.*//;
465 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
466 $type = $args{'parametertypes'}{$parameter};
467 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
468 # pointer-to-function
469 print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
470 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
471 print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
472 } else {
473 print " <i>$type</i> <b>$parameter</b>;<br>\n";
474 }
475 }
476 print "};<br>\n";
478 print "<h3>Members</h3>\n";
479 print "<dl>\n";
480 foreach $parameter (@{$args{'parameterlist'}}) {
481 ($parameter =~ /^#/) && next;
483 my $parameter_name = $parameter;
484 $parameter_name =~ s/\[.*//;
486 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
487 print "<dt><b>".$parameter."</b>\n";
488 print "<dd>";
489 output_highlight($args{'parameterdescs'}{$parameter_name});
490 }
491 print "</dl>\n";
492 output_section_html(@_);
493 print "<hr>\n";
494 }
496 # output function in html
497 sub output_function_html(%) {
498 my %args = %{$_[0]};
499 my ($parameter, $section);
500 my $count;
501 print "<h2>Function</h2>\n";
503 print "<i>".$args{'functiontype'}."</i>\n";
504 print "<b>".$args{'function'}."</b>\n";
505 print "(";
506 $count = 0;
507 foreach $parameter (@{$args{'parameterlist'}}) {
508 $type = $args{'parametertypes'}{$parameter};
509 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
510 # pointer-to-function
511 print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
512 } else {
513 print "<i>".$type."</i> <b>".$parameter."</b>";
514 }
515 if ($count != $#{$args{'parameterlist'}}) {
516 $count++;
517 print ",\n";
518 }
519 }
520 print ")\n";
522 print "<h3>Arguments</h3>\n";
523 print "<dl>\n";
524 foreach $parameter (@{$args{'parameterlist'}}) {
525 my $parameter_name = $parameter;
526 $parameter_name =~ s/\[.*//;
528 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
529 print "<dt><b>".$parameter."</b>\n";
530 print "<dd>";
531 output_highlight($args{'parameterdescs'}{$parameter_name});
532 }
533 print "</dl>\n";
534 output_section_html(@_);
535 print "<hr>\n";
536 }
538 # output intro in html
539 sub output_intro_html(%) {
540 my %args = %{$_[0]};
541 my ($parameter, $section);
542 my $count;
544 foreach $section (@{$args{'sectionlist'}}) {
545 print "<h3>$section</h3>\n";
546 print "<ul>\n";
547 output_highlight($args{'sections'}{$section});
548 print "</ul>\n";
549 }
550 print "<hr>\n";
551 }
553 sub output_section_xml(%) {
554 my %args = %{$_[0]};
555 my $section;
556 # print out each section
557 $lineprefix=" ";
558 foreach $section (@{$args{'sectionlist'}}) {
559 print "<refsect1>\n";
560 print "<title>$section</title>\n";
561 if ($section =~ m/EXAMPLE/i) {
562 print "<informalexample><programlisting>\n";
563 } else {
564 print "<para>\n";
565 }
566 output_highlight($args{'sections'}{$section});
567 if ($section =~ m/EXAMPLE/i) {
568 print "</programlisting></informalexample>\n";
569 } else {
570 print "</para>\n";
571 }
572 print "</refsect1>\n";
573 }
574 }
576 # output function in XML DocBook
577 sub output_function_xml(%) {
578 my %args = %{$_[0]};
579 my ($parameter, $section);
580 my $count;
581 my $id;
583 $id = "API-".$args{'function'};
584 $id =~ s/[^A-Za-z0-9]/-/g;
586 print "<refentry>\n";
587 print "<refentryinfo>\n";
588 print " <title>LINUX</title>\n";
589 print " <productname>Kernel Hackers Manual</productname>\n";
590 print " <date>$man_date</date>\n";
591 print "</refentryinfo>\n";
592 print "<refmeta>\n";
593 print " <refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
594 print " <manvolnum>9</manvolnum>\n";
595 print "</refmeta>\n";
596 print "<refnamediv>\n";
597 print " <refname>".$args{'function'}."</refname>\n";
598 print " <refpurpose>\n";
599 print " ";
600 output_highlight ($args{'purpose'});
601 print " </refpurpose>\n";
602 print "</refnamediv>\n";
604 print "<refsynopsisdiv>\n";
605 print " <title>Synopsis</title>\n";
606 print " <funcsynopsis><funcprototype>\n";
607 print " <funcdef>".$args{'functiontype'}." ";
608 print "<function>".$args{'function'}." </function></funcdef>\n";
610 $count = 0;
611 if ($#{$args{'parameterlist'}} >= 0) {
612 foreach $parameter (@{$args{'parameterlist'}}) {
613 $type = $args{'parametertypes'}{$parameter};
614 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
615 # pointer-to-function
616 print " <paramdef>$1<parameter>$parameter</parameter>)\n";
617 print " <funcparams>$2</funcparams></paramdef>\n";
618 } else {
619 print " <paramdef>".$type;
620 print " <parameter>$parameter</parameter></paramdef>\n";
621 }
622 }
623 } else {
624 print " <void/>\n";
625 }
626 print " </funcprototype></funcsynopsis>\n";
627 print "</refsynopsisdiv>\n";
629 # print parameters
630 print "<refsect1>\n <title>Arguments</title>\n";
631 if ($#{$args{'parameterlist'}} >= 0) {
632 print " <variablelist>\n";
633 foreach $parameter (@{$args{'parameterlist'}}) {
634 my $parameter_name = $parameter;
635 $parameter_name =~ s/\[.*//;
637 print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n";
638 print " <listitem>\n <para>\n";
639 $lineprefix=" ";
640 output_highlight($args{'parameterdescs'}{$parameter_name});
641 print " </para>\n </listitem>\n </varlistentry>\n";
642 }
643 print " </variablelist>\n";
644 } else {
645 print " <para>\n None\n </para>\n";
646 }
647 print "</refsect1>\n";
649 output_section_xml(@_);
650 print "</refentry>\n\n";
651 }
653 # output struct in XML DocBook
654 sub output_struct_xml(%) {
655 my %args = %{$_[0]};
656 my ($parameter, $section);
657 my $id;
659 $id = "API-struct-".$args{'struct'};
660 $id =~ s/[^A-Za-z0-9]/-/g;
662 print "<refentry>\n";
663 print "<refentryinfo>\n";
664 print " <title>LINUX</title>\n";
665 print " <productname>Kernel Hackers Manual</productname>\n";
666 print " <date>$man_date</date>\n";
667 print "</refentryinfo>\n";
668 print "<refmeta>\n";
669 print " <refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
670 print " <manvolnum>9</manvolnum>\n";
671 print "</refmeta>\n";
672 print "<refnamediv>\n";
673 print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
674 print " <refpurpose>\n";
675 print " ";
676 output_highlight ($args{'purpose'});
677 print " </refpurpose>\n";
678 print "</refnamediv>\n";
680 print "<refsynopsisdiv>\n";
681 print " <title>Synopsis</title>\n";
682 print " <programlisting>\n";
683 print $args{'type'}." ".$args{'struct'}." {\n";
684 foreach $parameter (@{$args{'parameterlist'}}) {
685 if ($parameter =~ /^#/) {
686 print "$parameter\n";
687 next;
688 }
690 my $parameter_name = $parameter;
691 $parameter_name =~ s/\[.*//;
693 defined($args{'parameterdescs'}{$parameter_name}) || next;
694 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
695 $type = $args{'parametertypes'}{$parameter};
696 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
697 # pointer-to-function
698 print " $1 $parameter) ($2);\n";
699 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
700 print " $1 $parameter$2;\n";
701 } else {
702 print " ".$type." ".$parameter.";\n";
703 }
704 }
705 print "};";
706 print " </programlisting>\n";
707 print "</refsynopsisdiv>\n";
709 print " <refsect1>\n";
710 print " <title>Members</title>\n";
712 print " <variablelist>\n";
713 foreach $parameter (@{$args{'parameterlist'}}) {
714 ($parameter =~ /^#/) && next;
716 my $parameter_name = $parameter;
717 $parameter_name =~ s/\[.*//;
719 defined($args{'parameterdescs'}{$parameter_name}) || next;
720 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
721 print " <varlistentry>";
722 print " <term>$parameter</term>\n";
723 print " <listitem><para>\n";
724 output_highlight($args{'parameterdescs'}{$parameter_name});
725 print " </para></listitem>\n";
726 print " </varlistentry>\n";
727 }
728 print " </variablelist>\n";
729 print " </refsect1>\n";
731 output_section_xml(@_);
733 print "</refentry>\n\n";
734 }
736 # output enum in XML DocBook
737 sub output_enum_xml(%) {
738 my %args = %{$_[0]};
739 my ($parameter, $section);
740 my $count;
741 my $id;
743 $id = "API-enum-".$args{'enum'};
744 $id =~ s/[^A-Za-z0-9]/-/g;
746 print "<refentry>\n";
747 print "<refentryinfo>\n";
748 print " <title>LINUX</title>\n";
749 print " <productname>Kernel Hackers Manual</productname>\n";
750 print " <date>$man_date</date>\n";
751 print "</refentryinfo>\n";
752 print "<refmeta>\n";
753 print " <refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n";
754 print " <manvolnum>9</manvolnum>\n";
755 print "</refmeta>\n";
756 print "<refnamediv>\n";
757 print " <refname>enum ".$args{'enum'}."</refname>\n";
758 print " <refpurpose>\n";
759 print " ";
760 output_highlight ($args{'purpose'});
761 print " </refpurpose>\n";
762 print "</refnamediv>\n";
764 print "<refsynopsisdiv>\n";
765 print " <title>Synopsis</title>\n";
766 print " <programlisting>\n";
767 print "enum ".$args{'enum'}." {\n";
768 $count = 0;
769 foreach $parameter (@{$args{'parameterlist'}}) {
770 print " $parameter";
771 if ($count != $#{$args{'parameterlist'}}) {
772 $count++;
773 print ",";
774 }
775 print "\n";
776 }
777 print "};";
778 print " </programlisting>\n";
779 print "</refsynopsisdiv>\n";
781 print "<refsect1>\n";
782 print " <title>Constants</title>\n";
783 print " <variablelist>\n";
784 foreach $parameter (@{$args{'parameterlist'}}) {
785 my $parameter_name = $parameter;
786 $parameter_name =~ s/\[.*//;
788 print " <varlistentry>";
789 print " <term>$parameter</term>\n";
790 print " <listitem><para>\n";
791 output_highlight($args{'parameterdescs'}{$parameter_name});
792 print " </para></listitem>\n";
793 print " </varlistentry>\n";
794 }
795 print " </variablelist>\n";
796 print "</refsect1>\n";
798 output_section_xml(@_);
800 print "</refentry>\n\n";
801 }
803 # output typedef in XML DocBook
804 sub output_typedef_xml(%) {
805 my %args = %{$_[0]};
806 my ($parameter, $section);
807 my $id;
809 $id = "API-typedef-".$args{'typedef'};
810 $id =~ s/[^A-Za-z0-9]/-/g;
812 print "<refentry>\n";
813 print "<refentryinfo>\n";
814 print " <title>LINUX</title>\n";
815 print " <productname>Kernel Hackers Manual</productname>\n";
816 print " <date>$man_date</date>\n";
817 print "</refentryinfo>\n";
818 print "<refmeta>\n";
819 print " <refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n";
820 print " <manvolnum>9</manvolnum>\n";
821 print "</refmeta>\n";
822 print "<refnamediv>\n";
823 print " <refname>typedef ".$args{'typedef'}."</refname>\n";
824 print " <refpurpose>\n";
825 print " ";
826 output_highlight ($args{'purpose'});
827 print " </refpurpose>\n";
828 print "</refnamediv>\n";
830 print "<refsynopsisdiv>\n";
831 print " <title>Synopsis</title>\n";
832 print " <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n";
833 print "</refsynopsisdiv>\n";
835 output_section_xml(@_);
837 print "</refentry>\n\n";
838 }
840 # output in XML DocBook
841 sub output_intro_xml(%) {
842 my %args = %{$_[0]};
843 my ($parameter, $section);
844 my $count;
846 my $id = $args{'module'};
847 $id =~ s/[^A-Za-z0-9]/-/g;
849 # print out each section
850 $lineprefix=" ";
851 foreach $section (@{$args{'sectionlist'}}) {
852 print "<refsect1>\n <title>$section</title>\n <para>\n";
853 if ($section =~ m/EXAMPLE/i) {
854 print "<example><para>\n";
855 }
856 output_highlight($args{'sections'}{$section});
857 if ($section =~ m/EXAMPLE/i) {
858 print "</para></example>\n";
859 }
860 print " </para>\n</refsect1>\n";
861 }
863 print "\n\n";
864 }
866 # output in XML DocBook
867 sub output_function_gnome {
868 my %args = %{$_[0]};
869 my ($parameter, $section);
870 my $count;
871 my $id;
873 $id = $args{'module'}."-".$args{'function'};
874 $id =~ s/[^A-Za-z0-9]/-/g;
876 print "<sect2>\n";
877 print " <title id=\"$id\">".$args{'function'}."</title>\n";
879 print " <funcsynopsis>\n";
880 print " <funcdef>".$args{'functiontype'}." ";
881 print "<function>".$args{'function'}." ";
882 print "</function></funcdef>\n";
884 $count = 0;
885 if ($#{$args{'parameterlist'}} >= 0) {
886 foreach $parameter (@{$args{'parameterlist'}}) {
887 $type = $args{'parametertypes'}{$parameter};
888 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
889 # pointer-to-function
890 print " <paramdef>$1 <parameter>$parameter</parameter>)\n";
891 print " <funcparams>$2</funcparams></paramdef>\n";
892 } else {
893 print " <paramdef>".$type;
894 print " <parameter>$parameter</parameter></paramdef>\n";
895 }
896 }
897 } else {
898 print " <void>\n";
899 }
900 print " </funcsynopsis>\n";
901 if ($#{$args{'parameterlist'}} >= 0) {
902 print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
903 print "<tgroup cols=\"2\">\n";
904 print "<colspec colwidth=\"2*\">\n";
905 print "<colspec colwidth=\"8*\">\n";
906 print "<tbody>\n";
907 foreach $parameter (@{$args{'parameterlist'}}) {
908 my $parameter_name = $parameter;
909 $parameter_name =~ s/\[.*//;
911 print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
912 print " <entry>\n";
913 $lineprefix=" ";
914 output_highlight($args{'parameterdescs'}{$parameter_name});
915 print " </entry></row>\n";
916 }
917 print " </tbody></tgroup></informaltable>\n";
918 } else {
919 print " <para>\n None\n </para>\n";
920 }
922 # print out each section
923 $lineprefix=" ";
924 foreach $section (@{$args{'sectionlist'}}) {
925 print "<simplesect>\n <title>$section</title>\n";
926 if ($section =~ m/EXAMPLE/i) {
927 print "<example><programlisting>\n";
928 } else {
929 }
930 print "<para>\n";
931 output_highlight($args{'sections'}{$section});
932 print "</para>\n";
933 if ($section =~ m/EXAMPLE/i) {
934 print "</programlisting></example>\n";
935 } else {
936 }
937 print " </simplesect>\n";
938 }
940 print "</sect2>\n\n";
941 }
943 ##
944 # output function in man
945 sub output_function_man(%) {
946 my %args = %{$_[0]};
947 my ($parameter, $section);
948 my $count;
950 print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
952 print ".SH NAME\n";
953 print $args{'function'}." \\- ".$args{'purpose'}."\n";
955 print ".SH SYNOPSIS\n";
956 print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n";
957 $count = 0;
958 my $parenth = "(";
959 my $post = ",";
960 foreach my $parameter (@{$args{'parameterlist'}}) {
961 if ($count == $#{$args{'parameterlist'}}) {
962 $post = ");";
963 }
964 $type = $args{'parametertypes'}{$parameter};
965 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
966 # pointer-to-function
967 print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n";
968 } else {
969 $type =~ s/([^\*])$/$1 /;
970 print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n";
971 }
972 $count++;
973 $parenth = "";
974 }
976 print ".SH ARGUMENTS\n";
977 foreach $parameter (@{$args{'parameterlist'}}) {
978 my $parameter_name = $parameter;
979 $parameter_name =~ s/\[.*//;
981 print ".IP \"".$parameter."\" 12\n";
982 output_highlight($args{'parameterdescs'}{$parameter_name});
983 }
984 foreach $section (@{$args{'sectionlist'}}) {
985 print ".SH \"", uc $section, "\"\n";
986 output_highlight($args{'sections'}{$section});
987 }
988 }
990 ##
991 # output enum in man
992 sub output_enum_man(%) {
993 my %args = %{$_[0]};
994 my ($parameter, $section);
995 my $count;
997 print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
999 print ".SH NAME\n";
1000 print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n";
1002 print ".SH SYNOPSIS\n";
1003 print "enum ".$args{'enum'}." {\n";
1004 $count = 0;
1005 foreach my $parameter (@{$args{'parameterlist'}}) {
1006 print ".br\n.BI \" $parameter\"\n";
1007 if ($count == $#{$args{'parameterlist'}}) {
1008 print "\n};\n";
1009 last;
1011 else {
1012 print ", \n.br\n";
1014 $count++;
1017 print ".SH Constants\n";
1018 foreach $parameter (@{$args{'parameterlist'}}) {
1019 my $parameter_name = $parameter;
1020 $parameter_name =~ s/\[.*//;
1022 print ".IP \"".$parameter."\" 12\n";
1023 output_highlight($args{'parameterdescs'}{$parameter_name});
1025 foreach $section (@{$args{'sectionlist'}}) {
1026 print ".SH \"$section\"\n";
1027 output_highlight($args{'sections'}{$section});
1031 ##
1032 # output struct in man
1033 sub output_struct_man(%) {
1034 my %args = %{$_[0]};
1035 my ($parameter, $section);
1037 print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n";
1039 print ".SH NAME\n";
1040 print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n";
1042 print ".SH SYNOPSIS\n";
1043 print $args{'type'}." ".$args{'struct'}." {\n.br\n";
1045 foreach my $parameter (@{$args{'parameterlist'}}) {
1046 if ($parameter =~ /^#/) {
1047 print ".BI \"$parameter\"\n.br\n";
1048 next;
1050 my $parameter_name = $parameter;
1051 $parameter_name =~ s/\[.*//;
1053 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1054 $type = $args{'parametertypes'}{$parameter};
1055 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1056 # pointer-to-function
1057 print ".BI \" ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n";
1058 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1059 # bitfield
1060 print ".BI \" ".$1."\ \" ".$parameter.$2." \""."\"\n;\n";
1061 } else {
1062 $type =~ s/([^\*])$/$1 /;
1063 print ".BI \" ".$type."\" ".$parameter." \""."\"\n;\n";
1065 print "\n.br\n";
1067 print "};\n.br\n";
1069 print ".SH Members\n";
1070 foreach $parameter (@{$args{'parameterlist'}}) {
1071 ($parameter =~ /^#/) && next;
1073 my $parameter_name = $parameter;
1074 $parameter_name =~ s/\[.*//;
1076 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1077 print ".IP \"".$parameter."\" 12\n";
1078 output_highlight($args{'parameterdescs'}{$parameter_name});
1080 foreach $section (@{$args{'sectionlist'}}) {
1081 print ".SH \"$section\"\n";
1082 output_highlight($args{'sections'}{$section});
1086 ##
1087 # output typedef in man
1088 sub output_typedef_man(%) {
1089 my %args = %{$_[0]};
1090 my ($parameter, $section);
1092 print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
1094 print ".SH NAME\n";
1095 print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n";
1097 foreach $section (@{$args{'sectionlist'}}) {
1098 print ".SH \"$section\"\n";
1099 output_highlight($args{'sections'}{$section});
1103 sub output_intro_man(%) {
1104 my %args = %{$_[0]};
1105 my ($parameter, $section);
1106 my $count;
1108 print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
1110 foreach $section (@{$args{'sectionlist'}}) {
1111 print ".SH \"$section\"\n";
1112 output_highlight($args{'sections'}{$section});
1116 ##
1117 # output in text
1118 sub output_function_text(%) {
1119 my %args = %{$_[0]};
1120 my ($parameter, $section);
1122 print "Name:\n\n";
1123 print $args{'function'}." - ".$args{'purpose'}."\n";
1125 print "\nSynopsis:\n\n";
1126 my $start=$args{'functiontype'}." ".$args{'function'}." (";
1127 print $start;
1128 my $count = 0;
1129 foreach my $parameter (@{$args{'parameterlist'}}) {
1130 $type = $args{'parametertypes'}{$parameter};
1131 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1132 # pointer-to-function
1133 print $1.$parameter.") (".$2;
1134 } else {
1135 print $type." ".$parameter;
1137 if ($count != $#{$args{'parameterlist'}}) {
1138 $count++;
1139 print ",\n";
1140 print " " x length($start);
1141 } else {
1142 print ");\n\n";
1146 print "Arguments:\n\n";
1147 foreach $parameter (@{$args{'parameterlist'}}) {
1148 my $parameter_name = $parameter;
1149 $parameter_name =~ s/\[.*//;
1151 print $parameter."\n\t".$args{'parameterdescs'}{$parameter_name}."\n";
1153 output_section_text(@_);
1156 #output sections in text
1157 sub output_section_text(%) {
1158 my %args = %{$_[0]};
1159 my $section;
1161 print "\n";
1162 foreach $section (@{$args{'sectionlist'}}) {
1163 print "$section:\n\n";
1164 output_highlight($args{'sections'}{$section});
1166 print "\n\n";
1169 # output enum in text
1170 sub output_enum_text(%) {
1171 my %args = %{$_[0]};
1172 my ($parameter);
1173 my $count;
1174 print "Enum:\n\n";
1176 print "enum ".$args{'enum'}." - ".$args{'purpose'}."\n\n";
1177 print "enum ".$args{'enum'}." {\n";
1178 $count = 0;
1179 foreach $parameter (@{$args{'parameterlist'}}) {
1180 print "\t$parameter";
1181 if ($count != $#{$args{'parameterlist'}}) {
1182 $count++;
1183 print ",";
1185 print "\n";
1187 print "};\n\n";
1189 print "Constants:\n\n";
1190 foreach $parameter (@{$args{'parameterlist'}}) {
1191 print "$parameter\n\t";
1192 print $args{'parameterdescs'}{$parameter}."\n";
1195 output_section_text(@_);
1198 # output typedef in text
1199 sub output_typedef_text(%) {
1200 my %args = %{$_[0]};
1201 my ($parameter);
1202 my $count;
1203 print "Typedef:\n\n";
1205 print "typedef ".$args{'typedef'}." - ".$args{'purpose'}."\n";
1206 output_section_text(@_);
1209 # output struct as text
1210 sub output_struct_text(%) {
1211 my %args = %{$_[0]};
1212 my ($parameter);
1214 print $args{'type'}." ".$args{'struct'}." - ".$args{'purpose'}."\n\n";
1215 print $args{'type'}." ".$args{'struct'}." {\n";
1216 foreach $parameter (@{$args{'parameterlist'}}) {
1217 if ($parameter =~ /^#/) {
1218 print "$parameter\n";
1219 next;
1222 my $parameter_name = $parameter;
1223 $parameter_name =~ s/\[.*//;
1225 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1226 $type = $args{'parametertypes'}{$parameter};
1227 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1228 # pointer-to-function
1229 print "\t$1 $parameter) ($2);\n";
1230 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1231 print "\t$1 $parameter$2;\n";
1232 } else {
1233 print "\t".$type." ".$parameter.";\n";
1236 print "};\n\n";
1238 print "Members:\n\n";
1239 foreach $parameter (@{$args{'parameterlist'}}) {
1240 ($parameter =~ /^#/) && next;
1242 my $parameter_name = $parameter;
1243 $parameter_name =~ s/\[.*//;
1245 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1246 print "$parameter\n\t";
1247 print $args{'parameterdescs'}{$parameter_name}."\n";
1249 print "\n";
1250 output_section_text(@_);
1253 sub output_intro_text(%) {
1254 my %args = %{$_[0]};
1255 my ($parameter, $section);
1257 foreach $section (@{$args{'sectionlist'}}) {
1258 print " $section:\n";
1259 print " -> ";
1260 output_highlight($args{'sections'}{$section});
1264 ##
1265 # generic output function for typedefs
1266 sub output_declaration {
1267 no strict 'refs';
1268 my $name = shift;
1269 my $functype = shift;
1270 my $func = "output_${functype}_$output_mode";
1271 if (($function_only==0) ||
1272 ( $function_only == 1 && defined($function_table{$name})) ||
1273 ( $function_only == 2 && !defined($function_table{$name})))
1275 &$func(@_);
1276 $section_counter++;
1280 ##
1281 # generic output function - calls the right one based
1282 # on current output mode.
1283 sub output_intro {
1284 no strict 'refs';
1285 my $func = "output_intro_".$output_mode;
1286 &$func(@_);
1287 $section_counter++;
1290 ##
1291 # takes a declaration (struct, union, enum, typedef) and
1292 # invokes the right handler. NOT called for functions.
1293 sub dump_declaration($$) {
1294 no strict 'refs';
1295 my ($prototype, $file) = @_;
1296 my $func = "dump_".$decl_type;
1297 &$func(@_);
1300 sub dump_union($$) {
1301 dump_struct(@_);
1304 sub dump_struct($$) {
1305 my $x = shift;
1306 my $file = shift;
1308 if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
1309 $declaration_name = $2;
1310 my $members = $3;
1312 # ignore embedded structs or unions
1313 $members =~ s/{.*?}//g;
1315 # ignore members marked private:
1316 $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
1317 $members =~ s/\/\*.*?private:.*//gos;
1318 # strip comments:
1319 $members =~ s/\/\*.*?\*\///gos;
1321 create_parameterlist($members, ';', $file);
1323 output_declaration($declaration_name,
1324 'struct',
1325 {'struct' => $declaration_name,
1326 'module' => $modulename,
1327 'parameterlist' => \@parameterlist,
1328 'parameterdescs' => \%parameterdescs,
1329 'parametertypes' => \%parametertypes,
1330 'sectionlist' => \@sectionlist,
1331 'sections' => \%sections,
1332 'purpose' => $declaration_purpose,
1333 'type' => $decl_type
1334 });
1336 else {
1337 print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
1338 ++$errors;
1342 sub dump_enum($$) {
1343 my $x = shift;
1344 my $file = shift;
1346 $x =~ s@/\*.*?\*/@@gos; # strip comments.
1347 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
1348 $declaration_name = $1;
1349 my $members = $2;
1351 foreach my $arg (split ',', $members) {
1352 $arg =~ s/^\s*(\w+).*/$1/;
1353 push @parameterlist, $arg;
1354 if (!$parameterdescs{$arg}) {
1355 $parameterdescs{$arg} = $undescribed;
1356 print STDERR "Warning(${file}:$.): Enum value '$arg' ".
1357 "not described in enum '$declaration_name'\n";
1362 output_declaration($declaration_name,
1363 'enum',
1364 {'enum' => $declaration_name,
1365 'module' => $modulename,
1366 'parameterlist' => \@parameterlist,
1367 'parameterdescs' => \%parameterdescs,
1368 'sectionlist' => \@sectionlist,
1369 'sections' => \%sections,
1370 'purpose' => $declaration_purpose
1371 });
1373 else {
1374 print STDERR "Error(${file}:$.): Cannot parse enum!\n";
1375 ++$errors;
1379 sub dump_typedef($$) {
1380 my $x = shift;
1381 my $file = shift;
1383 $x =~ s@/\*.*?\*/@@gos; # strip comments.
1384 while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
1385 $x =~ s/\(*.\)\s*;$/;/;
1386 $x =~ s/\[*.\]\s*;$/;/;
1389 if ($x =~ /typedef.*\s+(\w+)\s*;/) {
1390 $declaration_name = $1;
1392 output_declaration($declaration_name,
1393 'typedef',
1394 {'typedef' => $declaration_name,
1395 'module' => $modulename,
1396 'sectionlist' => \@sectionlist,
1397 'sections' => \%sections,
1398 'purpose' => $declaration_purpose
1399 });
1401 else {
1402 print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
1403 ++$errors;
1407 sub create_parameterlist($$$) {
1408 my $args = shift;
1409 my $splitter = shift;
1410 my $file = shift;
1411 my $type;
1412 my $param;
1414 # temporarily replace commas inside function pointer definition
1415 while ($args =~ /(\([^\),]+),/) {
1416 $args =~ s/(\([^\),]+),/$1#/g;
1419 foreach my $arg (split($splitter, $args)) {
1420 # strip comments
1421 $arg =~ s/\/\*.*\*\///;
1422 # strip leading/trailing spaces
1423 $arg =~ s/^\s*//;
1424 $arg =~ s/\s*$//;
1425 $arg =~ s/\s+/ /;
1427 if ($arg =~ /^#/) {
1428 # Treat preprocessor directive as a typeless variable just to fill
1429 # corresponding data structures "correctly". Catch it later in
1430 # output_* subs.
1431 push_parameter($arg, "", $file);
1432 } elsif ($arg =~ m/\(/) {
1433 # pointer-to-function
1434 $arg =~ tr/#/,/;
1435 $arg =~ m/[^\(]+\(\*([^\)]+)\)/;
1436 $param = $1;
1437 $type = $arg;
1438 $type =~ s/([^\(]+\(\*)$param/$1/;
1439 push_parameter($param, $type, $file);
1440 } elsif ($arg) {
1441 $arg =~ s/\s*:\s*/:/g;
1442 $arg =~ s/\s*\[/\[/g;
1444 my @args = split('\s*,\s*', $arg);
1445 if ($args[0] =~ m/\*/) {
1446 $args[0] =~ s/(\*+)\s*/ $1/;
1448 my @first_arg = split('\s+', shift @args);
1449 unshift(@args, pop @first_arg);
1450 $type = join " ", @first_arg;
1452 foreach $param (@args) {
1453 if ($param =~ m/^(\*+)\s*(.*)/) {
1454 push_parameter($2, "$type $1", $file);
1456 elsif ($param =~ m/(.*?):(\d+)/) {
1457 push_parameter($1, "$type:$2", $file)
1459 else {
1460 push_parameter($param, $type, $file);
1467 sub push_parameter($$$) {
1468 my $param = shift;
1469 my $type = shift;
1470 my $file = shift;
1472 my $param_name = $param;
1473 $param_name =~ s/\[.*//;
1475 if ($type eq "" && $param =~ /\.\.\.$/)
1477 $type="";
1478 $parameterdescs{$param} = "variable arguments";
1480 elsif ($type eq "" && ($param eq "" or $param eq "void"))
1482 $type="";
1483 $param="void";
1484 $parameterdescs{void} = "no arguments";
1486 # warn if parameter has no description
1487 # (but ignore ones starting with # as these are no parameters
1488 # but inline preprocessor statements
1489 if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
1491 $parameterdescs{$param_name} = $undescribed;
1493 if (($type eq 'function') || ($type eq 'enum')) {
1494 print STDERR "Warning(${file}:$.): Function parameter ".
1495 "or member '$param' not " .
1496 "described in '$declaration_name'\n";
1498 print STDERR "Warning(${file}:$.):".
1499 " No description found for parameter '$param'\n";
1500 ++$warnings;
1503 push @parameterlist, $param;
1504 $parametertypes{$param} = $type;
1507 ##
1508 # takes a function prototype and the name of the current file being
1509 # processed and spits out all the details stored in the global
1510 # arrays/hashes.
1511 sub dump_function($$) {
1512 my $prototype = shift;
1513 my $file = shift;
1515 $prototype =~ s/^static +//;
1516 $prototype =~ s/^extern +//;
1517 $prototype =~ s/^fastcall +//;
1518 $prototype =~ s/^asmlinkage +//;
1519 $prototype =~ s/^inline +//;
1520 $prototype =~ s/^__inline__ +//;
1521 $prototype =~ s/__devinit +//;
1522 $prototype =~ s/^#define +//; #ak added
1523 $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
1525 # Yes, this truly is vile. We are looking for:
1526 # 1. Return type (may be nothing if we're looking at a macro)
1527 # 2. Function name
1528 # 3. Function parameters.
1530 # All the while we have to watch out for function pointer parameters
1531 # (which IIRC is what the two sections are for), C types (these
1532 # regexps don't even start to express all the possibilities), and
1533 # so on.
1535 # If you mess with these regexps, it's a good idea to check that
1536 # the following functions' documentation still comes out right:
1537 # - parport_register_device (function pointer parameters)
1538 # - atomic_set (macro)
1539 # - pci_match_device, __copy_to_user (long return type)
1541 if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1542 $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1543 $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1544 $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1545 $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1546 $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1547 $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1548 $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1549 $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1550 $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1551 $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1552 $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1553 $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1554 $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1555 $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1556 $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) {
1557 $return_type = $1;
1558 $declaration_name = $2;
1559 my $args = $3;
1561 create_parameterlist($args, ',', $file);
1562 } else {
1563 print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n";
1564 ++$errors;
1565 return;
1568 output_declaration($declaration_name,
1569 'function',
1570 {'function' => $declaration_name,
1571 'module' => $modulename,
1572 'functiontype' => $return_type,
1573 'parameterlist' => \@parameterlist,
1574 'parameterdescs' => \%parameterdescs,
1575 'parametertypes' => \%parametertypes,
1576 'sectionlist' => \@sectionlist,
1577 'sections' => \%sections,
1578 'purpose' => $declaration_purpose
1579 });
1582 sub process_file($);
1584 # Read the file that maps relative names to absolute names for
1585 # separate source and object directories and for shadow trees.
1586 if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
1587 my ($relname, $absname);
1588 while(<SOURCE_MAP>) {
1589 chop();
1590 ($relname, $absname) = (split())[0..1];
1591 $relname =~ s:^/+::;
1592 $source_map{$relname} = $absname;
1594 close(SOURCE_MAP);
1597 if ($filelist) {
1598 open(FLIST,"<$filelist") or die "Can't open file list $filelist";
1599 while(<FLIST>) {
1600 chop;
1601 process_file($_);
1605 foreach (@ARGV) {
1606 chomp;
1607 process_file($_);
1609 if ($verbose && $errors) {
1610 print STDERR "$errors errors\n";
1612 if ($verbose && $warnings) {
1613 print STDERR "$warnings warnings\n";
1616 exit($errors);
1618 sub reset_state {
1619 $function = "";
1620 %constants = ();
1621 %parameterdescs = ();
1622 %parametertypes = ();
1623 @parameterlist = ();
1624 %sections = ();
1625 @sectionlist = ();
1626 $prototype = "";
1628 $state = 0;
1631 sub process_state3_function($$) {
1632 my $x = shift;
1633 my $file = shift;
1635 if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#define/)) {
1636 # do nothing
1638 elsif ($x =~ /([^\{]*)/) {
1639 $prototype .= $1;
1641 if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) {
1642 $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
1643 $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1644 $prototype =~ s@^\s+@@gos; # strip leading spaces
1645 dump_function($prototype,$file);
1646 reset_state();
1650 sub process_state3_type($$) {
1651 my $x = shift;
1652 my $file = shift;
1654 $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1655 $x =~ s@^\s+@@gos; # strip leading spaces
1656 $x =~ s@\s+$@@gos; # strip trailing spaces
1657 if ($x =~ /^#/) {
1658 # To distinguish preprocessor directive from regular declaration later.
1659 $x .= ";";
1662 while (1) {
1663 if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
1664 $prototype .= $1 . $2;
1665 ($2 eq '{') && $brcount++;
1666 ($2 eq '}') && $brcount--;
1667 if (($2 eq ';') && ($brcount == 0)) {
1668 dump_declaration($prototype,$file);
1669 reset_state();
1670 last;
1672 $x = $3;
1673 } else {
1674 $prototype .= $x;
1675 last;
1680 # replace <, >, and &
1681 sub xml_escape($) {
1682 my $text = shift;
1683 if (($output_mode eq "text") || ($output_mode eq "man")) {
1684 return $text;
1686 $text =~ s/\&/\\\\\\amp;/g;
1687 $text =~ s/\</\\\\\\lt;/g;
1688 $text =~ s/\>/\\\\\\gt;/g;
1689 return $text;
1692 sub process_file($) {
1693 my $file;
1694 my $identifier;
1695 my $func;
1696 my $initial_section_counter = $section_counter;
1698 if (defined($ENV{'SRCTREE'})) {
1699 $file = "$ENV{'SRCTREE'}" . "/" . "@_";
1701 else {
1702 $file = "@_";
1704 if (defined($source_map{$file})) {
1705 $file = $source_map{$file};
1708 if (!open(IN,"<$file")) {
1709 print STDERR "Error: Cannot open file $file\n";
1710 ++$errors;
1711 return;
1714 $section_counter = 0;
1715 while (<IN>) {
1716 if ($state == 0) {
1717 if (/$doc_start/o) {
1718 $state = 1; # next line is always the function name
1719 $in_doc_sect = 0;
1721 } elsif ($state == 1) { # this line is the function name (always)
1722 if (/$doc_block/o) {
1723 $state = 4;
1724 $contents = "";
1725 if ( $1 eq "" ) {
1726 $section = $section_intro;
1727 } else {
1728 $section = $1;
1731 elsif (/$doc_decl/o) {
1732 $identifier = $1;
1733 if (/\s*([\w\s]+?)\s*-/) {
1734 $identifier = $1;
1737 $state = 2;
1738 if (/-(.*)/) {
1739 $declaration_purpose = xml_escape($1);
1740 } else {
1741 $declaration_purpose = "";
1743 if ($identifier =~ m/^struct/) {
1744 $decl_type = 'struct';
1745 } elsif ($identifier =~ m/^union/) {
1746 $decl_type = 'union';
1747 } elsif ($identifier =~ m/^enum/) {
1748 $decl_type = 'enum';
1749 } elsif ($identifier =~ m/^typedef/) {
1750 $decl_type = 'typedef';
1751 } else {
1752 $decl_type = 'function';
1755 if ($verbose) {
1756 print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
1758 } else {
1759 print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
1760 " - I thought it was a doc line\n";
1761 ++$warnings;
1762 $state = 0;
1764 } elsif ($state == 2) { # look for head: lines, and include content
1765 if (/$doc_sect/o) {
1766 $newsection = $1;
1767 $newcontents = $2;
1769 if ($contents ne "") {
1770 if (!$in_doc_sect && $verbose) {
1771 print STDERR "Warning(${file}:$.): contents before sections\n";
1772 ++$warnings;
1774 dump_section($section, xml_escape($contents));
1775 $section = $section_default;
1778 $in_doc_sect = 1;
1779 $contents = $newcontents;
1780 if ($contents ne "") {
1781 if (substr($contents, 0, 1) eq " ") {
1782 $contents = substr($contents, 1);
1784 $contents .= "\n";
1786 $section = $newsection;
1787 } elsif (/$doc_end/) {
1789 if ($contents ne "") {
1790 dump_section($section, xml_escape($contents));
1791 $section = $section_default;
1792 $contents = "";
1795 $prototype = "";
1796 $state = 3;
1797 $brcount = 0;
1798 # print STDERR "end of doc comment, looking for prototype\n";
1799 } elsif (/$doc_content/) {
1800 # miguel-style comment kludge, look for blank lines after
1801 # @parameter line to signify start of description
1802 if ($1 eq "" &&
1803 ($section =~ m/^@/ || $section eq $section_context)) {
1804 dump_section($section, xml_escape($contents));
1805 $section = $section_default;
1806 $contents = "";
1807 } else {
1808 $contents .= $1."\n";
1810 } else {
1811 # i dont know - bad line? ignore.
1812 print STDERR "Warning(${file}:$.): bad line: $_";
1813 ++$warnings;
1815 } elsif ($state == 3) { # scanning for function '{' (end of prototype)
1816 if ($decl_type eq 'function') {
1817 process_state3_function($_, $file);
1818 } else {
1819 process_state3_type($_, $file);
1821 } elsif ($state == 4) {
1822 # Documentation block
1823 if (/$doc_block/) {
1824 dump_section($section, $contents);
1825 output_intro({'sectionlist' => \@sectionlist,
1826 'sections' => \%sections });
1827 $contents = "";
1828 $function = "";
1829 %constants = ();
1830 %parameterdescs = ();
1831 %parametertypes = ();
1832 @parameterlist = ();
1833 %sections = ();
1834 @sectionlist = ();
1835 $prototype = "";
1836 if ( $1 eq "" ) {
1837 $section = $section_intro;
1838 } else {
1839 $section = $1;
1842 elsif (/$doc_end/)
1844 dump_section($section, $contents);
1845 output_intro({'sectionlist' => \@sectionlist,
1846 'sections' => \%sections });
1847 $contents = "";
1848 $function = "";
1849 %constants = ();
1850 %parameterdescs = ();
1851 %parametertypes = ();
1852 @parameterlist = ();
1853 %sections = ();
1854 @sectionlist = ();
1855 $prototype = "";
1856 $state = 0;
1858 elsif (/$doc_content/)
1860 if ( $1 eq "" )
1862 $contents .= $blankline;
1864 else
1866 $contents .= $1 . "\n";
1871 if ($initial_section_counter == $section_counter) {
1872 print STDERR "Warning(${file}): no structured comments found\n";
1873 if ($output_mode eq "xml") {
1874 # The template wants at least one RefEntry here; make one.
1875 print "<refentry>\n";
1876 print " <refnamediv>\n";
1877 print " <refname>\n";
1878 print " ${file}\n";
1879 print " </refname>\n";
1880 print " <refpurpose>\n";
1881 print " Document generation inconsistency\n";
1882 print " </refpurpose>\n";
1883 print " </refnamediv>\n";
1884 print " <refsect1>\n";
1885 print " <title>\n";
1886 print " Oops\n";
1887 print " </title>\n";
1888 print " <warning>\n";
1889 print " <para>\n";
1890 print " The template for this document tried to insert\n";
1891 print " the structured comment from the file\n";
1892 print " <filename>${file}</filename> at this point,\n";
1893 print " but none was found.\n";
1894 print " This dummy section is inserted to allow\n";
1895 print " generation to continue.\n";
1896 print " </para>\n";
1897 print " </warning>\n";
1898 print " </refsect1>\n";
1899 print "</refentry>\n";