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