[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 | |
---|
| 32 | struct token_accumulator |
---|
| 33 | { |
---|
| 34 | unsigned int length; |
---|
| 35 | unsigned int index; |
---|
| 36 | char **tokens; |
---|
| 37 | }; |
---|
| 38 | |
---|
| 39 | static void |
---|
| 40 | initialize_token_accumulator (accumulator) |
---|
| 41 | struct token_accumulator *accumulator; |
---|
| 42 | { |
---|
| 43 | accumulator->length = 0; |
---|
| 44 | accumulator->index = 0; |
---|
| 45 | accumulator->tokens = NULL; |
---|
| 46 | } |
---|
| 47 | |
---|
| 48 | static void |
---|
| 49 | accumulate_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. */ |
---|
| 65 | static int |
---|
| 66 | scan_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. */ |
---|
| 107 | static char ** |
---|
| 108 | args_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 | |
---|
| 217 | static void |
---|
| 218 | process_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 | |
---|
| 276 | static char * |
---|
| 277 | next_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 | |
---|
| 297 | enum insertion_type |
---|
| 298 | get_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. */ |
---|
| 327 | static void |
---|
| 328 | defun_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. */ |
---|
| 713 | void |
---|
| 714 | cm_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 | } |
---|