156160Sru/* defun.c -- @defun and friends. 2146515Sru $Id: defun.c,v 1.11 2004/04/11 17:56:46 karl Exp $ 356160Sru 4146515Sru Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software 5116525Sru Foundation, Inc. 656160Sru 756160Sru This program is free software; you can redistribute it and/or modify 856160Sru it under the terms of the GNU General Public License as published by 956160Sru the Free Software Foundation; either version 2, or (at your option) 1056160Sru any later version. 1156160Sru 1256160Sru This program is distributed in the hope that it will be useful, 1356160Sru but WITHOUT ANY WARRANTY; without even the implied warranty of 1456160Sru MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1556160Sru GNU General Public License for more details. 1656160Sru 1756160Sru You should have received a copy of the GNU General Public License 1856160Sru along with this program; if not, write to the Free Software Foundation, 1956160Sru Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2056160Sru 2156160Sru#include "system.h" 2256160Sru#include "defun.h" 23114472Sru#include "xml.h" 2456160Sru#include "insertion.h" 2556160Sru#include "makeinfo.h" 26114472Sru#include "cmds.h" 27114472Sru#include "html.h" 2856160Sru 2956160Sru 3056160Sru#define DEFUN_SELF_DELIMITING(c) \ 3156160Sru ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']') 3256160Sru 3356160Srustruct token_accumulator 3456160Sru{ 3556160Sru unsigned int length; 3656160Sru unsigned int index; 3756160Sru char **tokens; 3856160Sru}; 3956160Sru 4056160Srustatic void 41146515Sruinitialize_token_accumulator (struct token_accumulator *accumulator) 4256160Sru{ 4356160Sru accumulator->length = 0; 4456160Sru accumulator->index = 0; 4556160Sru accumulator->tokens = NULL; 4656160Sru} 4756160Sru 4856160Srustatic void 49146515Sruaccumulate_token (struct token_accumulator *accumulator, char *token) 5056160Sru{ 5156160Sru if (accumulator->index >= accumulator->length) 5256160Sru { 5356160Sru accumulator->length += 10; 5456160Sru accumulator->tokens = xrealloc (accumulator->tokens, 5556160Sru (accumulator->length * sizeof (char *))); 5656160Sru } 5756160Sru accumulator->tokens[accumulator->index] = token; 5856160Sru accumulator->index += 1; 5956160Sru} 6056160Sru 6156160Sru/* Given STRING_POINTER pointing at an open brace, skip forward and return a 6256160Sru pointer to just past the matching close brace. */ 6356160Srustatic int 64146515Sruscan_group_in_string (char **string_pointer) 6556160Sru{ 6656160Sru char *scan_string = (*string_pointer) + 1; 6756160Sru unsigned int level = 1; 68100513Sru int started_command = 0; 6956160Sru 7056160Sru for (;;) 7156160Sru { 7256160Sru int c; 7356160Sru if (level == 0) 7456160Sru { 7556160Sru *string_pointer = scan_string; 7656160Sru return 1; 7756160Sru } 7856160Sru c = *scan_string++; 7956160Sru if (c == 0) 8056160Sru { 8156160Sru /* Tweak line_number to compensate for fact that 8256160Sru we gobbled the whole line before coming here. */ 83100513Sru line_number--; 8456160Sru line_error (_("Missing `}' in @def arg")); 85100513Sru line_number++; 8656160Sru *string_pointer = scan_string - 1; 8756160Sru return 0; 8856160Sru } 8956160Sru 90100513Sru if (c == '{' && !started_command) 91100513Sru level++; 92100513Sru if (c == '}' && !started_command) 93100513Sru level--; 94100513Sru 95100513Sru /* remember if at @. */ 96100513Sru started_command = (c == '@' && !started_command); 9756160Sru } 9856160Sru} 9956160Sru 10056160Sru/* Return a list of tokens from the contents of STRING. 10156160Sru Commands and brace-delimited groups count as single tokens. 10256160Sru Contiguous whitespace characters are converted to a token 10356160Sru consisting of a single space. */ 10456160Srustatic char ** 105146515Sruargs_from_string (char *string) 10656160Sru{ 10756160Sru struct token_accumulator accumulator; 10856160Sru char *token_start, *token_end; 10956160Sru char *scan_string = string; 11056160Sru 11156160Sru initialize_token_accumulator (&accumulator); 11256160Sru 11356160Sru while (*scan_string) 11456160Sru { /* Replace arbitrary whitespace by a single space. */ 11556160Sru if (whitespace (*scan_string)) 11656160Sru { 11756160Sru scan_string += 1; 11856160Sru while (whitespace (*scan_string)) 11956160Sru scan_string += 1; 12056160Sru accumulate_token ((&accumulator), (xstrdup (" "))); 12156160Sru continue; 12256160Sru } 12356160Sru 12456160Sru /* Commands count as single tokens. */ 12556160Sru if (*scan_string == COMMAND_PREFIX) 12656160Sru { 12756160Sru token_start = scan_string; 12856160Sru scan_string += 1; 12956160Sru if (self_delimiting (*scan_string)) 13056160Sru scan_string += 1; 13156160Sru else 13256160Sru { 13356160Sru int c; 13456160Sru while (1) 13556160Sru { 13656160Sru c = *scan_string++; 13756160Sru 13856160Sru if ((c == 0) || (c == '{') || (whitespace (c))) 13956160Sru { 14056160Sru scan_string -= 1; 14156160Sru break; 14256160Sru } 14356160Sru } 14456160Sru 14556160Sru if (*scan_string == '{') 14656160Sru { 14756160Sru char *s = scan_string; 14856160Sru (void) scan_group_in_string (&s); 14956160Sru scan_string = s; 15056160Sru } 15156160Sru } 15256160Sru token_end = scan_string; 15356160Sru } 15456160Sru 15556160Sru /* Parentheses and brackets are self-delimiting. */ 15656160Sru else if (DEFUN_SELF_DELIMITING (*scan_string)) 15756160Sru { 15856160Sru token_start = scan_string; 15956160Sru scan_string += 1; 16056160Sru token_end = scan_string; 16156160Sru } 16256160Sru 16356160Sru /* Open brace introduces a group that is a single token. */ 16456160Sru else if (*scan_string == '{') 16556160Sru { 16656160Sru char *s = scan_string; 16756160Sru int balanced = scan_group_in_string (&s); 16856160Sru 16956160Sru token_start = scan_string + 1; 17056160Sru scan_string = s; 17156160Sru token_end = balanced ? (scan_string - 1) : scan_string; 17256160Sru } 17356160Sru 174146515Sru /* Make commas separate tokens so to differentiate them from 175146515Sru parameter types in XML output. */ 176146515Sru else if (*scan_string == ',') 177146515Sru { 178146515Sru token_start = scan_string; 179146515Sru scan_string += 1; 180146515Sru token_end = scan_string; 181146515Sru } 182146515Sru 18356160Sru /* Otherwise a token is delimited by whitespace, parentheses, 18456160Sru brackets, or braces. A token is also ended by a command. */ 18556160Sru else 18656160Sru { 18756160Sru token_start = scan_string; 18856160Sru 18956160Sru for (;;) 19056160Sru { 19156160Sru int c; 19256160Sru 19356160Sru c = *scan_string++; 19456160Sru 19556160Sru /* Do not back up if we're looking at a }; since the only 19656160Sru valid }'s are those matched with {'s, we want to give 19756160Sru an error. If we back up, we go into an infinite loop. */ 19856160Sru if (!c || whitespace (c) || DEFUN_SELF_DELIMITING (c) 19956160Sru || c == '{') 20056160Sru { 20156160Sru scan_string--; 20256160Sru break; 20356160Sru } 20456160Sru 205146515Sru /* End token if we are looking at a comma, as commas are 206146515Sru delimiters too. */ 207146515Sru if (c == ',') 208146515Sru { 209146515Sru scan_string--; 210146515Sru break; 211146515Sru } 212146515Sru 21356160Sru /* If we encounter a command embedded within a token, 21456160Sru then end the token. */ 21556160Sru if (c == COMMAND_PREFIX) 21656160Sru { 21756160Sru scan_string--; 21856160Sru break; 21956160Sru } 22056160Sru } 22156160Sru token_end = scan_string; 22256160Sru } 22356160Sru 22456160Sru accumulate_token (&accumulator, substring (token_start, token_end)); 22556160Sru } 22656160Sru accumulate_token (&accumulator, NULL); 22756160Sru return accumulator.tokens; 22856160Sru} 22956160Sru 23056160Srustatic void 231146515Sruprocess_defun_args (char **defun_args, int auto_var_p) 23256160Sru{ 23356160Sru int pending_space = 0; 23456160Sru 235146515Sru if (xml) 236146515Sru { 237146515Sru xml_process_defun_args (defun_args, auto_var_p); 238146515Sru return; 239146515Sru } 240146515Sru 24156160Sru for (;;) 24256160Sru { 24356160Sru char *defun_arg = *defun_args++; 24456160Sru 24556160Sru if (defun_arg == NULL) 24656160Sru break; 24756160Sru 24856160Sru if (defun_arg[0] == ' ') 24956160Sru { 25056160Sru pending_space = 1; 25156160Sru continue; 25256160Sru } 25356160Sru 25456160Sru if (pending_space) 25556160Sru { 25656160Sru add_char (' '); 25756160Sru pending_space = 0; 25856160Sru } 25956160Sru 26056160Sru if (DEFUN_SELF_DELIMITING (defun_arg[0])) 261114472Sru { 262114472Sru /* Within @deffn and friends, texinfo.tex makes parentheses 263114472Sru sans serif and brackets bold. We use roman instead. */ 264146515Sru if (html) 265146515Sru insert_html_tag (START, ""); 266146515Sru 267114472Sru add_char (defun_arg[0]); 268146515Sru 269146515Sru if (html) 270146515Sru insert_html_tag (END, ""); 271114472Sru } 272146515Sru /* else if (defun_arg[0] == '&' || defun_arg[0] == COMMAND_PREFIX) */ 273146515Sru /* execute_string ("%s", defun_arg); */ 274146515Sru /* else if (auto_var_p) */ 275146515Sru /* execute_string ("%s", defun_arg); */ 276146515Sru else 27756160Sru execute_string ("%s", defun_arg); 27856160Sru } 27956160Sru} 28056160Sru 28156160Srustatic char * 282146515Srunext_nonwhite_defun_arg (char ***arg_pointer) 28356160Sru{ 28456160Sru char **scan = (*arg_pointer); 28556160Sru char *arg = (*scan++); 28656160Sru 28756160Sru if ((arg != 0) && (*arg == ' ')) 28856160Sru arg = *scan++; 28956160Sru 29056160Sru if (arg == 0) 29156160Sru scan -= 1; 29256160Sru 29356160Sru *arg_pointer = scan; 29456160Sru 29556160Sru return (arg == 0) ? "" : arg; 29656160Sru} 29756160Sru 29856160Sru 29956160Sru/* This is needed also in insertion.c. */ 30056160Sru 30156160Sruenum insertion_type 302146515Sruget_base_type (int type) 30356160Sru{ 304146515Sru int base_type; 30556160Sru switch (type) 30656160Sru { 30756160Sru case defivar: base_type = defcv; break; 30856160Sru case defmac: base_type = deffn; break; 30956160Sru case defmethod: base_type = defop; break; 31056160Sru case defopt: base_type = defvr; break; 31156160Sru case defspec: base_type = deffn; break; 312146515Sru case deftypecv: base_type = deftypecv; break; 31356160Sru case deftypefun: base_type = deftypefn; break; 31456160Sru case deftypeivar: base_type = deftypeivar; break; 31556160Sru case deftypemethod: base_type = deftypemethod; break; 31656160Sru case deftypeop: base_type = deftypeop; break; 31756160Sru case deftypevar: base_type = deftypevr; break; 31856160Sru case defun: base_type = deffn; break; 31956160Sru case defvar: base_type = defvr; break; 32056160Sru default: 32156160Sru base_type = type; 32256160Sru break; 32356160Sru } 32456160Sru 32556160Sru return base_type; 32656160Sru} 32756160Sru 32856160Sru/* Make the defun type insertion. 32956160Sru TYPE says which insertion this is. 33056160Sru X_P, if nonzero, says not to start a new insertion. */ 33156160Srustatic void 332146515Srudefun_internal (int type, int x_p) 33356160Sru{ 334146515Sru int base_type; 33556160Sru char **defun_args, **scan_args; 336116525Sru const char *category; 337146515Sru char *defined_name; 338146515Sru char *type_name = NULL; 339146515Sru char *type_name2 = NULL; 34056160Sru 34156160Sru { 34256160Sru char *line; 34356160Sru 34456160Sru /* The @def.. line is the only place in Texinfo where you are 34556160Sru allowed to use unquoted braces that don't delimit arguments of 34656160Sru a command or a macro; in any other place it will trigger an 34756160Sru error message from the reader loop. The special handling of 34856160Sru this case inside `args_from_string' is an extra special hack 34956160Sru which allows this. The side effect is that if we try to expand 35056160Sru the rest of the line below, the recursive reader loop will 35156160Sru signal an error if there are brace-delimited arguments on that line. 35256160Sru 35356160Sru The best solution to this would be to change the syntax of 35456160Sru @def.. commands so that it doesn't violate Texinfo's own rules. 35556160Sru But it's probably too late for this now, as it will break a lot 35656160Sru of existing manuals. 35756160Sru 35856160Sru Unfortunately, this means that you can't call macros, use @value, etc. 35956160Sru inside @def.. commands, sigh. */ 36056160Sru get_rest_of_line (0, &line); 361146515Sru 362146515Sru /* Basic line continuation. If a line ends with \s*@\s* concatanate 363146515Sru the next line. */ 364146515Sru { 365146515Sru char *next_line, *new_line; 366146515Sru int i; 367146515Sru 368146515Sru line_continuation: 369146515Sru i = strlen (line) - 1; 370146515Sru 371146515Sru if (line[i] == '@' && line[i-1] != '@') 372146515Sru { 373146515Sru get_rest_of_line (0, &next_line); 374146515Sru new_line = (char *) xmalloc (i + strlen (next_line) + 2); 375146515Sru strncpy (new_line, line, i); 376146515Sru new_line[i] = '\0'; 377146515Sru free (line); 378146515Sru strcat (new_line, " "); 379146515Sru strcat (new_line, next_line); 380146515Sru line = xstrdup (new_line); 381146515Sru free (next_line); 382146515Sru free (new_line); 383146515Sru 384146515Sru goto line_continuation; 385146515Sru } 386146515Sru } 387146515Sru 38856160Sru defun_args = (args_from_string (line)); 38956160Sru free (line); 39056160Sru } 39156160Sru 39256160Sru scan_args = defun_args; 39356160Sru 39456160Sru /* Get base type and category string. */ 39556160Sru base_type = get_base_type (type); 39656160Sru 39756160Sru /* xx all these const strings should be determined upon 39856160Sru documentlanguage argument and NOT via gettext (kama). */ 39956160Sru switch (type) 40056160Sru { 40156160Sru case defun: 40256160Sru case deftypefun: 40356160Sru category = _("Function"); 40456160Sru break; 40556160Sru case defmac: 40656160Sru category = _("Macro"); 40756160Sru break; 40856160Sru case defspec: 40956160Sru category = _("Special Form"); 41056160Sru break; 41156160Sru case defvar: 41256160Sru case deftypevar: 41356160Sru category = _("Variable"); 41456160Sru break; 41556160Sru case defopt: 41656160Sru category = _("User Option"); 41756160Sru break; 41856160Sru case defivar: 41956160Sru case deftypeivar: 42056160Sru category = _("Instance Variable"); 42156160Sru break; 42256160Sru case defmethod: 42356160Sru case deftypemethod: 42456160Sru category = _("Method"); 42556160Sru break; 42656160Sru default: 42756160Sru category = next_nonwhite_defun_arg (&scan_args); 42856160Sru break; 42956160Sru } 43056160Sru 43156160Sru /* The class name. */ 432146515Sru if ((base_type == deftypecv) 433146515Sru || (base_type == deftypefn) 43456160Sru || (base_type == deftypevr) 43556160Sru || (base_type == defcv) 43656160Sru || (base_type == defop) 43756160Sru || (base_type == deftypeivar) 43856160Sru || (base_type == deftypemethod) 43956160Sru || (base_type == deftypeop) 44056160Sru ) 44156160Sru type_name = next_nonwhite_defun_arg (&scan_args); 44256160Sru 44356160Sru /* The type name for typed languages. */ 444146515Sru if ((base_type == deftypecv) 44593139Sru || (base_type == deftypeivar) 446146515Sru || (base_type == deftypemethod) 44793139Sru || (base_type == deftypeop) 44856160Sru ) 44956160Sru type_name2 = next_nonwhite_defun_arg (&scan_args); 45056160Sru 45156160Sru /* The function or whatever that's actually being defined. */ 45256160Sru defined_name = next_nonwhite_defun_arg (&scan_args); 45356160Sru 45456160Sru /* This hack exists solely for the purposes of formatting the Texinfo 45556160Sru manual. I couldn't think of a better way. The token might be a 45656160Sru simple @@ followed immediately by more text. If this is the case, 45756160Sru then the next defun arg is part of this one, and we should 45856160Sru concatenate them. */ 45956160Sru if (*scan_args && **scan_args && !whitespace (**scan_args) 46056160Sru && STREQ (defined_name, "@@")) 46156160Sru { 46256160Sru char *tem = xmalloc (3 + strlen (scan_args[0])); 46356160Sru 46456160Sru sprintf (tem, "@@%s", scan_args[0]); 46556160Sru 46656160Sru free (scan_args[0]); 46756160Sru scan_args[0] = tem; 46856160Sru scan_args++; 46956160Sru defined_name = tem; 47056160Sru } 47156160Sru 47293139Sru /* It's easy to write @defun foo(arg1 arg2), but a following ( is 47393139Sru misparsed by texinfo.tex and this is next to impossible to fix. 47493139Sru Warn about it. */ 47593139Sru if (*scan_args && **scan_args && **scan_args == '(') 47693139Sru warning ("`%c' follows defined name `%s' instead of whitespace", 47793139Sru **scan_args, defined_name); 478116525Sru 47956160Sru if (!x_p) 48056160Sru begin_insertion (type); 48156160Sru 48256160Sru /* Write the definition header line. 48356160Sru This should start at the normal indentation. */ 48456160Sru current_indent -= default_indentation_increment; 48556160Sru start_paragraph (); 48656160Sru 487146515Sru if (!html && !xml) 48856160Sru switch (base_type) 48956160Sru { 49056160Sru case deffn: 49156160Sru case defvr: 49256160Sru case deftp: 493146515Sru execute_string (" --- %s: %s", category, defined_name); 49456160Sru break; 49556160Sru case deftypefn: 49656160Sru case deftypevr: 497146515Sru execute_string (" --- %s: %s %s", category, type_name, defined_name); 49856160Sru break; 49956160Sru case defcv: 500146515Sru execute_string (" --- %s %s %s: %s", category, _("of"), type_name, 50156160Sru defined_name); 50256160Sru break; 503146515Sru case deftypecv: 50456160Sru case deftypeivar: 505146515Sru execute_string (" --- %s %s %s: %s %s", category, _("of"), type_name, 50656160Sru type_name2, defined_name); 50756160Sru break; 50856160Sru case defop: 509146515Sru execute_string (" --- %s %s %s: %s", category, _("on"), type_name, 51056160Sru defined_name); 51156160Sru break; 51256160Sru case deftypeop: 513146515Sru execute_string (" --- %s %s %s: %s %s", category, _("on"), type_name, 51456160Sru type_name2, defined_name); 51556160Sru break; 51656160Sru case deftypemethod: 517146515Sru execute_string (" --- %s %s %s: %s %s", category, _("on"), type_name, 51856160Sru type_name2, defined_name); 51956160Sru break; 52056160Sru } 521146515Sru else if (html) 52256160Sru { 52356160Sru /* If this is not a @def...x version, it could only 52456160Sru be a normal version @def.... So start the table here. */ 52556160Sru if (!x_p) 526146515Sru insert_string ("<div class=\"defun\">\n"); 527146515Sru else 528146515Sru rollback_empty_tag ("blockquote"); 52956160Sru 530146515Sru /* xx The single words (on, off) used here, should depend on 531146515Sru documentlanguage and NOT on gettext --kama. */ 532146515Sru switch (base_type) 533146515Sru { 534146515Sru case deffn: 535146515Sru case defvr: 536146515Sru case deftp: 537146515Sru case deftypefn: 538146515Sru case deftypevr: 539146515Sru execute_string ("--- %s: ", category); 540146515Sru break; 54156160Sru 542146515Sru case defcv: 543146515Sru case deftypecv: 544146515Sru case deftypeivar: 545146515Sru execute_string ("--- %s %s %s: ", category, _("of"), type_name); 546146515Sru break; 547146515Sru 548146515Sru case defop: 549146515Sru case deftypemethod: 550146515Sru case deftypeop: 551146515Sru execute_string ("--- %s %s %s: ", category, _("on"), type_name); 552146515Sru break; 553146515Sru } /* switch (base_type)... */ 554146515Sru 55556160Sru switch (base_type) 55656160Sru { 55756160Sru case deffn: 55856160Sru case defvr: 55956160Sru case deftp: 560146515Sru /* <var> is for the following function arguments. */ 561114472Sru insert_html_tag (START, "b"); 56293139Sru execute_string ("%s", defined_name); 563114472Sru insert_html_tag (END, "b"); 564146515Sru insert_html_tag (START, "var"); 56556160Sru break; 56656160Sru case deftypefn: 56756160Sru case deftypevr: 56893139Sru execute_string ("%s ", type_name); 569114472Sru insert_html_tag (START, "b"); 57093139Sru execute_string ("%s", defined_name); 571114472Sru insert_html_tag (END, "b"); 572146515Sru insert_html_tag (START, "var"); 57356160Sru break; 57456160Sru case defcv: 57556160Sru case defop: 576114472Sru insert_html_tag (START, "b"); 57793139Sru execute_string ("%s", defined_name); 578114472Sru insert_html_tag (END, "b"); 579146515Sru insert_html_tag (START, "var"); 58056160Sru break; 581146515Sru case deftypecv: 582146515Sru case deftypeivar: 58356160Sru case deftypemethod: 58456160Sru case deftypeop: 58593139Sru execute_string ("%s ", type_name2); 586114472Sru insert_html_tag (START, "b"); 58793139Sru execute_string ("%s", defined_name); 588114472Sru insert_html_tag (END, "b"); 589146515Sru insert_html_tag (START, "var"); 59056160Sru break; 59156160Sru } 592146515Sru } 593146515Sru else if (xml) 594146515Sru xml_begin_def_term (base_type, category, defined_name, type_name, 595146515Sru type_name2); 59656160Sru 59756160Sru current_indent += default_indentation_increment; 59856160Sru 59956160Sru /* Now process the function arguments, if any. If these carry onto 60056160Sru the next line, they should be indented by two increments to 60156160Sru distinguish them from the body of the definition, which is indented 60256160Sru by one increment. */ 60356160Sru current_indent += default_indentation_increment; 60456160Sru 60556160Sru switch (base_type) 60656160Sru { 60756160Sru case deffn: 60856160Sru case defop: 60956160Sru process_defun_args (scan_args, 1); 61056160Sru break; 61156160Sru 61256160Sru /* Through Makeinfo 1.67 we processed remaining args only for deftp, 61356160Sru deftypefn, and deftypemethod. But the libc manual, for example, 61456160Sru needs to say: 61556160Sru @deftypevar {char *} tzname[2] 61656160Sru And simply allowing the extra text seems far simpler than trying 61756160Sru to invent yet more defn commands. In any case, we should either 61856160Sru output it or give an error, not silently ignore it. */ 61956160Sru default: 62056160Sru process_defun_args (scan_args, 0); 62156160Sru break; 62256160Sru } 62356160Sru 62456160Sru current_indent -= default_indentation_increment; 625146515Sru if (!html) 626146515Sru close_single_paragraph (); 62756160Sru 628146515Sru /* Make an entry in the appropriate index. (XML and 629146515Sru Docbook already got their entries, so skip them.) */ 630146515Sru if (!xml) 631146515Sru switch (base_type) 632146515Sru { 633146515Sru case deffn: 634146515Sru case deftypefn: 635146515Sru execute_string ("@findex %s\n", defined_name); 636146515Sru break; 637146515Sru case defcv: 638146515Sru case deftypecv: 639146515Sru case deftypevr: 640146515Sru case defvr: 641146515Sru execute_string ("@vindex %s\n", defined_name); 642146515Sru break; 643146515Sru case deftypeivar: 644146515Sru execute_string ("@vindex %s %s %s\n", defined_name, _("of"), 645146515Sru type_name); 646146515Sru break; 647146515Sru case defop: 648146515Sru case deftypeop: 649146515Sru case deftypemethod: 650146515Sru execute_string ("@findex %s %s %s\n", defined_name, _("on"), 651146515Sru type_name); 652146515Sru break; 653146515Sru case deftp: 654146515Sru execute_string ("@tindex %s\n", defined_name); 655146515Sru break; 656146515Sru } 65793139Sru 658146515Sru if (xml) 659146515Sru xml_end_def_term (); 660146515Sru else if (html) 66156160Sru { 662146515Sru inhibit_paragraph_indentation = 1; 663146515Sru no_indent = 1; 664146515Sru insert_html_tag (END, "var"); 665146515Sru insert_string ("<br>\n"); 666146515Sru /* Indent the definition a bit. */ 667146515Sru add_html_block_elt ("<blockquote>"); 668146515Sru no_indent = 0; 669146515Sru inhibit_paragraph_indentation = 0; 670146515Sru paragraph_is_open = 0; 67156160Sru } 67256160Sru 67356160Sru /* Deallocate the token list. */ 67456160Sru scan_args = defun_args; 67556160Sru while (1) 67656160Sru { 67756160Sru char * arg = (*scan_args++); 67856160Sru if (arg == NULL) 67956160Sru break; 68056160Sru free (arg); 68156160Sru } 68256160Sru free (defun_args); 68356160Sru} 68456160Sru 68556160Sru/* Add an entry for a function, macro, special form, variable, or option. 68656160Sru If the name of the calling command ends in `x', then this is an extra 68756160Sru entry included in the body of an insertion of the same type. */ 68856160Sruvoid 689146515Srucm_defun (void) 69056160Sru{ 691146515Sru int type; 692116525Sru char *base_command = xstrdup (command); /* command with any `x' removed */ 693116525Sru int x_p = (command[strlen (command) - 1] == 'x'); 69456160Sru 69556160Sru if (x_p) 696116525Sru base_command[strlen (base_command) - 1] = 0; 69756160Sru 698116525Sru type = find_type_from_name (base_command); 69956160Sru 70056160Sru /* If we are adding to an already existing insertion, then make sure 70156160Sru that we are already in an insertion of type TYPE. */ 702146515Sru if (x_p) 70356160Sru { 704146515Sru INSERTION_ELT *i = insertion_stack; 705146515Sru /* Skip over ifclear and ifset conditionals. */ 706146515Sru while (i && (i->insertion == ifset || i->insertion == ifclear)) 707146515Sru i = i->next; 708146515Sru 709146515Sru if (!i || i->insertion != type) 710146515Sru { 711146515Sru line_error (_("Must be in `@%s' environment to use `@%s'"), 712146515Sru base_command, command); 713146515Sru discard_until ("\n"); 714146515Sru return; 715146515Sru } 71656160Sru } 71756160Sru 718146515Sru defun_internal (type, x_p); 719116525Sru free (base_command); 72056160Sru} 721