* m4/gnulib-cache.m4: Update to newer gnulib-tool.
[m4/ericb.git] / src / builtin.c
blobe3530f67a0f04f254c5cf8916bfcb11fb391c9a6
1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2000, 2004, 2006
4 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 of the License, or
9 (at your option) any later version.
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
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA
22 /* Code for all builtin macros, initialisation of symbol table, and
23 expansion of user defined macros. */
25 #include "m4.h"
27 extern FILE *popen ();
29 #include "regex.h"
31 #if HAVE_SYS_WAIT_H
32 # include <sys/wait.h>
33 #endif
35 #define ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
37 /* Initialisation of builtin and predefined macros. The table
38 "builtin_tab" is both used for initialisation, and by the "builtin"
39 builtin. */
41 #define DECLARE(name) \
42 static void name (struct obstack *, int, token_data **)
44 DECLARE (m4___file__);
45 DECLARE (m4___line__);
46 DECLARE (m4___program__);
47 DECLARE (m4_builtin);
48 DECLARE (m4_changecom);
49 DECLARE (m4_changequote);
50 #ifdef ENABLE_CHANGEWORD
51 DECLARE (m4_changeword);
52 #endif
53 DECLARE (m4_debugmode);
54 DECLARE (m4_debugfile);
55 DECLARE (m4_decr);
56 DECLARE (m4_define);
57 DECLARE (m4_defn);
58 DECLARE (m4_divert);
59 DECLARE (m4_divnum);
60 DECLARE (m4_dnl);
61 DECLARE (m4_dumpdef);
62 DECLARE (m4_errprint);
63 DECLARE (m4_esyscmd);
64 DECLARE (m4_eval);
65 DECLARE (m4_format);
66 DECLARE (m4_ifdef);
67 DECLARE (m4_ifelse);
68 DECLARE (m4_include);
69 DECLARE (m4_incr);
70 DECLARE (m4_index);
71 DECLARE (m4_indir);
72 DECLARE (m4_len);
73 DECLARE (m4_m4exit);
74 DECLARE (m4_m4wrap);
75 DECLARE (m4_maketemp);
76 DECLARE (m4_patsubst);
77 DECLARE (m4_popdef);
78 DECLARE (m4_pushdef);
79 DECLARE (m4_regexp);
80 DECLARE (m4_shift);
81 DECLARE (m4_sinclude);
82 DECLARE (m4_substr);
83 DECLARE (m4_syscmd);
84 DECLARE (m4_sysval);
85 DECLARE (m4_traceoff);
86 DECLARE (m4_traceon);
87 DECLARE (m4_translit);
88 DECLARE (m4_undefine);
89 DECLARE (m4_undivert);
91 #undef DECLARE
93 static builtin
94 builtin_tab[] =
97 /* name GNUext macros blind function */
99 { "__file__", TRUE, FALSE, FALSE, m4___file__ },
100 { "__line__", TRUE, FALSE, FALSE, m4___line__ },
101 { "__program__", TRUE, FALSE, FALSE, m4___program__ },
102 { "builtin", TRUE, FALSE, TRUE, m4_builtin },
103 { "changecom", FALSE, FALSE, FALSE, m4_changecom },
104 { "changequote", FALSE, FALSE, FALSE, m4_changequote },
105 #ifdef ENABLE_CHANGEWORD
106 { "changeword", TRUE, FALSE, TRUE, m4_changeword },
107 #endif
108 { "debugmode", TRUE, FALSE, FALSE, m4_debugmode },
109 { "debugfile", TRUE, FALSE, FALSE, m4_debugfile },
110 { "decr", FALSE, FALSE, TRUE, m4_decr },
111 { "define", FALSE, TRUE, TRUE, m4_define },
112 { "defn", FALSE, FALSE, TRUE, m4_defn },
113 { "divert", FALSE, FALSE, FALSE, m4_divert },
114 { "divnum", FALSE, FALSE, FALSE, m4_divnum },
115 { "dnl", FALSE, FALSE, FALSE, m4_dnl },
116 { "dumpdef", FALSE, FALSE, FALSE, m4_dumpdef },
117 { "errprint", FALSE, FALSE, TRUE, m4_errprint },
118 { "esyscmd", TRUE, FALSE, TRUE, m4_esyscmd },
119 { "eval", FALSE, FALSE, TRUE, m4_eval },
120 { "format", TRUE, FALSE, TRUE, m4_format },
121 { "ifdef", FALSE, FALSE, TRUE, m4_ifdef },
122 { "ifelse", FALSE, FALSE, TRUE, m4_ifelse },
123 { "include", FALSE, FALSE, TRUE, m4_include },
124 { "incr", FALSE, FALSE, TRUE, m4_incr },
125 { "index", FALSE, FALSE, TRUE, m4_index },
126 { "indir", TRUE, FALSE, TRUE, m4_indir },
127 { "len", FALSE, FALSE, TRUE, m4_len },
128 { "m4exit", FALSE, FALSE, FALSE, m4_m4exit },
129 { "m4wrap", FALSE, FALSE, TRUE, m4_m4wrap },
130 { "maketemp", FALSE, FALSE, TRUE, m4_maketemp },
131 { "patsubst", TRUE, FALSE, TRUE, m4_patsubst },
132 { "popdef", FALSE, FALSE, TRUE, m4_popdef },
133 { "pushdef", FALSE, TRUE, TRUE, m4_pushdef },
134 { "regexp", TRUE, FALSE, TRUE, m4_regexp },
135 { "shift", FALSE, FALSE, TRUE, m4_shift },
136 { "sinclude", FALSE, FALSE, TRUE, m4_sinclude },
137 { "substr", FALSE, FALSE, TRUE, m4_substr },
138 { "syscmd", FALSE, FALSE, TRUE, m4_syscmd },
139 { "sysval", FALSE, FALSE, FALSE, m4_sysval },
140 { "traceoff", FALSE, FALSE, FALSE, m4_traceoff },
141 { "traceon", FALSE, FALSE, FALSE, m4_traceon },
142 { "translit", FALSE, FALSE, TRUE, m4_translit },
143 { "undefine", FALSE, FALSE, TRUE, m4_undefine },
144 { "undivert", FALSE, FALSE, FALSE, m4_undivert },
146 { 0, FALSE, FALSE, FALSE, 0 },
148 /* placeholder is intentionally stuck after the table end delimiter,
149 so that we can easily find it, while not treating it as a real
150 builtin. */
151 { "placeholder", TRUE, FALSE, FALSE, m4_placeholder },
154 static predefined const
155 predefined_tab[] =
157 #if UNIX
158 { "unix", "__unix__", "" },
159 #elif W32_NATIVE
160 { "windows", "__windows__", "" },
161 #elif OS2
162 { "os2", "__os2__", "" },
163 #else
164 # warning Platform macro not provided
165 #endif
166 { NULL, "__gnu__", "" },
168 { NULL, NULL, NULL },
171 /*----------------------------------------.
172 | Find the builtin, which lives on ADDR. |
173 `----------------------------------------*/
175 const builtin *
176 find_builtin_by_addr (builtin_func *func)
178 const builtin *bp;
180 for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
181 if (bp->func == func)
182 return bp;
183 if (func == m4_placeholder)
184 return bp + 1;
185 return NULL;
188 /*----------------------------------------------------------.
189 | Find the builtin, which has NAME. On failure, return the |
190 | placeholder builtin. |
191 `----------------------------------------------------------*/
193 const builtin *
194 find_builtin_by_name (const char *name)
196 const builtin *bp;
198 for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
199 if (strcmp (bp->name, name) == 0)
200 return bp;
201 return bp + 1;
204 /*-------------------------------------------------------------------------.
205 | Install a builtin macro with name NAME, bound to the C function given in |
206 | BP. MODE is SYMBOL_INSERT or SYMBOL_PUSHDEF. TRACED defines whether |
207 | NAME is to be traced. |
208 `-------------------------------------------------------------------------*/
210 void
211 define_builtin (const char *name, const builtin *bp, symbol_lookup mode)
213 symbol *sym;
215 sym = lookup_symbol (name, mode);
216 SYMBOL_TYPE (sym) = TOKEN_FUNC;
217 SYMBOL_MACRO_ARGS (sym) = bp->groks_macro_args;
218 SYMBOL_BLIND_NO_ARGS (sym) = bp->blind_if_no_args;
219 SYMBOL_FUNC (sym) = bp->func;
222 /*-------------------------------------------------------------------------.
223 | Define a predefined or user-defined macro, with name NAME, and expansion |
224 | TEXT. MODE destinguishes between the "define" and the "pushdef" case. |
225 | It is also used from main (). |
226 `-------------------------------------------------------------------------*/
228 void
229 define_user_macro (const char *name, const char *text, symbol_lookup mode)
231 symbol *s;
233 s = lookup_symbol (name, mode);
234 if (SYMBOL_TYPE (s) == TOKEN_TEXT)
235 free (SYMBOL_TEXT (s));
237 SYMBOL_TYPE (s) = TOKEN_TEXT;
238 SYMBOL_TEXT (s) = xstrdup (text);
241 /*-----------------------------------------------.
242 | Initialise all builtin and predefined macros. |
243 `-----------------------------------------------*/
245 void
246 builtin_init (void)
248 const builtin *bp;
249 const predefined *pp;
250 char *string;
252 for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
253 if (!no_gnu_extensions || !bp->gnu_extension)
255 if (prefix_all_builtins)
257 string = (char *) xmalloc (strlen (bp->name) + 4);
258 strcpy (string, "m4_");
259 strcat (string, bp->name);
260 define_builtin (string, bp, SYMBOL_INSERT);
261 free (string);
263 else
264 define_builtin (bp->name, bp, SYMBOL_INSERT);
267 for (pp = &predefined_tab[0]; pp->func != NULL; pp++)
268 if (no_gnu_extensions)
270 if (pp->unix_name != NULL)
271 define_user_macro (pp->unix_name, pp->func, SYMBOL_INSERT);
273 else
275 if (pp->gnu_name != NULL)
276 define_user_macro (pp->gnu_name, pp->func, SYMBOL_INSERT);
280 /*------------------------------------------------------------------------.
281 | Give friendly warnings if a builtin macro is passed an inappropriate |
282 | number of arguments. NAME is macro name for messages, ARGC is actual |
283 | number of arguments, MIN is the minimum number of acceptable arguments, |
284 | negative if not applicable, MAX is the maximum number, negative if not |
285 | applicable. |
286 `------------------------------------------------------------------------*/
288 static boolean
289 bad_argc (token_data *name, int argc, int min, int max)
291 boolean isbad = FALSE;
293 if (min > 0 && argc < min)
295 if (!suppress_warnings)
296 M4ERROR ((warning_status, 0,
297 "Warning: too few arguments to builtin `%s'",
298 TOKEN_DATA_TEXT (name)));
299 isbad = TRUE;
301 else if (max > 0 && argc > max && !suppress_warnings)
302 M4ERROR ((warning_status, 0,
303 "Warning: excess arguments to builtin `%s' ignored",
304 TOKEN_DATA_TEXT (name)));
306 return isbad;
309 /*--------------------------------------------------------------------------.
310 | The function numeric_arg () converts ARG to an int pointed to by VALUEP. |
311 | If the conversion fails, print error message for macro MACRO. Return |
312 | TRUE iff conversion succeeds. |
313 `--------------------------------------------------------------------------*/
315 static boolean
316 numeric_arg (token_data *macro, const char *arg, int *valuep)
318 char *endp;
320 if (*arg == '\0')
322 *valuep = 0;
323 M4ERROR ((warning_status, 0,
324 "empty string treated as 0 in builtin `%s'",
325 TOKEN_DATA_TEXT (macro)));
327 else
329 errno = 0;
330 *valuep = strtol (arg, &endp, 10);
331 if (*endp != '\0')
333 M4ERROR ((warning_status, 0,
334 "non-numeric argument to builtin `%s'",
335 TOKEN_DATA_TEXT (macro)));
336 return FALSE;
338 if (isspace (to_uchar (*arg)))
339 M4ERROR ((warning_status, 0,
340 "leading whitespace ignored in builtin `%s'",
341 TOKEN_DATA_TEXT (macro)));
342 else if (errno == ERANGE)
343 M4ERROR ((warning_status, 0,
344 "numeric overflow detected in builtin `%s'",
345 TOKEN_DATA_TEXT (macro)));
347 return TRUE;
350 /*------------------------------------------------------------------------.
351 | The function ntoa () converts VALUE to a signed ascii representation in |
352 | radix RADIX. |
353 `------------------------------------------------------------------------*/
355 /* Digits for number to ascii conversions. */
356 static char const digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
358 static const char *
359 ntoa (register eval_t value, int radix)
361 boolean negative;
362 unsigned_eval_t uvalue;
363 static char str[256];
364 register char *s = &str[sizeof str];
366 *--s = '\0';
368 if (value < 0)
370 negative = TRUE;
371 uvalue = (unsigned_eval_t) -value;
373 else
375 negative = FALSE;
376 uvalue = (unsigned_eval_t) value;
381 *--s = digits[uvalue % radix];
382 uvalue /= radix;
384 while (uvalue > 0);
386 if (negative)
387 *--s = '-';
388 return s;
391 /*----------------------------------------------------------------------.
392 | Format an int VAL, and stuff it into an obstack OBS. Used for macros |
393 | expanding to numbers. |
394 `----------------------------------------------------------------------*/
396 static void
397 shipout_int (struct obstack *obs, int val)
399 const char *s;
401 s = ntoa ((eval_t) val, 10);
402 obstack_grow (obs, s, strlen (s));
405 /*----------------------------------------------------------------------.
406 | Print ARGC arguments from the table ARGV to obstack OBS, separated by |
407 | SEP, and quoted by the current quotes, if QUOTED is TRUE. |
408 `----------------------------------------------------------------------*/
410 static void
411 dump_args (struct obstack *obs, int argc, token_data **argv,
412 const char *sep, boolean quoted)
414 int i;
415 size_t len = strlen (sep);
417 for (i = 1; i < argc; i++)
419 if (i > 1)
420 obstack_grow (obs, sep, len);
421 if (quoted)
422 obstack_grow (obs, lquote.string, lquote.length);
423 obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
424 strlen (TOKEN_DATA_TEXT (argv[i])));
425 if (quoted)
426 obstack_grow (obs, rquote.string, rquote.length);
430 /* The rest of this file is code for builtins and expansion of user
431 defined macros. All the functions for builtins have a prototype as:
433 void m4_MACRONAME (struct obstack *obs, int argc, char *argv[]);
435 The function are expected to leave their expansion on the obstack OBS,
436 as an unfinished object. ARGV is a table of ARGC pointers to the
437 individual arguments to the macro. Please note that in general
438 argv[argc] != NULL. */
440 /* The first section are macros for definining, undefining, examining,
441 changing, ... other macros. */
443 /*-------------------------------------------------------------------------.
444 | The function define_macro is common for the builtins "define", |
445 | "undefine", "pushdef" and "popdef". ARGC and ARGV is as for the caller, |
446 | and MODE argument determines how the macro name is entered into the |
447 | symbol table. |
448 `-------------------------------------------------------------------------*/
450 static void
451 define_macro (int argc, token_data **argv, symbol_lookup mode)
453 const builtin *bp;
455 if (bad_argc (argv[0], argc, 2, 3))
456 return;
458 if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
460 M4ERROR ((warning_status, 0,
461 "Warning: %s: invalid macro name ignored", ARG (0)));
462 return;
465 if (argc == 2)
467 define_user_macro (ARG (1), "", mode);
468 return;
471 switch (TOKEN_DATA_TYPE (argv[2]))
473 case TOKEN_TEXT:
474 define_user_macro (ARG (1), ARG (2), mode);
475 break;
477 case TOKEN_FUNC:
478 bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[2]));
479 if (bp == NULL)
480 return;
481 else
482 define_builtin (ARG (1), bp, mode);
483 break;
485 default:
486 M4ERROR ((warning_status, 0,
487 "INTERNAL ERROR: bad token data type in define_macro ()"));
488 abort ();
492 static void
493 m4_define (struct obstack *obs, int argc, token_data **argv)
495 define_macro (argc, argv, SYMBOL_INSERT);
498 static void
499 m4_undefine (struct obstack *obs, int argc, token_data **argv)
501 int i;
502 if (bad_argc (argv[0], argc, 2, -1))
503 return;
504 for (i = 1; i < argc; i++)
505 lookup_symbol (ARG (i), SYMBOL_DELETE);
508 static void
509 m4_pushdef (struct obstack *obs, int argc, token_data **argv)
511 define_macro (argc, argv, SYMBOL_PUSHDEF);
514 static void
515 m4_popdef (struct obstack *obs, int argc, token_data **argv)
517 int i;
518 if (bad_argc (argv[0], argc, 2, -1))
519 return;
520 for (i = 1; i < argc; i++)
521 lookup_symbol (ARG (i), SYMBOL_POPDEF);
524 /*---------------------.
525 | Conditionals of m4. |
526 `---------------------*/
528 static void
529 m4_ifdef (struct obstack *obs, int argc, token_data **argv)
531 symbol *s;
532 const char *result;
534 if (bad_argc (argv[0], argc, 3, 4))
535 return;
536 s = lookup_symbol (ARG (1), SYMBOL_LOOKUP);
538 if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
539 result = ARG (2);
540 else if (argc >= 4)
541 result = ARG (3);
542 else
543 result = NULL;
545 if (result != NULL)
546 obstack_grow (obs, result, strlen (result));
549 static void
550 m4_ifelse (struct obstack *obs, int argc, token_data **argv)
552 const char *result;
553 token_data *argv0;
555 if (argc == 2)
556 return;
558 if (bad_argc (argv[0], argc, 4, -1))
559 return;
560 else
561 /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments. */
562 bad_argc (argv[0], (argc + 2) % 3, -1, 1);
564 argv0 = argv[0];
565 argv++;
566 argc--;
568 result = NULL;
569 while (result == NULL)
571 if (strcmp (ARG (0), ARG (1)) == 0)
572 result = ARG (2);
574 else
575 switch (argc)
577 case 3:
578 return;
580 case 4:
581 case 5:
582 result = ARG (3);
583 break;
585 default:
586 argc -= 3;
587 argv += 3;
590 obstack_grow (obs, result, strlen (result));
593 /*---------------------------------------------------------------------.
594 | The function dump_symbol () is for use by "dumpdef". It builds up a |
595 | table of all defined, un-shadowed, symbols. |
596 `---------------------------------------------------------------------*/
598 /* The structure dump_symbol_data is used to pass the information needed
599 from call to call to dump_symbol. */
601 struct dump_symbol_data
603 struct obstack *obs; /* obstack for table */
604 symbol **base; /* base of table */
605 int size; /* size of table */
608 static void
609 dump_symbol (symbol *sym, struct dump_symbol_data *data)
611 if (!SYMBOL_SHADOWED (sym) && SYMBOL_TYPE (sym) != TOKEN_VOID)
613 obstack_blank (data->obs, sizeof (symbol *));
614 data->base = (symbol **) obstack_base (data->obs);
615 data->base[data->size++] = sym;
619 /*------------------------------------------------------------------------.
620 | qsort comparison routine, for sorting the table made in m4_dumpdef (). |
621 `------------------------------------------------------------------------*/
623 static int
624 dumpdef_cmp (const void *s1, const void *s2)
626 return strcmp (SYMBOL_NAME (* (symbol *const *) s1),
627 SYMBOL_NAME (* (symbol *const *) s2));
630 /*-------------------------------------------------------------------------.
631 | Implementation of "dumpdef" itself. It builds up a table of pointers to |
632 | symbols, sorts it and prints the sorted table. |
633 `-------------------------------------------------------------------------*/
635 static void
636 m4_dumpdef (struct obstack *obs, int argc, token_data **argv)
638 symbol *s;
639 int i;
640 struct dump_symbol_data data;
641 const builtin *bp;
643 data.obs = obs;
644 data.base = (symbol **) obstack_base (obs);
645 data.size = 0;
647 if (argc == 1)
649 hack_all_symbols (dump_symbol, (char *) &data);
651 else
653 for (i = 1; i < argc; i++)
655 s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
656 if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
657 dump_symbol (s, &data);
658 else
659 M4ERROR ((warning_status, 0,
660 "undefined macro `%s'", TOKEN_DATA_TEXT (argv[i])));
664 /* Make table of symbols invisible to expand_macro (). */
666 (void) obstack_finish (obs);
668 qsort ((char *) data.base, data.size, sizeof (symbol *), dumpdef_cmp);
670 for (; data.size > 0; --data.size, data.base++)
672 DEBUG_PRINT1 ("%s:\t", SYMBOL_NAME (data.base[0]));
674 switch (SYMBOL_TYPE (data.base[0]))
676 case TOKEN_TEXT:
677 if (debug_level & DEBUG_TRACE_QUOTE)
678 DEBUG_PRINT3 ("%s%s%s\n",
679 lquote.string, SYMBOL_TEXT (data.base[0]), rquote.string);
680 else
681 DEBUG_PRINT1 ("%s\n", SYMBOL_TEXT (data.base[0]));
682 break;
684 case TOKEN_FUNC:
685 bp = find_builtin_by_addr (SYMBOL_FUNC (data.base[0]));
686 if (bp == NULL)
688 M4ERROR ((warning_status, 0, "\
689 INTERNAL ERROR: builtin not found in builtin table"));
690 abort ();
692 DEBUG_PRINT1 ("<%s>\n", bp->name);
693 break;
695 default:
696 M4ERROR ((warning_status, 0,
697 "INTERNAL ERROR: bad token data type in m4_dumpdef ()"));
698 abort ();
699 break;
704 /*---------------------------------------------------------------------.
705 | The builtin "builtin" allows calls to builtin macros, even if their |
706 | definition has been overridden or shadowed. It is thus possible to |
707 | redefine builtins, and still access their original definition. This |
708 | macro is not available in compatibility mode. |
709 `---------------------------------------------------------------------*/
711 static void
712 m4_builtin (struct obstack *obs, int argc, token_data **argv)
714 const builtin *bp;
715 const char *name = ARG (1);
717 if (bad_argc (argv[0], argc, 2, -1))
718 return;
720 bp = find_builtin_by_name (name);
721 if (bp->func == m4_placeholder)
722 M4ERROR ((warning_status, 0,
723 "undefined builtin `%s'", name));
724 else
725 (*bp->func) (obs, argc - 1, argv + 1);
728 /*------------------------------------------------------------------------.
729 | The builtin "indir" allows indirect calls to macros, even if their name |
730 | is not a proper macro name. It is thus possible to define macros with |
731 | ill-formed names for internal use in larger macro packages. This macro |
732 | is not available in compatibility mode. |
733 `------------------------------------------------------------------------*/
735 static void
736 m4_indir (struct obstack *obs, int argc, token_data **argv)
738 symbol *s;
739 const char *name = ARG (1);
741 if (bad_argc (argv[0], argc, 2, -1))
742 return;
744 s = lookup_symbol (name, SYMBOL_LOOKUP);
745 if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
746 M4ERROR ((warning_status, 0,
747 "undefined macro `%s'", name));
748 else
749 call_macro (s, argc - 1, argv + 1, obs);
752 /*-------------------------------------------------------------------------.
753 | The macro "defn" returns the quoted definition of the macro named by the |
754 | first argument. If the macro is builtin, it will push a special |
755 | macro-definition token on ht input stack. |
756 `-------------------------------------------------------------------------*/
758 static void
759 m4_defn (struct obstack *obs, int argc, token_data **argv)
761 symbol *s;
762 builtin_func *b;
764 if (bad_argc (argv[0], argc, 2, 2))
765 return;
767 s = lookup_symbol (ARG (1), SYMBOL_LOOKUP);
768 if (s == NULL)
769 return;
771 switch (SYMBOL_TYPE (s))
773 case TOKEN_TEXT:
774 obstack_grow (obs, lquote.string, lquote.length);
775 obstack_grow (obs, SYMBOL_TEXT (s), strlen (SYMBOL_TEXT (s)));
776 obstack_grow (obs, rquote.string, rquote.length);
777 break;
779 case TOKEN_FUNC:
780 b = SYMBOL_FUNC (s);
781 if (b == m4_placeholder)
782 M4ERROR ((warning_status, 0, "\
783 builtin `%s' requested by frozen file is not supported", ARG (1)));
784 else
785 push_macro (b);
786 break;
788 case TOKEN_VOID:
789 break;
791 default:
792 M4ERROR ((warning_status, 0,
793 "INTERNAL ERROR: bad symbol type in m4_defn ()"));
794 abort ();
798 /*------------------------------------------------------------------------.
799 | This section contains macros to handle the builtins "syscmd", "esyscmd" |
800 | and "sysval". "esyscmd" is GNU specific. |
801 `------------------------------------------------------------------------*/
803 /* Helper macros for readability. */
804 #if UNIX || defined WEXITSTATUS
805 # define M4SYSVAL_EXITBITS(status) \
806 (WIFEXITED (status) ? WEXITSTATUS (status) : 0)
807 # define M4SYSVAL_TERMSIGBITS(status) \
808 (WIFSIGNALED (status) ? WTERMSIG (status) << 8 : 0)
810 #else /* ! UNIX && ! defined WEXITSTATUS */
811 /* Platforms such as mingw do not support the notion of reporting
812 which signal terminated a process. Furthermore if WEXITSTATUS was
813 not provided, then the exit value is in the low eight bits. */
814 # define M4SYSVAL_EXITBITS(status) status
815 # define M4SYSVAL_TERMSIGBITS(status) 0
816 #endif /* ! UNIX && ! defined WEXITSTATUS */
818 /* Fallback definitions if <stdlib.h> or <sys/wait.h> are inadequate. */
819 #ifndef WEXITSTATUS
820 # define WEXITSTATUS(status) (((status) >> 8) & 0xff)
821 #endif
822 #ifndef WTERMSIG
823 # define WTERMSIG(status) ((status) & 0x7f)
824 #endif
825 #ifndef WIFSIGNALED
826 # define WIFSIGNALED(status) (WTERMSIG (status) != 0)
827 #endif
828 #ifndef WIFEXITED
829 # define WIFEXITED(status) (WTERMSIG (status) == 0)
830 #endif
832 /* Exit code from last "syscmd" command. */
833 static int sysval;
835 static void
836 m4_syscmd (struct obstack *obs, int argc, token_data **argv)
838 if (bad_argc (argv[0], argc, 2, 2))
840 /* The empty command is successful. */
841 sysval = 0;
842 return;
845 debug_flush_files ();
846 sysval = system (ARG (1));
847 #if FUNC_SYSTEM_BROKEN
848 /* OS/2 has a buggy system() that returns exit status in the lowest eight
849 bits, although pclose() and WEXITSTATUS are defined to return exit
850 status in the next eight bits. This approach can't detect signals, but
851 at least syscmd(`ls') still works when stdout is a terminal. An
852 alternate approach is popen/insert_file/pclose, but that makes stdout
853 a pipe, which can change how some child processes behave. */
854 if (sysval != -1)
855 sysval <<= 8;
856 #endif /* FUNC_SYSTEM_BROKEN */
859 static void
860 m4_esyscmd (struct obstack *obs, int argc, token_data **argv)
862 FILE *pin;
863 int ch;
865 if (bad_argc (argv[0], argc, 2, 2))
867 /* The empty command is successful. */
868 sysval = 0;
869 return;
872 debug_flush_files ();
873 errno = 0;
874 pin = popen (ARG (1), "r");
875 if (pin == NULL)
877 M4ERROR ((warning_status, errno,
878 "cannot open pipe to command `%s'", ARG (1)));
879 sysval = -1;
881 else
883 while ((ch = getc (pin)) != EOF)
884 obstack_1grow (obs, (char) ch);
885 sysval = pclose (pin);
889 static void
890 m4_sysval (struct obstack *obs, int argc, token_data **argv)
892 shipout_int (obs, (sysval == -1 ? 127
893 : (M4SYSVAL_EXITBITS (sysval)
894 | M4SYSVAL_TERMSIGBITS (sysval))));
897 /*-------------------------------------------------------------------------.
898 | This section contains the top level code for the "eval" builtin. The |
899 | actual work is done in the function evaluate (), which lives in eval.c. |
900 `-------------------------------------------------------------------------*/
902 static void
903 m4_eval (struct obstack *obs, int argc, token_data **argv)
905 eval_t value = 0;
906 int radix = 10;
907 int min = 1;
908 const char *s;
910 if (bad_argc (argv[0], argc, 2, 4))
911 return;
913 if (*ARG (2) && !numeric_arg (argv[0], ARG (2), &radix))
914 return;
916 if (radix < 1 || radix > (int) strlen (digits))
918 M4ERROR ((warning_status, 0,
919 "radix in builtin `%s' out of range (radix = %d)",
920 ARG (0), radix));
921 return;
924 if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &min))
925 return;
926 if (min < 0)
928 M4ERROR ((warning_status, 0,
929 "negative width to builtin `%s'", ARG (0)));
930 return;
933 if (!*ARG (1))
934 M4ERROR ((warning_status, 0,
935 "empty string treated as 0 in builtin `%s'", ARG (0)));
936 else if (evaluate (ARG (1), &value))
937 return;
939 if (radix == 1)
941 if (value < 0)
943 obstack_1grow (obs, '-');
944 value = -value;
946 /* This assumes 2's-complement for correctly handling INT_MIN. */
947 while (min-- - value > 0)
948 obstack_1grow (obs, '0');
949 while (value-- != 0)
950 obstack_1grow (obs, '1');
951 obstack_1grow (obs, '\0');
952 return;
955 s = ntoa (value, radix);
957 if (*s == '-')
959 obstack_1grow (obs, '-');
960 s++;
962 for (min -= strlen (s); --min >= 0;)
963 obstack_1grow (obs, '0');
965 obstack_grow (obs, s, strlen (s));
968 static void
969 m4_incr (struct obstack *obs, int argc, token_data **argv)
971 int value;
973 if (bad_argc (argv[0], argc, 2, 2))
974 return;
976 if (!numeric_arg (argv[0], ARG (1), &value))
977 return;
979 shipout_int (obs, value + 1);
982 static void
983 m4_decr (struct obstack *obs, int argc, token_data **argv)
985 int value;
987 if (bad_argc (argv[0], argc, 2, 2))
988 return;
990 if (!numeric_arg (argv[0], ARG (1), &value))
991 return;
993 shipout_int (obs, value - 1);
996 /* This section contains the macros "divert", "undivert" and "divnum" for
997 handling diversion. The utility functions used lives in output.c. */
999 /*-----------------------------------------------------------------------.
1000 | Divert further output to the diversion given by ARGV[1]. Out of range |
1001 | means discard further output. |
1002 `-----------------------------------------------------------------------*/
1004 static void
1005 m4_divert (struct obstack *obs, int argc, token_data **argv)
1007 int i = 0;
1009 if (bad_argc (argv[0], argc, 1, 2))
1010 return;
1012 if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &i))
1013 return;
1015 make_diversion (i);
1018 /*-----------------------------------------------------.
1019 | Expand to the current diversion number, -1 if none. |
1020 `-----------------------------------------------------*/
1022 static void
1023 m4_divnum (struct obstack *obs, int argc, token_data **argv)
1025 if (bad_argc (argv[0], argc, 1, 1))
1026 return;
1027 shipout_int (obs, current_diversion);
1030 /*-----------------------------------------------------------------------.
1031 | Bring back the diversion given by the argument list. If none is |
1032 | specified, bring back all diversions. GNU specific is the option of |
1033 | undiverting named files, by passing a non-numeric argument to undivert |
1034 | (). |
1035 `-----------------------------------------------------------------------*/
1037 static void
1038 m4_undivert (struct obstack *obs, int argc, token_data **argv)
1040 int i, file;
1041 FILE *fp;
1042 char *endp;
1044 if (argc == 1)
1045 undivert_all ();
1046 else
1047 for (i = 1; i < argc; i++)
1049 file = strtol (ARG (i), &endp, 10);
1050 if (*endp == '\0' && !isspace (to_uchar (*ARG (i))))
1051 insert_diversion (file);
1052 else if (no_gnu_extensions)
1053 M4ERROR ((warning_status, 0,
1054 "non-numeric argument to builtin `%s'", ARG (0)));
1055 else
1057 fp = path_search (ARG (i), NULL);
1058 if (fp != NULL)
1060 insert_file (fp);
1061 fclose (fp);
1063 else
1064 M4ERROR ((warning_status, errno,
1065 "cannot undivert `%s'", ARG (i)));
1070 /* This section contains various macros, which does not fall into any
1071 specific group. These are "dnl", "shift", "changequote", "changecom"
1072 and "changeword". */
1074 /*------------------------------------------------------------------------.
1075 | Delete all subsequent whitespace from input. The function skip_line () |
1076 | lives in input.c. |
1077 `------------------------------------------------------------------------*/
1079 static void
1080 m4_dnl (struct obstack *obs, int argc, token_data **argv)
1082 if (bad_argc (argv[0], argc, 1, 1))
1083 return;
1085 skip_line ();
1088 /*-------------------------------------------------------------------------.
1089 | Shift all argument one to the left, discarding the first argument. Each |
1090 | output argument is quoted with the current quotes. |
1091 `-------------------------------------------------------------------------*/
1093 static void
1094 m4_shift (struct obstack *obs, int argc, token_data **argv)
1096 if (bad_argc (argv[0], argc, 2, -1))
1097 return;
1098 dump_args (obs, argc - 1, argv + 1, ",", TRUE);
1101 /*--------------------------------------------------------------------------.
1102 | Change the current quotes. The function set_quotes () lives in input.c. |
1103 `--------------------------------------------------------------------------*/
1105 static void
1106 m4_changequote (struct obstack *obs, int argc, token_data **argv)
1108 if (bad_argc (argv[0], argc, 1, 3))
1109 return;
1111 set_quotes ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
1112 (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
1115 /*--------------------------------------------------------------------.
1116 | Change the current comment delimiters. The function set_comment () |
1117 | lives in input.c. |
1118 `--------------------------------------------------------------------*/
1120 static void
1121 m4_changecom (struct obstack *obs, int argc, token_data **argv)
1123 if (bad_argc (argv[0], argc, 1, 3))
1124 return;
1126 if (argc == 1)
1127 set_comment ("", ""); /* disable comments */
1128 else
1129 set_comment (TOKEN_DATA_TEXT (argv[1]),
1130 (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
1133 #ifdef ENABLE_CHANGEWORD
1135 /*-----------------------------------------------------------------------.
1136 | Change the regular expression used for breaking the input into words. |
1137 | The function set_word_regexp () lives in input.c. |
1138 `-----------------------------------------------------------------------*/
1140 static void
1141 m4_changeword (struct obstack *obs, int argc, token_data **argv)
1143 if (bad_argc (argv[0], argc, 2, 2))
1144 return;
1146 set_word_regexp (TOKEN_DATA_TEXT (argv[1]));
1149 #endif /* ENABLE_CHANGEWORD */
1151 /* This section contains macros for inclusion of other files -- "include"
1152 and "sinclude". This differs from bringing back diversions, in that
1153 the input is scanned before being copied to the output. */
1155 /*-------------------------------------------------------------------------.
1156 | Generic include function. Include the file given by the first argument, |
1157 | if it exists. Complain about inaccesible files iff SILENT is FALSE. |
1158 `-------------------------------------------------------------------------*/
1160 static void
1161 include (int argc, token_data **argv, boolean silent)
1163 FILE *fp;
1164 const char *name;
1166 if (bad_argc (argv[0], argc, 2, 2))
1167 return;
1169 fp = path_search (ARG (1), &name);
1170 if (fp == NULL)
1172 if (!silent)
1173 M4ERROR ((warning_status, errno,
1174 "cannot open `%s'", ARG (1)));
1175 return;
1178 push_file (fp, name, TRUE);
1179 free ((char *) name);
1182 /*------------------------------------------------.
1183 | Include a file, complaining in case of errors. |
1184 `------------------------------------------------*/
1186 static void
1187 m4_include (struct obstack *obs, int argc, token_data **argv)
1189 include (argc, argv, FALSE);
1192 /*----------------------------------.
1193 | Include a file, ignoring errors. |
1194 `----------------------------------*/
1196 static void
1197 m4_sinclude (struct obstack *obs, int argc, token_data **argv)
1199 include (argc, argv, TRUE);
1202 /* More miscellaneous builtins -- "maketemp", "errprint", "__file__",
1203 "__line__", and "__program__". The last three are GNU specific. */
1205 /*------------------------------------------------------------------.
1206 | Use the first argument as at template for a temporary file name. |
1207 `------------------------------------------------------------------*/
1209 static void
1210 m4_maketemp (struct obstack *obs, int argc, token_data **argv)
1212 int fd;
1213 if (bad_argc (argv[0], argc, 2, 2))
1214 return;
1215 errno = 0;
1216 if ((fd = mkstemp (ARG (1))) < 0)
1218 M4ERROR ((warning_status, errno, "cannot create tempfile `%s'",
1219 ARG (1)));
1220 return;
1222 close(fd);
1223 obstack_grow (obs, ARG (1), strlen (ARG (1)));
1226 /*----------------------------------------.
1227 | Print all arguments on standard error. |
1228 `----------------------------------------*/
1230 static void
1231 m4_errprint (struct obstack *obs, int argc, token_data **argv)
1233 if (bad_argc (argv[0], argc, 2, -1))
1234 return;
1235 dump_args (obs, argc, argv, " ", FALSE);
1236 obstack_1grow (obs, '\0');
1237 debug_flush_files ();
1238 fprintf (stderr, "%s", (char *) obstack_finish (obs));
1239 fflush (stderr);
1242 static void
1243 m4___file__ (struct obstack *obs, int argc, token_data **argv)
1245 if (bad_argc (argv[0], argc, 1, 1))
1246 return;
1247 obstack_grow (obs, lquote.string, lquote.length);
1248 obstack_grow (obs, current_file, strlen (current_file));
1249 obstack_grow (obs, rquote.string, rquote.length);
1252 static void
1253 m4___line__ (struct obstack *obs, int argc, token_data **argv)
1255 if (bad_argc (argv[0], argc, 1, 1))
1256 return;
1257 shipout_int (obs, current_line);
1260 static void
1261 m4___program__ (struct obstack *obs, int argc, token_data **argv)
1263 if (bad_argc (argv[0], argc, 1, 1))
1264 return;
1265 obstack_grow (obs, lquote.string, lquote.length);
1266 obstack_grow (obs, program_name, strlen (program_name));
1267 obstack_grow (obs, rquote.string, rquote.length);
1270 /* This section contains various macros for exiting, saving input until
1271 EOF is seen, and tracing macro calls. That is: "m4exit", "m4wrap",
1272 "traceon" and "traceoff". */
1274 /*-------------------------------------------------------------------------.
1275 | Exit immediately, with exitcode specified by the first argument, 0 if no |
1276 | arguments are present. |
1277 `-------------------------------------------------------------------------*/
1279 static void
1280 m4_m4exit (struct obstack *obs, int argc, token_data **argv)
1282 int exit_code = EXIT_SUCCESS;
1284 /* Warn on bad arguments, but still exit. */
1285 bad_argc (argv[0], argc, 1, 2);
1286 if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &exit_code))
1287 exit_code = EXIT_FAILURE;
1288 if (exit_code < 0 || exit_code > 255)
1290 M4ERROR ((warning_status, 0,
1291 "exit status out of range: `%d'", exit_code));
1292 exit_code = EXIT_FAILURE;
1294 if (close_stream (stdout) != 0)
1296 M4ERROR ((warning_status, errno, "write error"));
1297 if (exit_code == 0)
1298 exit_code = EXIT_FAILURE;
1300 /* Change debug stream back to stderr, to force flushing debug stream and
1301 detect any errors it might have encountered. */
1302 debug_set_output (NULL);
1303 if (exit_code == 0 && retcode != 0)
1304 exit_code = retcode;
1305 exit (exit_code);
1308 /*-------------------------------------------------------------------------.
1309 | Save the argument text until EOF has been seen, allowing for user |
1310 | specified cleanup action. GNU version saves all arguments, the standard |
1311 | version only the first. |
1312 `-------------------------------------------------------------------------*/
1314 static void
1315 m4_m4wrap (struct obstack *obs, int argc, token_data **argv)
1317 if (bad_argc (argv[0], argc, 2, -1))
1318 return;
1319 if (no_gnu_extensions)
1320 obstack_grow (obs, ARG (1), strlen (ARG (1)));
1321 else
1322 dump_args (obs, argc, argv, " ", FALSE);
1323 obstack_1grow (obs, '\0');
1324 push_wrapup (obstack_finish (obs));
1327 /* Enable tracing of all specified macros, or all, if none is specified.
1328 Tracing is disabled by default, when a macro is defined. This can be
1329 overridden by the "t" debug flag. */
1331 /*-----------------------------------------------------------------------.
1332 | Set_trace () is used by "traceon" and "traceoff" to enable and disable |
1333 | tracing of a macro. It disables tracing if DATA is NULL, otherwise it |
1334 | enable tracing. |
1335 `-----------------------------------------------------------------------*/
1337 static void
1338 set_trace (symbol *sym, const char *data)
1340 SYMBOL_TRACED (sym) = (boolean) (data != NULL);
1341 /* Remove placeholder from table if macro is undefined and untraced. */
1342 if (SYMBOL_TYPE (sym) == TOKEN_VOID && data == NULL)
1343 lookup_symbol (SYMBOL_NAME (sym), SYMBOL_POPDEF);
1346 static void
1347 m4_traceon (struct obstack *obs, int argc, token_data **argv)
1349 symbol *s;
1350 int i;
1352 if (argc == 1)
1353 hack_all_symbols (set_trace, (char *) obs);
1354 else
1355 for (i = 1; i < argc; i++)
1357 s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_INSERT);
1358 set_trace (s, (char *) obs);
1362 /*------------------------------------------------------------------------.
1363 | Disable tracing of all specified macros, or all, if none is specified. |
1364 `------------------------------------------------------------------------*/
1366 static void
1367 m4_traceoff (struct obstack *obs, int argc, token_data **argv)
1369 symbol *s;
1370 int i;
1372 if (argc == 1)
1373 hack_all_symbols (set_trace, NULL);
1374 else
1375 for (i = 1; i < argc; i++)
1377 s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
1378 if (s != NULL)
1379 set_trace (s, NULL);
1383 /*----------------------------------------------------------------------.
1384 | On-the-fly control of the format of the tracing output. It takes one |
1385 | argument, which is a character string like given to the -d option, or |
1386 | none in which case the debug_level is zeroed. |
1387 `----------------------------------------------------------------------*/
1389 static void
1390 m4_debugmode (struct obstack *obs, int argc, token_data **argv)
1392 int new_debug_level;
1393 int change_flag;
1395 if (bad_argc (argv[0], argc, 1, 2))
1396 return;
1398 if (argc == 1)
1399 debug_level = 0;
1400 else
1402 if (ARG (1)[0] == '+' || ARG (1)[0] == '-')
1404 change_flag = ARG (1)[0];
1405 new_debug_level = debug_decode (ARG (1) + 1);
1407 else
1409 change_flag = 0;
1410 new_debug_level = debug_decode (ARG (1));
1413 if (new_debug_level < 0)
1414 M4ERROR ((warning_status, 0,
1415 "Debugmode: bad debug flags: `%s'", ARG (1)));
1416 else
1418 switch (change_flag)
1420 case 0:
1421 debug_level = new_debug_level;
1422 break;
1424 case '+':
1425 debug_level |= new_debug_level;
1426 break;
1428 case '-':
1429 debug_level &= ~new_debug_level;
1430 break;
1436 /*-------------------------------------------------------------------------.
1437 | Specify the destination of the debugging output. With one argument, the |
1438 | argument is taken as a file name, with no arguments, revert to stderr. |
1439 `-------------------------------------------------------------------------*/
1441 static void
1442 m4_debugfile (struct obstack *obs, int argc, token_data **argv)
1444 if (bad_argc (argv[0], argc, 1, 2))
1445 return;
1447 if (argc == 1)
1448 debug_set_output (NULL);
1449 else if (!debug_set_output (ARG (1)))
1450 M4ERROR ((warning_status, errno,
1451 "cannot set error file: `%s'", ARG (1)));
1454 /* This section contains text processing macros: "len", "index",
1455 "substr", "translit", "format", "regexp" and "patsubst". The last
1456 three are GNU specific. */
1458 /*---------------------------------------------.
1459 | Expand to the length of the first argument. |
1460 `---------------------------------------------*/
1462 static void
1463 m4_len (struct obstack *obs, int argc, token_data **argv)
1465 if (bad_argc (argv[0], argc, 2, 2))
1466 return;
1467 shipout_int (obs, strlen (ARG (1)));
1470 /*-------------------------------------------------------------------------.
1471 | The macro expands to the first index of the second argument in the first |
1472 | argument. |
1473 `-------------------------------------------------------------------------*/
1475 static void
1476 m4_index (struct obstack *obs, int argc, token_data **argv)
1478 const char *cp, *last;
1479 int l1, l2, retval;
1481 if (bad_argc (argv[0], argc, 3, 3))
1483 /* builtin(`index') is blank, but index(`abc') is 0. */
1484 if (argc == 2)
1485 shipout_int (obs, 0);
1486 return;
1489 l1 = strlen (ARG (1));
1490 l2 = strlen (ARG (2));
1492 last = ARG (1) + l1 - l2;
1494 for (cp = ARG (1); cp <= last; cp++)
1496 if (strncmp (cp, ARG (2), l2) == 0)
1497 break;
1499 retval = (cp <= last) ? cp - ARG (1) : -1;
1501 shipout_int (obs, retval);
1504 /*-------------------------------------------------------------------------.
1505 | The macro "substr" extracts substrings from the first argument, starting |
1506 | from the index given by the second argument, extending for a length |
1507 | given by the third argument. If the third argument is missing, the |
1508 | substring extends to the end of the first argument. |
1509 `-------------------------------------------------------------------------*/
1511 static void
1512 m4_substr (struct obstack *obs, int argc, token_data **argv)
1514 int start = 0;
1515 int length, avail;
1517 if (bad_argc (argv[0], argc, 3, 4))
1519 /* builtin(`substr') is blank, but substr(`abc') is abc. */
1520 if (argc == 2)
1521 obstack_grow (obs, ARG (1), strlen (ARG (1)));
1522 return;
1525 length = avail = strlen (ARG (1));
1526 if (!numeric_arg (argv[0], ARG (2), &start))
1527 return;
1529 if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &length))
1530 return;
1532 if (start < 0 || length <= 0 || start >= avail)
1533 return;
1535 if (start + length > avail)
1536 length = avail - start;
1537 obstack_grow (obs, ARG (1) + start, length);
1540 /*------------------------------------------------------------------------.
1541 | For "translit", ranges are allowed in the second and third argument. |
1542 | They are expanded in the following function, and the expanded strings, |
1543 | without any ranges left, are used to translate the characters of the |
1544 | first argument. A single - (dash) can be included in the strings by |
1545 | being the first or the last character in the string. If the first |
1546 | character in a range is after the first in the character set, the range |
1547 | is made backwards, thus 9-0 is the string 9876543210. |
1548 `------------------------------------------------------------------------*/
1550 static const char *
1551 expand_ranges (const char *s, struct obstack *obs)
1553 char from;
1554 char to;
1556 for (from = '\0'; *s != '\0'; from = *s++)
1558 if (*s == '-' && from != '\0')
1560 to = *++s;
1561 if (to == '\0')
1563 /* trailing dash */
1564 obstack_1grow (obs, '-');
1565 break;
1567 else if (from <= to)
1569 while (from++ < to)
1570 obstack_1grow (obs, from);
1572 else
1574 while (--from >= to)
1575 obstack_1grow (obs, from);
1578 else
1579 obstack_1grow (obs, *s);
1581 obstack_1grow (obs, '\0');
1582 return obstack_finish (obs);
1585 /*----------------------------------------------------------------------.
1586 | The macro "translit" translates all characters in the first argument, |
1587 | which are present in the second argument, into the corresponding |
1588 | character from the third argument. If the third argument is shorter |
1589 | than the second, the extra characters in the second argument, are |
1590 | deleted from the first (pueh). |
1591 `----------------------------------------------------------------------*/
1593 static void
1594 m4_translit (struct obstack *obs, int argc, token_data **argv)
1596 register const char *data, *tmp;
1597 const char *from, *to;
1598 int tolen;
1600 if (bad_argc (argv[0], argc, 3, 4))
1602 /* builtin(`translit') is blank, but translit(`abc') is abc. */
1603 if (argc == 2)
1604 obstack_grow (obs, ARG (1), strlen (ARG (1)));
1605 return;
1608 from = ARG (2);
1609 if (strchr (from, '-') != NULL)
1611 from = expand_ranges (from, obs);
1612 if (from == NULL)
1613 return;
1616 if (argc >= 4)
1618 to = ARG (3);
1619 if (strchr (to, '-') != NULL)
1621 to = expand_ranges (to, obs);
1622 if (to == NULL)
1623 return;
1626 else
1627 to = "";
1629 tolen = strlen (to);
1631 for (data = ARG (1); *data; data++)
1633 tmp = strchr (from, *data);
1634 if (tmp == NULL)
1636 obstack_1grow (obs, *data);
1638 else
1640 if (tmp - from < tolen)
1641 obstack_1grow (obs, *(to + (tmp - from)));
1646 /*----------------------------------------------------------------------.
1647 | Frontend for printf like formatting. The function format () lives in |
1648 | the file format.c. |
1649 `----------------------------------------------------------------------*/
1651 static void
1652 m4_format (struct obstack *obs, int argc, token_data **argv)
1654 if (bad_argc (argv[0], argc, 2, -1))
1655 return;
1656 format (obs, argc - 1, argv + 1);
1659 /*-------------------------------------------------------------------------.
1660 | Function to perform substitution by regular expressions. Used by the |
1661 | builtins regexp and patsubst. The changed text is placed on the |
1662 | obstack. The substitution is REPL, with \& substituted by this part of |
1663 | VICTIM matched by the last whole regular expression, taken from REGS[0], |
1664 | and \N substituted by the text matched by the Nth parenthesized |
1665 | sub-expression, taken from REGS[N]. |
1666 `-------------------------------------------------------------------------*/
1668 static int substitute_warned = 0;
1670 static void
1671 substitute (struct obstack *obs, const char *victim, const char *repl,
1672 struct re_registers *regs)
1674 register unsigned int ch;
1676 for (;;)
1678 while ((ch = *repl++) != '\\')
1680 if (ch == '\0')
1681 return;
1682 obstack_1grow (obs, ch);
1685 switch ((ch = *repl++))
1687 case '0':
1688 if (!substitute_warned)
1690 M4ERROR ((warning_status, 0, "\
1691 Warning: \\0 will disappear, use \\& instead in replacements"));
1692 substitute_warned = 1;
1694 /* Fall through. */
1696 case '&':
1697 obstack_grow (obs, victim + regs->start[0],
1698 regs->end[0] - regs->start[0]);
1699 break;
1701 case '1': case '2': case '3': case '4': case '5': case '6':
1702 case '7': case '8': case '9':
1703 ch -= '0';
1704 if (regs->num_regs - 1 <= ch)
1705 M4ERROR ((warning_status, 0, "\
1706 Warning: sub-expression %d not present", ch));
1707 else if (regs->end[ch] > 0)
1708 obstack_grow (obs, victim + regs->start[ch],
1709 regs->end[ch] - regs->start[ch]);
1710 break;
1712 case '\0':
1713 M4ERROR ((warning_status, 0, "\
1714 Warning: trailing \\ ignored in replacement"));
1715 return;
1717 default:
1718 obstack_1grow (obs, ch);
1719 break;
1724 /*------------------------------------------.
1725 | Initialize regular expression variables. |
1726 `------------------------------------------*/
1728 static void
1729 init_pattern_buffer (struct re_pattern_buffer *buf, struct re_registers *regs)
1731 buf->translate = NULL;
1732 buf->fastmap = NULL;
1733 buf->buffer = NULL;
1734 buf->allocated = 0;
1735 regs->start = NULL;
1736 regs->end = NULL;
1739 /*----------------------------------------.
1740 | Clean up regular expression variables. |
1741 `----------------------------------------*/
1743 static void
1744 free_pattern_buffer (struct re_pattern_buffer *buf, struct re_registers *regs)
1746 regfree (buf);
1747 free (regs->start);
1748 free (regs->end);
1751 /*--------------------------------------------------------------------------.
1752 | Regular expression version of index. Given two arguments, expand to the |
1753 | index of the first match of the second argument (a regexp) in the first. |
1754 | Expand to -1 if here is no match. Given a third argument, is changes |
1755 | the expansion to this argument. |
1756 `--------------------------------------------------------------------------*/
1758 static void
1759 m4_regexp (struct obstack *obs, int argc, token_data **argv)
1761 const char *victim; /* first argument */
1762 const char *regexp; /* regular expression */
1763 const char *repl; /* replacement string */
1765 struct re_pattern_buffer buf; /* compiled regular expression */
1766 struct re_registers regs; /* for subexpression matches */
1767 const char *msg; /* error message from re_compile_pattern */
1768 int startpos; /* start position of match */
1769 int length; /* length of first argument */
1771 if (bad_argc (argv[0], argc, 3, 4))
1773 /* builtin(`regexp') is blank, but regexp(`abc') is 0. */
1774 if (argc == 2)
1775 shipout_int (obs, 0);
1776 return;
1779 victim = TOKEN_DATA_TEXT (argv[1]);
1780 regexp = TOKEN_DATA_TEXT (argv[2]);
1782 init_pattern_buffer (&buf, &regs);
1783 msg = re_compile_pattern (regexp, strlen (regexp), &buf);
1785 if (msg != NULL)
1787 M4ERROR ((warning_status, 0,
1788 "bad regular expression: `%s': %s", regexp, msg));
1789 free_pattern_buffer (&buf, &regs);
1790 return;
1793 length = strlen (victim);
1794 /* Avoid overhead of allocating regs if we won't use it. */
1795 startpos = re_search (&buf, victim, length, 0, length,
1796 argc == 3 ? NULL : &regs);
1798 if (startpos == -2)
1799 M4ERROR ((warning_status, 0,
1800 "error matching regular expression `%s'", regexp));
1801 else if (argc == 3)
1802 shipout_int (obs, startpos);
1803 else if (startpos >= 0)
1805 repl = TOKEN_DATA_TEXT (argv[3]);
1806 substitute (obs, victim, repl, &regs);
1809 free_pattern_buffer (&buf, &regs);
1812 /*--------------------------------------------------------------------------.
1813 | Substitute all matches of a regexp occuring in a string. Each match of |
1814 | the second argument (a regexp) in the first argument is changed to the |
1815 | third argument, with \& substituted by the matched text, and \N |
1816 | substituted by the text matched by the Nth parenthesized sub-expression. |
1817 `--------------------------------------------------------------------------*/
1819 static void
1820 m4_patsubst (struct obstack *obs, int argc, token_data **argv)
1822 const char *victim; /* first argument */
1823 const char *regexp; /* regular expression */
1825 struct re_pattern_buffer buf; /* compiled regular expression */
1826 struct re_registers regs; /* for subexpression matches */
1827 const char *msg; /* error message from re_compile_pattern */
1828 int matchpos; /* start position of match */
1829 int offset; /* current match offset */
1830 int length; /* length of first argument */
1832 if (bad_argc (argv[0], argc, 3, 4))
1834 /* builtin(`patsubst') is blank, but patsubst(`abc') is abc. */
1835 if (argc == 2)
1836 obstack_grow (obs, ARG (1), strlen (ARG (1)));
1837 return;
1840 regexp = TOKEN_DATA_TEXT (argv[2]);
1842 init_pattern_buffer (&buf, &regs);
1843 msg = re_compile_pattern (regexp, strlen (regexp), &buf);
1845 if (msg != NULL)
1847 M4ERROR ((warning_status, 0,
1848 "bad regular expression `%s': %s", regexp, msg));
1849 free (buf.buffer);
1850 return;
1853 victim = TOKEN_DATA_TEXT (argv[1]);
1854 length = strlen (victim);
1856 offset = 0;
1857 matchpos = 0;
1858 while (offset <= length)
1860 matchpos = re_search (&buf, victim, length,
1861 offset, length - offset, &regs);
1862 if (matchpos < 0)
1865 /* Match failed -- either error or there is no match in the
1866 rest of the string, in which case the rest of the string is
1867 copied verbatim. */
1869 if (matchpos == -2)
1870 M4ERROR ((warning_status, 0,
1871 "error matching regular expression `%s'", regexp));
1872 else if (offset < length)
1873 obstack_grow (obs, victim + offset, length - offset);
1874 break;
1877 /* Copy the part of the string that was skipped by re_search (). */
1879 if (matchpos > offset)
1880 obstack_grow (obs, victim + offset, matchpos - offset);
1882 /* Handle the part of the string that was covered by the match. */
1884 substitute (obs, victim, ARG (3), &regs);
1886 /* Update the offset to the end of the match. If the regexp
1887 matched a null string, advance offset one more, to avoid
1888 infinite loops. */
1890 offset = regs.end[0];
1891 if (regs.start[0] == regs.end[0])
1892 obstack_1grow (obs, victim[offset++]);
1894 obstack_1grow (obs, '\0');
1896 free_pattern_buffer (&buf, &regs);
1899 /* Finally, a placeholder builtin. This builtin is not installed by
1900 default, but when reading back frozen files, this is associated
1901 with any builtin we don't recognize (for example, if the frozen
1902 file was created with a changeword capable m4, but is then loaded
1903 by a different m4 that does not support changeword). This way, we
1904 can keep 'm4 -R' quiet in the common case that the user did not
1905 know or care about the builtin when the frozen file was created,
1906 while still flagging it as a potential error if an attempt is made
1907 to actually use the builtin. */
1909 /*--------------------------------------------------------------------.
1910 | Issue a warning that this macro is a placeholder for an unsupported |
1911 | builtin that was requested while reloading a frozen file. |
1912 `--------------------------------------------------------------------*/
1914 void
1915 m4_placeholder (struct obstack *obs, int argc, token_data **argv)
1917 M4ERROR ((warning_status, 0, "\
1918 builtin `%s' requested by frozen file is not supported", ARG (0)));
1921 /*-------------------------------------------------------------------------.
1922 | This function handles all expansion of user defined and predefined |
1923 | macros. It is called with an obstack OBS, where the macros expansion |
1924 | will be placed, as an unfinished object. SYM points to the macro |
1925 | definition, giving the expansion text. ARGC and ARGV are the arguments, |
1926 | as usual. |
1927 `-------------------------------------------------------------------------*/
1929 void
1930 expand_user_macro (struct obstack *obs, symbol *sym,
1931 int argc, token_data **argv)
1933 register const char *text;
1934 int i;
1936 for (text = SYMBOL_TEXT (sym); *text != '\0';)
1938 if (*text != '$')
1940 obstack_1grow (obs, *text);
1941 text++;
1942 continue;
1944 text++;
1945 switch (*text)
1947 case '0': case '1': case '2': case '3': case '4':
1948 case '5': case '6': case '7': case '8': case '9':
1949 if (no_gnu_extensions)
1951 i = *text++ - '0';
1953 else
1955 for (i = 0; isdigit (to_uchar (*text)); text++)
1956 i = i*10 + (*text - '0');
1958 if (i < argc)
1959 obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
1960 strlen (TOKEN_DATA_TEXT (argv[i])));
1961 break;
1963 case '#': /* number of arguments */
1964 shipout_int (obs, argc - 1);
1965 text++;
1966 break;
1968 case '*': /* all arguments */
1969 case '@': /* ... same, but quoted */
1970 dump_args (obs, argc, argv, ",", *text == '@');
1971 text++;
1972 break;
1974 default:
1975 obstack_1grow (obs, '$');
1976 break;