Commit 272057447f646c51bc77c60044eb21c683fa366d

Authored by Randy Dunlap
Committed by Linus Torvalds
1 parent c751c1dbb1

[PATCH] kernel-doc: make parameter description indentation uniform

- In parameter descriptions, strip all whitespace between the parameter
  name (e.g., @len) and its description so that the description is
  indented uniformly in text and man page modes.  Previously, spaces
  or tabs (which are used for cleaner source code viewing) affected
  the produced output in a negative way.

Before (man mode):
       to            Destination address, in user space.
       from        Source address, in kernel space.
       n              Number of bytes to copy.

After (man mode):
       to          Destination address, in user space.
       from        Source address, in kernel space.
       n           Number of bytes to copy.

- Fix/clarify a few function description comments.

Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 7 additions and 5 deletions Inline Diff

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