Imported Upstream version 1.4.16
[platform/upstream/m4.git] / src / builtin.c
1 /* GNU m4 -- A simple macro processor
2
3    Copyright (C) 1989-1994, 2000, 2004, 2006-2011 Free Software
4    Foundation, Inc.
5
6    This file is part of GNU M4.
7
8    GNU M4 is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12
13    GNU M4 is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /* Code for all builtin macros, initialization of symbol table, and
23    expansion of user defined macros.  */
24
25 #include "m4.h"
26
27 #include "execute.h"
28 #include "memchr2.h"
29 #include "regex.h"
30 #include "spawn-pipe.h"
31 #include "wait-process.h"
32
33 #define ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
34
35 /* Initialization of builtin and predefined macros.  The table
36    "builtin_tab" is both used for initialization, and by the "builtin"
37    builtin.  */
38
39 #define DECLARE(name) \
40   static void name (struct obstack *, int, token_data **)
41
42 DECLARE (m4___file__);
43 DECLARE (m4___line__);
44 DECLARE (m4___program__);
45 DECLARE (m4_builtin);
46 DECLARE (m4_changecom);
47 DECLARE (m4_changequote);
48 #ifdef ENABLE_CHANGEWORD
49 DECLARE (m4_changeword);
50 #endif
51 DECLARE (m4_debugmode);
52 DECLARE (m4_debugfile);
53 DECLARE (m4_decr);
54 DECLARE (m4_define);
55 DECLARE (m4_defn);
56 DECLARE (m4_divert);
57 DECLARE (m4_divnum);
58 DECLARE (m4_dnl);
59 DECLARE (m4_dumpdef);
60 DECLARE (m4_errprint);
61 DECLARE (m4_esyscmd);
62 DECLARE (m4_eval);
63 DECLARE (m4_format);
64 DECLARE (m4_ifdef);
65 DECLARE (m4_ifelse);
66 DECLARE (m4_include);
67 DECLARE (m4_incr);
68 DECLARE (m4_index);
69 DECLARE (m4_indir);
70 DECLARE (m4_len);
71 DECLARE (m4_m4exit);
72 DECLARE (m4_m4wrap);
73 DECLARE (m4_maketemp);
74 DECLARE (m4_mkstemp);
75 DECLARE (m4_patsubst);
76 DECLARE (m4_popdef);
77 DECLARE (m4_pushdef);
78 DECLARE (m4_regexp);
79 DECLARE (m4_shift);
80 DECLARE (m4_sinclude);
81 DECLARE (m4_substr);
82 DECLARE (m4_syscmd);
83 DECLARE (m4_sysval);
84 DECLARE (m4_traceoff);
85 DECLARE (m4_traceon);
86 DECLARE (m4_translit);
87 DECLARE (m4_undefine);
88 DECLARE (m4_undivert);
89
90 #undef DECLARE
91
92 static builtin const builtin_tab[] =
93 {
94
95   /* name               GNUext  macros  blind   function */
96
97   { "__file__",         true,   false,  false,  m4___file__ },
98   { "__line__",         true,   false,  false,  m4___line__ },
99   { "__program__",      true,   false,  false,  m4___program__ },
100   { "builtin",          true,   true,   true,   m4_builtin },
101   { "changecom",        false,  false,  false,  m4_changecom },
102   { "changequote",      false,  false,  false,  m4_changequote },
103 #ifdef ENABLE_CHANGEWORD
104   { "changeword",       true,   false,  true,   m4_changeword },
105 #endif
106   { "debugmode",        true,   false,  false,  m4_debugmode },
107   { "debugfile",        true,   false,  false,  m4_debugfile },
108   { "decr",             false,  false,  true,   m4_decr },
109   { "define",           false,  true,   true,   m4_define },
110   { "defn",             false,  false,  true,   m4_defn },
111   { "divert",           false,  false,  false,  m4_divert },
112   { "divnum",           false,  false,  false,  m4_divnum },
113   { "dnl",              false,  false,  false,  m4_dnl },
114   { "dumpdef",          false,  false,  false,  m4_dumpdef },
115   { "errprint",         false,  false,  true,   m4_errprint },
116   { "esyscmd",          true,   false,  true,   m4_esyscmd },
117   { "eval",             false,  false,  true,   m4_eval },
118   { "format",           true,   false,  true,   m4_format },
119   { "ifdef",            false,  false,  true,   m4_ifdef },
120   { "ifelse",           false,  false,  true,   m4_ifelse },
121   { "include",          false,  false,  true,   m4_include },
122   { "incr",             false,  false,  true,   m4_incr },
123   { "index",            false,  false,  true,   m4_index },
124   { "indir",            true,   true,   true,   m4_indir },
125   { "len",              false,  false,  true,   m4_len },
126   { "m4exit",           false,  false,  false,  m4_m4exit },
127   { "m4wrap",           false,  false,  true,   m4_m4wrap },
128   { "maketemp",         false,  false,  true,   m4_maketemp },
129   { "mkstemp",          false,  false,  true,   m4_mkstemp },
130   { "patsubst",         true,   false,  true,   m4_patsubst },
131   { "popdef",           false,  false,  true,   m4_popdef },
132   { "pushdef",          false,  true,   true,   m4_pushdef },
133   { "regexp",           true,   false,  true,   m4_regexp },
134   { "shift",            false,  false,  true,   m4_shift },
135   { "sinclude",         false,  false,  true,   m4_sinclude },
136   { "substr",           false,  false,  true,   m4_substr },
137   { "syscmd",           false,  false,  true,   m4_syscmd },
138   { "sysval",           false,  false,  false,  m4_sysval },
139   { "traceoff",         false,  false,  false,  m4_traceoff },
140   { "traceon",          false,  false,  false,  m4_traceon },
141   { "translit",         false,  false,  true,   m4_translit },
142   { "undefine",         false,  false,  true,   m4_undefine },
143   { "undivert",         false,  false,  false,  m4_undivert },
144
145   { 0,                  false,  false,  false,  0 },
146
147   /* placeholder is intentionally stuck after the table end delimiter,
148      so that we can easily find it, while not treating it as a real
149      builtin.  */
150   { "placeholder",      true,   false,  false,  m4_placeholder },
151 };
152
153 static predefined const predefined_tab[] =
154 {
155 #if UNIX
156   { "unix",     "__unix__",     "" },
157 #endif
158 #if W32_NATIVE
159   { "windows",  "__windows__",  "" },
160 #endif
161 #if OS2
162   { "os2",      "__os2__",      "" },
163 #endif
164 #if !UNIX && !W32_NATIVE && !OS2
165 # warning Platform macro not provided
166 #endif
167   { NULL,       "__gnu__",      "" },
168
169   { NULL,       NULL,           NULL },
170 };
171 \f
172 /*----------------------------------------.
173 | Find the builtin, which lives on ADDR.  |
174 `----------------------------------------*/
175
176 const builtin *
177 find_builtin_by_addr (builtin_func *func)
178 {
179   const builtin *bp;
180
181   for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
182     if (bp->func == func)
183       return bp;
184   if (func == m4_placeholder)
185     return bp + 1;
186   return NULL;
187 }
188
189 /*----------------------------------------------------------.
190 | Find the builtin, which has NAME.  On failure, return the |
191 | placeholder builtin.                                      |
192 `----------------------------------------------------------*/
193
194 const builtin *
195 find_builtin_by_name (const char *name)
196 {
197   const builtin *bp;
198
199   for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
200     if (STREQ (bp->name, name))
201       return bp;
202   return bp + 1;
203 }
204 \f
205 /*----------------------------------------------------------------.
206 | Install a builtin macro with name NAME, bound to the C function |
207 | given in BP.  MODE is SYMBOL_INSERT or SYMBOL_PUSHDEF.          |
208 `----------------------------------------------------------------*/
209
210 void
211 define_builtin (const char *name, const builtin *bp, symbol_lookup mode)
212 {
213   symbol *sym;
214
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;
220 }
221
222 /* Storage for the compiled regular expression of
223    --warn-macro-sequence.  */
224 static struct re_pattern_buffer macro_sequence_buf;
225
226 /* Storage for the matches of --warn-macro-sequence.  */
227 static struct re_registers macro_sequence_regs;
228
229 /* True if --warn-macro-sequence is in effect.  */
230 static bool macro_sequence_inuse;
231
232 /*----------------------------------------.
233 | Clean up regular expression variables.  |
234 `----------------------------------------*/
235
236 static void
237 free_pattern_buffer (struct re_pattern_buffer *buf, struct re_registers *regs)
238 {
239   regfree (buf);
240   free (regs->start);
241   free (regs->end);
242 }
243
244 /*-----------------------------------------------------------------.
245 | Set the regular expression of --warn-macro-sequence that will be |
246 | checked during define and pushdef.  Exit on failure.             |
247 `-----------------------------------------------------------------*/
248 void
249 set_macro_sequence (const char *regexp)
250 {
251   const char *msg;
252
253   if (! regexp)
254     regexp = DEFAULT_MACRO_SEQUENCE;
255   else if (regexp[0] == '\0')
256     {
257       macro_sequence_inuse = false;
258       return;
259     }
260
261   msg = re_compile_pattern (regexp, strlen (regexp), &macro_sequence_buf);
262   if (msg != NULL)
263     {
264       M4ERROR ((EXIT_FAILURE, 0,
265                 "--warn-macro-sequence: bad regular expression `%s': %s",
266                 regexp, msg));
267     }
268   re_set_registers (&macro_sequence_buf, &macro_sequence_regs,
269                     macro_sequence_regs.num_regs,
270                     macro_sequence_regs.start, macro_sequence_regs.end);
271   macro_sequence_inuse = true;
272 }
273
274 /*-----------------------------------------------------------.
275 | Free dynamic memory utilized by the macro sequence regular |
276 | expression during the define builtin.                      |
277 `-----------------------------------------------------------*/
278 void
279 free_macro_sequence (void)
280 {
281   free_pattern_buffer (&macro_sequence_buf, &macro_sequence_regs);
282 }
283
284 /*-----------------------------------------------------------------.
285 | Define a predefined or user-defined macro, with name NAME, and   |
286 | expansion TEXT.  MODE destinguishes between the "define" and the |
287 | "pushdef" case.  It is also used from main.                      |
288 `-----------------------------------------------------------------*/
289
290 void
291 define_user_macro (const char *name, const char *text, symbol_lookup mode)
292 {
293   symbol *s;
294   char *defn = xstrdup (text ? text : "");
295
296   s = lookup_symbol (name, mode);
297   if (SYMBOL_TYPE (s) == TOKEN_TEXT)
298     free (SYMBOL_TEXT (s));
299
300   SYMBOL_TYPE (s) = TOKEN_TEXT;
301   SYMBOL_TEXT (s) = defn;
302
303   /* Implement --warn-macro-sequence.  */
304   if (macro_sequence_inuse && text)
305     {
306       regoff_t offset = 0;
307       size_t len = strlen (defn);
308
309       while ((offset = re_search (&macro_sequence_buf, defn, len, offset,
310                                   len - offset, &macro_sequence_regs)) >= 0)
311         {
312           /* Skip empty matches.  */
313           if (macro_sequence_regs.start[0] == macro_sequence_regs.end[0])
314             offset++;
315           else
316             {
317               char tmp;
318               offset = macro_sequence_regs.end[0];
319               tmp = defn[offset];
320               defn[offset] = '\0';
321               M4ERROR ((warning_status, 0,
322                         "Warning: definition of `%s' contains sequence `%s'",
323                         name, defn + macro_sequence_regs.start[0]));
324               defn[offset] = tmp;
325             }
326         }
327       if (offset == -2)
328         M4ERROR ((warning_status, 0,
329                   "error checking --warn-macro-sequence for macro `%s'",
330                   name));
331     }
332 }
333
334 /*-----------------------------------------------.
335 | Initialize all builtin and predefined macros.  |
336 `-----------------------------------------------*/
337
338 void
339 builtin_init (void)
340 {
341   const builtin *bp;
342   const predefined *pp;
343   char *string;
344
345   for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
346     if (!no_gnu_extensions || !bp->gnu_extension)
347       {
348         if (prefix_all_builtins)
349           {
350             string = (char *) xmalloc (strlen (bp->name) + 4);
351             strcpy (string, "m4_");
352             strcat (string, bp->name);
353             define_builtin (string, bp, SYMBOL_INSERT);
354             free (string);
355           }
356         else
357           define_builtin (bp->name, bp, SYMBOL_INSERT);
358       }
359
360   for (pp = &predefined_tab[0]; pp->func != NULL; pp++)
361     if (no_gnu_extensions)
362       {
363         if (pp->unix_name != NULL)
364           define_user_macro (pp->unix_name, pp->func, SYMBOL_INSERT);
365       }
366     else
367       {
368         if (pp->gnu_name != NULL)
369           define_user_macro (pp->gnu_name, pp->func, SYMBOL_INSERT);
370       }
371 }
372
373 /*-------------------------------------------------------------------.
374 | Give friendly warnings if a builtin macro is passed an             |
375 | inappropriate number of arguments.  NAME is the macro name for     |
376 | messages, ARGC is actual number of arguments, MIN is the minimum   |
377 | number of acceptable arguments, negative if not applicable, MAX is |
378 | the maximum number, negative if not applicable.                    |
379 `-------------------------------------------------------------------*/
380
381 static bool
382 bad_argc (token_data *name, int argc, int min, int max)
383 {
384   bool isbad = false;
385
386   if (min > 0 && argc < min)
387     {
388       if (!suppress_warnings)
389         M4ERROR ((warning_status, 0,
390                   "Warning: too few arguments to builtin `%s'",
391                   TOKEN_DATA_TEXT (name)));
392       isbad = true;
393     }
394   else if (max > 0 && argc > max && !suppress_warnings)
395     M4ERROR ((warning_status, 0,
396               "Warning: excess arguments to builtin `%s' ignored",
397               TOKEN_DATA_TEXT (name)));
398
399   return isbad;
400 }
401
402 /*-----------------------------------------------------------------.
403 | The function numeric_arg () converts ARG to an int pointed to by |
404 | VALUEP.  If the conversion fails, print error message for macro  |
405 | MACRO.  Return true iff conversion succeeds.                     |
406 `-----------------------------------------------------------------*/
407
408 static bool
409 numeric_arg (token_data *macro, const char *arg, int *valuep)
410 {
411   char *endp;
412
413   if (*arg == '\0')
414     {
415       *valuep = 0;
416       M4ERROR ((warning_status, 0,
417                 "empty string treated as 0 in builtin `%s'",
418                 TOKEN_DATA_TEXT (macro)));
419     }
420   else
421     {
422       errno = 0;
423       *valuep = strtol (arg, &endp, 10);
424       if (*endp != '\0')
425         {
426           M4ERROR ((warning_status, 0,
427                     "non-numeric argument to builtin `%s'",
428                     TOKEN_DATA_TEXT (macro)));
429           return false;
430         }
431       if (isspace (to_uchar (*arg)))
432         M4ERROR ((warning_status, 0,
433                   "leading whitespace ignored in builtin `%s'",
434                   TOKEN_DATA_TEXT (macro)));
435       else if (errno == ERANGE)
436         M4ERROR ((warning_status, 0,
437                   "numeric overflow detected in builtin `%s'",
438                   TOKEN_DATA_TEXT (macro)));
439     }
440   return true;
441 }
442
443 /*------------------------------------------------------.
444 | The function ntoa () converts VALUE to a signed ASCII |
445 | representation in radix RADIX.                        |
446 `------------------------------------------------------*/
447
448 /* Digits for number to ASCII conversions.  */
449 static char const digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
450
451 const char *
452 ntoa (int32_t value, int radix)
453 {
454   bool negative;
455   uint32_t uvalue;
456   static char str[256];
457   char *s = &str[sizeof str];
458
459   *--s = '\0';
460
461   if (value < 0)
462     {
463       negative = true;
464       uvalue = -(uint32_t) value;
465     }
466   else
467     {
468       negative = false;
469       uvalue = (uint32_t) value;
470     }
471
472   do
473     {
474       *--s = digits[uvalue % radix];
475       uvalue /= radix;
476     }
477   while (uvalue > 0);
478
479   if (negative)
480     *--s = '-';
481   return s;
482 }
483
484 /*---------------------------------------------------------------.
485 | Format an int VAL, and stuff it into an obstack OBS.  Used for |
486 | macros expanding to numbers.                                   |
487 `---------------------------------------------------------------*/
488
489 static void
490 shipout_int (struct obstack *obs, int val)
491 {
492   const char *s;
493
494   s = ntoa ((int32_t) val, 10);
495   obstack_grow (obs, s, strlen (s));
496 }
497
498 /*-------------------------------------------------------------------.
499 | Print ARGC arguments from the table ARGV to obstack OBS, separated |
500 | by SEP, and quoted by the current quotes if QUOTED is true.        |
501 `-------------------------------------------------------------------*/
502
503 static void
504 dump_args (struct obstack *obs, int argc, token_data **argv,
505            const char *sep, bool quoted)
506 {
507   int i;
508   size_t len = strlen (sep);
509
510   for (i = 1; i < argc; i++)
511     {
512       if (i > 1)
513         obstack_grow (obs, sep, len);
514       if (quoted)
515         obstack_grow (obs, lquote.string, lquote.length);
516       obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
517                     strlen (TOKEN_DATA_TEXT (argv[i])));
518       if (quoted)
519         obstack_grow (obs, rquote.string, rquote.length);
520     }
521 }
522 \f
523 /* The rest of this file is code for builtins and expansion of user
524    defined macros.  All the functions for builtins have a prototype as:
525
526         void m4_MACRONAME (struct obstack *obs, int argc, char *argv[]);
527
528    The function are expected to leave their expansion on the obstack OBS,
529    as an unfinished object.  ARGV is a table of ARGC pointers to the
530    individual arguments to the macro.  Please note that in general
531    argv[argc] != NULL.  */
532
533 /* The first section are macros for definining, undefining, examining,
534    changing, ... other macros.  */
535
536 /*-------------------------------------------------------------------.
537 | The function define_macro is common for the builtins "define",     |
538 | "undefine", "pushdef" and "popdef".  ARGC and ARGV is as for the   |
539 | caller, and MODE argument determines how the macro name is entered |
540 | into the symbol table.                                             |
541 `-------------------------------------------------------------------*/
542
543 static void
544 define_macro (int argc, token_data **argv, symbol_lookup mode)
545 {
546   const builtin *bp;
547
548   if (bad_argc (argv[0], argc, 2, 3))
549     return;
550
551   if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
552     {
553       M4ERROR ((warning_status, 0,
554                 "Warning: %s: invalid macro name ignored", ARG (0)));
555       return;
556     }
557
558   if (argc == 2)
559     {
560       define_user_macro (ARG (1), "", mode);
561       return;
562     }
563
564   switch (TOKEN_DATA_TYPE (argv[2]))
565     {
566     case TOKEN_TEXT:
567       define_user_macro (ARG (1), ARG (2), mode);
568       break;
569
570     case TOKEN_FUNC:
571       bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[2]));
572       if (bp == NULL)
573         return;
574       else
575         define_builtin (ARG (1), bp, mode);
576       break;
577
578     case TOKEN_VOID:
579     default:
580       M4ERROR ((warning_status, 0,
581                 "INTERNAL ERROR: bad token data type in define_macro ()"));
582       abort ();
583     }
584 }
585
586 static void
587 m4_define (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
588 {
589   define_macro (argc, argv, SYMBOL_INSERT);
590 }
591
592 static void
593 m4_undefine (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
594 {
595   int i;
596   if (bad_argc (argv[0], argc, 2, -1))
597     return;
598   for (i = 1; i < argc; i++)
599     lookup_symbol (ARG (i), SYMBOL_DELETE);
600 }
601
602 static void
603 m4_pushdef (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
604 {
605   define_macro (argc, argv,  SYMBOL_PUSHDEF);
606 }
607
608 static void
609 m4_popdef (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
610 {
611   int i;
612   if (bad_argc (argv[0], argc, 2, -1))
613     return;
614   for (i = 1; i < argc; i++)
615     lookup_symbol (ARG (i), SYMBOL_POPDEF);
616 }
617 \f
618 /*---------------------.
619 | Conditionals of m4.  |
620 `---------------------*/
621
622 static void
623 m4_ifdef (struct obstack *obs, int argc, token_data **argv)
624 {
625   symbol *s;
626   const char *result;
627
628   if (bad_argc (argv[0], argc, 3, 4))
629     return;
630   s = lookup_symbol (ARG (1), SYMBOL_LOOKUP);
631
632   if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
633     result = ARG (2);
634   else if (argc >= 4)
635     result = ARG (3);
636   else
637     result = NULL;
638
639   if (result != NULL)
640     obstack_grow (obs, result, strlen (result));
641 }
642
643 static void
644 m4_ifelse (struct obstack *obs, int argc, token_data **argv)
645 {
646   const char *result;
647   token_data *me = argv[0];
648
649   if (argc == 2)
650     return;
651
652   if (bad_argc (me, argc, 4, -1))
653     return;
654   else
655     /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments.  */
656     bad_argc (me, (argc + 2) % 3, -1, 1);
657
658   argv++;
659   argc--;
660
661   result = NULL;
662   while (result == NULL)
663
664     if (STREQ (ARG (0), ARG (1)))
665       result = ARG (2);
666
667     else
668       switch (argc)
669         {
670         case 3:
671           return;
672
673         case 4:
674         case 5:
675           result = ARG (3);
676           break;
677
678         default:
679           argc -= 3;
680           argv += 3;
681         }
682
683   obstack_grow (obs, result, strlen (result));
684 }
685 \f
686 /*-------------------------------------------------------------------.
687 | The function dump_symbol () is for use by "dumpdef".  It builds up |
688 | a table of all defined, un-shadowed, symbols.                      |
689 `-------------------------------------------------------------------*/
690
691 /* The structure dump_symbol_data is used to pass the information needed
692    from call to call to dump_symbol.  */
693
694 struct dump_symbol_data
695 {
696   struct obstack *obs;          /* obstack for table */
697   symbol **base;                /* base of table */
698   int size;                     /* size of table */
699 };
700
701 static void
702 dump_symbol (symbol *sym, void *arg)
703 {
704   struct dump_symbol_data *data = (struct dump_symbol_data *) arg;
705   if (!SYMBOL_SHADOWED (sym) && SYMBOL_TYPE (sym) != TOKEN_VOID)
706     {
707       obstack_blank (data->obs, sizeof (symbol *));
708       data->base = (symbol **) obstack_base (data->obs);
709       data->base[data->size++] = sym;
710     }
711 }
712
713 /*------------------------------------------------------------------------.
714 | qsort comparison routine, for sorting the table made in m4_dumpdef ().  |
715 `------------------------------------------------------------------------*/
716
717 static int
718 dumpdef_cmp (const void *s1, const void *s2)
719 {
720   return strcmp (SYMBOL_NAME (* (symbol *const *) s1),
721                  SYMBOL_NAME (* (symbol *const *) s2));
722 }
723
724 /*-------------------------------------------------------------.
725 | Implementation of "dumpdef" itself.  It builds up a table of |
726 | pointers to symbols, sorts it and prints the sorted table.   |
727 `-------------------------------------------------------------*/
728
729 static void
730 m4_dumpdef (struct obstack *obs, int argc, token_data **argv)
731 {
732   symbol *s;
733   int i;
734   struct dump_symbol_data data;
735   const builtin *bp;
736
737   data.obs = obs;
738   data.base = (symbol **) obstack_base (obs);
739   data.size = 0;
740
741   if (argc == 1)
742     {
743       hack_all_symbols (dump_symbol, &data);
744     }
745   else
746     {
747       for (i = 1; i < argc; i++)
748         {
749           s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
750           if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
751             dump_symbol (s, &data);
752           else
753             M4ERROR ((warning_status, 0,
754                       "undefined macro `%s'", TOKEN_DATA_TEXT (argv[i])));
755         }
756     }
757
758   /* Make table of symbols invisible to expand_macro ().  */
759
760   obstack_finish (obs);
761
762   qsort (data.base, data.size, sizeof (symbol *), dumpdef_cmp);
763
764   for (; data.size > 0; --data.size, data.base++)
765     {
766       DEBUG_PRINT1 ("%s:\t", SYMBOL_NAME (data.base[0]));
767
768       switch (SYMBOL_TYPE (data.base[0]))
769         {
770         case TOKEN_TEXT:
771           if (debug_level & DEBUG_TRACE_QUOTE)
772             DEBUG_PRINT3 ("%s%s%s\n",
773                           lquote.string, SYMBOL_TEXT (data.base[0]), rquote.string);
774           else
775             DEBUG_PRINT1 ("%s\n", SYMBOL_TEXT (data.base[0]));
776           break;
777
778         case TOKEN_FUNC:
779           bp = find_builtin_by_addr (SYMBOL_FUNC (data.base[0]));
780           if (bp == NULL)
781             {
782               M4ERROR ((warning_status, 0, "\
783 INTERNAL ERROR: builtin not found in builtin table"));
784               abort ();
785             }
786           DEBUG_PRINT1 ("<%s>\n", bp->name);
787           break;
788
789         case TOKEN_VOID:
790         default:
791           M4ERROR ((warning_status, 0,
792                     "INTERNAL ERROR: bad token data type in m4_dumpdef ()"));
793           abort ();
794           break;
795         }
796     }
797 }
798
799 /*-----------------------------------------------------------------.
800 | The builtin "builtin" allows calls to builtin macros, even if    |
801 | their definition has been overridden or shadowed.  It is thus    |
802 | possible to redefine builtins, and still access their original   |
803 | definition.  This macro is not available in compatibility mode.  |
804 `-----------------------------------------------------------------*/
805
806 static void
807 m4_builtin (struct obstack *obs, int argc, token_data **argv)
808 {
809   const builtin *bp;
810   const char *name;
811
812   if (bad_argc (argv[0], argc, 2, -1))
813     return;
814   if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
815     {
816       M4ERROR ((warning_status, 0,
817                 "Warning: %s: invalid macro name ignored", ARG (0)));
818       return;
819     }
820
821   name = ARG (1);
822   bp = find_builtin_by_name (name);
823   if (bp->func == m4_placeholder)
824     M4ERROR ((warning_status, 0,
825               "undefined builtin `%s'", name));
826   else
827     {
828       int i;
829       if (! bp->groks_macro_args)
830         for (i = 2; i < argc; i++)
831           if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT)
832             {
833               TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT;
834               TOKEN_DATA_TEXT (argv[i]) = (char *) "";
835             }
836       bp->func (obs, argc - 1, argv + 1);
837     }
838 }
839
840 /*-------------------------------------------------------------------.
841 | The builtin "indir" allows indirect calls to macros, even if their |
842 | name is not a proper macro name.  It is thus possible to define    |
843 | macros with ill-formed names for internal use in larger macro      |
844 | packages.  This macro is not available in compatibility mode.      |
845 `-------------------------------------------------------------------*/
846
847 static void
848 m4_indir (struct obstack *obs, int argc, token_data **argv)
849 {
850   symbol *s;
851   const char *name;
852
853   if (bad_argc (argv[0], argc, 2, -1))
854     return;
855   if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
856     {
857       M4ERROR ((warning_status, 0,
858                 "Warning: %s: invalid macro name ignored", ARG (0)));
859       return;
860     }
861
862   name = ARG (1);
863   s = lookup_symbol (name, SYMBOL_LOOKUP);
864   if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
865     M4ERROR ((warning_status, 0,
866               "undefined macro `%s'", name));
867   else
868     {
869       int i;
870       if (! SYMBOL_MACRO_ARGS (s))
871         for (i = 2; i < argc; i++)
872           if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT)
873             {
874               TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT;
875               TOKEN_DATA_TEXT (argv[i]) = (char *) "";
876             }
877       call_macro (s, argc - 1, argv + 1, obs);
878     }
879 }
880
881 /*------------------------------------------------------------------.
882 | The macro "defn" returns the quoted definition of the macro named |
883 | by the first argument.  If the macro is builtin, it will push a   |
884 | special macro-definition token on the input stack.                |
885 `------------------------------------------------------------------*/
886
887 static void
888 m4_defn (struct obstack *obs, int argc, token_data **argv)
889 {
890   symbol *s;
891   builtin_func *b;
892   unsigned int i;
893
894   if (bad_argc (argv[0], argc, 2, -1))
895     return;
896
897   assert (0 < argc && argc <= INT_MAX);
898   for (i = 1; i < (unsigned) argc; i++)
899     {
900       const char *arg = ARG((int) i);
901       s = lookup_symbol (arg, SYMBOL_LOOKUP);
902       if (s == NULL)
903         continue;
904
905       switch (SYMBOL_TYPE (s))
906         {
907         case TOKEN_TEXT:
908           obstack_grow (obs, lquote.string, lquote.length);
909           obstack_grow (obs, SYMBOL_TEXT (s), strlen (SYMBOL_TEXT (s)));
910           obstack_grow (obs, rquote.string, rquote.length);
911           break;
912
913         case TOKEN_FUNC:
914           b = SYMBOL_FUNC (s);
915           if (b == m4_placeholder)
916             M4ERROR ((warning_status, 0, "\
917 builtin `%s' requested by frozen file is not supported", arg));
918           else if (argc != 2)
919             M4ERROR ((warning_status, 0,
920                       "Warning: cannot concatenate builtin `%s'",
921                       arg));
922           else
923             push_macro (b);
924           break;
925
926         case TOKEN_VOID:
927           /* Nothing to do for traced but undefined macro.  */
928           break;
929
930         default:
931           M4ERROR ((warning_status, 0,
932                     "INTERNAL ERROR: bad symbol type in m4_defn ()"));
933           abort ();
934         }
935     }
936 }
937 \f
938 /*--------------------------------------------------------------.
939 | This section contains macros to handle the builtins "syscmd", |
940 | "esyscmd" and "sysval".  "esyscmd" is GNU specific.           |
941 `--------------------------------------------------------------*/
942
943 /* Exit code from last "syscmd" command.  */
944 static int sysval;
945
946 static void
947 m4_syscmd (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
948 {
949   const char *cmd = ARG (1);
950   int status;
951   int sig_status;
952   const char *prog_args[4] = { "sh", "-c" };
953   if (bad_argc (argv[0], argc, 2, 2) || !*cmd)
954     {
955       /* The empty command is successful.  */
956       sysval = 0;
957       return;
958     }
959
960   debug_flush_files ();
961 #if W32_NATIVE
962   if (strstr (SYSCMD_SHELL, "cmd"))
963     {
964       prog_args[0] = "cmd";
965       prog_args[1] = "/c";
966     }
967 #endif
968   prog_args[2] = cmd;
969   errno = 0;
970   status = execute (ARG (0), SYSCMD_SHELL, (char **) prog_args, false,
971                     false, false, false, true, false, &sig_status);
972   if (sig_status)
973     {
974       assert (status == 127);
975       sysval = sig_status << 8;
976     }
977   else
978     {
979       if (status == 127 && errno)
980         M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
981       sysval = status;
982     }
983 }
984
985 static void
986 m4_esyscmd (struct obstack *obs, int argc, token_data **argv)
987 {
988   const char *cmd = ARG (1);
989   const char *prog_args[4] = { "sh", "-c" };
990   pid_t child;
991   int fd;
992   FILE *pin;
993   int status;
994   int sig_status;
995
996   if (bad_argc (argv[0], argc, 2, 2) || !*cmd)
997     {
998       /* The empty command is successful.  */
999       sysval = 0;
1000       return;
1001     }
1002
1003   debug_flush_files ();
1004 #if W32_NATIVE
1005   if (strstr (SYSCMD_SHELL, "cmd"))
1006     {
1007       prog_args[0] = "cmd";
1008       prog_args[1] = "/c";
1009     }
1010 #endif
1011   prog_args[2] = cmd;
1012   errno = 0;
1013   child = create_pipe_in (ARG (0), SYSCMD_SHELL, (char **) prog_args,
1014                           NULL, false, true, false, &fd);
1015   if (child == -1)
1016     {
1017       M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
1018       sysval = 127;
1019       return;
1020     }
1021   pin = fdopen (fd, "r");
1022   if (pin == NULL)
1023     {
1024       M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
1025       sysval = 127;
1026       close (fd);
1027       return;
1028     }
1029   while (1)
1030     {
1031       size_t avail = obstack_room (obs);
1032       size_t len;
1033       if (!avail)
1034         {
1035           int ch = getc (pin);
1036           if (ch == EOF)
1037             break;
1038           obstack_1grow (obs, ch);
1039           continue;
1040         }
1041       len = fread (obstack_next_free (obs), 1, avail, pin);
1042       if (len <= 0)
1043         break;
1044       obstack_blank_fast (obs, len);
1045     }
1046   if (ferror (pin) || fclose (pin))
1047     M4ERROR ((EXIT_FAILURE, errno, "cannot read pipe"));
1048   errno = 0;
1049   status = wait_subprocess (child, ARG (0), false, true, true, false,
1050                             &sig_status);
1051   if (sig_status)
1052     {
1053       assert (status == 127);
1054       sysval = sig_status << 8;
1055     }
1056   else
1057     {
1058       if (status == 127 && errno)
1059         M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
1060       sysval = status;
1061     }
1062 }
1063
1064 static void
1065 m4_sysval (struct obstack *obs, int argc M4_GNUC_UNUSED,
1066            token_data **argv M4_GNUC_UNUSED)
1067 {
1068   shipout_int (obs, sysval);
1069 }
1070 \f
1071 /*------------------------------------------------------------------.
1072 | This section contains the top level code for the "eval" builtin.  |
1073 | The actual work is done in the function evaluate (), which lives  |
1074 | in eval.c.                                                        |
1075 `------------------------------------------------------------------*/
1076
1077 static void
1078 m4_eval (struct obstack *obs, int argc, token_data **argv)
1079 {
1080   int32_t value = 0;
1081   int radix = 10;
1082   int min = 1;
1083   const char *s;
1084
1085   if (bad_argc (argv[0], argc, 2, 4))
1086     return;
1087
1088   if (*ARG (2) && !numeric_arg (argv[0], ARG (2), &radix))
1089     return;
1090
1091   if (radix < 1 || radix > (int) strlen (digits))
1092     {
1093       M4ERROR ((warning_status, 0,
1094                 "radix %d in builtin `%s' out of range",
1095                 radix, ARG (0)));
1096       return;
1097     }
1098
1099   if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &min))
1100     return;
1101   if (min < 0)
1102     {
1103       M4ERROR ((warning_status, 0,
1104                 "negative width to builtin `%s'", ARG (0)));
1105       return;
1106     }
1107
1108   if (!*ARG (1))
1109     M4ERROR ((warning_status, 0,
1110               "empty string treated as 0 in builtin `%s'", ARG (0)));
1111   else if (evaluate (ARG (1), &value))
1112     return;
1113
1114   if (radix == 1)
1115     {
1116       if (value < 0)
1117         {
1118           obstack_1grow (obs, '-');
1119           value = -value;
1120         }
1121       /* This assumes 2's-complement for correctly handling INT_MIN.  */
1122       while (min-- - value > 0)
1123         obstack_1grow (obs, '0');
1124       while (value-- != 0)
1125         obstack_1grow (obs, '1');
1126       obstack_1grow (obs, '\0');
1127       return;
1128     }
1129
1130   s = ntoa (value, radix);
1131
1132   if (*s == '-')
1133     {
1134       obstack_1grow (obs, '-');
1135       s++;
1136     }
1137   for (min -= strlen (s); --min >= 0;)
1138     obstack_1grow (obs, '0');
1139
1140   obstack_grow (obs, s, strlen (s));
1141 }
1142
1143 static void
1144 m4_incr (struct obstack *obs, int argc, token_data **argv)
1145 {
1146   int value;
1147
1148   if (bad_argc (argv[0], argc, 2, 2))
1149     return;
1150
1151   if (!numeric_arg (argv[0], ARG (1), &value))
1152     return;
1153
1154   shipout_int (obs, value + 1);
1155 }
1156
1157 static void
1158 m4_decr (struct obstack *obs, int argc, token_data **argv)
1159 {
1160   int value;
1161
1162   if (bad_argc (argv[0], argc, 2, 2))
1163     return;
1164
1165   if (!numeric_arg (argv[0], ARG (1), &value))
1166     return;
1167
1168   shipout_int (obs, value - 1);
1169 }
1170 \f
1171 /* This section contains the macros "divert", "undivert" and "divnum" for
1172    handling diversion.  The utility functions used lives in output.c.  */
1173
1174 /*-----------------------------------------------------------------.
1175 | Divert further output to the diversion given by ARGV[1].  Out of |
1176 | range means discard further output.                              |
1177 `-----------------------------------------------------------------*/
1178
1179 static void
1180 m4_divert (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1181 {
1182   int i = 0;
1183
1184   if (bad_argc (argv[0], argc, 1, 2))
1185     return;
1186
1187   if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &i))
1188     return;
1189
1190   make_diversion (i);
1191 }
1192
1193 /*-----------------------------------------------------.
1194 | Expand to the current diversion number, -1 if none.  |
1195 `-----------------------------------------------------*/
1196
1197 static void
1198 m4_divnum (struct obstack *obs, int argc, token_data **argv)
1199 {
1200   if (bad_argc (argv[0], argc, 1, 1))
1201     return;
1202   shipout_int (obs, current_diversion);
1203 }
1204
1205 /*------------------------------------------------------------------.
1206 | Bring back the diversion given by the argument list.  If none is  |
1207 | specified, bring back all diversions.  GNU specific is the option |
1208 | of undiverting named files, by passing a non-numeric argument to  |
1209 | undivert ().                                                      |
1210 `------------------------------------------------------------------*/
1211
1212 static void
1213 m4_undivert (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1214 {
1215   int i, file;
1216   FILE *fp;
1217   char *endp;
1218
1219   if (argc == 1)
1220     undivert_all ();
1221   else
1222     for (i = 1; i < argc; i++)
1223       {
1224         file = strtol (ARG (i), &endp, 10);
1225         if (*endp == '\0' && !isspace (to_uchar (*ARG (i))))
1226           insert_diversion (file);
1227         else if (no_gnu_extensions)
1228           M4ERROR ((warning_status, 0,
1229                     "non-numeric argument to builtin `%s'", ARG (0)));
1230         else
1231           {
1232             fp = m4_path_search (ARG (i), NULL);
1233             if (fp != NULL)
1234               {
1235                 insert_file (fp);
1236                 if (fclose (fp) == EOF)
1237                   M4ERROR ((warning_status, errno,
1238                             "error undiverting `%s'", ARG (i)));
1239               }
1240             else
1241               M4ERROR ((warning_status, errno,
1242                         "cannot undivert `%s'", ARG (i)));
1243           }
1244       }
1245 }
1246 \f
1247 /* This section contains various macros, which does not fall into any
1248    specific group.  These are "dnl", "shift", "changequote", "changecom"
1249    and "changeword".  */
1250
1251 /*-----------------------------------------------------------.
1252 | Delete all subsequent whitespace from input.  The function |
1253 | skip_line () lives in input.c.                             |
1254 `-----------------------------------------------------------*/
1255
1256 static void
1257 m4_dnl (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1258 {
1259   if (bad_argc (argv[0], argc, 1, 1))
1260     return;
1261
1262   skip_line ();
1263 }
1264
1265 /*--------------------------------------------------------------------.
1266 | Shift all arguments one to the left, discarding the first           |
1267 | argument.  Each output argument is quoted with the current quotes.  |
1268 `--------------------------------------------------------------------*/
1269
1270 static void
1271 m4_shift (struct obstack *obs, int argc, token_data **argv)
1272 {
1273   if (bad_argc (argv[0], argc, 2, -1))
1274     return;
1275   dump_args (obs, argc - 1, argv + 1, ",", true);
1276 }
1277
1278 /*--------------------------------------------------------------------------.
1279 | Change the current quotes.  The function set_quotes () lives in input.c.  |
1280 `--------------------------------------------------------------------------*/
1281
1282 static void
1283 m4_changequote (struct obstack *obs M4_GNUC_UNUSED, int argc,
1284                 token_data **argv)
1285 {
1286   if (bad_argc (argv[0], argc, 1, 3))
1287     return;
1288
1289   /* Explicit NULL distinguishes between empty and missing argument.  */
1290   set_quotes ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
1291              (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
1292 }
1293
1294 /*-----------------------------------------------------------------.
1295 | Change the current comment delimiters.  The function set_comment |
1296 | () lives in input.c.                                             |
1297 `-----------------------------------------------------------------*/
1298
1299 static void
1300 m4_changecom (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1301 {
1302   if (bad_argc (argv[0], argc, 1, 3))
1303     return;
1304
1305   /* Explicit NULL distinguishes between empty and missing argument.  */
1306   set_comment ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
1307                (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
1308 }
1309
1310 #ifdef ENABLE_CHANGEWORD
1311
1312 /*---------------------------------------------------------------.
1313 | Change the regular expression used for breaking the input into |
1314 | words.  The function set_word_regexp () lives in input.c.      |
1315 `---------------------------------------------------------------*/
1316
1317 static void
1318 m4_changeword (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1319 {
1320   if (bad_argc (argv[0], argc, 2, 2))
1321     return;
1322
1323   set_word_regexp (TOKEN_DATA_TEXT (argv[1]));
1324 }
1325
1326 #endif /* ENABLE_CHANGEWORD */
1327 \f
1328 /* This section contains macros for inclusion of other files -- "include"
1329    and "sinclude".  This differs from bringing back diversions, in that
1330    the input is scanned before being copied to the output.  */
1331
1332 /*---------------------------------------------------------------.
1333 | Generic include function.  Include the file given by the first |
1334 | argument, if it exists.  Complain about inaccessible files iff |
1335 | SILENT is false.                                               |
1336 `---------------------------------------------------------------*/
1337
1338 static void
1339 include (int argc, token_data **argv, bool silent)
1340 {
1341   FILE *fp;
1342   char *name;
1343
1344   if (bad_argc (argv[0], argc, 2, 2))
1345     return;
1346
1347   fp = m4_path_search (ARG (1), &name);
1348   if (fp == NULL)
1349     {
1350       if (!silent)
1351         {
1352           M4ERROR ((warning_status, errno, "cannot open `%s'", ARG (1)));
1353           retcode = EXIT_FAILURE;
1354         }
1355       return;
1356     }
1357
1358   push_file (fp, name, true);
1359   free (name);
1360 }
1361
1362 /*------------------------------------------------.
1363 | Include a file, complaining in case of errors.  |
1364 `------------------------------------------------*/
1365
1366 static void
1367 m4_include (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1368 {
1369   include (argc, argv, false);
1370 }
1371
1372 /*----------------------------------.
1373 | Include a file, ignoring errors.  |
1374 `----------------------------------*/
1375
1376 static void
1377 m4_sinclude (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1378 {
1379   include (argc, argv, true);
1380 }
1381 \f
1382 /* More miscellaneous builtins -- "maketemp", "errprint", "__file__",
1383    "__line__", and "__program__".  The last three are GNU specific.  */
1384
1385 /*------------------------------------------------------------------.
1386 | Use the first argument as at template for a temporary file name.  |
1387 `------------------------------------------------------------------*/
1388
1389 /* Add trailing 'X' to PATTERN of length LEN as necessary, then
1390    securely create the file, and place the quoted new file name on
1391    OBS.  Report errors on behalf of ME.  */
1392 static void
1393 mkstemp_helper (struct obstack *obs, const char *me, const char *pattern,
1394                 size_t len)
1395 {
1396   int fd;
1397   size_t i;
1398   char *name;
1399
1400   /* Guarantee that there are six trailing 'X' characters, even if the
1401      user forgot to supply them.  Output must be quoted if
1402      successful.  */
1403   obstack_grow (obs, lquote.string, lquote.length);
1404   obstack_grow (obs, pattern, len);
1405   for (i = 0; len > 0 && i < 6; i++)
1406     if (pattern[len - i - 1] != 'X')
1407       break;
1408   obstack_grow0 (obs, "XXXXXX", 6 - i);
1409   name = (char *) obstack_base (obs) + lquote.length;
1410
1411   errno = 0;
1412   fd = mkstemp (name);
1413   if (fd < 0)
1414     {
1415       M4ERROR ((0, errno, "%s: cannot create tempfile `%s'", me, pattern));
1416       obstack_free (obs, obstack_finish (obs));
1417     }
1418   else
1419     {
1420       close (fd);
1421       /* Remove NUL, then finish quote.  */
1422       obstack_blank (obs, -1);
1423       obstack_grow (obs, rquote.string, rquote.length);
1424     }
1425 }
1426
1427 static void
1428 m4_maketemp (struct obstack *obs, int argc, token_data **argv)
1429 {
1430   if (bad_argc (argv[0], argc, 2, 2))
1431     return;
1432   if (no_gnu_extensions)
1433     {
1434       /* POSIX states "any trailing 'X' characters [are] replaced with
1435          the current process ID as a string", without referencing the
1436          file system.  Horribly insecure, but we have to do it when we
1437          are in traditional mode.
1438
1439          For reference, Solaris m4 does:
1440            maketemp() -> `'
1441            maketemp(X) -> `X'
1442            maketemp(XX) -> `Xn', where n is last digit of pid
1443            maketemp(XXXXXXXX) -> `X00nnnnn', where nnnnn is 16-bit pid
1444       */
1445       const char *str = ARG (1);
1446       int len = strlen (str);
1447       int i;
1448       int len2;
1449
1450       M4ERROR ((warning_status, 0, "recommend using mkstemp instead"));
1451       for (i = len; i > 1; i--)
1452         if (str[i - 1] != 'X')
1453           break;
1454       obstack_grow (obs, str, i);
1455       str = ntoa ((int32_t) getpid (), 10);
1456       len2 = strlen (str);
1457       if (len2 > len - i)
1458         obstack_grow0 (obs, str + len2 - (len - i), len - i);
1459       else
1460         {
1461           while (i++ < len - len2)
1462             obstack_1grow (obs, '0');
1463           obstack_grow0 (obs, str, len2);
1464         }
1465     }
1466   else
1467     mkstemp_helper (obs, ARG (0), ARG (1), strlen (ARG (1)));
1468 }
1469
1470 static void
1471 m4_mkstemp (struct obstack *obs, int argc, token_data **argv)
1472 {
1473   if (bad_argc (argv[0], argc, 2, 2))
1474     return;
1475   mkstemp_helper (obs, ARG (0), ARG (1), strlen (ARG (1)));
1476 }
1477
1478 /*----------------------------------------.
1479 | Print all arguments on standard error.  |
1480 `----------------------------------------*/
1481
1482 static void
1483 m4_errprint (struct obstack *obs, int argc, token_data **argv)
1484 {
1485   if (bad_argc (argv[0], argc, 2, -1))
1486     return;
1487   dump_args (obs, argc, argv, " ", false);
1488   obstack_1grow (obs, '\0');
1489   debug_flush_files ();
1490   xfprintf (stderr, "%s", (char *) obstack_finish (obs));
1491   fflush (stderr);
1492 }
1493
1494 static void
1495 m4___file__ (struct obstack *obs, int argc, token_data **argv)
1496 {
1497   if (bad_argc (argv[0], argc, 1, 1))
1498     return;
1499   obstack_grow (obs, lquote.string, lquote.length);
1500   obstack_grow (obs, current_file, strlen (current_file));
1501   obstack_grow (obs, rquote.string, rquote.length);
1502 }
1503
1504 static void
1505 m4___line__ (struct obstack *obs, int argc, token_data **argv)
1506 {
1507   if (bad_argc (argv[0], argc, 1, 1))
1508     return;
1509   shipout_int (obs, current_line);
1510 }
1511
1512 static void
1513 m4___program__ (struct obstack *obs, int argc, token_data **argv)
1514 {
1515   if (bad_argc (argv[0], argc, 1, 1))
1516     return;
1517   obstack_grow (obs, lquote.string, lquote.length);
1518   obstack_grow (obs, program_name, strlen (program_name));
1519   obstack_grow (obs, rquote.string, rquote.length);
1520 }
1521 \f
1522 /* This section contains various macros for exiting, saving input until
1523    EOF is seen, and tracing macro calls.  That is: "m4exit", "m4wrap",
1524    "traceon" and "traceoff".  */
1525
1526 /*----------------------------------------------------------.
1527 | Exit immediately, with exit status specified by the first |
1528 | argument, or 0 if no arguments are present.               |
1529 `----------------------------------------------------------*/
1530
1531 static void M4_GNUC_NORETURN
1532 m4_m4exit (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1533 {
1534   int exit_code = EXIT_SUCCESS;
1535
1536   /* Warn on bad arguments, but still exit.  */
1537   bad_argc (argv[0], argc, 1, 2);
1538   if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &exit_code))
1539     exit_code = EXIT_FAILURE;
1540   if (exit_code < 0 || exit_code > 255)
1541     {
1542       M4ERROR ((warning_status, 0,
1543                 "exit status out of range: `%d'", exit_code));
1544       exit_code = EXIT_FAILURE;
1545     }
1546   /* Change debug stream back to stderr, to force flushing debug stream and
1547      detect any errors it might have encountered.  */
1548   debug_set_output (NULL);
1549   debug_flush_files ();
1550   if (exit_code == EXIT_SUCCESS && retcode != EXIT_SUCCESS)
1551     exit_code = retcode;
1552   /* Propagate non-zero status to atexit handlers.  */
1553   if (exit_code != EXIT_SUCCESS)
1554     exit_failure = exit_code;
1555   exit (exit_code);
1556 }
1557
1558 /*------------------------------------------------------------------.
1559 | Save the argument text until EOF has been seen, allowing for user |
1560 | specified cleanup action.  GNU version saves all arguments, the   |
1561 | standard version only the first.                                  |
1562 `------------------------------------------------------------------*/
1563
1564 static void
1565 m4_m4wrap (struct obstack *obs, int argc, token_data **argv)
1566 {
1567   if (bad_argc (argv[0], argc, 2, -1))
1568     return;
1569   if (no_gnu_extensions)
1570     obstack_grow (obs, ARG (1), strlen (ARG (1)));
1571   else
1572     dump_args (obs, argc, argv, " ", false);
1573   obstack_1grow (obs, '\0');
1574   push_wrapup ((char *) obstack_finish (obs));
1575 }
1576 \f
1577 /* Enable tracing of all specified macros, or all, if none is specified.
1578    Tracing is disabled by default, when a macro is defined.  This can be
1579    overridden by the "t" debug flag.  */
1580
1581 /*------------------------------------------------------------------.
1582 | Set_trace () is used by "traceon" and "traceoff" to enable and    |
1583 | disable tracing of a macro.  It disables tracing if DATA is NULL, |
1584 | otherwise it enables tracing.                                     |
1585 `------------------------------------------------------------------*/
1586
1587 static void
1588 set_trace (symbol *sym, void *data)
1589 {
1590   SYMBOL_TRACED (sym) = data != NULL;
1591   /* Remove placeholder from table if macro is undefined and untraced.  */
1592   if (SYMBOL_TYPE (sym) == TOKEN_VOID && data == NULL)
1593     lookup_symbol (SYMBOL_NAME (sym), SYMBOL_POPDEF);
1594 }
1595
1596 static void
1597 m4_traceon (struct obstack *obs, int argc, token_data **argv)
1598 {
1599   symbol *s;
1600   int i;
1601
1602   if (argc == 1)
1603     hack_all_symbols (set_trace, obs);
1604   else
1605     for (i = 1; i < argc; i++)
1606       {
1607         s = lookup_symbol (ARG (i), SYMBOL_LOOKUP);
1608         if (!s)
1609           s = lookup_symbol (ARG (i), SYMBOL_INSERT);
1610         set_trace (s, obs);
1611       }
1612 }
1613
1614 /*------------------------------------------------------------------------.
1615 | Disable tracing of all specified macros, or all, if none is specified.  |
1616 `------------------------------------------------------------------------*/
1617
1618 static void
1619 m4_traceoff (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1620 {
1621   symbol *s;
1622   int i;
1623
1624   if (argc == 1)
1625     hack_all_symbols (set_trace, NULL);
1626   else
1627     for (i = 1; i < argc; i++)
1628       {
1629         s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
1630         if (s != NULL)
1631           set_trace (s, NULL);
1632       }
1633 }
1634
1635 /*------------------------------------------------------------------.
1636 | On-the-fly control of the format of the tracing output.  It takes |
1637 | one argument, which is a character string like given to the -d    |
1638 | option, or none in which case the debug_level is zeroed.          |
1639 `------------------------------------------------------------------*/
1640
1641 static void
1642 m4_debugmode (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1643 {
1644   int new_debug_level;
1645   int change_flag;
1646
1647   if (bad_argc (argv[0], argc, 1, 2))
1648     return;
1649
1650   if (argc == 1)
1651     debug_level = 0;
1652   else
1653     {
1654       if (ARG (1)[0] == '+' || ARG (1)[0] == '-')
1655         {
1656           change_flag = ARG (1)[0];
1657           new_debug_level = debug_decode (ARG (1) + 1);
1658         }
1659       else
1660         {
1661           change_flag = 0;
1662           new_debug_level = debug_decode (ARG (1));
1663         }
1664
1665       if (new_debug_level < 0)
1666         M4ERROR ((warning_status, 0,
1667                   "Debugmode: bad debug flags: `%s'", ARG (1)));
1668       else
1669         {
1670           switch (change_flag)
1671             {
1672             case 0:
1673               debug_level = new_debug_level;
1674               break;
1675
1676             case '+':
1677               debug_level |= new_debug_level;
1678               break;
1679
1680             case '-':
1681               debug_level &= ~new_debug_level;
1682               break;
1683
1684             default:
1685               M4ERROR ((warning_status, 0,
1686                         "INTERNAL ERROR: bad flag in m4_debugmode ()"));
1687               abort ();
1688             }
1689         }
1690     }
1691 }
1692
1693 /*-------------------------------------------------------------------------.
1694 | Specify the destination of the debugging output.  With one argument, the |
1695 | argument is taken as a file name, with no arguments, revert to stderr.   |
1696 `-------------------------------------------------------------------------*/
1697
1698 static void
1699 m4_debugfile (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
1700 {
1701   if (bad_argc (argv[0], argc, 1, 2))
1702     return;
1703
1704   if (argc == 1)
1705     debug_set_output (NULL);
1706   else if (!debug_set_output (ARG (1)))
1707     M4ERROR ((warning_status, errno,
1708               "cannot set debug file `%s'", ARG (1)));
1709 }
1710 \f
1711 /* This section contains text processing macros: "len", "index",
1712    "substr", "translit", "format", "regexp" and "patsubst".  The last
1713    three are GNU specific.  */
1714
1715 /*---------------------------------------------.
1716 | Expand to the length of the first argument.  |
1717 `---------------------------------------------*/
1718
1719 static void
1720 m4_len (struct obstack *obs, int argc, token_data **argv)
1721 {
1722   if (bad_argc (argv[0], argc, 2, 2))
1723     return;
1724   shipout_int (obs, strlen (ARG (1)));
1725 }
1726
1727 /*-------------------------------------------------------------------.
1728 | The macro expands to the first index of the second argument in the |
1729 | first argument.                                                    |
1730 `-------------------------------------------------------------------*/
1731
1732 static void
1733 m4_index (struct obstack *obs, int argc, token_data **argv)
1734 {
1735   const char *haystack;
1736   const char *result;
1737   int retval;
1738
1739   if (bad_argc (argv[0], argc, 3, 3))
1740     {
1741       /* builtin(`index') is blank, but index(`abc') is 0.  */
1742       if (argc == 2)
1743         shipout_int (obs, 0);
1744       return;
1745     }
1746
1747   haystack = ARG (1);
1748   result = strstr (haystack, ARG (2));
1749   retval = result ? result - haystack : -1;
1750
1751   shipout_int (obs, retval);
1752 }
1753
1754 /*-----------------------------------------------------------------.
1755 | The macro "substr" extracts substrings from the first argument,  |
1756 | starting from the index given by the second argument, extending  |
1757 | for a length given by the third argument.  If the third argument |
1758 | is missing, the substring extends to the end of the first        |
1759 | argument.                                                        |
1760 `-----------------------------------------------------------------*/
1761
1762 static void
1763 m4_substr (struct obstack *obs, int argc, token_data **argv)
1764 {
1765   int start = 0;
1766   int length, avail;
1767
1768   if (bad_argc (argv[0], argc, 3, 4))
1769     {
1770       /* builtin(`substr') is blank, but substr(`abc') is abc.  */
1771       if (argc == 2)
1772         obstack_grow (obs, ARG (1), strlen (ARG (1)));
1773       return;
1774     }
1775
1776   length = avail = strlen (ARG (1));
1777   if (!numeric_arg (argv[0], ARG (2), &start))
1778     return;
1779
1780   if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &length))
1781     return;
1782
1783   if (start < 0 || length <= 0 || start >= avail)
1784     return;
1785
1786   if (start + length > avail)
1787     length = avail - start;
1788   obstack_grow (obs, ARG (1) + start, length);
1789 }
1790
1791 /*------------------------------------------------------------------.
1792 | For "translit", ranges are allowed in the second and third        |
1793 | argument.  They are expanded in the following function, and the   |
1794 | expanded strings, without any ranges left, are used to translate  |
1795 | the characters of the first argument.  A single - (dash) can be   |
1796 | included in the strings by being the first or the last character  |
1797 | in the string.  If the first character in a range is after the    |
1798 | first in the character set, the range is made backwards, thus 9-0 |
1799 | is the string 9876543210.                                         |
1800 `------------------------------------------------------------------*/
1801
1802 static const char *
1803 expand_ranges (const char *s, struct obstack *obs)
1804 {
1805   unsigned char from;
1806   unsigned char to;
1807
1808   for (from = '\0'; *s != '\0'; from = to_uchar (*s++))
1809     {
1810       if (*s == '-' && from != '\0')
1811         {
1812           to = to_uchar (*++s);
1813           if (to == '\0')
1814             {
1815               /* trailing dash */
1816               obstack_1grow (obs, '-');
1817               break;
1818             }
1819           else if (from <= to)
1820             {
1821               while (from++ < to)
1822                 obstack_1grow (obs, from);
1823             }
1824           else
1825             {
1826               while (--from >= to)
1827                 obstack_1grow (obs, from);
1828             }
1829         }
1830       else
1831         obstack_1grow (obs, *s);
1832     }
1833   obstack_1grow (obs, '\0');
1834   return (char *) obstack_finish (obs);
1835 }
1836
1837 /*-----------------------------------------------------------------.
1838 | The macro "translit" translates all characters in the first      |
1839 | argument, which are present in the second argument, into the     |
1840 | corresponding character from the third argument.  If the third   |
1841 | argument is shorter than the second, the extra characters in the |
1842 | second argument are deleted from the first.                      |
1843 `-----------------------------------------------------------------*/
1844
1845 static void
1846 m4_translit (struct obstack *obs, int argc, token_data **argv)
1847 {
1848   const char *data = ARG (1);
1849   const char *from = ARG (2);
1850   const char *to;
1851   char map[UCHAR_MAX + 1];
1852   char found[UCHAR_MAX + 1];
1853   unsigned char ch;
1854
1855   if (bad_argc (argv[0], argc, 3, 4) || !*data || !*from)
1856     {
1857       /* builtin(`translit') is blank, but translit(`abc') is abc.  */
1858       if (2 <= argc)
1859         obstack_grow (obs, data, strlen (data));
1860       return;
1861     }
1862
1863   to = ARG (3);
1864   if (strchr (to, '-') != NULL)
1865     {
1866       to = expand_ranges (to, obs);
1867       assert (to && *to);
1868     }
1869
1870   /* If there are only one or two bytes to replace, it is faster to
1871      use memchr2.  Using expand_ranges does nothing unless there are
1872      at least three bytes.  */
1873   if (!from[1] || !from[2])
1874     {
1875       const char *p;
1876       size_t len = strlen (data);
1877       while ((p = (char *) memchr2 (data, from[0], from[1], len)))
1878         {
1879           obstack_grow (obs, data, p - data);
1880           len -= p - data;
1881           if (!len)
1882             return;
1883           data = p + 1;
1884           len--;
1885           if (*p == from[0] && to[0])
1886             obstack_1grow (obs, to[0]);
1887           else if (*p == from[1] && to[0] && to[1])
1888             obstack_1grow (obs, to[1]);
1889         }
1890       obstack_grow (obs, data, len);
1891       return;
1892     }
1893
1894   if (strchr (from, '-') != NULL)
1895     {
1896       from = expand_ranges (from, obs);
1897       assert (from && *from);
1898     }
1899
1900   /* Calling strchr(from) for each character in data is quadratic,
1901      since both strings can be arbitrarily long.  Instead, create a
1902      from-to mapping in one pass of from, then use that map in one
1903      pass of data, for linear behavior.  Traditional behavior is that
1904      only the first instance of a character in from is consulted,
1905      hence the found map.  */
1906   memset (map, 0, sizeof map);
1907   memset (found, 0, sizeof found);
1908   for ( ; (ch = *from) != '\0'; from++)
1909     {
1910       if (! found[ch])
1911         {
1912           found[ch] = 1;
1913           map[ch] = *to;
1914         }
1915       if (*to != '\0')
1916         to++;
1917     }
1918
1919   for (data = ARG (1); (ch = *data) != '\0'; data++)
1920     {
1921       if (! found[ch])
1922         obstack_1grow (obs, ch);
1923       else if (map[ch])
1924         obstack_1grow (obs, map[ch]);
1925     }
1926 }
1927
1928 /*-------------------------------------------------------------------.
1929 | Frontend for printf like formatting.  The function format () lives |
1930 | in the file format.c.                                              |
1931 `-------------------------------------------------------------------*/
1932
1933 static void
1934 m4_format (struct obstack *obs, int argc, token_data **argv)
1935 {
1936   if (bad_argc (argv[0], argc, 2, -1))
1937     return;
1938   expand_format (obs, argc - 1, argv + 1);
1939 }
1940
1941 /*------------------------------------------------------------------.
1942 | Function to perform substitution by regular expressions.  Used by |
1943 | the builtins regexp and patsubst.  The changed text is placed on  |
1944 | the obstack.  The substitution is REPL, with \& substituted by    |
1945 | this part of VICTIM matched by the last whole regular expression, |
1946 | taken from REGS[0], and \N substituted by the text matched by the |
1947 | Nth parenthesized sub-expression, taken from REGS[N].             |
1948 `------------------------------------------------------------------*/
1949
1950 static int substitute_warned = 0;
1951
1952 static void
1953 substitute (struct obstack *obs, const char *victim, const char *repl,
1954             struct re_registers *regs)
1955 {
1956   int ch;
1957   __re_size_t ind;
1958   while (1)
1959     {
1960       const char *backslash = strchr (repl, '\\');
1961       if (!backslash)
1962         {
1963           obstack_grow (obs, repl, strlen (repl));
1964           return;
1965         }
1966       obstack_grow (obs, repl, backslash - repl);
1967       repl = backslash;
1968       ch = *++repl;
1969       switch (ch)
1970         {
1971         case '0':
1972           if (!substitute_warned)
1973             {
1974               M4ERROR ((warning_status, 0, "\
1975 Warning: \\0 will disappear, use \\& instead in replacements"));
1976               substitute_warned = 1;
1977             }
1978           /* Fall through.  */
1979
1980         case '&':
1981           obstack_grow (obs, victim + regs->start[0],
1982                         regs->end[0] - regs->start[0]);
1983           repl++;
1984           break;
1985
1986         case '1': case '2': case '3': case '4': case '5': case '6':
1987         case '7': case '8': case '9':
1988           ind = ch -= '0';
1989           if (regs->num_regs - 1 <= ind)
1990             M4ERROR ((warning_status, 0,
1991                       "Warning: sub-expression %d not present", ch));
1992           else if (regs->end[ch] > 0)
1993             obstack_grow (obs, victim + regs->start[ch],
1994                           regs->end[ch] - regs->start[ch]);
1995           repl++;
1996           break;
1997
1998         case '\0':
1999           M4ERROR ((warning_status, 0,
2000                     "Warning: trailing \\ ignored in replacement"));
2001           return;
2002
2003         default:
2004           obstack_1grow (obs, ch);
2005           repl++;
2006           break;
2007         }
2008     }
2009 }
2010
2011 /*------------------------------------------.
2012 | Initialize regular expression variables.  |
2013 `------------------------------------------*/
2014
2015 void
2016 init_pattern_buffer (struct re_pattern_buffer *buf, struct re_registers *regs)
2017 {
2018   buf->translate = NULL;
2019   buf->fastmap = NULL;
2020   buf->buffer = NULL;
2021   buf->allocated = 0;
2022   if (regs)
2023     {
2024       regs->start = NULL;
2025       regs->end = NULL;
2026     }
2027 }
2028
2029 /*------------------------------------------------------------------.
2030 | Regular expression version of index.  Given two arguments, expand |
2031 | to the index of the first match of the second argument (a regexp) |
2032 | in the first.  Expand to -1 if here is no match.  Given a third   |
2033 | argument, it changes the expansion to this argument.              |
2034 `------------------------------------------------------------------*/
2035
2036 static void
2037 m4_regexp (struct obstack *obs, int argc, token_data **argv)
2038 {
2039   const char *victim;           /* first argument */
2040   const char *regexp;           /* regular expression */
2041   const char *repl;             /* replacement string */
2042
2043   struct re_pattern_buffer buf; /* compiled regular expression */
2044   struct re_registers regs;     /* for subexpression matches */
2045   const char *msg;              /* error message from re_compile_pattern */
2046   int startpos;                 /* start position of match */
2047   int length;                   /* length of first argument */
2048
2049   if (bad_argc (argv[0], argc, 3, 4))
2050     {
2051       /* builtin(`regexp') is blank, but regexp(`abc') is 0.  */
2052       if (argc == 2)
2053         shipout_int (obs, 0);
2054       return;
2055     }
2056
2057   victim = TOKEN_DATA_TEXT (argv[1]);
2058   regexp = TOKEN_DATA_TEXT (argv[2]);
2059
2060   init_pattern_buffer (&buf, &regs);
2061   msg = re_compile_pattern (regexp, strlen (regexp), &buf);
2062
2063   if (msg != NULL)
2064     {
2065       M4ERROR ((warning_status, 0,
2066                 "bad regular expression: `%s': %s", regexp, msg));
2067       free_pattern_buffer (&buf, &regs);
2068       return;
2069     }
2070
2071   length = strlen (victim);
2072   /* Avoid overhead of allocating regs if we won't use it.  */
2073   startpos = re_search (&buf, victim, length, 0, length,
2074                         argc == 3 ? NULL : &regs);
2075
2076   if (startpos == -2)
2077     M4ERROR ((warning_status, 0,
2078                "error matching regular expression `%s'", regexp));
2079   else if (argc == 3)
2080     shipout_int (obs, startpos);
2081   else if (startpos >= 0)
2082     {
2083       repl = TOKEN_DATA_TEXT (argv[3]);
2084       substitute (obs, victim, repl, &regs);
2085     }
2086
2087   free_pattern_buffer (&buf, &regs);
2088 }
2089
2090 /*--------------------------------------------------------------------------.
2091 | Substitute all matches of a regexp occuring in a string.  Each match of   |
2092 | the second argument (a regexp) in the first argument is changed to the    |
2093 | third argument, with \& substituted by the matched text, and \N           |
2094 | substituted by the text matched by the Nth parenthesized sub-expression.  |
2095 `--------------------------------------------------------------------------*/
2096
2097 static void
2098 m4_patsubst (struct obstack *obs, int argc, token_data **argv)
2099 {
2100   const char *victim;           /* first argument */
2101   const char *regexp;           /* regular expression */
2102
2103   struct re_pattern_buffer buf; /* compiled regular expression */
2104   struct re_registers regs;     /* for subexpression matches */
2105   const char *msg;              /* error message from re_compile_pattern */
2106   int matchpos;                 /* start position of match */
2107   int offset;                   /* current match offset */
2108   int length;                   /* length of first argument */
2109
2110   if (bad_argc (argv[0], argc, 3, 4))
2111     {
2112       /* builtin(`patsubst') is blank, but patsubst(`abc') is abc.  */
2113       if (argc == 2)
2114         obstack_grow (obs, ARG (1), strlen (ARG (1)));
2115       return;
2116     }
2117
2118   regexp = TOKEN_DATA_TEXT (argv[2]);
2119
2120   init_pattern_buffer (&buf, &regs);
2121   msg = re_compile_pattern (regexp, strlen (regexp), &buf);
2122
2123   if (msg != NULL)
2124     {
2125       M4ERROR ((warning_status, 0,
2126                 "bad regular expression `%s': %s", regexp, msg));
2127       free (buf.buffer);
2128       return;
2129     }
2130
2131   victim = TOKEN_DATA_TEXT (argv[1]);
2132   length = strlen (victim);
2133
2134   offset = 0;
2135   while (offset <= length)
2136     {
2137       matchpos = re_search (&buf, victim, length,
2138                             offset, length - offset, &regs);
2139       if (matchpos < 0)
2140         {
2141
2142           /* Match failed -- either error or there is no match in the
2143              rest of the string, in which case the rest of the string is
2144              copied verbatim.  */
2145
2146           if (matchpos == -2)
2147             M4ERROR ((warning_status, 0,
2148                       "error matching regular expression `%s'", regexp));
2149           else if (offset < length)
2150             obstack_grow (obs, victim + offset, length - offset);
2151           break;
2152         }
2153
2154       /* Copy the part of the string that was skipped by re_search ().  */
2155
2156       if (matchpos > offset)
2157         obstack_grow (obs, victim + offset, matchpos - offset);
2158
2159       /* Handle the part of the string that was covered by the match.  */
2160
2161       substitute (obs, victim, ARG (3), &regs);
2162
2163       /* Update the offset to the end of the match.  If the regexp
2164          matched a null string, advance offset one more, to avoid
2165          infinite loops.  */
2166
2167       offset = regs.end[0];
2168       if (regs.start[0] == regs.end[0])
2169         obstack_1grow (obs, victim[offset++]);
2170     }
2171   obstack_1grow (obs, '\0');
2172
2173   free_pattern_buffer (&buf, &regs);
2174 }
2175 \f
2176 /* Finally, a placeholder builtin.  This builtin is not installed by
2177    default, but when reading back frozen files, this is associated
2178    with any builtin we don't recognize (for example, if the frozen
2179    file was created with a changeword capable m4, but is then loaded
2180    by a different m4 that does not support changeword).  This way, we
2181    can keep 'm4 -R' quiet in the common case that the user did not
2182    know or care about the builtin when the frozen file was created,
2183    while still flagging it as a potential error if an attempt is made
2184    to actually use the builtin.  */
2185
2186 /*--------------------------------------------------------------------.
2187 | Issue a warning that this macro is a placeholder for an unsupported |
2188 | builtin that was requested while reloading a frozen file.           |
2189 `--------------------------------------------------------------------*/
2190
2191 void
2192 m4_placeholder (struct obstack *obs M4_GNUC_UNUSED, int argc,
2193                 token_data **argv)
2194 {
2195   M4ERROR ((warning_status, 0, "\
2196 builtin `%s' requested by frozen file is not supported", ARG (0)));
2197 }
2198 \f
2199 /*-------------------------------------------------------------------.
2200 | This function handles all expansion of user defined and predefined |
2201 | macros.  It is called with an obstack OBS, where the macros        |
2202 | expansion will be placed, as an unfinished object.  SYM points to  |
2203 | the macro definition, giving the expansion text.  ARGC and ARGV    |
2204 | are the arguments, as usual.                                       |
2205 `-------------------------------------------------------------------*/
2206
2207 void
2208 expand_user_macro (struct obstack *obs, symbol *sym,
2209                    int argc, token_data **argv)
2210 {
2211   const char *text = SYMBOL_TEXT (sym);
2212   int i;
2213   while (1)
2214     {
2215       const char *dollar = strchr (text, '$');
2216       if (!dollar)
2217         {
2218           obstack_grow (obs, text, strlen (text));
2219           return;
2220         }
2221       obstack_grow (obs, text, dollar - text);
2222       text = dollar;
2223       switch (*++text)
2224         {
2225         case '0': case '1': case '2': case '3': case '4':
2226         case '5': case '6': case '7': case '8': case '9':
2227           if (no_gnu_extensions)
2228             {
2229               i = *text++ - '0';
2230             }
2231           else
2232             {
2233               for (i = 0; isdigit (to_uchar (*text)); text++)
2234                 i = i*10 + (*text - '0');
2235             }
2236           if (i < argc)
2237             obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
2238                           strlen (TOKEN_DATA_TEXT (argv[i])));
2239           break;
2240
2241         case '#': /* number of arguments */
2242           shipout_int (obs, argc - 1);
2243           text++;
2244           break;
2245
2246         case '*': /* all arguments */
2247         case '@': /* ... same, but quoted */
2248           dump_args (obs, argc, argv, ",", *text == '@');
2249           text++;
2250           break;
2251
2252         default:
2253           obstack_1grow (obs, '$');
2254           break;
2255         }
2256     }
2257 }