This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU M4 source repository".
http://git.sv.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=ac8845562f0066ef07d74a1f5b0e749eceb19b89 The branch, branch-1_4 has been updated via ac8845562f0066ef07d74a1f5b0e749eceb19b89 (commit) from 9de0b8950ca83762363605805c40f8f8614acbc8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ac8845562f0066ef07d74a1f5b0e749eceb19b89 Author: Eric Blake <[EMAIL PROTECTED]> Date: Fri Oct 19 07:43:34 2007 -0600 Stage 1: convert token_data** into new object. * m4/gnulib-cache.m4: Import flexmember module. * src/m4.h (struct macro_arguments, struct token_chain): New structs. (builtin_func): Alter signature. (token_data): Add new TOKEN_COMP alternative. * src/builtin.c: All builtins changed. (ARG, dump_args, define_macro, expand_user_macro): Update to use struct. * src/debug.c (trace_pre, trace_post): Likewise. * src/format.c (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE, format): Likewise. * src/macro.c (collect_arguments): Build new struct. (call_macro, expand_macro): Update to use new struct. (cherry picked from commit 44f5da7de32ac8f71f26d9e441316fa563db30d6) Signed-off-by: Eric Blake <[EMAIL PROTECTED]> ----------------------------------------------------------------------- Summary of changes: ChangeLog | 17 +++++ m4/gnulib-cache.m4 | 4 +- src/builtin.c | 201 ++++++++++++++++++++++++++++++---------------------- src/debug.c | 10 ++-- src/format.c | 45 +++++------- src/m4.h | 71 ++++++++++++++----- src/macro.c | 51 ++++++++------ 7 files changed, 243 insertions(+), 156 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9bbf726..14deb9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2007-11-24 Eric Blake <[EMAIL PROTECTED]> + + Stage 1: convert token_data** into new object. + * m4/gnulib-cache.m4: Import flexmember module. + * src/m4.h (struct macro_arguments, struct token_chain): New + structs. + (builtin_func): Alter signature. + (token_data): Add new TOKEN_COMP alternative. + * src/builtin.c: All builtins changed. + (ARG, dump_args, define_macro, expand_user_macro): Update to use + struct. + * src/debug.c (trace_pre, trace_post): Likewise. + * src/format.c (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE, format): + Likewise. + * src/macro.c (collect_arguments): Build new struct. + (call_macro, expand_macro): Update to use new struct. + 2007-11-22 Eric Blake <[EMAIL PROTECTED]> More error messages tied to macro names. diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index 4d1727d..a89650c 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -15,11 +15,11 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --local-dir=local --lib=libm4 --source-base=lib --m4-base=m4 --doc-base=doc --aux-dir=build-aux --with-tests --no-libtool --macro-prefix=M4 assert avltree-oset binary-io clean-temp cloexec close-stream closein config-h error fdl fflush fopen-safer free fseeko gendocs getopt gnupload gpl-3.0 mkstemp obstack regex stdbool stdint stdlib-safer strtol unlocked-io verror version-etc version-etc-fsf xalloc xprintf xvasprintf-posix +# gnulib-tool --import --dir=. --local-dir=local --lib=libm4 --source-base=lib --m4-base=m4 --doc-base=doc --aux-dir=build-aux --with-tests --no-libtool --macro-prefix=M4 assert avltree-oset binary-io clean-temp cloexec close-stream closein config-h error fdl fflush flexmember fopen-safer free fseeko gendocs getopt gnupload gpl-3.0 mkstemp obstack regex stdbool stdint stdlib-safer strtol unlocked-io verror version-etc version-etc-fsf xalloc xprintf xvasprintf-posix # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([local]) -gl_MODULES([assert avltree-oset binary-io clean-temp cloexec close-stream closein config-h error fdl fflush fopen-safer free fseeko gendocs getopt gnupload gpl-3.0 mkstemp obstack regex stdbool stdint stdlib-safer strtol unlocked-io verror version-etc version-etc-fsf xalloc xprintf xvasprintf-posix]) +gl_MODULES([assert avltree-oset binary-io clean-temp cloexec close-stream closein config-h error fdl fflush flexmember fopen-safer free fseeko gendocs getopt gnupload gpl-3.0 mkstemp obstack regex stdbool stdint stdlib-safer strtol unlocked-io verror version-etc version-etc-fsf xalloc xprintf xvasprintf-posix]) gl_AVOID([]) gl_SOURCE_BASE([lib]) gl_M4_BASE([m4]) diff --git a/src/builtin.c b/src/builtin.c index cc4e469..eb66465 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -30,14 +30,16 @@ # include <sys/wait.h> #endif -#define ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "") +#define ARG(i) \ + ((i) == 0 ? argv->argv0 \ + : argv->argc > (i) ? TOKEN_DATA_TEXT (argv->array[(i) - 1]) : "") /* Initialization of builtin and predefined macros. The table "builtin_tab" is both used for initialization, and by the "builtin" builtin. */ #define DECLARE(name) \ - static void name (struct obstack *, int, token_data **) + static void name (struct obstack *, int, macro_arguments *) DECLARE (m4___file__); DECLARE (m4___line__); @@ -602,16 +604,19 @@ shipout_int (struct obstack *obs, int val) `----------------------------------------------------------------------*/ static void -dump_args (struct obstack *obs, int argc, token_data **argv, +dump_args (struct obstack *obs, int start, macro_arguments *argv, const char *sep, bool quoted) { int i; + bool dump_sep = false; size_t len = strlen (sep); - for (i = 1; i < argc; i++) + for (i = start; i < argv->argc; i++) { - if (i > 1) + if (dump_sep) obstack_grow (obs, sep, len); + else + dump_sep = true; if (quoted) obstack_grow (obs, lquote.string, lquote.length); obstack_grow (obs, ARG (i), strlen (ARG (i))); @@ -623,14 +628,15 @@ dump_args (struct obstack *obs, int argc, token_data **argv, /* The rest of this file is code for builtins and expansion of user defined macros. All the functions for builtins have a prototype as: - void m4_MACRONAME (struct obstack *obs, int argc, char *argv[]); + void m4_MACRONAME (struct obstack *obs, int argc, macro_arguments *argv); - The function are expected to leave their expansion on the obstack OBS, - as an unfinished object. ARGV is a table of ARGC pointers to the - individual arguments to the macro. Please note that in general - argv[argc] != NULL. */ + The functions are expected to leave their expansion on the obstack OBS, + as an unfinished object. ARGV is an object representing ARGC pointers + to the individual arguments to the macro; the object may be compressed + due to references to $@ expansions, so accessors should be used. Please + note that in general argv[argc] != NULL. */ -/* The first section are macros for definining, undefining, examining, +/* The first section are macros for defining, undefining, examining, changing, ... other macros. */ /*-------------------------------------------------------------------------. @@ -641,7 +647,7 @@ dump_args (struct obstack *obs, int argc, token_data **argv, `-------------------------------------------------------------------------*/ static void -define_macro (int argc, token_data **argv, symbol_lookup mode) +define_macro (int argc, macro_arguments *argv, symbol_lookup mode) { const builtin *bp; const char *me = ARG (0); @@ -649,7 +655,7 @@ define_macro (int argc, token_data **argv, symbol_lookup mode) if (bad_argc (me, argc, 1, 2)) return; - if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT) + if (TOKEN_DATA_TYPE (argv->array[0]) != TOKEN_TEXT) { m4_warn (0, me, _("invalid macro name ignored")); return; @@ -661,14 +667,14 @@ define_macro (int argc, token_data **argv, symbol_lookup mode) return; } - switch (TOKEN_DATA_TYPE (argv[2])) + switch (TOKEN_DATA_TYPE (argv->array[1])) { case TOKEN_TEXT: define_user_macro (ARG (1), ARG (2), mode); break; case TOKEN_FUNC: - bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[2])); + bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv->array[1])); if (bp == NULL) return; else @@ -682,13 +688,13 @@ define_macro (int argc, token_data **argv, symbol_lookup mode) } static void -m4_define (struct obstack *obs, int argc, token_data **argv) +m4_define (struct obstack *obs, int argc, macro_arguments *argv) { define_macro (argc, argv, SYMBOL_INSERT); } static void -m4_undefine (struct obstack *obs, int argc, token_data **argv) +m4_undefine (struct obstack *obs, int argc, macro_arguments *argv) { int i; if (bad_argc (ARG (0), argc, 1, -1)) @@ -698,13 +704,13 @@ m4_undefine (struct obstack *obs, int argc, token_data **argv) } static void -m4_pushdef (struct obstack *obs, int argc, token_data **argv) +m4_pushdef (struct obstack *obs, int argc, macro_arguments *argv) { - define_macro (argc, argv, SYMBOL_PUSHDEF); + define_macro (argc, argv, SYMBOL_PUSHDEF); } static void -m4_popdef (struct obstack *obs, int argc, token_data **argv) +m4_popdef (struct obstack *obs, int argc, macro_arguments *argv) { int i; if (bad_argc (ARG (0), argc, 1, -1)) @@ -718,7 +724,7 @@ m4_popdef (struct obstack *obs, int argc, token_data **argv) `---------------------*/ static void -m4_ifdef (struct obstack *obs, int argc, token_data **argv) +m4_ifdef (struct obstack *obs, int argc, macro_arguments *argv) { symbol *s; const char *result; @@ -739,10 +745,11 @@ m4_ifdef (struct obstack *obs, int argc, token_data **argv) } static void -m4_ifelse (struct obstack *obs, int argc, token_data **argv) +m4_ifelse (struct obstack *obs, int argc, macro_arguments *argv) { const char *result; const char *me; + int index; if (argc == 2) return; @@ -754,14 +761,14 @@ m4_ifelse (struct obstack *obs, int argc, token_data **argv) /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments. */ bad_argc (me, argc, 0, argc - 2); - argv++; + index = 1; argc--; result = NULL; while (result == NULL) - if (strcmp (ARG (0), ARG (1)) == 0) - result = ARG (2); + if (strcmp (ARG (index), ARG (index + 1)) == 0) + result = ARG (index + 2); else switch (argc) @@ -771,12 +778,12 @@ m4_ifelse (struct obstack *obs, int argc, token_data **argv) case 4: case 5: - result = ARG (3); + result = ARG (index + 3); break; default: argc -= 3; - argv += 3; + index += 3; } obstack_grow (obs, result, strlen (result)); @@ -826,7 +833,7 @@ dumpdef_cmp (const void *s1, const void *s2) `-------------------------------------------------------------------------*/ static void -m4_dumpdef (struct obstack *obs, int argc, token_data **argv) +m4_dumpdef (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); symbol *s; @@ -900,7 +907,7 @@ m4_dumpdef (struct obstack *obs, int argc, token_data **argv) `---------------------------------------------------------------------*/ static void -m4_builtin (struct obstack *obs, int argc, token_data **argv) +m4_builtin (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); const builtin *bp; @@ -908,7 +915,7 @@ m4_builtin (struct obstack *obs, int argc, token_data **argv) if (bad_argc (me, argc, 1, -1)) return; - if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT) + if (TOKEN_DATA_TYPE (argv->array[0]) != TOKEN_TEXT) { m4_warn (0, me, _("invalid macro name ignored")); return; @@ -921,14 +928,25 @@ m4_builtin (struct obstack *obs, int argc, token_data **argv) else { int i; + /* TODO make use of $@ reference, instead of copying argv. */ + macro_arguments *new_argv = xmalloc (offsetof (macro_arguments, array) + + ((argc - 2) + * sizeof (token_data *))); + new_argv->argc = argc - 1; + new_argv->inuse = false; + new_argv->argv0 = name; + new_argv->arraylen = argc - 2; + memcpy (&new_argv->array[0], &argv->array[1], + (argc - 2) * sizeof (token_data *)); if (!bp->groks_macro_args) for (i = 2; i < argc; i++) - if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT) + if (TOKEN_DATA_TYPE (new_argv->array[i - 2]) != TOKEN_TEXT) { - TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT; - TOKEN_DATA_TEXT (argv[i]) = (char *) ""; + TOKEN_DATA_TYPE (new_argv->array[i - 2]) = TOKEN_TEXT; + TOKEN_DATA_TEXT (new_argv->array[i - 2]) = (char *) ""; } - bp->func (obs, argc - 1, argv + 1); + bp->func (obs, argc - 1, new_argv); + free (new_argv); } } @@ -940,7 +958,7 @@ m4_builtin (struct obstack *obs, int argc, token_data **argv) `------------------------------------------------------------------------*/ static void -m4_indir (struct obstack *obs, int argc, token_data **argv) +m4_indir (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); symbol *s; @@ -948,7 +966,7 @@ m4_indir (struct obstack *obs, int argc, token_data **argv) if (bad_argc (me, argc, 1, -1)) return; - if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT) + if (TOKEN_DATA_TYPE (argv->array[0]) != TOKEN_TEXT) { m4_warn (0, me, _("invalid macro name ignored")); return; @@ -961,14 +979,25 @@ m4_indir (struct obstack *obs, int argc, token_data **argv) else { int i; + /* TODO make use of $@ reference, instead of copying argv. */ + macro_arguments *new_argv = xmalloc (offsetof (macro_arguments, array) + + ((argc - 2) + * sizeof (token_data *))); + new_argv->argc = argc - 1; + new_argv->inuse = false; + new_argv->argv0 = name; + new_argv->arraylen = argc - 2; + memcpy (&new_argv->array[0], &argv->array[1], + (argc - 2) * sizeof (token_data *)); if (!SYMBOL_MACRO_ARGS (s)) for (i = 2; i < argc; i++) - if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT) + if (TOKEN_DATA_TYPE (new_argv->array[i - 2]) != TOKEN_TEXT) { - TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT; - TOKEN_DATA_TEXT (argv[i]) = (char *) ""; + TOKEN_DATA_TYPE (new_argv->array[i - 2]) = TOKEN_TEXT; + TOKEN_DATA_TEXT (new_argv->array[i - 2]) = (char *) ""; } - call_macro (s, argc - 1, argv + 1, obs); + call_macro (s, argc - 1, new_argv, obs); + free (new_argv); } } @@ -979,7 +1008,7 @@ m4_indir (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_defn (struct obstack *obs, int argc, token_data **argv) +m4_defn (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); symbol *s; @@ -1060,7 +1089,7 @@ m4_defn (struct obstack *obs, int argc, token_data **argv) static int sysval; static void -m4_syscmd (struct obstack *obs, int argc, token_data **argv) +m4_syscmd (struct obstack *obs, int argc, macro_arguments *argv) { if (bad_argc (ARG (0), argc, 1, 1)) { @@ -1084,7 +1113,7 @@ m4_syscmd (struct obstack *obs, int argc, token_data **argv) } static void -m4_esyscmd (struct obstack *obs, int argc, token_data **argv) +m4_esyscmd (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); FILE *pin; @@ -1114,7 +1143,7 @@ m4_esyscmd (struct obstack *obs, int argc, token_data **argv) } static void -m4_sysval (struct obstack *obs, int argc, token_data **argv) +m4_sysval (struct obstack *obs, int argc, macro_arguments *argv) { shipout_int (obs, (sysval == -1 ? 127 : (M4SYSVAL_EXITBITS (sysval) @@ -1127,7 +1156,7 @@ m4_sysval (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_eval (struct obstack *obs, int argc, token_data **argv) +m4_eval (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); int32_t value = 0; @@ -1190,7 +1219,7 @@ m4_eval (struct obstack *obs, int argc, token_data **argv) } static void -m4_incr (struct obstack *obs, int argc, token_data **argv) +m4_incr (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); int value; @@ -1205,7 +1234,7 @@ m4_incr (struct obstack *obs, int argc, token_data **argv) } static void -m4_decr (struct obstack *obs, int argc, token_data **argv) +m4_decr (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); int value; @@ -1228,7 +1257,7 @@ m4_decr (struct obstack *obs, int argc, token_data **argv) `-----------------------------------------------------------------------*/ static void -m4_divert (struct obstack *obs, int argc, token_data **argv) +m4_divert (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); int i = 0; @@ -1245,7 +1274,7 @@ m4_divert (struct obstack *obs, int argc, token_data **argv) `-----------------------------------------------------*/ static void -m4_divnum (struct obstack *obs, int argc, token_data **argv) +m4_divnum (struct obstack *obs, int argc, macro_arguments *argv) { bad_argc (ARG (0), argc, 0, 0); shipout_int (obs, current_diversion); @@ -1259,7 +1288,7 @@ m4_divnum (struct obstack *obs, int argc, token_data **argv) `-----------------------------------------------------------------------*/ static void -m4_undivert (struct obstack *obs, int argc, token_data **argv) +m4_undivert (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); int i; @@ -1303,7 +1332,7 @@ m4_undivert (struct obstack *obs, int argc, token_data **argv) `------------------------------------------------------------------------*/ static void -m4_dnl (struct obstack *obs, int argc, token_data **argv) +m4_dnl (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); @@ -1317,11 +1346,12 @@ m4_dnl (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_shift (struct obstack *obs, int argc, token_data **argv) +m4_shift (struct obstack *obs, int argc, macro_arguments *argv) { if (bad_argc (ARG (0), argc, 1, -1)) return; - dump_args (obs, argc - 1, argv + 1, ",", true); + /* TODO push a $@ reference. */ + dump_args (obs, 2, argv, ",", true); } /*--------------------------------------------------------------------------. @@ -1329,13 +1359,13 @@ m4_shift (struct obstack *obs, int argc, token_data **argv) `--------------------------------------------------------------------------*/ static void -m4_changequote (struct obstack *obs, int argc, token_data **argv) +m4_changequote (struct obstack *obs, int argc, macro_arguments *argv) { bad_argc (ARG (0), argc, 0, 2); /* Explicit NULL distinguishes between empty and missing argument. */ set_quotes ((argc >= 2) ? ARG (1) : NULL, - (argc >= 3) ? ARG (2) : NULL); + (argc >= 3) ? ARG (2) : NULL); } /*--------------------------------------------------------------------. @@ -1344,7 +1374,7 @@ m4_changequote (struct obstack *obs, int argc, token_data **argv) `--------------------------------------------------------------------*/ static void -m4_changecom (struct obstack *obs, int argc, token_data **argv) +m4_changecom (struct obstack *obs, int argc, macro_arguments *argv) { bad_argc (ARG (0), argc, 0, 2); @@ -1361,7 +1391,7 @@ m4_changecom (struct obstack *obs, int argc, token_data **argv) `-----------------------------------------------------------------------*/ static void -m4_changeword (struct obstack *obs, int argc, token_data **argv) +m4_changeword (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); @@ -1382,7 +1412,7 @@ m4_changeword (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -include (int argc, token_data **argv, bool silent) +include (int argc, macro_arguments *argv, bool silent) { const char *me = ARG (0); FILE *fp; @@ -1408,7 +1438,7 @@ include (int argc, token_data **argv, bool silent) `------------------------------------------------*/ static void -m4_include (struct obstack *obs, int argc, token_data **argv) +m4_include (struct obstack *obs, int argc, macro_arguments *argv) { include (argc, argv, false); } @@ -1418,7 +1448,7 @@ m4_include (struct obstack *obs, int argc, token_data **argv) `----------------------------------*/ static void -m4_sinclude (struct obstack *obs, int argc, token_data **argv) +m4_sinclude (struct obstack *obs, int argc, macro_arguments *argv) { include (argc, argv, true); } @@ -1462,7 +1492,7 @@ mkstemp_helper (struct obstack *obs, const char *me, const char *name) } static void -m4_maketemp (struct obstack *obs, int argc, token_data **argv) +m4_maketemp (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); @@ -1507,7 +1537,7 @@ m4_maketemp (struct obstack *obs, int argc, token_data **argv) } static void -m4_mkstemp (struct obstack *obs, int argc, token_data **argv) +m4_mkstemp (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); @@ -1521,11 +1551,11 @@ m4_mkstemp (struct obstack *obs, int argc, token_data **argv) `----------------------------------------*/ static void -m4_errprint (struct obstack *obs, int argc, token_data **argv) +m4_errprint (struct obstack *obs, int argc, macro_arguments *argv) { if (bad_argc (ARG (0), argc, 1, -1)) return; - dump_args (obs, argc, argv, " ", false); + dump_args (obs, 1, argv, " ", false); obstack_1grow (obs, '\0'); debug_flush_files (); xfprintf (stderr, "%s", (char *) obstack_finish (obs)); @@ -1533,7 +1563,7 @@ m4_errprint (struct obstack *obs, int argc, token_data **argv) } static void -m4___file__ (struct obstack *obs, int argc, token_data **argv) +m4___file__ (struct obstack *obs, int argc, macro_arguments *argv) { bad_argc (ARG (0), argc, 0, 0); obstack_grow (obs, lquote.string, lquote.length); @@ -1542,14 +1572,14 @@ m4___file__ (struct obstack *obs, int argc, token_data **argv) } static void -m4___line__ (struct obstack *obs, int argc, token_data **argv) +m4___line__ (struct obstack *obs, int argc, macro_arguments *argv) { bad_argc (ARG (0), argc, 0, 0); shipout_int (obs, current_line); } static void -m4___program__ (struct obstack *obs, int argc, token_data **argv) +m4___program__ (struct obstack *obs, int argc, macro_arguments *argv) { bad_argc (ARG (0), argc, 0, 0); obstack_grow (obs, lquote.string, lquote.length); @@ -1567,7 +1597,7 @@ m4___program__ (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_m4exit (struct obstack *obs, int argc, token_data **argv) +m4_m4exit (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); int exit_code = EXIT_SUCCESS; @@ -1600,14 +1630,14 @@ m4_m4exit (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_m4wrap (struct obstack *obs, int argc, token_data **argv) +m4_m4wrap (struct obstack *obs, int argc, macro_arguments *argv) { if (bad_argc (ARG (0), argc, 1, -1)) return; if (no_gnu_extensions) obstack_grow (obs, ARG (1), strlen (ARG (1))); else - dump_args (obs, argc, argv, " ", false); + dump_args (obs, 1, argv, " ", false); obstack_1grow (obs, '\0'); push_wrapup ((char *) obstack_finish (obs)); } @@ -1632,7 +1662,7 @@ set_trace (symbol *sym, void *data) } static void -m4_traceon (struct obstack *obs, int argc, token_data **argv) +m4_traceon (struct obstack *obs, int argc, macro_arguments *argv) { symbol *s; int i; @@ -1652,7 +1682,7 @@ m4_traceon (struct obstack *obs, int argc, token_data **argv) `------------------------------------------------------------------------*/ static void -m4_traceoff (struct obstack *obs, int argc, token_data **argv) +m4_traceoff (struct obstack *obs, int argc, macro_arguments *argv) { symbol *s; int i; @@ -1675,7 +1705,7 @@ m4_traceoff (struct obstack *obs, int argc, token_data **argv) `----------------------------------------------------------------------*/ static void -m4_debugmode (struct obstack *obs, int argc, token_data **argv) +m4_debugmode (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); const char *str = ARG (1); @@ -1727,7 +1757,7 @@ m4_debugmode (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_debugfile (struct obstack *obs, int argc, token_data **argv) +m4_debugfile (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); @@ -1748,7 +1778,7 @@ m4_debugfile (struct obstack *obs, int argc, token_data **argv) `---------------------------------------------*/ static void -m4_len (struct obstack *obs, int argc, token_data **argv) +m4_len (struct obstack *obs, int argc, macro_arguments *argv) { if (bad_argc (ARG (0), argc, 1, 1)) return; @@ -1761,7 +1791,7 @@ m4_len (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_index (struct obstack *obs, int argc, token_data **argv) +m4_index (struct obstack *obs, int argc, macro_arguments *argv) { const char *haystack; const char *needle; @@ -1801,7 +1831,7 @@ m4_index (struct obstack *obs, int argc, token_data **argv) `-------------------------------------------------------------------------*/ static void -m4_substr (struct obstack *obs, int argc, token_data **argv) +m4_substr (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); int start = 0; @@ -1885,7 +1915,7 @@ expand_ranges (const char *s, struct obstack *obs) `----------------------------------------------------------------------*/ static void -m4_translit (struct obstack *obs, int argc, token_data **argv) +m4_translit (struct obstack *obs, int argc, macro_arguments *argv) { const char *data; const char *from; @@ -1950,7 +1980,7 @@ m4_translit (struct obstack *obs, int argc, token_data **argv) `--------------------------------------------------------------*/ static void -m4_format (struct obstack *obs, int argc, token_data **argv) +m4_format (struct obstack *obs, int argc, macro_arguments *argv) { if (bad_argc (ARG (0), argc, 1, -1)) return; @@ -2047,7 +2077,7 @@ init_pattern_buffer (struct re_pattern_buffer *buf, struct re_registers *regs) `------------------------------------------------------------------*/ static void -m4_regexp (struct obstack *obs, int argc, token_data **argv) +m4_regexp (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); const char *victim; /* first argument */ @@ -2117,7 +2147,7 @@ m4_regexp (struct obstack *obs, int argc, token_data **argv) `------------------------------------------------------------------*/ static void -m4_patsubst (struct obstack *obs, int argc, token_data **argv) +m4_patsubst (struct obstack *obs, int argc, macro_arguments *argv) { const char *me = ARG (0); const char *victim; /* first argument */ @@ -2222,7 +2252,7 @@ m4_patsubst (struct obstack *obs, int argc, token_data **argv) `--------------------------------------------------------------------*/ void -m4_placeholder (struct obstack *obs, int argc, token_data **argv) +m4_placeholder (struct obstack *obs, int argc, macro_arguments *argv) { m4_warn (0, NULL, _("builtin `%s' requested by frozen file not found"), ARG (0)); @@ -2238,7 +2268,7 @@ m4_placeholder (struct obstack *obs, int argc, token_data **argv) void expand_user_macro (struct obstack *obs, symbol *sym, - int argc, token_data **argv) + int argc, macro_arguments *argv) { const char *text; int i; @@ -2263,7 +2293,7 @@ expand_user_macro (struct obstack *obs, symbol *sym, else { for (i = 0; isdigit (to_uchar (*text)); text++) - i = i*10 + (*text - '0'); + i = i * 10 + (*text - '0'); } if (i < argc) obstack_grow (obs, ARG (i), strlen (ARG (i))); @@ -2276,7 +2306,8 @@ expand_user_macro (struct obstack *obs, symbol *sym, case '*': /* all arguments */ case '@': /* ... same, but quoted */ - dump_args (obs, argc, argv, ",", *text == '@'); + /* TODO push a $@ reference. */ + dump_args (obs, 1, argv, ",", *text == '@'); text++; break; diff --git a/src/debug.c b/src/debug.c index c22a482..e5bd280 100644 --- a/src/debug.c +++ b/src/debug.c @@ -362,7 +362,7 @@ trace_prepre (const char *name, int id) `-----------------------------------------------------------------------*/ void -trace_pre (const char *name, int id, int argc, token_data **argv) +trace_pre (const char *name, int id, int argc, macro_arguments *argv) { int i; const builtin *bp; @@ -379,14 +379,14 @@ trace_pre (const char *name, int id, int argc, token_data **argv) if (i != 1) trace_format (", "); - switch (TOKEN_DATA_TYPE (argv[i])) + switch (TOKEN_DATA_TYPE (argv->array[i - 1])) { case TOKEN_TEXT: - trace_format ("%l%S%r", TOKEN_DATA_TEXT (argv[i])); + trace_format ("%l%S%r", TOKEN_DATA_TEXT (argv->array[i - 1])); break; case TOKEN_FUNC: - bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[i])); + bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv->array[i - 1])); if (bp == NULL) { assert (!"trace_pre"); @@ -417,7 +417,7 @@ trace_pre (const char *name, int id, int argc, token_data **argv) `-------------------------------------------------------------------*/ void -trace_post (const char *name, int id, int argc, token_data **argv, +trace_post (const char *name, int id, int argc, macro_arguments *argv, const char *expanded) { if (debug_level & DEBUG_TRACE_CALL) diff --git a/src/format.c b/src/format.c index 96ac562..4c2b60a 100644 --- a/src/format.c +++ b/src/format.c @@ -27,21 +27,17 @@ /* Simple varargs substitute. We assume int and unsigned int are the same size; likewise for long and unsigned long. */ -#define ARG_INT(argc, argv) \ - ((argc == 0) ? 0 : \ - (--argc, argv++, atoi (TOKEN_DATA_TEXT (argv[-1])))) +#define ARG_INT(i, argc, argv) \ + ((i == argc) ? 0 : atoi (TOKEN_DATA_TEXT (argv->array[i++ - 1]))) -#define ARG_LONG(argc, argv) \ - ((argc == 0) ? 0 : \ - (--argc, argv++, atol (TOKEN_DATA_TEXT (argv[-1])))) +#define ARG_LONG(i, argc, argv) \ + ((i == argc) ? 0L : atol (TOKEN_DATA_TEXT (argv->array[i++ - 1]))) -#define ARG_STR(argc, argv) \ - ((argc == 0) ? "" : \ - (--argc, argv++, TOKEN_DATA_TEXT (argv[-1]))) +#define ARG_STR(i, argc, argv) \ + ((i == argc) ? "" : TOKEN_DATA_TEXT (argv->array[i++ - 1])) -#define ARG_DOUBLE(argc, argv) \ - ((argc == 0) ? 0 : \ - (--argc, argv++, atof (TOKEN_DATA_TEXT (argv[-1])))) +#define ARG_DOUBLE(i, argc, argv) \ + ((i == argc) ? 0.0 : atof (TOKEN_DATA_TEXT (argv->array[i++ - 1]))) /*------------------------------------------------------------------. @@ -53,14 +49,15 @@ `------------------------------------------------------------------*/ void -format (struct obstack *obs, int argc, token_data **argv) +format (struct obstack *obs, int argc, macro_arguments *argv) { - const char *me = TOKEN_DATA_TEXT (argv[0]); + const char *me = argv->argv0; const char *f; /* format control string */ const char *fmt; /* position within f */ char fstart[] = "%'+- 0#*.*hhd"; /* current format spec */ char *p; /* position within fstart */ unsigned char c; /* a simple character */ + int index = 1; /* index within argc used so far */ /* Flags. */ char flags; /* flags to use in fstart */ @@ -88,9 +85,7 @@ format (struct obstack *obs, int argc, token_data **argv) char *str; /* malloc'd buffer of formatted text */ enum {CHAR, INT, LONG, DOUBLE, STR} datatype; - argv++; - argc--; - f = fmt = ARG_STR (argc, argv); + f = fmt = ARG_STR (index, argc, argv); memset (ok, 0, sizeof ok); for (;;) { @@ -175,7 +170,7 @@ format (struct obstack *obs, int argc, token_data **argv) *p++ = '*'; if (*fmt == '*') { - width = ARG_INT (argc, argv); + width = ARG_INT (index, argc, argv); fmt++; } else @@ -195,7 +190,7 @@ format (struct obstack *obs, int argc, token_data **argv) ok['c'] = 0; if (*(++fmt) == '*') { - prec = ARG_INT (argc, argv); + prec = ARG_INT (index, argc, argv); ++fmt; } else @@ -280,27 +275,27 @@ format (struct obstack *obs, int argc, token_data **argv) switch (datatype) { case CHAR: - str = xasprintf (fstart, width, ARG_INT(argc, argv)); + str = xasprintf (fstart, width, ARG_INT (index, argc, argv)); break; case INT: - str = xasprintf (fstart, width, prec, ARG_INT(argc, argv)); + str = xasprintf (fstart, width, prec, ARG_INT (index, argc, argv)); break; case LONG: - str = xasprintf (fstart, width, prec, ARG_LONG(argc, argv)); + str = xasprintf (fstart, width, prec, ARG_LONG (index, argc, argv)); break; case DOUBLE: - str = xasprintf (fstart, width, prec, ARG_DOUBLE(argc, argv)); + str = xasprintf (fstart, width, prec, ARG_DOUBLE (index, argc, argv)); break; case STR: - str = xasprintf (fstart, width, prec, ARG_STR(argc, argv)); + str = xasprintf (fstart, width, prec, ARG_STR (index, argc, argv)); break; default: - abort(); + abort (); } /* NULL was returned on failure, such as invalid format string. diff --git a/src/m4.h b/src/m4.h index 4f1fa1f..94276e9 100644 --- a/src/m4.h +++ b/src/m4.h @@ -89,7 +89,8 @@ typedef struct string STRING; /* Those must come first. */ typedef struct token_data token_data; -typedef void builtin_func (struct obstack *, int, token_data **); +typedef struct macro_arguments macro_arguments; +typedef void builtin_func (struct obstack *, int, macro_arguments *); /* Gnulib's stdbool doesn't work with bool bitfields. For nicer debugging, use bool when we know it works, but use the more @@ -103,14 +104,14 @@ typedef unsigned int bool_bitfield; /* Take advantage of GNU C compiler source level optimization hints, using portable macros. */ #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6) -# define M4_GNUC_ATTRIBUTE(args) __attribute__(args) +# define M4_GNUC_ATTRIBUTE(args) __attribute__ (args) #else # define M4_GNUC_ATTRIBUTE(args) #endif /* __GNUC__ */ -#define M4_GNUC_UNUSED M4_GNUC_ATTRIBUTE((__unused__)) +#define M4_GNUC_UNUSED M4_GNUC_ATTRIBUTE ((__unused__)) #define M4_GNUC_PRINTF(fmt, arg) \ - M4_GNUC_ATTRIBUTE((__format__ (__printf__, fmt, arg))) + M4_GNUC_ATTRIBUTE ((__format__ (__printf__, fmt, arg))) /* File: m4.c --- global definitions. */ @@ -132,12 +133,13 @@ extern const char *user_word_regexp; /* -W */ extern int retcode; extern const char *program_name; -void m4_error (int, int, const char *, const char *, ...) M4_GNUC_PRINTF(4, 5); +void m4_error (int, int, const char *, const char *, ...) + M4_GNUC_PRINTF (4, 5); void m4_error_at_line (int, int, const char *, int, const char *, - const char *, ...) M4_GNUC_PRINTF(6, 7); -void m4_warn (int, const char *, const char *, ...) M4_GNUC_PRINTF(3, 4); + const char *, ...) M4_GNUC_PRINTF (6, 7); +void m4_warn (int, const char *, const char *, ...) M4_GNUC_PRINTF (3, 4); void m4_warn_at_line (int, const char *, int, const char *, - const char *, ...) M4_GNUC_PRINTF(5, 6); + const char *, ...) M4_GNUC_PRINTF (5, 6); #ifdef USE_STACKOVF void setup_stackovf_trap (char *const *, char *const *, @@ -235,11 +237,13 @@ bool debug_set_output (const char *, const char *); void debug_message_prefix (void); void trace_prepre (const char *, int); -void trace_pre (const char *, int, int, token_data **); -void trace_post (const char *, int, int, token_data **, const char *); +void trace_pre (const char *, int, int, macro_arguments *); +void trace_post (const char *, int, int, macro_arguments *, const char *); /* File: input.c --- lexical definitions. */ +typedef struct token_chain token_chain; + /* Various different token types. */ enum token_type { @@ -256,9 +260,19 @@ enum token_type /* The data for a token, a macro argument, and a macro definition. */ enum token_data_type { - TOKEN_VOID, - TOKEN_TEXT, - TOKEN_FUNC + TOKEN_VOID, /* Token still being constructed, u is invalid. */ + TOKEN_TEXT, /* Straight text, u.u_t is valid. */ + TOKEN_FUNC, /* Builtin function definition, u.func is valid. */ + TOKEN_COMP /* Composite argument, u.chain is valid. */ +}; + +/* Composite tokens are built of a linked list of chains. */ +struct token_chain +{ + token_chain *next; /* Pointer to next link of chain. */ + char *str; /* NUL-terminated string if text, else NULL. */ + macro_arguments *argv; /* Reference to earlier [EMAIL PROTECTED] */ + unsigned int index; /* Index within argv to start reading from. */ }; struct token_data @@ -275,10 +289,31 @@ struct token_data } u_t; builtin_func *func; + + /* Composite text: a linked list of straight text and $@ + placeholders. */ + token_chain *chain; } u; }; +struct macro_arguments +{ + /* Number of arguments owned by this object, may be larger than + arraylen since the array can refer to multiple arguments via a + single $@ reference. */ + unsigned int argc; + /* False unless the macro expansion refers to $@, determines whether + this object can be freed at end of macro expansion or must wait + until next byte read from file. */ + bool inuse; + const char *argv0; /* The macro name being expanded. */ + size_t arraylen; /* True length of allocated elements in array. */ + /* Used as a variable-length array, storing information about each + argument. */ + token_data *array[FLEXIBLE_ARRAY_MEMBER]; +}; + #define TOKEN_DATA_TYPE(Td) ((Td)->type) #define TOKEN_DATA_TEXT(Td) ((Td)->u.u_t.text) #ifdef ENABLE_CHANGEWORD @@ -358,7 +393,7 @@ struct symbol int pending_expansions; char *name; - token_data data; + token_data data; /* Type should be only TOKEN_TEXT or TOKEN_FUNC. */ }; #define SYMBOL_NEXT(S) ((S)->next) @@ -391,7 +426,7 @@ void hack_all_symbols (hack_symbol *, void *); extern int expansion_level; void expand_input (void); -void call_macro (symbol *, int, token_data **, struct obstack *); +void call_macro (symbol *, int, macro_arguments *, struct obstack *); /* File: builtin.c --- builtins. */ @@ -427,8 +462,8 @@ void set_macro_sequence (const char *); void free_regex (void); void define_user_macro (const char *, const char *, symbol_lookup); void undivert_all (void); -void expand_user_macro (struct obstack *, symbol *, int, token_data **); -void m4_placeholder (struct obstack *, int, token_data **); +void expand_user_macro (struct obstack *, symbol *, int, macro_arguments *); +void m4_placeholder (struct obstack *, int, macro_arguments *); void init_pattern_buffer (struct re_pattern_buffer *, struct re_registers *); const char *ntoa (int32_t, int); @@ -448,7 +483,7 @@ bool evaluate (const char *, const char *, int32_t *); /* File: format.c --- printf like formatting. */ -void format (struct obstack *, int, token_data **); +void format (struct obstack *, int, macro_arguments *); /* File: freeze.c --- frozen state files. */ diff --git a/src/macro.c b/src/macro.c index 8a678d4..d2f2cb7 100644 --- a/src/macro.c +++ b/src/macro.c @@ -241,19 +241,22 @@ expand_argument (struct obstack *obs, token_data *argp, const char *caller) | on the obstack ARGPTR. | `-------------------------------------------------------------------------*/ -static void -collect_arguments (symbol *sym, struct obstack *argptr, +static macro_arguments * +collect_arguments (symbol *sym, struct obstack *argptr, unsigned argv_base, struct obstack *arguments) { token_data td; token_data *tdp; bool more_args; bool groks_macro_args = SYMBOL_MACRO_ARGS (sym); + macro_arguments args; + macro_arguments *argv; - TOKEN_DATA_TYPE (&td) = TOKEN_TEXT; - TOKEN_DATA_TEXT (&td) = SYMBOL_NAME (sym); - tdp = (token_data *) obstack_copy (arguments, &td, sizeof td); - obstack_ptr_grow (argptr, tdp); + args.argc = 1; + args.inuse = false; + args.argv0 = SYMBOL_NAME (sym); + args.arraylen = 0; + obstack_grow (argptr, &args, offsetof (macro_arguments, array)); if (peek_token () == TOKEN_OPEN) { @@ -269,9 +272,15 @@ collect_arguments (symbol *sym, struct obstack *argptr, } tdp = (token_data *) obstack_copy (arguments, &td, sizeof td); obstack_ptr_grow (argptr, tdp); + args.arraylen++; + args.argc++; } while (more_args); } + argv = (macro_arguments *) ((char *) obstack_base (argptr) + argv_base); + argv->argc = args.argc; + argv->arraylen = args.arraylen; + return argv; } @@ -285,13 +294,13 @@ collect_arguments (symbol *sym, struct obstack *argptr, `------------------------------------------------------------------------*/ void -call_macro (symbol *sym, int argc, token_data **argv, - struct obstack *expansion) +call_macro (symbol *sym, int argc, macro_arguments *argv, + struct obstack *expansion) { switch (SYMBOL_TYPE (sym)) { case TOKEN_FUNC: - (*SYMBOL_FUNC (sym)) (expansion, argc, argv); + SYMBOL_FUNC (sym) (expansion, argc, argv); break; case TOKEN_TEXT: @@ -319,8 +328,8 @@ expand_macro (symbol *sym) { struct obstack arguments; /* Alternate obstack if argc_stack is busy. */ unsigned argv_base; /* Size of argv_stack on entry. */ - bool use_argc_stack = true; /* Whether argc_stack is safe. */ - token_data **argv; + void *argc_start; /* Start of argc_stack, else NULL if unsafe. */ + macro_arguments *argv; int argc; struct obstack *expansion; const char *expanded; @@ -357,18 +366,17 @@ expand_macro (symbol *sym) outer invocation has an unfinished argument being collected. */ obstack_init (&arguments); - use_argc_stack = false; + argc_start = NULL; } + else + argc_start = obstack_finish (&argc_stack); if (traced && (debug_level & DEBUG_TRACE_CALL)) trace_prepre (SYMBOL_NAME (sym), my_call_id); - collect_arguments (sym, &argv_stack, - use_argc_stack ? &argc_stack : &arguments); - - argc = ((obstack_object_size (&argv_stack) - argv_base) - / sizeof (token_data *)); - argv = (token_data **) ((char *) obstack_base (&argv_stack) + argv_base); + argv = collect_arguments (sym, &argv_stack, argv_base, + argc_start ? &argc_stack : &arguments); + argc = argv->argc; loc_close_file = current_file; loc_close_line = current_line; @@ -394,9 +402,10 @@ expand_macro (symbol *sym) if (SYMBOL_DELETED (sym)) free_symbol (sym); - if (use_argc_stack) - obstack_free (&argc_stack, argv[0]); + /* TODO pay attention to argv->inuse, in case someone is depending on [EMAIL PROTECTED] */ + if (argc_start) + obstack_free (&argc_stack, argc_start); else obstack_free (&arguments, NULL); - obstack_blank (&argv_stack, -argc * sizeof (token_data *)); + obstack_blank (&argv_stack, argv_base - obstack_object_size (&argv_stack)); } hooks/post-receive -- GNU M4 source repository
