source: vendor/m4/1.4.8/src/builtin.c

Last change on this file was 3090, checked in by bird, 18 years ago

m4 1.4.8

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