1 /* macro.c -- user-defined macros for Texinfo.
2 $Id: macro.c,v 1.12 2002/03/02 15:05:21 karl Exp $
4 Copyright (C) 1998, 99, 2002 Free Software Foundation, Inc.
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)
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.
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. */
24 #include "insertion.h"
26 /* If non-NULL, this is an output stream to write the full macro expansion
27 of the input text to. The result is another texinfo file, but
28 missing @include, @infoinclude, @macro, and macro invocations. Instead,
29 all of the text is placed within the file. */
30 FILE *macro_expansion_output_stream = NULL;
32 /* Output file for -E. */
33 char *macro_expansion_filename;
35 /* Nonzero means a macro string is in execution, as opposed to a file. */
36 int me_executing_string = 0;
38 /* Nonzero means we want only to expand macros and
39 leave everything else intact. */
40 int only_macro_expansion = 0;
42 static ITEXT **itext_info = NULL;
43 static int itext_size = 0;
45 /* Return the arglist on the current line. This can behave in two different
46 ways, depending on the variable BRACES_REQUIRED_FOR_MACRO_ARGS. */
47 int braces_required_for_macro_args = 0;
49 /* Array of macros and definitions. */
50 MACRO_DEF **macro_list = NULL;
52 int macro_list_len = 0; /* Number of elements. */
53 int macro_list_size = 0; /* Number of slots in total. */
55 /* Return the length of the array in ARRAY. */
63 for (i = 0; array[i]; i++);
75 for (i = 0; array[i]; i++)
82 /* Return the macro definition of NAME or NULL if NAME is not defined. */
91 for (i = 0; macro_list && (def = macro_list[i]); i++)
93 if ((!def->inhibited) && (strcmp (def->name, name) == 0))
99 /* Add the macro NAME with ARGLIST and BODY to the list of defined macros.
100 SOURCE_FILE is the name of the file where this definition can be found,
101 and SOURCE_LINENO is the line number within that file. If a macro already
102 exists with NAME, then a warning is produced, and that previous
103 definition is overwritten. */
105 add_macro (name, arglist, body, source_file, source_lineno, flags)
110 int source_lineno, flags;
114 def = find_macro (name);
118 if (macro_list_len + 2 >= macro_list_size)
119 macro_list = xrealloc
120 (macro_list, ((macro_list_size += 10) * sizeof (MACRO_DEF *)));
122 macro_list[macro_list_len] = xmalloc (sizeof (MACRO_DEF));
123 macro_list[macro_list_len + 1] = NULL;
125 def = macro_list[macro_list_len];
131 char *temp_filename = input_filename;
132 int temp_line = line_number;
134 warning (_("macro `%s' previously defined"), name);
136 input_filename = def->source_file;
137 line_number = def->source_lineno;
138 warning (_("here is the previous definition of `%s'"), name);
140 input_filename = temp_filename;
141 line_number = temp_line;
147 for (i = 0; def->arglist[i]; i++)
148 free (def->arglist[i]);
152 free (def->source_file);
156 def->source_file = xstrdup (source_file);
157 def->source_lineno = source_lineno;
159 def->arglist = arglist;
166 get_brace_args (quote_single)
169 char **arglist, *word;
170 int arglist_index, arglist_size;
171 int character, escape_seen, start;
174 /* There is an arglist in braces here, so gather the args inside of it. */
175 skip_whitespace_and_newlines ();
178 arglist_index = arglist_size = 0;
181 skip_whitespace_and_newlines ();
182 start = input_text_offset;
185 while ((character = curchar ()))
187 if (character == '\\')
189 input_text_offset += 2;
192 else if (character == '{')
197 else if ((character == ',' && !quote_single) ||
198 ((character == '}') && depth == 1))
200 int len = input_text_offset - start;
202 if (len || (character != '}'))
204 word = xmalloc (1 + len);
205 memcpy (word, input_text + start, len);
208 /* Clean up escaped characters. */
212 for (i = 0; word[i]; i++)
214 memmove (word + i, word + i + 1,
215 1 + strlen (word + i + 1));
218 if (arglist_index + 2 >= arglist_size)
220 (arglist, (arglist_size += 10) * sizeof (char *));
222 arglist[arglist_index++] = word;
223 arglist[arglist_index] = NULL;
227 if (character == '}')
232 else if (character == '}')
240 if (character == '\n') line_number++;
253 /* Quickly check to see if this macro has been invoked with any arguments.
254 If not, then don't skip any of the following whitespace. */
255 for (i = input_text_offset; i < input_text_length; i++)
256 if (!cr_or_whitespace (input_text[i]))
259 if (input_text[i] != '{')
261 if (braces_required_for_macro_args)
267 /* Braces are not required to fill out the macro arguments. If
268 this macro takes one argument, it is considered to be the
269 remainder of the line, sans whitespace. */
270 if (def->arglist && def->arglist[0] && !def->arglist[1])
274 get_rest_of_line (0, &word);
275 if (input_text[input_text_offset - 1] == '\n')
280 /* canon_white (word); */
281 arglist = xmalloc (2 * sizeof (char *));
288 /* The macro either took no arguments, or took more than
289 one argument. In that case, it must be invoked with
290 arguments surrounded by braces. */
295 return get_brace_args (def->flags & ME_QUOTE_ARG);
298 /* Substitute actual parameters for named parameters in body.
299 The named parameters which appear in BODY must by surrounded
300 reverse slashes, as in \foo\. */
302 apply (named, actuals, body)
303 char **named, **actuals, *body;
306 int new_body_index, new_body_size;
307 char *new_body, *text;
308 int length_of_actuals;
310 length_of_actuals = array_len (actuals);
311 new_body_size = strlen (body);
312 new_body = xmalloc (1 + new_body_size);
314 /* Copy chars from BODY into NEW_BODY. */
319 { /* Anything but a \ is easy. */
321 new_body[new_body_index++] = body[i++];
323 { /* Snarf parameter name, check against named parameters. */
325 int param_start, which, len;
328 while (body[i] && body[i] != '\\')
331 len = i - param_start;
332 param = xmalloc (1 + len);
333 memcpy (param, body + param_start, len);
336 if (body[i]) /* move past \ */
339 /* Now check against named parameters. */
340 for (which = 0; named && named[which]; which++)
341 if (STREQ (named[which], param))
344 if (named && named[which])
346 text = which < length_of_actuals ? actuals[which] : NULL;
352 { /* not a parameter, either it's \\ (if len==0) or an
353 error. In either case, restore one \ at least. */
355 warning (_("\\ in macro expansion followed by `%s' instead of \\ or parameter name"),
359 text = xmalloc (1 + len);
360 sprintf (text, "\\%s", param);
363 if (strlen (param) + 2 < len)
365 new_body_size += len + 1;
366 new_body = xrealloc (new_body, new_body_size);
371 strcpy (new_body + new_body_index, text);
372 new_body_index += len;
374 if (!named || !named[which])
379 new_body[new_body_index] = 0;
383 /* Expand macro passed in DEF, a pointer to a MACRO_DEF, and
384 return its expansion as a string. */
391 char *execution_string = NULL;
392 int start_line = line_number;
394 /* Find out how many arguments this macro definition takes. */
395 num_args = array_len (def->arglist);
397 /* Gather the arguments present on the line if there are any. */
398 arglist = get_macro_args (def);
400 if (num_args < array_len (arglist))
402 free_array (arglist);
403 line_error (_("Macro `%s' called on line %d with too many args"),
404 def->name, start_line);
405 return execution_string;
409 execution_string = apply (def->arglist, arglist, def->body);
411 free_array (arglist);
412 return execution_string;
415 /* Execute the macro passed in DEF, a pointer to a MACRO_DEF. */
420 char *execution_string;
421 int start_line = line_number, end_line;
423 if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion)
424 me_append_before_this_command ();
426 execution_string = expand_macro (def);
427 if (!execution_string)
432 /* Reset the line number to where the macro arguments began.
433 This makes line numbers reported in error messages correct in
434 case the macro arguments span several lines and the expanded
435 arguments invoke other commands. */
436 end_line = line_number;
437 line_number = start_line;
439 if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion)
441 remember_itext (input_text, input_text_offset);
442 me_execute_string (execution_string);
445 execute_string ("%s", execution_string);
447 free (execution_string);
448 line_number = end_line;
453 /* Read and remember the definition of a macro. If RECURSIVE is set,
454 set the ME_RECURSE flag. MACTYPE is either "macro" or "rmacro", and
455 tells us what the matching @end should be. */
457 define_macro (mactype, recursive)
462 char *name, **arglist, *body, *line, *last_end;
463 int body_size, body_index;
465 int defining_line = line_number;
473 if (macro_expansion_output_stream && !executing_string)
474 me_append_before_this_command ();
478 /* Get the name of the macro. This is the set of characters which are
479 not whitespace and are not `{' immediately following the @macro. */
481 int start = input_text_offset;
485 (i < input_text_length) &&
486 (input_text[i] != '{') &&
487 (!cr_or_whitespace (input_text[i]));
491 name = xmalloc (1 + len);
492 memcpy (name, input_text + start, len);
494 input_text_offset = i;
499 /* It is not required that the definition of a macro includes an arglist.
500 If not, don't try to get the named parameters, just use a null list. */
501 if (curchar () == '{')
504 int arglist_index = 0, arglist_size = 0;
505 int gathering_words = 1;
508 /* Read the words inside of the braces which determine the arglist.
509 These words will be replaced within the body of the macro at
513 skip_whitespace_and_newlines ();
515 while (gathering_words)
519 for (i = input_text_offset;
520 (character = input_text[i]);
531 /* Found the end of the current arglist word. Save it. */
532 len = i - input_text_offset;
533 word = xmalloc (1 + len);
534 memcpy (word, input_text + input_text_offset, len);
536 input_text_offset = i;
538 /* Advance to the comma or close-brace that signified
539 the end of the argument. */
540 while ((character = curchar ())
545 if (character == '\n')
549 /* Add the word to our list of words. */
550 if (arglist_index + 2 >= arglist_size)
553 arglist = xrealloc (arglist,
554 arglist_size * sizeof (char *));
557 arglist[arglist_index++] = word;
558 arglist[arglist_index] = NULL;
562 if (character == '}')
569 if (character == ',')
572 skip_whitespace_and_newlines ();
573 i = input_text_offset - 1;
578 /* If we have exactly one argument, do @quote-arg implicitly. Not
579 only does this match TeX's behavior (which can't feasibly be
580 changed), but it's a good idea. */
581 if (arglist_index == 1)
582 flags |= ME_QUOTE_ARG;
585 /* Read the text carefully until we find an "@end macro" which
586 matches this one. The text in between is the body of the macro. */
587 skip_whitespace_and_newlines ();
591 if ((input_text_offset + 9) > input_text_length)
593 file_line_error (input_filename, defining_line,
594 _("%cend macro not found"), COMMAND_PREFIX);
598 get_rest_of_line (0, &line);
600 /* Handle commands only meaningful within a macro. */
601 if ((*line == COMMAND_PREFIX) && (depth == 1) &&
602 (strncmp (line + 1, "allow-recursion", 15) == 0) &&
603 (line[16] == 0 || whitespace (line[16])))
605 for (i = 16; whitespace (line[i]); i++);
606 strcpy (line, line + i);
615 if ((*line == COMMAND_PREFIX) && (depth == 1) &&
616 (strncmp (line + 1, "quote-arg", 9) == 0) &&
617 (line[10] == 0 || whitespace (line[10])))
619 for (i = 10; whitespace (line[i]); i++);
620 strcpy (line, line + i);
622 if (arglist && arglist[0] && !arglist[1])
624 flags |= ME_QUOTE_ARG;
632 line_error (_("@quote-arg only useful for single-argument macros"));
635 if (*line == COMMAND_PREFIX
636 && (strncmp (line + 1, "macro ", 6) == 0
637 || strncmp (line + 1, "rmacro ", 7) == 0))
640 /* Incorrect implementation of nesting -- just check that the last
641 @end matches what we started with. Since nested macros don't
642 work in TeX anyway, this isn't worth the trouble to get right. */
643 if (*line == COMMAND_PREFIX && strncmp (line + 1, "end macro", 9) == 0)
648 if (*line == COMMAND_PREFIX && strncmp (line + 1, "end rmacro", 9) == 0)
656 if ((body_index + strlen (line) + 3) >= body_size)
657 body = xrealloc (body, body_size += 3 + strlen (line));
658 strcpy (body + body_index, line);
659 body_index += strlen (line);
660 body[body_index++] = '\n';
661 body[body_index] = 0;
666 /* Check that @end matched the macro command. */
667 if (!STREQ (last_end, mactype))
668 warning (_("mismatched @end %s with @%s"), last_end, mactype);
670 /* If it was an empty macro like
673 create an empty body. (Otherwise, the macro is not expanded.) */
676 body = (char *)malloc(1);
680 /* We now have the name, the arglist, and the body. However, BODY
681 includes the final newline which preceded the `@end macro' text.
683 if (body && strlen (body))
684 body[strlen (body) - 1] = 0;
689 add_macro (name, arglist, body, input_filename, defining_line, flags);
691 if (macro_expansion_output_stream && !executing_string)
692 remember_itext (input_text, input_text_offset);
698 define_macro ("macro", 0);
704 define_macro ("rmacro", 1);
707 /* Delete the macro with name NAME. The macro is deleted from the list,
708 but it is also returned. If there was no macro defined, NULL is
720 for (i = 0; macro_list && (def = macro_list[i]); i++)
721 if (strcmp (def->name, name) == 0)
723 memmove (macro_list + i, macro_list + i + 1,
724 ((macro_list_len + 1) - i) * sizeof (MACRO_DEF *));
738 if (macro_expansion_output_stream && !executing_string)
739 me_append_before_this_command ();
741 get_rest_of_line (0, &line);
743 for (i = 0; line[i] && !whitespace (line[i]); i++);
744 name = xmalloc (i + 1);
745 memcpy (name, line, i);
748 def = delete_macro (name);
752 free (def->source_file);
760 for (i = 0; def->arglist[i]; i++)
761 free (def->arglist[i]);
772 if (macro_expansion_output_stream && !executing_string)
773 remember_itext (input_text, input_text_offset);
776 /* How to output sections of the input file verbatim. */
778 /* Set the value of POINTER's offset to OFFSET. */
780 remember_itext (pointer, offset)
787 /* If we have no info, initialize a blank list. */
790 itext_info = xmalloc ((itext_size = 10) * sizeof (ITEXT *));
791 for (i = 0; i < itext_size; i++)
792 itext_info[i] = NULL;
795 /* If the pointer is already present in the list, then set the offset. */
796 for (i = 0; i < itext_size; i++)
797 if ((itext_info[i]) &&
798 (itext_info[i]->pointer == pointer))
800 itext = itext_info[i];
801 itext_info[i]->offset = offset;
807 /* Find a blank slot (or create a new one), and remember the
808 pointer and offset. */
809 for (i = 0; i < itext_size; i++)
810 if (itext_info[i] == NULL)
813 /* If not found, then add some slots. */
818 itext_info = xrealloc
819 (itext_info, (itext_size += 10) * sizeof (ITEXT *));
821 for (j = i; j < itext_size; j++)
822 itext_info[j] = NULL;
825 /* Now add the pointer and the offset. */
826 itext_info[i] = xmalloc (sizeof (ITEXT));
827 itext_info[i]->pointer = pointer;
828 itext_info[i]->offset = offset;
829 itext = itext_info[i];
834 /* Forget the input text associated with POINTER. */
836 forget_itext (pointer)
841 for (i = 0; i < itext_size; i++)
842 if (itext_info[i] && (itext_info[i]->pointer == pointer))
844 free (itext_info[i]);
845 itext_info[i] = NULL;
850 /* Append the text which appeared in input_text from the last offset to
851 the character just before the command that we are currently executing. */
853 me_append_before_this_command ()
857 for (i = input_text_offset; i && (input_text[i] != COMMAND_PREFIX); i--)
859 maybe_write_itext (input_text, i);
862 /* Similar to execute_string, but only takes a single string argument,
863 and remembers the input text location, etc. */
865 me_execute_string (execution_string)
866 char *execution_string;
868 int saved_escape_html = escape_html;
869 int saved_in_paragraph = in_paragraph;
870 escape_html = me_executing_string == 0;
874 input_text_offset = 0;
875 /* The following xstrdup is so we can relocate input_text at will. */
876 input_text = xstrdup (execution_string);
877 input_filename = xstrdup (input_filename);
878 input_text_length = strlen (execution_string);
880 remember_itext (input_text, 0);
882 me_executing_string++;
885 free (input_filename);
887 me_executing_string--;
889 in_paragraph = saved_in_paragraph;
890 escape_html = saved_escape_html;
893 /* A wrapper around me_execute_string which saves and restores
894 variables important for output generation. This is called
895 when we need to produce macro-expanded output for input which
896 leaves no traces in the Info output. */
898 me_execute_string_keep_state (execution_string, append_string)
899 char *execution_string, *append_string;
901 int op_orig, opcol_orig, popen_orig;
902 int fill_orig, newline_orig, indent_orig, meta_pos_orig;
904 remember_itext (input_text, input_text_offset);
905 op_orig = output_paragraph_offset;
906 meta_pos_orig = meta_char_pos;
907 opcol_orig = output_column;
908 popen_orig = paragraph_is_open;
909 fill_orig = filling_enabled;
910 newline_orig = last_char_was_newline;
912 indent_orig = no_indent;
914 me_execute_string (execution_string);
916 write_region_to_macro_output (append_string, 0, strlen (append_string));
917 output_paragraph_offset = op_orig;
918 meta_char_pos = meta_pos_orig;
919 output_column = opcol_orig;
920 paragraph_is_open = popen_orig;
921 filling_enabled = fill_orig;
922 last_char_was_newline = newline_orig;
923 no_indent = indent_orig;
926 /* Append the text which appears in input_text from the last offset to
927 the current OFFSET. */
929 append_to_expansion_output (offset)
935 for (i = 0; i < itext_size; i++)
936 if (itext_info[i] && itext_info[i]->pointer == input_text)
938 itext = itext_info[i];
945 if (offset > itext->offset)
947 write_region_to_macro_output (input_text, itext->offset, offset);
948 remember_itext (input_text, offset);
952 /* Only write this input text iff it appears in our itext list. */
954 maybe_write_itext (pointer, offset)
961 for (i = 0; i < itext_size; i++)
962 if (itext_info[i] && (itext_info[i]->pointer == pointer))
964 itext = itext_info[i];
968 if (itext && (itext->offset < offset))
970 write_region_to_macro_output (itext->pointer, itext->offset, offset);
971 remember_itext (pointer, offset);
976 write_region_to_macro_output (string, start, end)
980 if (macro_expansion_output_stream)
981 fwrite (string + start, 1, end - start, macro_expansion_output_stream);
986 typedef struct alias_struct
990 struct alias_struct *next;
993 static alias_type *aliases;
999 alias_type *a = xmalloc (sizeof (alias_type));
1002 get_until_in_line (1, "=", &(a->alias));
1003 canon_white (a->alias);
1005 discard_until ("=");
1007 get_until_in_line (0, " ", &(a->mapto));
1013 /* Perform an alias expansion. Called from read_command. */
1018 alias_type *findit = aliases;
1021 if (strcmp (findit->alias, tok) == 0)
1024 return alias_expand (xstrdup (findit->mapto));
1027 findit = findit->next;
1032 /* definfoenclose implementation. */
1034 /* This structure is used to track enclosure macros. When an enclosure
1035 macro is recognized, a pointer to the enclosure block corresponding
1036 to its name is saved in the brace element for its argument. */
1037 typedef struct enclose_struct
1042 struct enclose_struct *next;
1045 static enclosure_type *enclosures;
1047 typedef struct enclosure_stack_struct
1049 enclosure_type *current;
1050 struct enclosure_stack_struct *next;
1051 } enclosure_stack_type;
1053 static enclosure_stack_type *enclosure_stack;
1055 /* @definfoenclose */
1057 cm_definfoenclose ()
1059 enclosure_type *e = xmalloc (sizeof (enclosure_type));
1062 get_until_in_line (1, ",", &(e->enclose));
1063 discard_until (",");
1064 get_until_in_line (0, ",", &(e->before));
1065 discard_until (",");
1066 get_until_in_line (0, "\n", &(e->after));
1068 e->next = enclosures;
1072 /* If TOK is an enclosure command, push it on the enclosure stack and
1073 return 1. Else return 0. */
1076 enclosure_command (tok)
1079 enclosure_type *findit = enclosures;
1082 if (strcmp (findit->enclose, tok) == 0)
1084 enclosure_stack_type *new = xmalloc (sizeof (enclosure_stack_type));
1085 new->current = findit;
1086 new->next = enclosure_stack;
1087 enclosure_stack = new;
1092 findit = findit->next;
1097 /* actually perform the enclosure expansion */
1099 enclosure_expand (arg, start, end)
1100 int arg, start, end;
1103 add_word (enclosure_stack->current->before);
1106 enclosure_stack_type *temp;
1108 add_word (enclosure_stack->current->after);
1110 temp = enclosure_stack;
1111 enclosure_stack = enclosure_stack->next;