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