1 | /* defun.c -- @defun and friends. |
---|
2 | $Id: defun.c,v 1.1.1.2 2003-02-28 17:44:39 amb Exp $ |
---|
3 | |
---|
4 | Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
---|
5 | |
---|
6 | This program is free software; you can redistribute it and/or modify |
---|
7 | it under the terms of the GNU General Public License as published by |
---|
8 | the Free Software Foundation; either version 2, or (at your option) |
---|
9 | any later version. |
---|
10 | |
---|
11 | This program is distributed in the hope that it will be useful, |
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | GNU General Public License for more details. |
---|
15 | |
---|
16 | You should have received a copy of the GNU General Public License |
---|
17 | along with this program; if not, write to the Free Software Foundation, |
---|
18 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
---|
19 | |
---|
20 | #include "system.h" |
---|
21 | #include "defun.h" |
---|
22 | #include "xml.h" |
---|
23 | #include "insertion.h" |
---|
24 | #include "makeinfo.h" |
---|
25 | #include "cmds.h" |
---|
26 | #include "html.h" |
---|
27 | |
---|
28 | |
---|
29 | #define DEFUN_SELF_DELIMITING(c) \ |
---|
30 | ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']') |
---|
31 | |
---|
32 | struct token_accumulator |
---|
33 | { |
---|
34 | unsigned int length; |
---|
35 | unsigned int index; |
---|
36 | char **tokens; |
---|
37 | }; |
---|
38 | |
---|
39 | static void |
---|
40 | initialize_token_accumulator (accumulator) |
---|
41 | struct token_accumulator *accumulator; |
---|
42 | { |
---|
43 | accumulator->length = 0; |
---|
44 | accumulator->index = 0; |
---|
45 | accumulator->tokens = NULL; |
---|
46 | } |
---|
47 | |
---|
48 | static void |
---|
49 | accumulate_token (accumulator, token) |
---|
50 | struct token_accumulator *accumulator; |
---|
51 | char *token; |
---|
52 | { |
---|
53 | if (accumulator->index >= accumulator->length) |
---|
54 | { |
---|
55 | accumulator->length += 10; |
---|
56 | accumulator->tokens = xrealloc (accumulator->tokens, |
---|
57 | (accumulator->length * sizeof (char *))); |
---|
58 | } |
---|
59 | accumulator->tokens[accumulator->index] = token; |
---|
60 | accumulator->index += 1; |
---|
61 | } |
---|
62 | |
---|
63 | /* Given STRING_POINTER pointing at an open brace, skip forward and return a |
---|
64 | pointer to just past the matching close brace. */ |
---|
65 | static int |
---|
66 | scan_group_in_string (string_pointer) |
---|
67 | char **string_pointer; |
---|
68 | { |
---|
69 | char *scan_string = (*string_pointer) + 1; |
---|
70 | unsigned int level = 1; |
---|
71 | int started_command = 0; |
---|
72 | |
---|
73 | for (;;) |
---|
74 | { |
---|
75 | int c; |
---|
76 | if (level == 0) |
---|
77 | { |
---|
78 | *string_pointer = scan_string; |
---|
79 | return 1; |
---|
80 | } |
---|
81 | c = *scan_string++; |
---|
82 | if (c == 0) |
---|
83 | { |
---|
84 | /* Tweak line_number to compensate for fact that |
---|
85 | we gobbled the whole line before coming here. */ |
---|
86 | line_number--; |
---|
87 | line_error (_("Missing `}' in @def arg")); |
---|
88 | line_number++; |
---|
89 | *string_pointer = scan_string - 1; |
---|
90 | return 0; |
---|
91 | } |
---|
92 | |
---|
93 | if (c == '{' && !started_command) |
---|
94 | level++; |
---|
95 | if (c == '}' && !started_command) |
---|
96 | level--; |
---|
97 | |
---|
98 | /* remember if at @. */ |
---|
99 | started_command = (c == '@' && !started_command); |
---|
100 | } |
---|
101 | } |
---|
102 | |
---|
103 | /* Return a list of tokens from the contents of STRING. |
---|
104 | Commands and brace-delimited groups count as single tokens. |
---|
105 | Contiguous whitespace characters are converted to a token |
---|
106 | consisting of a single space. */ |
---|
107 | static char ** |
---|
108 | args_from_string (string) |
---|
109 | char *string; |
---|
110 | { |
---|
111 | struct token_accumulator accumulator; |
---|
112 | char *token_start, *token_end; |
---|
113 | char *scan_string = string; |
---|
114 | |
---|
115 | initialize_token_accumulator (&accumulator); |
---|
116 | |
---|
117 | while (*scan_string) |
---|
118 | { /* Replace arbitrary whitespace by a single space. */ |
---|
119 | if (whitespace (*scan_string)) |
---|
120 | { |
---|
121 | scan_string += 1; |
---|
122 | while (whitespace (*scan_string)) |
---|
123 | scan_string += 1; |
---|
124 | accumulate_token ((&accumulator), (xstrdup (" "))); |
---|
125 | continue; |
---|
126 | } |
---|
127 | |
---|
128 | /* Commands count as single tokens. */ |
---|
129 | if (*scan_string == COMMAND_PREFIX) |
---|
130 | { |
---|
131 | token_start = scan_string; |
---|
132 | scan_string += 1; |
---|
133 | if (self_delimiting (*scan_string)) |
---|
134 | scan_string += 1; |
---|
135 | else |
---|
136 | { |
---|
137 | int c; |
---|
138 | while (1) |
---|
139 | { |
---|
140 | c = *scan_string++; |
---|
141 | |
---|
142 | if ((c == 0) || (c == '{') || (whitespace (c))) |
---|
143 | { |
---|
144 | scan_string -= 1; |
---|
145 | break; |
---|
146 | } |
---|
147 | } |
---|
148 | |
---|
149 | if (*scan_string == '{') |
---|
150 | { |
---|
151 | char *s = scan_string; |
---|
152 | (void) scan_group_in_string (&s); |
---|
153 | scan_string = s; |
---|
154 | } |
---|
155 | } |
---|
156 | token_end = scan_string; |
---|
157 | } |
---|
158 | |
---|
159 | /* Parentheses and brackets are self-delimiting. */ |
---|
160 | else if (DEFUN_SELF_DELIMITING (*scan_string)) |
---|
161 | { |
---|
162 | token_start = scan_string; |
---|
163 | scan_string += 1; |
---|
164 | token_end = scan_string; |
---|
165 | } |
---|
166 | |
---|
167 | /* Open brace introduces a group that is a single token. */ |
---|
168 | else if (*scan_string == '{') |
---|
169 | { |
---|
170 | char *s = scan_string; |
---|
171 | int balanced = scan_group_in_string (&s); |
---|
172 | |
---|
173 | token_start = scan_string + 1; |
---|
174 | scan_string = s; |
---|
175 | token_end = balanced ? (scan_string - 1) : scan_string; |
---|
176 | } |
---|
177 | |
---|
178 | /* Otherwise a token is delimited by whitespace, parentheses, |
---|
179 | brackets, or braces. A token is also ended by a command. */ |
---|
180 | else |
---|
181 | { |
---|
182 | token_start = scan_string; |
---|
183 | |
---|
184 | for (;;) |
---|
185 | { |
---|
186 | int c; |
---|
187 | |
---|
188 | c = *scan_string++; |
---|
189 | |
---|
190 | /* Do not back up if we're looking at a }; since the only |
---|
191 | valid }'s are those matched with {'s, we want to give |
---|
192 | an error. If we back up, we go into an infinite loop. */ |
---|
193 | if (!c || whitespace (c) || DEFUN_SELF_DELIMITING (c) |
---|
194 | || c == '{') |
---|
195 | { |
---|
196 | scan_string--; |
---|
197 | break; |
---|
198 | } |
---|
199 | |
---|
200 | /* If we encounter a command embedded within a token, |
---|
201 | then end the token. */ |
---|
202 | if (c == COMMAND_PREFIX) |
---|
203 | { |
---|
204 | scan_string--; |
---|
205 | break; |
---|
206 | } |
---|
207 | } |
---|
208 | token_end = scan_string; |
---|
209 | } |
---|
210 | |
---|
211 | accumulate_token (&accumulator, substring (token_start, token_end)); |
---|
212 | } |
---|
213 | accumulate_token (&accumulator, NULL); |
---|
214 | return accumulator.tokens; |
---|
215 | } |
---|
216 | |
---|
217 | static void |
---|
218 | process_defun_args (defun_args, auto_var_p) |
---|
219 | char **defun_args; |
---|
220 | int auto_var_p; |
---|
221 | { |
---|
222 | int pending_space = 0; |
---|
223 | |
---|
224 | for (;;) |
---|
225 | { |
---|
226 | char *defun_arg = *defun_args++; |
---|
227 | |
---|
228 | if (defun_arg == NULL) |
---|
229 | break; |
---|
230 | |
---|
231 | if (defun_arg[0] == ' ') |
---|
232 | { |
---|
233 | pending_space = 1; |
---|
234 | continue; |
---|
235 | } |
---|
236 | |
---|
237 | if (pending_space) |
---|
238 | { |
---|
239 | add_char (' '); |
---|
240 | pending_space = 0; |
---|
241 | } |
---|
242 | |
---|
243 | if (DEFUN_SELF_DELIMITING (defun_arg[0])) |
---|
244 | { |
---|
245 | /* Within @deffn and friends, texinfo.tex makes parentheses |
---|
246 | sans serif and brackets bold. We use roman instead. */ |
---|
247 | insert_html_tag (START, ""); |
---|
248 | add_char (defun_arg[0]); |
---|
249 | insert_html_tag (END, ""); |
---|
250 | } |
---|
251 | else if (defun_arg[0] == '&') |
---|
252 | if (html) |
---|
253 | { |
---|
254 | defun_arg = escape_string (xstrdup (defun_arg)); |
---|
255 | add_word (defun_arg); |
---|
256 | free (defun_arg); |
---|
257 | } |
---|
258 | else |
---|
259 | add_word (defun_arg); |
---|
260 | else if (defun_arg[0] == COMMAND_PREFIX) |
---|
261 | execute_string ("%s", defun_arg); |
---|
262 | else if (auto_var_p) |
---|
263 | if (html) |
---|
264 | { |
---|
265 | defun_arg = escape_string (xstrdup (defun_arg)); |
---|
266 | add_word (defun_arg); |
---|
267 | free (defun_arg); |
---|
268 | } |
---|
269 | else |
---|
270 | add_word (defun_arg); |
---|
271 | else |
---|
272 | add_word (defun_arg); |
---|
273 | } |
---|
274 | } |
---|
275 | |
---|
276 | static char * |
---|
277 | next_nonwhite_defun_arg (arg_pointer) |
---|
278 | char ***arg_pointer; |
---|
279 | { |
---|
280 | char **scan = (*arg_pointer); |
---|
281 | char *arg = (*scan++); |
---|
282 | |
---|
283 | if ((arg != 0) && (*arg == ' ')) |
---|
284 | arg = *scan++; |
---|
285 | |
---|
286 | if (arg == 0) |
---|
287 | scan -= 1; |
---|
288 | |
---|
289 | *arg_pointer = scan; |
---|
290 | |
---|
291 | return (arg == 0) ? "" : arg; |
---|
292 | } |
---|
293 | |
---|
294 | |
---|
295 | /* This is needed also in insertion.c. */ |
---|
296 | |
---|
297 | enum insertion_type |
---|
298 | get_base_type (type) |
---|
299 | enum insertion_type type; |
---|
300 | { |
---|
301 | enum insertion_type base_type; |
---|
302 | switch (type) |
---|
303 | { |
---|
304 | case defivar: base_type = defcv; break; |
---|
305 | case defmac: base_type = deffn; break; |
---|
306 | case defmethod: base_type = defop; break; |
---|
307 | case defopt: base_type = defvr; break; |
---|
308 | case defspec: base_type = deffn; break; |
---|
309 | case deftypefun: base_type = deftypefn; break; |
---|
310 | case deftypeivar: base_type = deftypeivar; break; |
---|
311 | case deftypemethod: base_type = deftypemethod; break; |
---|
312 | case deftypeop: base_type = deftypeop; break; |
---|
313 | case deftypevar: base_type = deftypevr; break; |
---|
314 | case defun: base_type = deffn; break; |
---|
315 | case defvar: base_type = defvr; break; |
---|
316 | default: |
---|
317 | base_type = type; |
---|
318 | break; |
---|
319 | } |
---|
320 | |
---|
321 | return base_type; |
---|
322 | } |
---|
323 | |
---|
324 | /* Make the defun type insertion. |
---|
325 | TYPE says which insertion this is. |
---|
326 | X_P, if nonzero, says not to start a new insertion. */ |
---|
327 | static void |
---|
328 | defun_internal (type, x_p) |
---|
329 | enum insertion_type type; |
---|
330 | int x_p; |
---|
331 | { |
---|
332 | enum insertion_type base_type; |
---|
333 | char **defun_args, **scan_args; |
---|
334 | char *category, *defined_name, *type_name, *type_name2; |
---|
335 | |
---|
336 | { |
---|
337 | char *line; |
---|
338 | |
---|
339 | /* The @def.. line is the only place in Texinfo where you are |
---|
340 | allowed to use unquoted braces that don't delimit arguments of |
---|
341 | a command or a macro; in any other place it will trigger an |
---|
342 | error message from the reader loop. The special handling of |
---|
343 | this case inside `args_from_string' is an extra special hack |
---|
344 | which allows this. The side effect is that if we try to expand |
---|
345 | the rest of the line below, the recursive reader loop will |
---|
346 | signal an error if there are brace-delimited arguments on that line. |
---|
347 | |
---|
348 | The best solution to this would be to change the syntax of |
---|
349 | @def.. commands so that it doesn't violate Texinfo's own rules. |
---|
350 | But it's probably too late for this now, as it will break a lot |
---|
351 | of existing manuals. |
---|
352 | |
---|
353 | Unfortunately, this means that you can't call macros, use @value, etc. |
---|
354 | inside @def.. commands, sigh. */ |
---|
355 | get_rest_of_line (0, &line); |
---|
356 | defun_args = (args_from_string (line)); |
---|
357 | free (line); |
---|
358 | } |
---|
359 | |
---|
360 | scan_args = defun_args; |
---|
361 | |
---|
362 | /* Get base type and category string. */ |
---|
363 | base_type = get_base_type (type); |
---|
364 | |
---|
365 | /* xx all these const strings should be determined upon |
---|
366 | documentlanguage argument and NOT via gettext (kama). */ |
---|
367 | switch (type) |
---|
368 | { |
---|
369 | case defun: |
---|
370 | case deftypefun: |
---|
371 | category = _("Function"); |
---|
372 | break; |
---|
373 | case defmac: |
---|
374 | category = _("Macro"); |
---|
375 | break; |
---|
376 | case defspec: |
---|
377 | category = _("Special Form"); |
---|
378 | break; |
---|
379 | case defvar: |
---|
380 | case deftypevar: |
---|
381 | category = _("Variable"); |
---|
382 | break; |
---|
383 | case defopt: |
---|
384 | category = _("User Option"); |
---|
385 | break; |
---|
386 | case defivar: |
---|
387 | case deftypeivar: |
---|
388 | category = _("Instance Variable"); |
---|
389 | break; |
---|
390 | case defmethod: |
---|
391 | case deftypemethod: |
---|
392 | category = _("Method"); |
---|
393 | break; |
---|
394 | default: |
---|
395 | category = next_nonwhite_defun_arg (&scan_args); |
---|
396 | break; |
---|
397 | } |
---|
398 | |
---|
399 | /* The class name. */ |
---|
400 | if ((base_type == deftypefn) |
---|
401 | || (base_type == deftypevr) |
---|
402 | || (base_type == defcv) |
---|
403 | || (base_type == defop) |
---|
404 | || (base_type == deftypeivar) |
---|
405 | || (base_type == deftypemethod) |
---|
406 | || (base_type == deftypeop) |
---|
407 | ) |
---|
408 | type_name = next_nonwhite_defun_arg (&scan_args); |
---|
409 | |
---|
410 | /* The type name for typed languages. */ |
---|
411 | if ((base_type == deftypemethod) |
---|
412 | || (base_type == deftypeivar) |
---|
413 | || (base_type == deftypeop) |
---|
414 | ) |
---|
415 | type_name2 = next_nonwhite_defun_arg (&scan_args); |
---|
416 | |
---|
417 | /* The function or whatever that's actually being defined. */ |
---|
418 | defined_name = next_nonwhite_defun_arg (&scan_args); |
---|
419 | |
---|
420 | /* This hack exists solely for the purposes of formatting the Texinfo |
---|
421 | manual. I couldn't think of a better way. The token might be a |
---|
422 | simple @@ followed immediately by more text. If this is the case, |
---|
423 | then the next defun arg is part of this one, and we should |
---|
424 | concatenate them. */ |
---|
425 | if (*scan_args && **scan_args && !whitespace (**scan_args) |
---|
426 | && STREQ (defined_name, "@@")) |
---|
427 | { |
---|
428 | char *tem = xmalloc (3 + strlen (scan_args[0])); |
---|
429 | |
---|
430 | sprintf (tem, "@@%s", scan_args[0]); |
---|
431 | |
---|
432 | free (scan_args[0]); |
---|
433 | scan_args[0] = tem; |
---|
434 | scan_args++; |
---|
435 | defined_name = tem; |
---|
436 | } |
---|
437 | |
---|
438 | /* It's easy to write @defun foo(arg1 arg2), but a following ( is |
---|
439 | misparsed by texinfo.tex and this is next to impossible to fix. |
---|
440 | Warn about it. */ |
---|
441 | if (*scan_args && **scan_args && **scan_args == '(') |
---|
442 | warning ("`%c' follows defined name `%s' instead of whitespace", |
---|
443 | **scan_args, defined_name); |
---|
444 | |
---|
445 | if (!x_p) |
---|
446 | begin_insertion (type); |
---|
447 | |
---|
448 | /* Write the definition header line. |
---|
449 | This should start at the normal indentation. */ |
---|
450 | current_indent -= default_indentation_increment; |
---|
451 | start_paragraph (); |
---|
452 | |
---|
453 | if (!x_p) { |
---|
454 | /* Start the definition on new paragraph. */ |
---|
455 | if (html) |
---|
456 | add_word ("<p>\n"); |
---|
457 | } |
---|
458 | |
---|
459 | if (!html && !docbook) |
---|
460 | switch (base_type) |
---|
461 | { |
---|
462 | case deffn: |
---|
463 | case defvr: |
---|
464 | case deftp: |
---|
465 | execute_string (" -- %s: %s", category, defined_name); |
---|
466 | break; |
---|
467 | case deftypefn: |
---|
468 | case deftypevr: |
---|
469 | execute_string (" -- %s: %s %s", category, type_name, defined_name); |
---|
470 | break; |
---|
471 | case defcv: |
---|
472 | execute_string (" -- %s %s %s: %s", category, _("of"), type_name, |
---|
473 | defined_name); |
---|
474 | break; |
---|
475 | case deftypeivar: |
---|
476 | execute_string (" -- %s %s %s: %s %s", category, _("of"), type_name, |
---|
477 | type_name2, defined_name); |
---|
478 | break; |
---|
479 | case defop: |
---|
480 | execute_string (" -- %s %s %s: %s", category, _("on"), type_name, |
---|
481 | defined_name); |
---|
482 | break; |
---|
483 | case deftypeop: |
---|
484 | execute_string (" -- %s %s %s: %s %s", category, _("on"), type_name, |
---|
485 | type_name2, defined_name); |
---|
486 | break; |
---|
487 | case deftypemethod: |
---|
488 | execute_string (" -- %s %s %s: %s %s", category, _("on"), type_name, |
---|
489 | type_name2, defined_name); |
---|
490 | break; |
---|
491 | } |
---|
492 | |
---|
493 | if (html) |
---|
494 | { |
---|
495 | /* If this is not a @def...x version, it could only |
---|
496 | be a normal version @def.... So start the table here. */ |
---|
497 | if (!x_p) |
---|
498 | { |
---|
499 | add_html_elt ("<table width="); |
---|
500 | add_word ("\"100%\">\n"); |
---|
501 | } |
---|
502 | |
---|
503 | /* If this is an @def...x there has to be an other @def... before |
---|
504 | it, so this is only a new row within an existing table. With |
---|
505 | two complete standalone tables the gap between them is too big. */ |
---|
506 | add_word ("<tr>\n"); |
---|
507 | add_html_elt ("<td align=\"left\">"); |
---|
508 | |
---|
509 | switch (base_type) |
---|
510 | { |
---|
511 | case deffn: |
---|
512 | case defvr: |
---|
513 | case deftp: |
---|
514 | /* <i> is for the following function arguments. */ |
---|
515 | insert_html_tag (START, "b"); |
---|
516 | execute_string ("%s", defined_name); |
---|
517 | insert_html_tag (END, "b"); |
---|
518 | insert_html_tag (START, "i"); |
---|
519 | break; |
---|
520 | case deftypefn: |
---|
521 | case deftypevr: |
---|
522 | execute_string ("%s ", type_name); |
---|
523 | insert_html_tag (START, "b"); |
---|
524 | execute_string ("%s", defined_name); |
---|
525 | insert_html_tag (END, "b"); |
---|
526 | insert_html_tag (START, "i"); |
---|
527 | break; |
---|
528 | case defcv: |
---|
529 | case defop: |
---|
530 | insert_html_tag (START, "b"); |
---|
531 | execute_string ("%s", defined_name); |
---|
532 | insert_html_tag (END, "b"); |
---|
533 | insert_html_tag (START, "i"); |
---|
534 | break; |
---|
535 | case deftypemethod: |
---|
536 | case deftypeop: |
---|
537 | case deftypeivar: |
---|
538 | execute_string ("%s ", type_name2); |
---|
539 | insert_html_tag (START, "b"); |
---|
540 | execute_string ("%s", defined_name); |
---|
541 | insert_html_tag (END, "b"); |
---|
542 | insert_html_tag (START, "i"); |
---|
543 | break; |
---|
544 | } |
---|
545 | } /* if (html)... */ |
---|
546 | |
---|
547 | if (docbook) |
---|
548 | { |
---|
549 | switch (base_type) |
---|
550 | { |
---|
551 | case deffn: |
---|
552 | case defvr: |
---|
553 | case deftp: |
---|
554 | case defcv: |
---|
555 | case defop: |
---|
556 | xml_insert_element (FUNCTION, START); |
---|
557 | execute_string ("%s", defined_name); |
---|
558 | xml_insert_element (FUNCTION, END); |
---|
559 | break; |
---|
560 | case deftypefn: |
---|
561 | case deftypevr: |
---|
562 | execute_string ("%s", type_name); |
---|
563 | xml_insert_element (FUNCTION, START); |
---|
564 | execute_string ("%s", defined_name); |
---|
565 | xml_insert_element (FUNCTION, END); |
---|
566 | break; |
---|
567 | case deftypemethod: |
---|
568 | case deftypeop: |
---|
569 | case deftypeivar: |
---|
570 | execute_string ("%s", type_name2); |
---|
571 | xml_insert_element (FUNCTION, START); |
---|
572 | execute_string ("%s", defined_name); |
---|
573 | xml_insert_element (FUNCTION, END); |
---|
574 | break; |
---|
575 | } |
---|
576 | |
---|
577 | } /* if (docbook)... */ |
---|
578 | |
---|
579 | current_indent += default_indentation_increment; |
---|
580 | |
---|
581 | /* Now process the function arguments, if any. If these carry onto |
---|
582 | the next line, they should be indented by two increments to |
---|
583 | distinguish them from the body of the definition, which is indented |
---|
584 | by one increment. */ |
---|
585 | current_indent += default_indentation_increment; |
---|
586 | |
---|
587 | switch (base_type) |
---|
588 | { |
---|
589 | case deffn: |
---|
590 | case defop: |
---|
591 | process_defun_args (scan_args, 1); |
---|
592 | break; |
---|
593 | |
---|
594 | /* Through Makeinfo 1.67 we processed remaining args only for deftp, |
---|
595 | deftypefn, and deftypemethod. But the libc manual, for example, |
---|
596 | needs to say: |
---|
597 | @deftypevar {char *} tzname[2] |
---|
598 | And simply allowing the extra text seems far simpler than trying |
---|
599 | to invent yet more defn commands. In any case, we should either |
---|
600 | output it or give an error, not silently ignore it. */ |
---|
601 | default: |
---|
602 | process_defun_args (scan_args, 0); |
---|
603 | break; |
---|
604 | } |
---|
605 | |
---|
606 | current_indent -= default_indentation_increment; |
---|
607 | close_single_paragraph (); |
---|
608 | |
---|
609 | if (html) |
---|
610 | { |
---|
611 | /* xx The single words (on, off) used here, should depend on |
---|
612 | documentlanguage and NOT on gettext --kama. */ |
---|
613 | switch (base_type) |
---|
614 | { |
---|
615 | case deffn: |
---|
616 | case defvr: |
---|
617 | case deftp: |
---|
618 | case deftypefn: |
---|
619 | case deftypevr: |
---|
620 | insert_html_tag (END, "i"); /* close italic area for arguments */ |
---|
621 | /* put the rest into the second column */ |
---|
622 | add_word ("</td>\n"); |
---|
623 | add_html_elt ("<td align=\"right\">"); |
---|
624 | execute_string ("%s", category); |
---|
625 | break; |
---|
626 | |
---|
627 | case defcv: |
---|
628 | add_word ("</td>\n"); |
---|
629 | add_html_elt ("<td align=\"right\">"); |
---|
630 | execute_string ("%s %s %s", category, _("of"), type_name); |
---|
631 | break; |
---|
632 | |
---|
633 | case defop: |
---|
634 | case deftypemethod: |
---|
635 | case deftypeop: |
---|
636 | insert_html_tag (END, "i"); |
---|
637 | add_word ("</td>\n"); |
---|
638 | add_html_elt ("<td align=\"right\">"); |
---|
639 | execute_string ("%s %s %s", category, _("on"), type_name); |
---|
640 | break; |
---|
641 | |
---|
642 | case deftypeivar: |
---|
643 | insert_html_tag (END, "i"); |
---|
644 | add_word ("</td>\n"); |
---|
645 | add_html_elt ("<td align=\"right\">"); |
---|
646 | execute_string ("%s %s %s", category, _("of"), type_name); |
---|
647 | break; |
---|
648 | } /* switch (base_type)... */ |
---|
649 | |
---|
650 | add_word ("</td>\n"); /* close second column */ |
---|
651 | add_word ("</tr>\n"); /* close row */ |
---|
652 | |
---|
653 | /* This is needed because I have to know if the next line is |
---|
654 | normal text or another @def..x. If text follows, create a new |
---|
655 | table to get the indentation for the following text. |
---|
656 | |
---|
657 | This construction would fail if someone uses: |
---|
658 | @deffn |
---|
659 | @sp 2 |
---|
660 | @deffnx |
---|
661 | . |
---|
662 | @end deffn |
---|
663 | But we don't care. */ |
---|
664 | if (!looking_at ("@def")) |
---|
665 | { |
---|
666 | add_word ("</table>\n"); |
---|
667 | add_html_elt ("<table width=\"95%\" align=\"center\">"); |
---|
668 | add_word ("\n<tr><td>\n"); |
---|
669 | } |
---|
670 | |
---|
671 | } /* if (html)... */ |
---|
672 | |
---|
673 | /* Make an entry in the appropriate index. */ |
---|
674 | switch (base_type) |
---|
675 | { |
---|
676 | case deffn: |
---|
677 | case deftypefn: |
---|
678 | execute_string ("@findex %s\n", defined_name); |
---|
679 | break; |
---|
680 | case defvr: |
---|
681 | case deftypevr: |
---|
682 | case defcv: |
---|
683 | execute_string ("@vindex %s\n", defined_name); |
---|
684 | break; |
---|
685 | case deftypeivar: |
---|
686 | execute_string ("@vindex %s %s %s\n", defined_name, _("of"), type_name); |
---|
687 | break; |
---|
688 | case defop: |
---|
689 | case deftypeop: |
---|
690 | case deftypemethod: |
---|
691 | execute_string ("@findex %s %s %s\n", defined_name, _("on"), type_name); |
---|
692 | break; |
---|
693 | case deftp: |
---|
694 | execute_string ("@tindex %s\n", defined_name); |
---|
695 | break; |
---|
696 | } |
---|
697 | |
---|
698 | /* Deallocate the token list. */ |
---|
699 | scan_args = defun_args; |
---|
700 | while (1) |
---|
701 | { |
---|
702 | char * arg = (*scan_args++); |
---|
703 | if (arg == NULL) |
---|
704 | break; |
---|
705 | free (arg); |
---|
706 | } |
---|
707 | free (defun_args); |
---|
708 | } |
---|
709 | |
---|
710 | /* Add an entry for a function, macro, special form, variable, or option. |
---|
711 | If the name of the calling command ends in `x', then this is an extra |
---|
712 | entry included in the body of an insertion of the same type. */ |
---|
713 | void |
---|
714 | cm_defun () |
---|
715 | { |
---|
716 | int x_p; |
---|
717 | enum insertion_type type; |
---|
718 | char *temp = xstrdup (command); |
---|
719 | |
---|
720 | x_p = (command[strlen (command) - 1] == 'x'); |
---|
721 | |
---|
722 | if (x_p) |
---|
723 | temp[strlen (temp) - 1] = 0; |
---|
724 | |
---|
725 | type = find_type_from_name (temp); |
---|
726 | free (temp); |
---|
727 | |
---|
728 | /* If we are adding to an already existing insertion, then make sure |
---|
729 | that we are already in an insertion of type TYPE. */ |
---|
730 | if (x_p && (!insertion_level || insertion_stack->insertion != type)) |
---|
731 | { |
---|
732 | line_error (_("Must be in `%s' insertion to use `%sx'"), |
---|
733 | command, command); |
---|
734 | discard_until ("\n"); |
---|
735 | return; |
---|
736 | } |
---|
737 | |
---|
738 | defun_internal (type, x_p); |
---|
739 | } |
---|