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