source: trunk/third/texinfo/makeinfo/defun.c @ 18945

Revision 18945, 20.6 KB checked in by amb, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18944, which included commits to RCS files with non-trunk default branches.
RevLine 
[17659]1/* defun.c -- @defun and friends.
[18944]2   $Id: defun.c,v 1.1.1.2 2003-02-28 17:44:39 amb Exp $
[17659]3
[18944]4   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
[17659]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"
[18944]22#include "xml.h"
[17659]23#include "insertion.h"
24#include "makeinfo.h"
[18944]25#include "cmds.h"
26#include "html.h"
[17659]27
28
29#define DEFUN_SELF_DELIMITING(c) \
30  ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']')
31
32struct token_accumulator
33{
34  unsigned int length;
35  unsigned int index;
36  char **tokens;
37};
38
39static void
40initialize_token_accumulator (accumulator)
41     struct token_accumulator *accumulator;
42{
43  accumulator->length = 0;
44  accumulator->index = 0;
45  accumulator->tokens = NULL;
46}
47
48static void
49accumulate_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. */
65static int
66scan_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. */
107static char **
108args_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
217static void
218process_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]))
[18944]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        }
[17659]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
276static char *
277next_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
297enum insertion_type
298get_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. */
327static void
328defun_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.  */
[18944]515          insert_html_tag (START, "b");
[17659]516          execute_string ("%s", defined_name);
[18944]517          insert_html_tag (END, "b");
518          insert_html_tag (START, "i");
[17659]519          break;
520        case deftypefn:
521        case deftypevr:
522          execute_string ("%s ", type_name);
[18944]523          insert_html_tag (START, "b");
[17659]524          execute_string ("%s", defined_name);
[18944]525          insert_html_tag (END, "b");
526          insert_html_tag (START, "i");
[17659]527          break;
528        case defcv:
529        case defop:
[18944]530          insert_html_tag (START, "b");
[17659]531          execute_string ("%s", defined_name);
[18944]532          insert_html_tag (END, "b");
533          insert_html_tag (START, "i");
[17659]534          break;
535        case deftypemethod:
536        case deftypeop:
537        case deftypeivar:
538          execute_string ("%s ", type_name2);
[18944]539          insert_html_tag (START, "b");
[17659]540          execute_string ("%s", defined_name);
[18944]541          insert_html_tag (END, "b");
542          insert_html_tag (START, "i");
[17659]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:
[18944]556          xml_insert_element (FUNCTION, START);
557          execute_string ("%s", defined_name);
558          xml_insert_element (FUNCTION, END);
[17659]559          break;
560        case deftypefn:
561        case deftypevr:
[18944]562          execute_string ("%s", type_name);
563          xml_insert_element (FUNCTION, START);
564          execute_string ("%s", defined_name);
565          xml_insert_element (FUNCTION, END);
[17659]566          break;
567        case deftypemethod:
568        case deftypeop:
569        case deftypeivar:
[18944]570          execute_string ("%s", type_name2);
571          xml_insert_element (FUNCTION, START);
572          execute_string ("%s", defined_name);
573          xml_insert_element (FUNCTION, END);
[17659]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:
[18944]620          insert_html_tag (END, "i"); /* close italic area for arguments */
[17659]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:
[18944]636          insert_html_tag (END, "i");
[17659]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:
[18944]643          insert_html_tag (END, "i");
[17659]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. */
713void
714cm_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}
Note: See TracBrowser for help on using the repository browser.