source: trunk/essentials/sys-apps/texinfo/makeinfo/defun.c

Last change on this file was 2617, checked in by bird, 19 years ago

GNU Texinfo 4.8

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