source: trunk/essentials/sys-devel/m4/src/builtin.c

Last change on this file was 3090, checked in by bird, 19 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