aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/bison
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-05-17 18:21:10 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-05-17 18:31:30 +0300
commit6ca1d898180d9f6a6b4b08ce72607c3d7971f4e9 (patch)
tree865a89ca2e0dbdf633d0138f7d799f6d8ca63f4d /contrib/tools/bison
parentce74f15f22c2159c7fbb402a2804cc463fb7698b (diff)
downloadydb-6ca1d898180d9f6a6b4b08ce72607c3d7971f4e9.tar.gz
Move bison/m4 and bison/induced out of contrib/tools/bison
520961d4315ab4738f60613278b7e63765341b85
Diffstat (limited to 'contrib/tools/bison')
-rw-r--r--contrib/tools/bison/induced/ya.make14
-rw-r--r--contrib/tools/bison/m4/src/builtin.c2258
-rw-r--r--contrib/tools/bison/m4/src/cpp.cpp3
-rw-r--r--contrib/tools/bison/m4/src/debug.c442
-rw-r--r--contrib/tools/bison/m4/src/eval.c855
-rw-r--r--contrib/tools/bison/m4/src/format.c394
-rw-r--r--contrib/tools/bison/m4/src/freeze.c398
-rw-r--r--contrib/tools/bison/m4/src/input.c1156
-rw-r--r--contrib/tools/bison/m4/src/m4.c695
-rw-r--r--contrib/tools/bison/m4/src/m4.h491
-rw-r--r--contrib/tools/bison/m4/src/macro.c391
-rw-r--r--contrib/tools/bison/m4/src/output.c1017
-rw-r--r--contrib/tools/bison/m4/src/path.c205
-rw-r--r--contrib/tools/bison/m4/src/symtab.c401
-rw-r--r--contrib/tools/bison/m4/ya.make36
15 files changed, 0 insertions, 8756 deletions
diff --git a/contrib/tools/bison/induced/ya.make b/contrib/tools/bison/induced/ya.make
deleted file mode 100644
index a6893e34d6..0000000000
--- a/contrib/tools/bison/induced/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-# This is a special library used to induce licenses onto bison-generated code
-# It is intentionally empty.
-
-LIBRARY()
-
-LICENSE(GPL-3.0-or-later WITH Bison-exception-2.2)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
-NO_UTIL()
-
-NO_RUNTIME()
-
-END()
diff --git a/contrib/tools/bison/m4/src/builtin.c b/contrib/tools/bison/m4/src/builtin.c
deleted file mode 100644
index 01ede38017..0000000000
--- a/contrib/tools/bison/m4/src/builtin.c
+++ /dev/null
@@ -1,2258 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2000, 2004, 2006-2013 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Code for all builtin macros, initialization of symbol table, and
- expansion of user defined macros. */
-
-#include "m4.h"
-
-#include "execute.h"
-#include "memchr2.h"
-#include "progname.h"
-#include <contrib/tools/bison/gnulib/src/regex.h>
-#include "spawn-pipe.h"
-#include "wait-process.h"
-
-#define ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
-
-/* 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 **)
-
-DECLARE (m4___file__);
-DECLARE (m4___line__);
-DECLARE (m4___program__);
-DECLARE (m4_builtin);
-DECLARE (m4_changecom);
-DECLARE (m4_changequote);
-#ifdef ENABLE_CHANGEWORD
-DECLARE (m4_changeword);
-#endif
-DECLARE (m4_debugmode);
-DECLARE (m4_debugfile);
-DECLARE (m4_decr);
-DECLARE (m4_define);
-DECLARE (m4_defn);
-DECLARE (m4_divert);
-DECLARE (m4_divnum);
-DECLARE (m4_dnl);
-DECLARE (m4_dumpdef);
-DECLARE (m4_errprint);
-DECLARE (m4_esyscmd);
-DECLARE (m4_eval);
-DECLARE (m4_format);
-DECLARE (m4_ifdef);
-DECLARE (m4_ifelse);
-DECLARE (m4_include);
-DECLARE (m4_incr);
-DECLARE (m4_index);
-DECLARE (m4_indir);
-DECLARE (m4_len);
-DECLARE (m4_m4exit);
-DECLARE (m4_m4wrap);
-DECLARE (m4_maketemp);
-DECLARE (m4_mkstemp);
-DECLARE (m4_patsubst);
-DECLARE (m4_popdef);
-DECLARE (m4_pushdef);
-DECLARE (m4_regexp);
-DECLARE (m4_shift);
-DECLARE (m4_sinclude);
-DECLARE (m4_substr);
-DECLARE (m4_syscmd);
-DECLARE (m4_sysval);
-DECLARE (m4_traceoff);
-DECLARE (m4_traceon);
-DECLARE (m4_translit);
-DECLARE (m4_undefine);
-DECLARE (m4_undivert);
-
-#undef DECLARE
-
-static builtin const builtin_tab[] =
-{
-
- /* name GNUext macros blind function */
-
- { "__file__", true, false, false, m4___file__ },
- { "__line__", true, false, false, m4___line__ },
- { "__program__", true, false, false, m4___program__ },
- { "builtin", true, true, true, m4_builtin },
- { "changecom", false, false, false, m4_changecom },
- { "changequote", false, false, false, m4_changequote },
-#ifdef ENABLE_CHANGEWORD
- { "changeword", true, false, true, m4_changeword },
-#endif
- { "debugmode", true, false, false, m4_debugmode },
- { "debugfile", true, false, false, m4_debugfile },
- { "decr", false, false, true, m4_decr },
- { "define", false, true, true, m4_define },
- { "defn", false, false, true, m4_defn },
- { "divert", false, false, false, m4_divert },
- { "divnum", false, false, false, m4_divnum },
- { "dnl", false, false, false, m4_dnl },
- { "dumpdef", false, false, false, m4_dumpdef },
- { "errprint", false, false, true, m4_errprint },
- { "esyscmd", true, false, true, m4_esyscmd },
- { "eval", false, false, true, m4_eval },
- { "format", true, false, true, m4_format },
- { "ifdef", false, false, true, m4_ifdef },
- { "ifelse", false, false, true, m4_ifelse },
- { "include", false, false, true, m4_include },
- { "incr", false, false, true, m4_incr },
- { "index", false, false, true, m4_index },
- { "indir", true, true, true, m4_indir },
- { "len", false, false, true, m4_len },
- { "m4exit", false, false, false, m4_m4exit },
- { "m4wrap", false, false, true, m4_m4wrap },
- { "maketemp", false, false, true, m4_maketemp },
- { "mkstemp", false, false, true, m4_mkstemp },
- { "patsubst", true, false, true, m4_patsubst },
- { "popdef", false, false, true, m4_popdef },
- { "pushdef", false, true, true, m4_pushdef },
- { "regexp", true, false, true, m4_regexp },
- { "shift", false, false, true, m4_shift },
- { "sinclude", false, false, true, m4_sinclude },
- { "substr", false, false, true, m4_substr },
- { "syscmd", false, false, true, m4_syscmd },
- { "sysval", false, false, false, m4_sysval },
- { "traceoff", false, false, false, m4_traceoff },
- { "traceon", false, false, false, m4_traceon },
- { "translit", false, false, true, m4_translit },
- { "undefine", false, false, true, m4_undefine },
- { "undivert", false, false, false, m4_undivert },
-
- { 0, false, false, false, 0 },
-
- /* placeholder is intentionally stuck after the table end delimiter,
- so that we can easily find it, while not treating it as a real
- builtin. */
- { "placeholder", true, false, false, m4_placeholder },
-};
-
-static predefined const predefined_tab[] =
-{
-#if UNIX
- { "unix", "__unix__", "" },
-#endif
-#if W32_NATIVE
- { "windows", "__windows__", "" },
-#endif
-#if OS2
- { "os2", "__os2__", "" },
-#endif
-#if !UNIX && !W32_NATIVE && !OS2
-# warning Platform macro not provided
-#endif
- { NULL, "__gnu__", "" },
-
- { NULL, NULL, NULL },
-};
-
-/*----------------------------------------.
-| Find the builtin, which lives on ADDR. |
-`----------------------------------------*/
-
-const builtin * M4_GNUC_PURE
-find_builtin_by_addr (builtin_func *func)
-{
- const builtin *bp;
-
- for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
- if (bp->func == func)
- return bp;
- if (func == m4_placeholder)
- return bp + 1;
- return NULL;
-}
-
-/*----------------------------------------------------------.
-| Find the builtin, which has NAME. On failure, return the |
-| placeholder builtin. |
-`----------------------------------------------------------*/
-
-const builtin * M4_GNUC_PURE
-find_builtin_by_name (const char *name)
-{
- const builtin *bp;
-
- for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
- if (STREQ (bp->name, name))
- return bp;
- return bp + 1;
-}
-
-/*----------------------------------------------------------------.
-| Install a builtin macro with name NAME, bound to the C function |
-| given in BP. MODE is SYMBOL_INSERT or SYMBOL_PUSHDEF. |
-`----------------------------------------------------------------*/
-
-void
-define_builtin (const char *name, const builtin *bp, symbol_lookup mode)
-{
- symbol *sym;
-
- sym = lookup_symbol (name, mode);
- SYMBOL_TYPE (sym) = TOKEN_FUNC;
- SYMBOL_MACRO_ARGS (sym) = bp->groks_macro_args;
- SYMBOL_BLIND_NO_ARGS (sym) = bp->blind_if_no_args;
- SYMBOL_FUNC (sym) = bp->func;
-}
-
-/* Storage for the compiled regular expression of
- --warn-macro-sequence. */
-static struct re_pattern_buffer macro_sequence_buf;
-
-/* Storage for the matches of --warn-macro-sequence. */
-static struct re_registers macro_sequence_regs;
-
-/* True if --warn-macro-sequence is in effect. */
-static bool macro_sequence_inuse;
-
-/*----------------------------------------.
-| Clean up regular expression variables. |
-`----------------------------------------*/
-
-static void
-free_pattern_buffer (struct re_pattern_buffer *buf, struct re_registers *regs)
-{
- regfree (buf);
- free (regs->start);
- free (regs->end);
-}
-
-/*-----------------------------------------------------------------.
-| Set the regular expression of --warn-macro-sequence that will be |
-| checked during define and pushdef. Exit on failure. |
-`-----------------------------------------------------------------*/
-void
-set_macro_sequence (const char *regexp)
-{
- const char *msg;
-
- if (! regexp)
- regexp = DEFAULT_MACRO_SEQUENCE;
- else if (regexp[0] == '\0')
- {
- macro_sequence_inuse = false;
- return;
- }
-
- msg = re_compile_pattern (regexp, strlen (regexp), &macro_sequence_buf);
- if (msg != NULL)
- {
- M4ERROR ((EXIT_FAILURE, 0,
- "--warn-macro-sequence: bad regular expression `%s': %s",
- regexp, msg));
- }
- re_set_registers (&macro_sequence_buf, &macro_sequence_regs,
- macro_sequence_regs.num_regs,
- macro_sequence_regs.start, macro_sequence_regs.end);
- macro_sequence_inuse = true;
-}
-
-/*-----------------------------------------------------------.
-| Free dynamic memory utilized by the macro sequence regular |
-| expression during the define builtin. |
-`-----------------------------------------------------------*/
-void
-free_macro_sequence (void)
-{
- free_pattern_buffer (&macro_sequence_buf, &macro_sequence_regs);
-}
-
-/*-----------------------------------------------------------------.
-| Define a predefined or user-defined macro, with name NAME, and |
-| expansion TEXT. MODE destinguishes between the "define" and the |
-| "pushdef" case. It is also used from main. |
-`-----------------------------------------------------------------*/
-
-void
-define_user_macro (const char *name, const char *text, symbol_lookup mode)
-{
- symbol *s;
- char *defn = xstrdup (text ? text : "");
-
- s = lookup_symbol (name, mode);
- if (SYMBOL_TYPE (s) == TOKEN_TEXT)
- free (SYMBOL_TEXT (s));
-
- SYMBOL_TYPE (s) = TOKEN_TEXT;
- SYMBOL_TEXT (s) = defn;
-
- /* Implement --warn-macro-sequence. */
- if (macro_sequence_inuse && text)
- {
- regoff_t offset = 0;
- size_t len = strlen (defn);
-
- while ((offset = re_search (&macro_sequence_buf, defn, len, offset,
- len - offset, &macro_sequence_regs)) >= 0)
- {
- /* Skip empty matches. */
- if (macro_sequence_regs.start[0] == macro_sequence_regs.end[0])
- offset++;
- else
- {
- char tmp;
- offset = macro_sequence_regs.end[0];
- tmp = defn[offset];
- defn[offset] = '\0';
- M4ERROR ((warning_status, 0,
- "Warning: definition of `%s' contains sequence `%s'",
- name, defn + macro_sequence_regs.start[0]));
- defn[offset] = tmp;
- }
- }
- if (offset == -2)
- M4ERROR ((warning_status, 0,
- "error checking --warn-macro-sequence for macro `%s'",
- name));
- }
-}
-
-/*-----------------------------------------------.
-| Initialize all builtin and predefined macros. |
-`-----------------------------------------------*/
-
-void
-builtin_init (void)
-{
- const builtin *bp;
- const predefined *pp;
- char *string;
-
- for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
- if (!no_gnu_extensions || !bp->gnu_extension)
- {
- if (prefix_all_builtins)
- {
- string = (char *) xmalloc (strlen (bp->name) + 4);
- strcpy (string, "m4_");
- strcat (string, bp->name);
- define_builtin (string, bp, SYMBOL_INSERT);
- free (string);
- }
- else
- define_builtin (bp->name, bp, SYMBOL_INSERT);
- }
-
- for (pp = &predefined_tab[0]; pp->func != NULL; pp++)
- if (no_gnu_extensions)
- {
- if (pp->unix_name != NULL)
- define_user_macro (pp->unix_name, pp->func, SYMBOL_INSERT);
- }
- else
- {
- if (pp->gnu_name != NULL)
- define_user_macro (pp->gnu_name, pp->func, SYMBOL_INSERT);
- }
-}
-
-/*-------------------------------------------------------------------.
-| Give friendly warnings if a builtin macro is passed an |
-| inappropriate number of arguments. NAME is the macro name for |
-| messages, ARGC is actual number of arguments, MIN is the minimum |
-| number of acceptable arguments, negative if not applicable, MAX is |
-| the maximum number, negative if not applicable. |
-`-------------------------------------------------------------------*/
-
-static bool
-bad_argc (token_data *name, int argc, int min, int max)
-{
- bool isbad = false;
-
- if (min > 0 && argc < min)
- {
- if (!suppress_warnings)
- M4ERROR ((warning_status, 0,
- "Warning: too few arguments to builtin `%s'",
- TOKEN_DATA_TEXT (name)));
- isbad = true;
- }
- else if (max > 0 && argc > max && !suppress_warnings)
- M4ERROR ((warning_status, 0,
- "Warning: excess arguments to builtin `%s' ignored",
- TOKEN_DATA_TEXT (name)));
-
- return isbad;
-}
-
-/*-----------------------------------------------------------------.
-| The function numeric_arg () converts ARG to an int pointed to by |
-| VALUEP. If the conversion fails, print error message for macro |
-| MACRO. Return true iff conversion succeeds. |
-`-----------------------------------------------------------------*/
-
-static bool
-numeric_arg (token_data *macro, const char *arg, int *valuep)
-{
- char *endp;
-
- if (*arg == '\0')
- {
- *valuep = 0;
- M4ERROR ((warning_status, 0,
- "empty string treated as 0 in builtin `%s'",
- TOKEN_DATA_TEXT (macro)));
- }
- else
- {
- errno = 0;
- *valuep = strtol (arg, &endp, 10);
- if (*endp != '\0')
- {
- M4ERROR ((warning_status, 0,
- "non-numeric argument to builtin `%s'",
- TOKEN_DATA_TEXT (macro)));
- return false;
- }
- if (isspace (to_uchar (*arg)))
- M4ERROR ((warning_status, 0,
- "leading whitespace ignored in builtin `%s'",
- TOKEN_DATA_TEXT (macro)));
- else if (errno == ERANGE)
- M4ERROR ((warning_status, 0,
- "numeric overflow detected in builtin `%s'",
- TOKEN_DATA_TEXT (macro)));
- }
- return true;
-}
-
-/*------------------------------------------------------.
-| The function ntoa () converts VALUE to a signed ASCII |
-| representation in radix RADIX. |
-`------------------------------------------------------*/
-
-/* Digits for number to ASCII conversions. */
-static char const digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-
-const char *
-ntoa (int32_t value, int radix)
-{
- bool negative;
- uint32_t uvalue;
- static char str[256];
- char *s = &str[sizeof str];
-
- *--s = '\0';
-
- if (value < 0)
- {
- negative = true;
- uvalue = -(uint32_t) value;
- }
- else
- {
- negative = false;
- uvalue = (uint32_t) value;
- }
-
- do
- {
- *--s = digits[uvalue % radix];
- uvalue /= radix;
- }
- while (uvalue > 0);
-
- if (negative)
- *--s = '-';
- return s;
-}
-
-/*---------------------------------------------------------------.
-| Format an int VAL, and stuff it into an obstack OBS. Used for |
-| macros expanding to numbers. |
-`---------------------------------------------------------------*/
-
-static void
-shipout_int (struct obstack *obs, int val)
-{
- const char *s;
-
- s = ntoa ((int32_t) val, 10);
- obstack_grow (obs, s, strlen (s));
-}
-
-/*-------------------------------------------------------------------.
-| Print ARGC arguments from the table ARGV to obstack OBS, separated |
-| by SEP, and quoted by the current quotes if QUOTED is true. |
-`-------------------------------------------------------------------*/
-
-static void
-dump_args (struct obstack *obs, int argc, token_data **argv,
- const char *sep, bool quoted)
-{
- int i;
- size_t len = strlen (sep);
-
- for (i = 1; i < argc; i++)
- {
- if (i > 1)
- obstack_grow (obs, sep, len);
- if (quoted)
- obstack_grow (obs, lquote.string, lquote.length);
- obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
- strlen (TOKEN_DATA_TEXT (argv[i])));
- if (quoted)
- obstack_grow (obs, rquote.string, rquote.length);
- }
-}
-
-/* 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[]);
-
- 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 first section are macros for definining, undefining, examining,
- changing, ... other macros. */
-
-/*-------------------------------------------------------------------.
-| The function define_macro is common for the builtins "define", |
-| "undefine", "pushdef" and "popdef". ARGC and ARGV is as for the |
-| caller, and MODE argument determines how the macro name is entered |
-| into the symbol table. |
-`-------------------------------------------------------------------*/
-
-static void
-define_macro (int argc, token_data **argv, symbol_lookup mode)
-{
- const builtin *bp;
-
- if (bad_argc (argv[0], argc, 2, 3))
- return;
-
- if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
- {
- M4ERROR ((warning_status, 0,
- "Warning: %s: invalid macro name ignored", ARG (0)));
- return;
- }
-
- if (argc == 2)
- {
- define_user_macro (ARG (1), "", mode);
- return;
- }
-
- switch (TOKEN_DATA_TYPE (argv[2]))
- {
- 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]));
- if (bp == NULL)
- return;
- else
- define_builtin (ARG (1), bp, mode);
- break;
-
- case TOKEN_VOID:
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad token data type in define_macro ()"));
- abort ();
- }
-}
-
-static void
-m4_define (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- define_macro (argc, argv, SYMBOL_INSERT);
-}
-
-static void
-m4_undefine (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- int i;
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- for (i = 1; i < argc; i++)
- lookup_symbol (ARG (i), SYMBOL_DELETE);
-}
-
-static void
-m4_pushdef (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- define_macro (argc, argv, SYMBOL_PUSHDEF);
-}
-
-static void
-m4_popdef (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- int i;
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- for (i = 1; i < argc; i++)
- lookup_symbol (ARG (i), SYMBOL_POPDEF);
-}
-
-/*---------------------.
-| Conditionals of m4. |
-`---------------------*/
-
-static void
-m4_ifdef (struct obstack *obs, int argc, token_data **argv)
-{
- symbol *s;
- const char *result;
-
- if (bad_argc (argv[0], argc, 3, 4))
- return;
- s = lookup_symbol (ARG (1), SYMBOL_LOOKUP);
-
- if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
- result = ARG (2);
- else if (argc >= 4)
- result = ARG (3);
- else
- result = NULL;
-
- if (result != NULL)
- obstack_grow (obs, result, strlen (result));
-}
-
-static void
-m4_ifelse (struct obstack *obs, int argc, token_data **argv)
-{
- const char *result;
- token_data *me = argv[0];
-
- if (argc == 2)
- return;
-
- if (bad_argc (me, argc, 4, -1))
- return;
- else
- /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments. */
- bad_argc (me, (argc + 2) % 3, -1, 1);
-
- argv++;
- argc--;
-
- result = NULL;
- while (result == NULL)
-
- if (STREQ (ARG (0), ARG (1)))
- result = ARG (2);
-
- else
- switch (argc)
- {
- case 3:
- return;
-
- case 4:
- case 5:
- result = ARG (3);
- break;
-
- default:
- argc -= 3;
- argv += 3;
- }
-
- obstack_grow (obs, result, strlen (result));
-}
-
-/*-------------------------------------------------------------------.
-| The function dump_symbol () is for use by "dumpdef". It builds up |
-| a table of all defined, un-shadowed, symbols. |
-`-------------------------------------------------------------------*/
-
-/* The structure dump_symbol_data is used to pass the information needed
- from call to call to dump_symbol. */
-
-struct dump_symbol_data
-{
- struct obstack *obs; /* obstack for table */
- symbol **base; /* base of table */
- int size; /* size of table */
-};
-
-static void
-dump_symbol (symbol *sym, void *arg)
-{
- struct dump_symbol_data *data = (struct dump_symbol_data *) arg;
- if (!SYMBOL_SHADOWED (sym) && SYMBOL_TYPE (sym) != TOKEN_VOID)
- {
- obstack_blank (data->obs, sizeof (symbol *));
- data->base = (symbol **) obstack_base (data->obs);
- data->base[data->size++] = sym;
- }
-}
-
-/*------------------------------------------------------------------------.
-| qsort comparison routine, for sorting the table made in m4_dumpdef (). |
-`------------------------------------------------------------------------*/
-
-static int
-dumpdef_cmp (const void *s1, const void *s2)
-{
- return strcmp (SYMBOL_NAME (* (symbol *const *) s1),
- SYMBOL_NAME (* (symbol *const *) s2));
-}
-
-/*-------------------------------------------------------------.
-| Implementation of "dumpdef" itself. It builds up a table of |
-| pointers to symbols, sorts it and prints the sorted table. |
-`-------------------------------------------------------------*/
-
-static void
-m4_dumpdef (struct obstack *obs, int argc, token_data **argv)
-{
- symbol *s;
- int i;
- struct dump_symbol_data data;
- const builtin *bp;
-
- data.obs = obs;
- data.base = (symbol **) obstack_base (obs);
- data.size = 0;
-
- if (argc == 1)
- {
- hack_all_symbols (dump_symbol, &data);
- }
- else
- {
- for (i = 1; i < argc; i++)
- {
- s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
- if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
- dump_symbol (s, &data);
- else
- M4ERROR ((warning_status, 0,
- "undefined macro `%s'", TOKEN_DATA_TEXT (argv[i])));
- }
- }
-
- /* Make table of symbols invisible to expand_macro (). */
-
- obstack_finish (obs);
-
- qsort (data.base, data.size, sizeof (symbol *), dumpdef_cmp);
-
- for (; data.size > 0; --data.size, data.base++)
- {
- DEBUG_PRINT1 ("%s:\t", SYMBOL_NAME (data.base[0]));
-
- switch (SYMBOL_TYPE (data.base[0]))
- {
- case TOKEN_TEXT:
- if (debug_level & DEBUG_TRACE_QUOTE)
- DEBUG_PRINT3 ("%s%s%s\n",
- lquote.string, SYMBOL_TEXT (data.base[0]), rquote.string);
- else
- DEBUG_PRINT1 ("%s\n", SYMBOL_TEXT (data.base[0]));
- break;
-
- case TOKEN_FUNC:
- bp = find_builtin_by_addr (SYMBOL_FUNC (data.base[0]));
- if (bp == NULL)
- {
- M4ERROR ((warning_status, 0, "\
-INTERNAL ERROR: builtin not found in builtin table"));
- abort ();
- }
- DEBUG_PRINT1 ("<%s>\n", bp->name);
- break;
-
- case TOKEN_VOID:
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad token data type in m4_dumpdef ()"));
- abort ();
- break;
- }
- }
-}
-
-/*-----------------------------------------------------------------.
-| The builtin "builtin" allows calls to builtin macros, even if |
-| their definition has been overridden or shadowed. It is thus |
-| possible to redefine builtins, and still access their original |
-| definition. This macro is not available in compatibility mode. |
-`-----------------------------------------------------------------*/
-
-static void
-m4_builtin (struct obstack *obs, int argc, token_data **argv)
-{
- const builtin *bp;
- const char *name;
-
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
- {
- M4ERROR ((warning_status, 0,
- "Warning: %s: invalid macro name ignored", ARG (0)));
- return;
- }
-
- name = ARG (1);
- bp = find_builtin_by_name (name);
- if (bp->func == m4_placeholder)
- M4ERROR ((warning_status, 0,
- "undefined builtin `%s'", name));
- else
- {
- int i;
- if (! bp->groks_macro_args)
- for (i = 2; i < argc; i++)
- if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT)
- {
- TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT;
- TOKEN_DATA_TEXT (argv[i]) = (char *) "";
- }
- bp->func (obs, argc - 1, argv + 1);
- }
-}
-
-/*-------------------------------------------------------------------.
-| The builtin "indir" allows indirect calls to macros, even if their |
-| name is not a proper macro name. It is thus possible to define |
-| macros with ill-formed names for internal use in larger macro |
-| packages. This macro is not available in compatibility mode. |
-`-------------------------------------------------------------------*/
-
-static void
-m4_indir (struct obstack *obs, int argc, token_data **argv)
-{
- symbol *s;
- const char *name;
-
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
- {
- M4ERROR ((warning_status, 0,
- "Warning: %s: invalid macro name ignored", ARG (0)));
- return;
- }
-
- name = ARG (1);
- s = lookup_symbol (name, SYMBOL_LOOKUP);
- if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
- M4ERROR ((warning_status, 0,
- "undefined macro `%s'", name));
- else
- {
- int i;
- if (! SYMBOL_MACRO_ARGS (s))
- for (i = 2; i < argc; i++)
- if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT)
- {
- TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT;
- TOKEN_DATA_TEXT (argv[i]) = (char *) "";
- }
- call_macro (s, argc - 1, argv + 1, obs);
- }
-}
-
-/*------------------------------------------------------------------.
-| The macro "defn" returns the quoted definition of the macro named |
-| by the first argument. If the macro is builtin, it will push a |
-| special macro-definition token on the input stack. |
-`------------------------------------------------------------------*/
-
-static void
-m4_defn (struct obstack *obs, int argc, token_data **argv)
-{
- symbol *s;
- builtin_func *b;
- unsigned int i;
-
- if (bad_argc (argv[0], argc, 2, -1))
- return;
-
- assert (0 < argc);
- for (i = 1; i < (unsigned) argc; i++)
- {
- const char *arg = ARG((int) i);
- s = lookup_symbol (arg, SYMBOL_LOOKUP);
- if (s == NULL)
- continue;
-
- switch (SYMBOL_TYPE (s))
- {
- case TOKEN_TEXT:
- obstack_grow (obs, lquote.string, lquote.length);
- obstack_grow (obs, SYMBOL_TEXT (s), strlen (SYMBOL_TEXT (s)));
- obstack_grow (obs, rquote.string, rquote.length);
- break;
-
- case TOKEN_FUNC:
- b = SYMBOL_FUNC (s);
- if (b == m4_placeholder)
- M4ERROR ((warning_status, 0, "\
-builtin `%s' requested by frozen file is not supported", arg));
- else if (argc != 2)
- M4ERROR ((warning_status, 0,
- "Warning: cannot concatenate builtin `%s'",
- arg));
- else
- push_macro (b);
- break;
-
- case TOKEN_VOID:
- /* Nothing to do for traced but undefined macro. */
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad symbol type in m4_defn ()"));
- abort ();
- }
- }
-}
-
-/*--------------------------------------------------------------.
-| This section contains macros to handle the builtins "syscmd", |
-| "esyscmd" and "sysval". "esyscmd" is GNU specific. |
-`--------------------------------------------------------------*/
-
-/* Exit code from last "syscmd" command. */
-static int sysval;
-
-static void
-m4_syscmd (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- const char *cmd = ARG (1);
- int status;
- int sig_status;
- const char *prog_args[4] = { "sh", "-c" };
- if (bad_argc (argv[0], argc, 2, 2) || !*cmd)
- {
- /* The empty command is successful. */
- sysval = 0;
- return;
- }
-
- debug_flush_files ();
-#if W32_NATIVE
- if (strstr (SYSCMD_SHELL, "cmd"))
- {
- prog_args[0] = "cmd";
- prog_args[1] = "/c";
- }
-#endif
- prog_args[2] = cmd;
- errno = 0;
- status = execute (ARG (0), SYSCMD_SHELL, (char **) prog_args, false,
- false, false, false, true, false, &sig_status);
- if (sig_status)
- {
- assert (status == 127);
- sysval = sig_status << 8;
- }
- else
- {
- if (status == 127 && errno)
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
- sysval = status;
- }
-}
-
-static void
-m4_esyscmd (struct obstack *obs, int argc, token_data **argv)
-{
- const char *cmd = ARG (1);
- const char *prog_args[4] = { "sh", "-c" };
- pid_t child;
- int fd;
- FILE *pin;
- int status;
- int sig_status;
-
- if (bad_argc (argv[0], argc, 2, 2) || !*cmd)
- {
- /* The empty command is successful. */
- sysval = 0;
- return;
- }
-
- debug_flush_files ();
-#if W32_NATIVE
- if (strstr (SYSCMD_SHELL, "cmd"))
- {
- prog_args[0] = "cmd";
- prog_args[1] = "/c";
- }
-#endif
- prog_args[2] = cmd;
- errno = 0;
- child = create_pipe_in (ARG (0), SYSCMD_SHELL, (char **) prog_args,
- NULL, false, true, false, &fd);
- if (child == -1)
- {
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
- sysval = 127;
- return;
- }
- pin = fdopen (fd, "r");
- if (pin == NULL)
- {
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
- sysval = 127;
- close (fd);
- return;
- }
- while (1)
- {
- size_t avail = obstack_room (obs);
- size_t len;
- if (!avail)
- {
- int ch = getc (pin);
- if (ch == EOF)
- break;
- obstack_1grow (obs, ch);
- continue;
- }
- len = fread (obstack_next_free (obs), 1, avail, pin);
- if (len <= 0)
- break;
- obstack_blank_fast (obs, len);
- }
- if (ferror (pin) || fclose (pin))
- M4ERROR ((EXIT_FAILURE, errno, "cannot read pipe"));
- errno = 0;
- status = wait_subprocess (child, ARG (0), false, true, true, false,
- &sig_status);
- if (sig_status)
- {
- assert (status == 127);
- sysval = sig_status << 8;
- }
- else
- {
- if (status == 127 && errno)
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
- sysval = status;
- }
-}
-
-static void
-m4_sysval (struct obstack *obs, int argc M4_GNUC_UNUSED,
- token_data **argv M4_GNUC_UNUSED)
-{
- shipout_int (obs, sysval);
-}
-
-/*------------------------------------------------------------------.
-| This section contains the top level code for the "eval" builtin. |
-| The actual work is done in the function evaluate (), which lives |
-| in eval.c. |
-`------------------------------------------------------------------*/
-
-static void
-m4_eval (struct obstack *obs, int argc, token_data **argv)
-{
- int32_t value = 0;
- int radix = 10;
- int min = 1;
- const char *s;
-
- if (bad_argc (argv[0], argc, 2, 4))
- return;
-
- if (*ARG (2) && !numeric_arg (argv[0], ARG (2), &radix))
- return;
-
- if (radix < 1 || radix > (int) strlen (digits))
- {
- M4ERROR ((warning_status, 0,
- "radix %d in builtin `%s' out of range",
- radix, ARG (0)));
- return;
- }
-
- if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &min))
- return;
- if (min < 0)
- {
- M4ERROR ((warning_status, 0,
- "negative width to builtin `%s'", ARG (0)));
- return;
- }
-
- if (!*ARG (1))
- M4ERROR ((warning_status, 0,
- "empty string treated as 0 in builtin `%s'", ARG (0)));
- else if (evaluate (ARG (1), &value))
- return;
-
- if (radix == 1)
- {
- if (value < 0)
- {
- obstack_1grow (obs, '-');
- value = -value;
- }
- /* This assumes 2's-complement for correctly handling INT_MIN. */
- while (min-- - value > 0)
- obstack_1grow (obs, '0');
- while (value-- != 0)
- obstack_1grow (obs, '1');
- obstack_1grow (obs, '\0');
- return;
- }
-
- s = ntoa (value, radix);
-
- if (*s == '-')
- {
- obstack_1grow (obs, '-');
- s++;
- }
- for (min -= strlen (s); --min >= 0;)
- obstack_1grow (obs, '0');
-
- obstack_grow (obs, s, strlen (s));
-}
-
-static void
-m4_incr (struct obstack *obs, int argc, token_data **argv)
-{
- int value;
-
- if (bad_argc (argv[0], argc, 2, 2))
- return;
-
- if (!numeric_arg (argv[0], ARG (1), &value))
- return;
-
- shipout_int (obs, value + 1);
-}
-
-static void
-m4_decr (struct obstack *obs, int argc, token_data **argv)
-{
- int value;
-
- if (bad_argc (argv[0], argc, 2, 2))
- return;
-
- if (!numeric_arg (argv[0], ARG (1), &value))
- return;
-
- shipout_int (obs, value - 1);
-}
-
-/* This section contains the macros "divert", "undivert" and "divnum" for
- handling diversion. The utility functions used lives in output.c. */
-
-/*-----------------------------------------------------------------.
-| Divert further output to the diversion given by ARGV[1]. Out of |
-| range means discard further output. |
-`-----------------------------------------------------------------*/
-
-static void
-m4_divert (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- int i = 0;
-
- if (bad_argc (argv[0], argc, 1, 2))
- return;
-
- if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &i))
- return;
-
- make_diversion (i);
-}
-
-/*-----------------------------------------------------.
-| Expand to the current diversion number, -1 if none. |
-`-----------------------------------------------------*/
-
-static void
-m4_divnum (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 1))
- return;
- shipout_int (obs, current_diversion);
-}
-
-/*------------------------------------------------------------------.
-| Bring back the diversion given by the argument list. If none is |
-| specified, bring back all diversions. GNU specific is the option |
-| of undiverting named files, by passing a non-numeric argument to |
-| undivert (). |
-`------------------------------------------------------------------*/
-
-static void
-m4_undivert (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- int i, file;
- FILE *fp;
- char *endp;
-
- if (argc == 1)
- undivert_all ();
- else
- for (i = 1; i < argc; i++)
- {
- file = strtol (ARG (i), &endp, 10);
- if (*endp == '\0' && !isspace (to_uchar (*ARG (i))))
- insert_diversion (file);
- else if (no_gnu_extensions)
- M4ERROR ((warning_status, 0,
- "non-numeric argument to builtin `%s'", ARG (0)));
- else
- {
- fp = m4_path_search (ARG (i), NULL);
- if (fp != NULL)
- {
- insert_file (fp);
- if (fclose (fp) == EOF)
- M4ERROR ((warning_status, errno,
- "error undiverting `%s'", ARG (i)));
- }
- else
- M4ERROR ((warning_status, errno,
- "cannot undivert `%s'", ARG (i)));
- }
- }
-}
-
-/* This section contains various macros, which does not fall into any
- specific group. These are "dnl", "shift", "changequote", "changecom"
- and "changeword". */
-
-/*-----------------------------------------------------------.
-| Delete all subsequent whitespace from input. The function |
-| skip_line () lives in input.c. |
-`-----------------------------------------------------------*/
-
-static void
-m4_dnl (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 1))
- return;
-
- skip_line ();
-}
-
-/*--------------------------------------------------------------------.
-| Shift all arguments one to the left, discarding the first |
-| argument. Each output argument is quoted with the current quotes. |
-`--------------------------------------------------------------------*/
-
-static void
-m4_shift (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- dump_args (obs, argc - 1, argv + 1, ",", true);
-}
-
-/*--------------------------------------------------------------------------.
-| Change the current quotes. The function set_quotes () lives in input.c. |
-`--------------------------------------------------------------------------*/
-
-static void
-m4_changequote (struct obstack *obs M4_GNUC_UNUSED, int argc,
- token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 3))
- return;
-
- /* Explicit NULL distinguishes between empty and missing argument. */
- set_quotes ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
- (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
-}
-
-/*-----------------------------------------------------------------.
-| Change the current comment delimiters. The function set_comment |
-| () lives in input.c. |
-`-----------------------------------------------------------------*/
-
-static void
-m4_changecom (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 3))
- return;
-
- /* Explicit NULL distinguishes between empty and missing argument. */
- set_comment ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
- (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
-}
-
-#ifdef ENABLE_CHANGEWORD
-
-/*---------------------------------------------------------------.
-| Change the regular expression used for breaking the input into |
-| words. The function set_word_regexp () lives in input.c. |
-`---------------------------------------------------------------*/
-
-static void
-m4_changeword (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, 2))
- return;
-
- set_word_regexp (TOKEN_DATA_TEXT (argv[1]));
-}
-
-#endif /* ENABLE_CHANGEWORD */
-
-/* This section contains macros for inclusion of other files -- "include"
- and "sinclude". This differs from bringing back diversions, in that
- the input is scanned before being copied to the output. */
-
-/*---------------------------------------------------------------.
-| Generic include function. Include the file given by the first |
-| argument, if it exists. Complain about inaccessible files iff |
-| SILENT is false. |
-`---------------------------------------------------------------*/
-
-static void
-include (int argc, token_data **argv, bool silent)
-{
- FILE *fp;
- char *name;
-
- if (bad_argc (argv[0], argc, 2, 2))
- return;
-
- fp = m4_path_search (ARG (1), &name);
- if (fp == NULL)
- {
- if (!silent)
- {
- M4ERROR ((warning_status, errno, "cannot open `%s'", ARG (1)));
- retcode = EXIT_FAILURE;
- }
- return;
- }
-
- push_file (fp, name, true);
- free (name);
-}
-
-/*------------------------------------------------.
-| Include a file, complaining in case of errors. |
-`------------------------------------------------*/
-
-static void
-m4_include (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- include (argc, argv, false);
-}
-
-/*----------------------------------.
-| Include a file, ignoring errors. |
-`----------------------------------*/
-
-static void
-m4_sinclude (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- include (argc, argv, true);
-}
-
-/* More miscellaneous builtins -- "maketemp", "errprint", "__file__",
- "__line__", and "__program__". The last three are GNU specific. */
-
-/*------------------------------------------------------------------.
-| Use the first argument as at template for a temporary file name. |
-`------------------------------------------------------------------*/
-
-/* Add trailing 'X' to PATTERN of length LEN as necessary, then
- securely create the file, and place the quoted new file name on
- OBS. Report errors on behalf of ME. */
-static void
-mkstemp_helper (struct obstack *obs, const char *me, const char *pattern,
- size_t len)
-{
- int fd;
- size_t i;
- char *name;
-
- /* Guarantee that there are six trailing 'X' characters, even if the
- user forgot to supply them. Output must be quoted if
- successful. */
- obstack_grow (obs, lquote.string, lquote.length);
- obstack_grow (obs, pattern, len);
- for (i = 0; len > 0 && i < 6; i++)
- if (pattern[len - i - 1] != 'X')
- break;
- obstack_grow0 (obs, "XXXXXX", 6 - i);
- name = (char *) obstack_base (obs) + lquote.length;
-
- errno = 0;
- fd = mkstemp (name);
- if (fd < 0)
- {
- M4ERROR ((0, errno, "%s: cannot create tempfile `%s'", me, pattern));
- obstack_free (obs, obstack_finish (obs));
- }
- else
- {
- close (fd);
- /* Remove NUL, then finish quote. */
- obstack_blank (obs, -1);
- obstack_grow (obs, rquote.string, rquote.length);
- }
-}
-
-static void
-m4_maketemp (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, 2))
- return;
- if (no_gnu_extensions)
- {
- /* POSIX states "any trailing 'X' characters [are] replaced with
- the current process ID as a string", without referencing the
- file system. Horribly insecure, but we have to do it when we
- are in traditional mode.
-
- For reference, Solaris m4 does:
- maketemp() -> `'
- maketemp(X) -> `X'
- maketemp(XX) -> `Xn', where n is last digit of pid
- maketemp(XXXXXXXX) -> `X00nnnnn', where nnnnn is 16-bit pid
- */
- const char *str = ARG (1);
- int len = strlen (str);
- int i;
- int len2;
-
- M4ERROR ((warning_status, 0, "recommend using mkstemp instead"));
- for (i = len; i > 1; i--)
- if (str[i - 1] != 'X')
- break;
- obstack_grow (obs, str, i);
- str = ntoa ((int32_t) getpid (), 10);
- len2 = strlen (str);
- if (len2 > len - i)
- obstack_grow0 (obs, str + len2 - (len - i), len - i);
- else
- {
- while (i++ < len - len2)
- obstack_1grow (obs, '0');
- obstack_grow0 (obs, str, len2);
- }
- }
- else
- mkstemp_helper (obs, ARG (0), ARG (1), strlen (ARG (1)));
-}
-
-static void
-m4_mkstemp (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, 2))
- return;
- mkstemp_helper (obs, ARG (0), ARG (1), strlen (ARG (1)));
-}
-
-/*----------------------------------------.
-| Print all arguments on standard error. |
-`----------------------------------------*/
-
-static void
-m4_errprint (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- dump_args (obs, argc, argv, " ", false);
- obstack_1grow (obs, '\0');
- debug_flush_files ();
- xfprintf (stderr, "%s", (char *) obstack_finish (obs));
- fflush (stderr);
-}
-
-static void
-m4___file__ (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 1))
- return;
- obstack_grow (obs, lquote.string, lquote.length);
- obstack_grow (obs, current_file, strlen (current_file));
- obstack_grow (obs, rquote.string, rquote.length);
-}
-
-static void
-m4___line__ (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 1))
- return;
- shipout_int (obs, current_line);
-}
-
-static void
-m4___program__ (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 1))
- return;
- obstack_grow (obs, lquote.string, lquote.length);
- obstack_grow (obs, program_name, strlen (program_name));
- obstack_grow (obs, rquote.string, rquote.length);
-}
-
-/* This section contains various macros for exiting, saving input until
- EOF is seen, and tracing macro calls. That is: "m4exit", "m4wrap",
- "traceon" and "traceoff". */
-
-/*----------------------------------------------------------.
-| Exit immediately, with exit status specified by the first |
-| argument, or 0 if no arguments are present. |
-`----------------------------------------------------------*/
-
-static void M4_GNUC_NORETURN
-m4_m4exit (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- int exit_code = EXIT_SUCCESS;
-
- /* Warn on bad arguments, but still exit. */
- bad_argc (argv[0], argc, 1, 2);
- if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &exit_code))
- exit_code = EXIT_FAILURE;
- if (exit_code < 0 || exit_code > 255)
- {
- M4ERROR ((warning_status, 0,
- "exit status out of range: `%d'", exit_code));
- exit_code = EXIT_FAILURE;
- }
- /* Change debug stream back to stderr, to force flushing debug stream and
- detect any errors it might have encountered. */
- debug_set_output (NULL);
- debug_flush_files ();
- if (exit_code == EXIT_SUCCESS && retcode != EXIT_SUCCESS)
- exit_code = retcode;
- /* Propagate non-zero status to atexit handlers. */
- if (exit_code != EXIT_SUCCESS)
- exit_failure = exit_code;
- exit (exit_code);
-}
-
-/*------------------------------------------------------------------.
-| Save the argument text until EOF has been seen, allowing for user |
-| specified cleanup action. GNU version saves all arguments, the |
-| standard version only the first. |
-`------------------------------------------------------------------*/
-
-static void
-m4_m4wrap (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- if (no_gnu_extensions)
- obstack_grow (obs, ARG (1), strlen (ARG (1)));
- else
- dump_args (obs, argc, argv, " ", false);
- obstack_1grow (obs, '\0');
- push_wrapup ((char *) obstack_finish (obs));
-}
-
-/* Enable tracing of all specified macros, or all, if none is specified.
- Tracing is disabled by default, when a macro is defined. This can be
- overridden by the "t" debug flag. */
-
-/*------------------------------------------------------------------.
-| Set_trace () is used by "traceon" and "traceoff" to enable and |
-| disable tracing of a macro. It disables tracing if DATA is NULL, |
-| otherwise it enables tracing. |
-`------------------------------------------------------------------*/
-
-static void
-set_trace (symbol *sym, void *data)
-{
- SYMBOL_TRACED (sym) = data != NULL;
- /* Remove placeholder from table if macro is undefined and untraced. */
- if (SYMBOL_TYPE (sym) == TOKEN_VOID && data == NULL)
- lookup_symbol (SYMBOL_NAME (sym), SYMBOL_POPDEF);
-}
-
-static void
-m4_traceon (struct obstack *obs, int argc, token_data **argv)
-{
- symbol *s;
- int i;
-
- if (argc == 1)
- hack_all_symbols (set_trace, obs);
- else
- for (i = 1; i < argc; i++)
- {
- s = lookup_symbol (ARG (i), SYMBOL_LOOKUP);
- if (!s)
- s = lookup_symbol (ARG (i), SYMBOL_INSERT);
- set_trace (s, obs);
- }
-}
-
-/*------------------------------------------------------------------------.
-| Disable tracing of all specified macros, or all, if none is specified. |
-`------------------------------------------------------------------------*/
-
-static void
-m4_traceoff (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- symbol *s;
- int i;
-
- if (argc == 1)
- hack_all_symbols (set_trace, NULL);
- else
- for (i = 1; i < argc; i++)
- {
- s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
- if (s != NULL)
- set_trace (s, NULL);
- }
-}
-
-/*------------------------------------------------------------------.
-| On-the-fly control of the format of the tracing output. It takes |
-| one argument, which is a character string like given to the -d |
-| option, or none in which case the debug_level is zeroed. |
-`------------------------------------------------------------------*/
-
-static void
-m4_debugmode (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- int new_debug_level;
- int change_flag;
-
- if (bad_argc (argv[0], argc, 1, 2))
- return;
-
- if (argc == 1)
- debug_level = 0;
- else
- {
- if (ARG (1)[0] == '+' || ARG (1)[0] == '-')
- {
- change_flag = ARG (1)[0];
- new_debug_level = debug_decode (ARG (1) + 1);
- }
- else
- {
- change_flag = 0;
- new_debug_level = debug_decode (ARG (1));
- }
-
- if (new_debug_level < 0)
- M4ERROR ((warning_status, 0,
- "Debugmode: bad debug flags: `%s'", ARG (1)));
- else
- {
- switch (change_flag)
- {
- case 0:
- debug_level = new_debug_level;
- break;
-
- case '+':
- debug_level |= new_debug_level;
- break;
-
- case '-':
- debug_level &= ~new_debug_level;
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad flag in m4_debugmode ()"));
- abort ();
- }
- }
- }
-}
-
-/*-------------------------------------------------------------------------.
-| Specify the destination of the debugging output. With one argument, the |
-| argument is taken as a file name, with no arguments, revert to stderr. |
-`-------------------------------------------------------------------------*/
-
-static void
-m4_debugfile (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 1, 2))
- return;
-
- if (argc == 1)
- debug_set_output (NULL);
- else if (!debug_set_output (ARG (1)))
- M4ERROR ((warning_status, errno,
- "cannot set debug file `%s'", ARG (1)));
-}
-
-/* This section contains text processing macros: "len", "index",
- "substr", "translit", "format", "regexp" and "patsubst". The last
- three are GNU specific. */
-
-/*---------------------------------------------.
-| Expand to the length of the first argument. |
-`---------------------------------------------*/
-
-static void
-m4_len (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, 2))
- return;
- shipout_int (obs, strlen (ARG (1)));
-}
-
-/*-------------------------------------------------------------------.
-| The macro expands to the first index of the second argument in the |
-| first argument. |
-`-------------------------------------------------------------------*/
-
-static void
-m4_index (struct obstack *obs, int argc, token_data **argv)
-{
- const char *haystack;
- const char *result;
- int retval;
-
- if (bad_argc (argv[0], argc, 3, 3))
- {
- /* builtin(`index') is blank, but index(`abc') is 0. */
- if (argc == 2)
- shipout_int (obs, 0);
- return;
- }
-
- haystack = ARG (1);
- result = strstr (haystack, ARG (2));
- retval = result ? result - haystack : -1;
-
- shipout_int (obs, retval);
-}
-
-/*-----------------------------------------------------------------.
-| The macro "substr" extracts substrings from the first argument, |
-| starting from the index given by the second argument, extending |
-| for a length given by the third argument. If the third argument |
-| is missing, the substring extends to the end of the first |
-| argument. |
-`-----------------------------------------------------------------*/
-
-static void
-m4_substr (struct obstack *obs, int argc, token_data **argv)
-{
- int start = 0;
- int length, avail;
-
- if (bad_argc (argv[0], argc, 3, 4))
- {
- /* builtin(`substr') is blank, but substr(`abc') is abc. */
- if (argc == 2)
- obstack_grow (obs, ARG (1), strlen (ARG (1)));
- return;
- }
-
- length = avail = strlen (ARG (1));
- if (!numeric_arg (argv[0], ARG (2), &start))
- return;
-
- if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &length))
- return;
-
- if (start < 0 || length <= 0 || start >= avail)
- return;
-
- if (start + length > avail)
- length = avail - start;
- obstack_grow (obs, ARG (1) + start, length);
-}
-
-/*------------------------------------------------------------------.
-| For "translit", ranges are allowed in the second and third |
-| argument. They are expanded in the following function, and the |
-| expanded strings, without any ranges left, are used to translate |
-| the characters of the first argument. A single - (dash) can be |
-| included in the strings by being the first or the last character |
-| in the string. If the first character in a range is after the |
-| first in the character set, the range is made backwards, thus 9-0 |
-| is the string 9876543210. |
-`------------------------------------------------------------------*/
-
-static const char *
-expand_ranges (const char *s, struct obstack *obs)
-{
- unsigned char from;
- unsigned char to;
-
- for (from = '\0'; *s != '\0'; from = to_uchar (*s++))
- {
- if (*s == '-' && from != '\0')
- {
- to = to_uchar (*++s);
- if (to == '\0')
- {
- /* trailing dash */
- obstack_1grow (obs, '-');
- break;
- }
- else if (from <= to)
- {
- while (from++ < to)
- obstack_1grow (obs, from);
- }
- else
- {
- while (--from >= to)
- obstack_1grow (obs, from);
- }
- }
- else
- obstack_1grow (obs, *s);
- }
- obstack_1grow (obs, '\0');
- return (char *) obstack_finish (obs);
-}
-
-/*-----------------------------------------------------------------.
-| The macro "translit" translates all characters in the first |
-| argument, which are present in the second argument, into the |
-| corresponding character from the third argument. If the third |
-| argument is shorter than the second, the extra characters in the |
-| second argument are deleted from the first. |
-`-----------------------------------------------------------------*/
-
-static void
-m4_translit (struct obstack *obs, int argc, token_data **argv)
-{
- const char *data = ARG (1);
- const char *from = ARG (2);
- const char *to;
- char map[UCHAR_MAX + 1];
- char found[UCHAR_MAX + 1];
- unsigned char ch;
-
- if (bad_argc (argv[0], argc, 3, 4) || !*data || !*from)
- {
- /* builtin(`translit') is blank, but translit(`abc') is abc. */
- if (2 <= argc)
- obstack_grow (obs, data, strlen (data));
- return;
- }
-
- to = ARG (3);
- if (strchr (to, '-') != NULL)
- {
- to = expand_ranges (to, obs);
- assert (to && *to);
- }
-
- /* If there are only one or two bytes to replace, it is faster to
- use memchr2. Using expand_ranges does nothing unless there are
- at least three bytes. */
- if (!from[1] || !from[2])
- {
- const char *p;
- size_t len = strlen (data);
- while ((p = (char *) memchr2 (data, from[0], from[1], len)))
- {
- obstack_grow (obs, data, p - data);
- len -= p - data;
- if (!len)
- return;
- data = p + 1;
- len--;
- if (*p == from[0] && to[0])
- obstack_1grow (obs, to[0]);
- else if (*p == from[1] && to[0] && to[1])
- obstack_1grow (obs, to[1]);
- }
- obstack_grow (obs, data, len);
- return;
- }
-
- if (strchr (from, '-') != NULL)
- {
- from = expand_ranges (from, obs);
- assert (from && *from);
- }
-
- /* Calling strchr(from) for each character in data is quadratic,
- since both strings can be arbitrarily long. Instead, create a
- from-to mapping in one pass of from, then use that map in one
- pass of data, for linear behavior. Traditional behavior is that
- only the first instance of a character in from is consulted,
- hence the found map. */
- memset (map, 0, sizeof map);
- memset (found, 0, sizeof found);
- for ( ; (ch = *from) != '\0'; from++)
- {
- if (! found[ch])
- {
- found[ch] = 1;
- map[ch] = *to;
- }
- if (*to != '\0')
- to++;
- }
-
- for (data = ARG (1); (ch = *data) != '\0'; data++)
- {
- if (! found[ch])
- obstack_1grow (obs, ch);
- else if (map[ch])
- obstack_1grow (obs, map[ch]);
- }
-}
-
-/*-------------------------------------------------------------------.
-| Frontend for printf like formatting. The function format () lives |
-| in the file format.c. |
-`-------------------------------------------------------------------*/
-
-static void
-m4_format (struct obstack *obs, int argc, token_data **argv)
-{
- if (bad_argc (argv[0], argc, 2, -1))
- return;
- expand_format (obs, argc - 1, argv + 1);
-}
-
-/*------------------------------------------------------------------.
-| Function to perform substitution by regular expressions. Used by |
-| the builtins regexp and patsubst. The changed text is placed on |
-| the obstack. The substitution is REPL, with \& substituted by |
-| this part of VICTIM matched by the last whole regular expression, |
-| taken from REGS[0], and \N substituted by the text matched by the |
-| Nth parenthesized sub-expression, taken from REGS[N]. |
-`------------------------------------------------------------------*/
-
-static int substitute_warned = 0;
-
-static void
-substitute (struct obstack *obs, const char *victim, const char *repl,
- struct re_registers *regs)
-{
- int ch;
- __re_size_t ind;
- while (1)
- {
- const char *backslash = strchr (repl, '\\');
- if (!backslash)
- {
- obstack_grow (obs, repl, strlen (repl));
- return;
- }
- obstack_grow (obs, repl, backslash - repl);
- repl = backslash;
- ch = *++repl;
- switch (ch)
- {
- case '0':
- if (!substitute_warned)
- {
- M4ERROR ((warning_status, 0, "\
-Warning: \\0 will disappear, use \\& instead in replacements"));
- substitute_warned = 1;
- }
- /* Fall through. */
-
- case '&':
- obstack_grow (obs, victim + regs->start[0],
- regs->end[0] - regs->start[0]);
- repl++;
- break;
-
- case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': case '8': case '9':
- ind = ch -= '0';
- if (regs->num_regs - 1 <= ind)
- M4ERROR ((warning_status, 0,
- "Warning: sub-expression %d not present", ch));
- else if (regs->end[ch] > 0)
- obstack_grow (obs, victim + regs->start[ch],
- regs->end[ch] - regs->start[ch]);
- repl++;
- break;
-
- case '\0':
- M4ERROR ((warning_status, 0,
- "Warning: trailing \\ ignored in replacement"));
- return;
-
- default:
- obstack_1grow (obs, ch);
- repl++;
- break;
- }
- }
-}
-
-/*------------------------------------------.
-| Initialize regular expression variables. |
-`------------------------------------------*/
-
-void
-init_pattern_buffer (struct re_pattern_buffer *buf, struct re_registers *regs)
-{
- buf->translate = NULL;
- buf->fastmap = NULL;
- buf->buffer = NULL;
- buf->allocated = 0;
- if (regs)
- {
- regs->start = NULL;
- regs->end = NULL;
- }
-}
-
-/*------------------------------------------------------------------.
-| Regular expression version of index. Given two arguments, expand |
-| to the index of the first match of the second argument (a regexp) |
-| in the first. Expand to -1 if here is no match. Given a third |
-| argument, it changes the expansion to this argument. |
-`------------------------------------------------------------------*/
-
-static void
-m4_regexp (struct obstack *obs, int argc, token_data **argv)
-{
- const char *victim; /* first argument */
- const char *regexp; /* regular expression */
- const char *repl; /* replacement string */
-
- struct re_pattern_buffer buf; /* compiled regular expression */
- struct re_registers regs; /* for subexpression matches */
- const char *msg; /* error message from re_compile_pattern */
- int startpos; /* start position of match */
- int length; /* length of first argument */
-
- if (bad_argc (argv[0], argc, 3, 4))
- {
- /* builtin(`regexp') is blank, but regexp(`abc') is 0. */
- if (argc == 2)
- shipout_int (obs, 0);
- return;
- }
-
- victim = TOKEN_DATA_TEXT (argv[1]);
- regexp = TOKEN_DATA_TEXT (argv[2]);
-
- init_pattern_buffer (&buf, &regs);
- msg = re_compile_pattern (regexp, strlen (regexp), &buf);
-
- if (msg != NULL)
- {
- M4ERROR ((warning_status, 0,
- "bad regular expression: `%s': %s", regexp, msg));
- free_pattern_buffer (&buf, &regs);
- return;
- }
-
- length = strlen (victim);
- /* Avoid overhead of allocating regs if we won't use it. */
- startpos = re_search (&buf, victim, length, 0, length,
- argc == 3 ? NULL : &regs);
-
- if (startpos == -2)
- M4ERROR ((warning_status, 0,
- "error matching regular expression `%s'", regexp));
- else if (argc == 3)
- shipout_int (obs, startpos);
- else if (startpos >= 0)
- {
- repl = TOKEN_DATA_TEXT (argv[3]);
- substitute (obs, victim, repl, &regs);
- }
-
- free_pattern_buffer (&buf, &regs);
-}
-
-/*--------------------------------------------------------------------------.
-| Substitute all matches of a regexp occuring in a string. Each match of |
-| the second argument (a regexp) in the first argument is changed to the |
-| third argument, with \& substituted by the matched text, and \N |
-| substituted by the text matched by the Nth parenthesized sub-expression. |
-`--------------------------------------------------------------------------*/
-
-static void
-m4_patsubst (struct obstack *obs, int argc, token_data **argv)
-{
- const char *victim; /* first argument */
- const char *regexp; /* regular expression */
-
- struct re_pattern_buffer buf; /* compiled regular expression */
- struct re_registers regs; /* for subexpression matches */
- const char *msg; /* error message from re_compile_pattern */
- int matchpos; /* start position of match */
- int offset; /* current match offset */
- int length; /* length of first argument */
-
- if (bad_argc (argv[0], argc, 3, 4))
- {
- /* builtin(`patsubst') is blank, but patsubst(`abc') is abc. */
- if (argc == 2)
- obstack_grow (obs, ARG (1), strlen (ARG (1)));
- return;
- }
-
- regexp = TOKEN_DATA_TEXT (argv[2]);
-
- init_pattern_buffer (&buf, &regs);
- msg = re_compile_pattern (regexp, strlen (regexp), &buf);
-
- if (msg != NULL)
- {
- M4ERROR ((warning_status, 0,
- "bad regular expression `%s': %s", regexp, msg));
- free (buf.buffer);
- return;
- }
-
- victim = TOKEN_DATA_TEXT (argv[1]);
- length = strlen (victim);
-
- offset = 0;
- while (offset <= length)
- {
- matchpos = re_search (&buf, victim, length,
- offset, length - offset, &regs);
- if (matchpos < 0)
- {
-
- /* Match failed -- either error or there is no match in the
- rest of the string, in which case the rest of the string is
- copied verbatim. */
-
- if (matchpos == -2)
- M4ERROR ((warning_status, 0,
- "error matching regular expression `%s'", regexp));
- else if (offset < length)
- obstack_grow (obs, victim + offset, length - offset);
- break;
- }
-
- /* Copy the part of the string that was skipped by re_search (). */
-
- if (matchpos > offset)
- obstack_grow (obs, victim + offset, matchpos - offset);
-
- /* Handle the part of the string that was covered by the match. */
-
- substitute (obs, victim, ARG (3), &regs);
-
- /* Update the offset to the end of the match. If the regexp
- matched a null string, advance offset one more, to avoid
- infinite loops. */
-
- offset = regs.end[0];
- if (regs.start[0] == regs.end[0])
- obstack_1grow (obs, victim[offset++]);
- }
- obstack_1grow (obs, '\0');
-
- free_pattern_buffer (&buf, &regs);
-}
-
-/* Finally, a placeholder builtin. This builtin is not installed by
- default, but when reading back frozen files, this is associated
- with any builtin we don't recognize (for example, if the frozen
- file was created with a changeword capable m4, but is then loaded
- by a different m4 that does not support changeword). This way, we
- can keep 'm4 -R' quiet in the common case that the user did not
- know or care about the builtin when the frozen file was created,
- while still flagging it as a potential error if an attempt is made
- to actually use the builtin. */
-
-/*--------------------------------------------------------------------.
-| Issue a warning that this macro is a placeholder for an unsupported |
-| builtin that was requested while reloading a frozen file. |
-`--------------------------------------------------------------------*/
-
-void
-m4_placeholder (struct obstack *obs M4_GNUC_UNUSED, int argc,
- token_data **argv)
-{
- M4ERROR ((warning_status, 0, "\
-builtin `%s' requested by frozen file is not supported", ARG (0)));
-}
-
-/*-------------------------------------------------------------------.
-| This function handles all expansion of user defined and predefined |
-| macros. It is called with an obstack OBS, where the macros |
-| expansion will be placed, as an unfinished object. SYM points to |
-| the macro definition, giving the expansion text. ARGC and ARGV |
-| are the arguments, as usual. |
-`-------------------------------------------------------------------*/
-
-void
-expand_user_macro (struct obstack *obs, symbol *sym,
- int argc, token_data **argv)
-{
- const char *text = SYMBOL_TEXT (sym);
- int i;
- while (1)
- {
- const char *dollar = strchr (text, '$');
- if (!dollar)
- {
- obstack_grow (obs, text, strlen (text));
- return;
- }
- obstack_grow (obs, text, dollar - text);
- text = dollar;
- switch (*++text)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (no_gnu_extensions)
- {
- i = *text++ - '0';
- }
- else
- {
- for (i = 0; isdigit (to_uchar (*text)); text++)
- i = i*10 + (*text - '0');
- }
- if (i < argc)
- obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
- strlen (TOKEN_DATA_TEXT (argv[i])));
- break;
-
- case '#': /* number of arguments */
- shipout_int (obs, argc - 1);
- text++;
- break;
-
- case '*': /* all arguments */
- case '@': /* ... same, but quoted */
- dump_args (obs, argc, argv, ",", *text == '@');
- text++;
- break;
-
- default:
- obstack_1grow (obs, '$');
- break;
- }
- }
-}
diff --git a/contrib/tools/bison/m4/src/cpp.cpp b/contrib/tools/bison/m4/src/cpp.cpp
deleted file mode 100644
index 19c4a90e13..0000000000
--- a/contrib/tools/bison/m4/src/cpp.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// Just include a C++ header to tell stupid MSVC to link in C++ runtime providing wctype().
-
-#include <cassert>
diff --git a/contrib/tools/bison/m4/src/debug.c b/contrib/tools/bison/m4/src/debug.c
deleted file mode 100644
index c13a205b89..0000000000
--- a/contrib/tools/bison/m4/src/debug.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1991-1994, 2004, 2006-2007, 2009-2013 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "m4.h"
-
-#include <stdarg.h>
-#include <sys/stat.h>
-
-/* File for debugging output. */
-FILE *debug = NULL;
-
-/* Obstack for trace messages. */
-static struct obstack trace;
-
-static void debug_set_file (FILE *);
-
-/*----------------------------------.
-| Initialise the debugging module. |
-`----------------------------------*/
-
-void
-debug_init (void)
-{
- debug_set_file (stderr);
- obstack_init (&trace);
-}
-
-/*-----------------------------------------------------------------.
-| Function to decode the debugging flags OPTS. Used by main while |
-| processing option -d, and by the builtin debugmode (). |
-`-----------------------------------------------------------------*/
-
-int
-debug_decode (const char *opts)
-{
- int level;
-
- if (opts == NULL || *opts == '\0')
- level = DEBUG_TRACE_DEFAULT;
- else
- {
- for (level = 0; *opts; opts++)
- {
- switch (*opts)
- {
- case 'a':
- level |= DEBUG_TRACE_ARGS;
- break;
-
- case 'e':
- level |= DEBUG_TRACE_EXPANSION;
- break;
-
- case 'q':
- level |= DEBUG_TRACE_QUOTE;
- break;
-
- case 't':
- level |= DEBUG_TRACE_ALL;
- break;
-
- case 'l':
- level |= DEBUG_TRACE_LINE;
- break;
-
- case 'f':
- level |= DEBUG_TRACE_FILE;
- break;
-
- case 'p':
- level |= DEBUG_TRACE_PATH;
- break;
-
- case 'c':
- level |= DEBUG_TRACE_CALL;
- break;
-
- case 'i':
- level |= DEBUG_TRACE_INPUT;
- break;
-
- case 'x':
- level |= DEBUG_TRACE_CALLID;
- break;
-
- case 'V':
- level |= DEBUG_TRACE_VERBOSE;
- break;
-
- default:
- return -1;
- }
- }
- }
-
- /* This is to avoid screwing up the trace output due to changes in the
- debug_level. */
-
- obstack_free (&trace, obstack_finish (&trace));
-
- return level;
-}
-
-/*-----------------------------------------------------------------.
-| Change the debug output stream to FP. If the underlying file is |
-| the same as stdout, use stdout instead so that debug messages |
-| appear in the correct relative position. |
-`-----------------------------------------------------------------*/
-
-static void
-debug_set_file (FILE *fp)
-{
- struct stat stdout_stat, debug_stat;
-
- if (debug != NULL && debug != stderr && debug != stdout
- && close_stream (debug) != 0)
- {
- M4ERROR ((warning_status, errno, "error writing to debug stream"));
- retcode = EXIT_FAILURE;
- }
- debug = fp;
-
- if (debug != NULL && debug != stdout)
- {
- if (fstat (STDOUT_FILENO, &stdout_stat) < 0)
- return;
- if (fstat (fileno (debug), &debug_stat) < 0)
- return;
-
- /* mingw has a bug where fstat on a regular file reports st_ino
- of 0. On normal system, st_ino should never be 0. */
- if (stdout_stat.st_ino == debug_stat.st_ino
- && stdout_stat.st_dev == debug_stat.st_dev
- && stdout_stat.st_ino != 0)
- {
- if (debug != stderr && close_stream (debug) != 0)
- {
- M4ERROR ((warning_status, errno,
- "error writing to debug stream"));
- retcode = EXIT_FAILURE;
- }
- debug = stdout;
- }
- }
-}
-
-/*-----------------------------------------------------------.
-| Serialize files. Used before executing a system command. |
-`-----------------------------------------------------------*/
-
-void
-debug_flush_files (void)
-{
- fflush (stdout);
- fflush (stderr);
- if (debug != NULL && debug != stdout && debug != stderr)
- fflush (debug);
- /* POSIX requires that if m4 doesn't consume all input, but stdin is
- opened on a seekable file, that the file pointer be left at the
- next character on exit (but places no restrictions on the file
- pointer location on a non-seekable file). It also requires that
- fflush() followed by fseeko() on an input file set the underlying
- file pointer, and gnulib guarantees these semantics. However,
- fflush() on a non-seekable file can lose buffered data, which we
- might otherwise want to process after syscmd. Hence, we must
- check whether stdin is seekable. We must also be tolerant of
- operating with stdin closed, so we don't report any failures in
- this attempt. The stdio-safer module and friends are essential,
- so that if stdin was closed, this lseek is not on some other file
- that we have since opened. */
- if (lseek (STDIN_FILENO, 0, SEEK_CUR) >= 0
- && fflush (stdin) == 0)
- {
- fseeko (stdin, 0, SEEK_CUR);
- }
-}
-
-/*--------------------------------------------------------------.
-| Change the debug output to file NAME. If NAME is NULL, debug |
-| output is reverted to stderr, and if empty, debug output is |
-| discarded. Return true iff the output stream was changed. |
-`--------------------------------------------------------------*/
-
-bool
-debug_set_output (const char *name)
-{
- FILE *fp;
-
- if (name == NULL)
- debug_set_file (stderr);
- else if (*name == '\0')
- debug_set_file (NULL);
- else
- {
- fp = fopen (name, "a");
- if (fp == NULL)
- return false;
-
- if (set_cloexec_flag (fileno (fp), true) != 0)
- M4ERROR ((warning_status, errno,
- "Warning: cannot protect debug file across forks"));
- debug_set_file (fp);
- }
- return true;
-}
-
-/*--------------------------------------------------------------.
-| Print the header of a one-line debug message, starting by "m4 |
-| debug". |
-`--------------------------------------------------------------*/
-
-void
-debug_message_prefix (void)
-{
- xfprintf (debug, "m4debug:");
- if (current_line)
- {
- if (debug_level & DEBUG_TRACE_FILE)
- xfprintf (debug, "%s:", current_file);
- if (debug_level & DEBUG_TRACE_LINE)
- xfprintf (debug, "%d:", current_line);
- }
- putc (' ', debug);
-}
-
-/* The rest of this file contains the functions for macro tracing output.
- All tracing output for a macro call is collected on an obstack TRACE,
- and printed whenever the line is complete. This prevents tracing
- output from interfering with other debug messages generated by the
- various builtins. */
-
-/*------------------------------------------------------------------.
-| Tracing output is formatted here, by a simplified |
-| printf-to-obstack function trace_format (). Understands only %S, |
-| %s, %d, %l (optional left quote) and %r (optional right quote). |
-`------------------------------------------------------------------*/
-
-static void
-trace_format (const char *fmt, ...)
-{
- va_list args;
- char ch;
-
- int d;
- const char *s;
- int slen;
- int maxlen;
-
- va_start (args, fmt);
-
- while (true)
- {
- while ((ch = *fmt++) != '\0' && ch != '%')
- obstack_1grow (&trace, ch);
-
- if (ch == '\0')
- break;
-
- maxlen = 0;
- switch (*fmt++)
- {
- case 'S':
- maxlen = max_debug_argument_length;
- /* fall through */
-
- case 's':
- s = va_arg (args, const char *);
- break;
-
- case 'l':
- s = (debug_level & DEBUG_TRACE_QUOTE) ? lquote.string : "";
- break;
-
- case 'r':
- s = (debug_level & DEBUG_TRACE_QUOTE) ? rquote.string : "";
- break;
-
- case 'd':
- d = va_arg (args, int);
- s = ntoa (d, 10);
- break;
-
- default:
- s = "";
- break;
- }
-
- slen = strlen (s);
- if (maxlen == 0 || maxlen > slen)
- obstack_grow (&trace, s, slen);
- else
- {
- obstack_grow (&trace, s, maxlen);
- obstack_grow (&trace, "...", 3);
- }
- }
-
- va_end (args);
-}
-
-/*------------------------------------------------------------------.
-| Format the standard header attached to all tracing output lines. |
-`------------------------------------------------------------------*/
-
-static void
-trace_header (int id)
-{
- trace_format ("m4trace:");
- if (current_line)
- {
- if (debug_level & DEBUG_TRACE_FILE)
- trace_format ("%s:", current_file);
- if (debug_level & DEBUG_TRACE_LINE)
- trace_format ("%d:", current_line);
- }
- trace_format (" -%d- ", expansion_level);
- if (debug_level & DEBUG_TRACE_CALLID)
- trace_format ("id %d: ", id);
-}
-
-/*----------------------------------------------------.
-| Print current tracing line, and clear the obstack. |
-`----------------------------------------------------*/
-
-static void
-trace_flush (void)
-{
- char *line;
-
- obstack_1grow (&trace, '\0');
- line = (char *) obstack_finish (&trace);
- DEBUG_PRINT1 ("%s\n", line);
- obstack_free (&trace, line);
-}
-
-/*-------------------------------------------------------------.
-| Do pre-argument-collction tracing for macro NAME. Used from |
-| expand_macro (). |
-`-------------------------------------------------------------*/
-
-void
-trace_prepre (const char *name, int id)
-{
- trace_header (id);
- trace_format ("%s ...", name);
- trace_flush ();
-}
-
-/*--------------------------------------------------------------.
-| Format the parts of a trace line, that can be made before the |
-| macro is actually expanded. Used from expand_macro (). |
-`--------------------------------------------------------------*/
-
-void
-trace_pre (const char *name, int id, int argc, token_data **argv)
-{
- int i;
- const builtin *bp;
-
- trace_header (id);
- trace_format ("%s", name);
-
- if (argc > 1 && (debug_level & DEBUG_TRACE_ARGS))
- {
- trace_format ("(");
-
- for (i = 1; i < argc; i++)
- {
- if (i != 1)
- trace_format (", ");
-
- switch (TOKEN_DATA_TYPE (argv[i]))
- {
- case TOKEN_TEXT:
- trace_format ("%l%S%r", TOKEN_DATA_TEXT (argv[i]));
- break;
-
- case TOKEN_FUNC:
- bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[i]));
- if (bp == NULL)
- {
- M4ERROR ((warning_status, 0, "\
-INTERNAL ERROR: builtin not found in builtin table! (trace_pre ())"));
- abort ();
- }
- trace_format ("<%s>", bp->name);
- break;
-
- case TOKEN_VOID:
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad token data type (trace_pre ())"));
- abort ();
- }
-
- }
- trace_format (")");
- }
-
- if (debug_level & DEBUG_TRACE_CALL)
- {
- trace_format (" -> ???");
- trace_flush ();
- }
-}
-
-/*-------------------------------------------------------------------.
-| Format the final part of a trace line and print it all. Used from |
-| expand_macro (). |
-`-------------------------------------------------------------------*/
-
-void
-trace_post (const char *name, int id, int argc, const char *expanded)
-{
- if (debug_level & DEBUG_TRACE_CALL)
- {
- trace_header (id);
- trace_format ("%s%s", name, (argc > 1) ? "(...)" : "");
- }
-
- if (expanded && (debug_level & DEBUG_TRACE_EXPANSION))
- trace_format (" -> %l%S%r", expanded);
- trace_flush ();
-}
diff --git a/contrib/tools/bison/m4/src/eval.c b/contrib/tools/bison/m4/src/eval.c
deleted file mode 100644
index 8b4b05afb1..0000000000
--- a/contrib/tools/bison/m4/src/eval.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2006-2007, 2009-2013 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* This file contains the functions to evaluate integer expressions for
- the "eval" macro. It is a little, fairly self-contained module, with
- its own scanner, and a recursive descent parser. The only entry point
- is evaluate (). */
-
-#include "m4.h"
-
-/* Evaluates token types. */
-
-typedef enum eval_token
- {
- ERROR, BADOP,
- PLUS, MINUS,
- EXPONENT,
- TIMES, DIVIDE, MODULO,
- ASSIGN, EQ, NOTEQ, GT, GTEQ, LS, LSEQ,
- LSHIFT, RSHIFT,
- LNOT, LAND, LOR,
- NOT, AND, OR, XOR,
- LEFTP, RIGHTP,
- NUMBER, EOTEXT
- }
-eval_token;
-
-/* Error types. */
-
-typedef enum eval_error
- {
- NO_ERROR,
- DIVIDE_ZERO,
- MODULO_ZERO,
- NEGATIVE_EXPONENT,
- /* All errors prior to SYNTAX_ERROR can be ignored in a dead
- branch of && and ||. All errors after are just more details
- about a syntax error. */
- SYNTAX_ERROR,
- MISSING_RIGHT,
- UNKNOWN_INPUT,
- EXCESS_INPUT,
- INVALID_OPERATOR
- }
-eval_error;
-
-static eval_error logical_or_term (eval_token, int32_t *);
-static eval_error logical_and_term (eval_token, int32_t *);
-static eval_error or_term (eval_token, int32_t *);
-static eval_error xor_term (eval_token, int32_t *);
-static eval_error and_term (eval_token, int32_t *);
-static eval_error equality_term (eval_token, int32_t *);
-static eval_error cmp_term (eval_token, int32_t *);
-static eval_error shift_term (eval_token, int32_t *);
-static eval_error add_term (eval_token, int32_t *);
-static eval_error mult_term (eval_token, int32_t *);
-static eval_error exp_term (eval_token, int32_t *);
-static eval_error unary_term (eval_token, int32_t *);
-static eval_error simple_term (eval_token, int32_t *);
-
-/*--------------------.
-| Lexical functions. |
-`--------------------*/
-
-/* Pointer to next character of input text. */
-static const char *eval_text;
-
-/* Value of eval_text, from before last call of eval_lex (). This is so we
- can back up, if we have read too much. */
-static const char *last_text;
-
-static void
-eval_init_lex (const char *text)
-{
- eval_text = text;
- last_text = NULL;
-}
-
-static void
-eval_undo (void)
-{
- eval_text = last_text;
-}
-
-/* VAL is numerical value, if any. */
-
-static eval_token
-eval_lex (int32_t *val)
-{
- while (isspace (to_uchar (*eval_text)))
- eval_text++;
-
- last_text = eval_text;
-
- if (*eval_text == '\0')
- return EOTEXT;
-
- if (isdigit (to_uchar (*eval_text)))
- {
- int base, digit;
-
- if (*eval_text == '0')
- {
- eval_text++;
- switch (*eval_text)
- {
- case 'x':
- case 'X':
- base = 16;
- eval_text++;
- break;
-
- case 'b':
- case 'B':
- base = 2;
- eval_text++;
- break;
-
- case 'r':
- case 'R':
- base = 0;
- eval_text++;
- while (isdigit (to_uchar (*eval_text)) && base <= 36)
- base = 10 * base + *eval_text++ - '0';
- if (base == 0 || base > 36 || *eval_text != ':')
- return ERROR;
- eval_text++;
- break;
-
- default:
- base = 8;
- }
- }
- else
- base = 10;
-
- /* FIXME - this calculation can overflow. Consider xstrtol. */
- *val = 0;
- for (; *eval_text; eval_text++)
- {
- if (isdigit (to_uchar (*eval_text)))
- digit = *eval_text - '0';
- else if (islower (to_uchar (*eval_text)))
- digit = *eval_text - 'a' + 10;
- else if (isupper (to_uchar (*eval_text)))
- digit = *eval_text - 'A' + 10;
- else
- break;
-
- if (base == 1)
- {
- if (digit == 1)
- (*val)++;
- else if (digit == 0 && !*val)
- continue;
- else
- break;
- }
- else if (digit >= base)
- break;
- else
- *val = *val * base + digit;
- }
- return NUMBER;
- }
-
- switch (*eval_text++)
- {
- case '+':
- if (*eval_text == '+' || *eval_text == '=')
- return BADOP;
- return PLUS;
- case '-':
- if (*eval_text == '-' || *eval_text == '=')
- return BADOP;
- return MINUS;
- case '*':
- if (*eval_text == '*')
- {
- eval_text++;
- return EXPONENT;
- }
- else if (*eval_text == '=')
- return BADOP;
- return TIMES;
- case '/':
- if (*eval_text == '=')
- return BADOP;
- return DIVIDE;
- case '%':
- if (*eval_text == '=')
- return BADOP;
- return MODULO;
- case '=':
- if (*eval_text == '=')
- {
- eval_text++;
- return EQ;
- }
- return ASSIGN;
- case '!':
- if (*eval_text == '=')
- {
- eval_text++;
- return NOTEQ;
- }
- return LNOT;
- case '>':
- if (*eval_text == '=')
- {
- eval_text++;
- return GTEQ;
- }
- else if (*eval_text == '>')
- {
- if (*++eval_text == '=')
- return BADOP;
- return RSHIFT;
- }
- return GT;
- case '<':
- if (*eval_text == '=')
- {
- eval_text++;
- return LSEQ;
- }
- else if (*eval_text == '<')
- {
- if (*++eval_text == '=')
- return BADOP;
- return LSHIFT;
- }
- return LS;
- case '^':
- if (*eval_text == '=')
- return BADOP;
- return XOR;
- case '~':
- return NOT;
- case '&':
- if (*eval_text == '&')
- {
- eval_text++;
- return LAND;
- }
- else if (*eval_text == '=')
- return BADOP;
- return AND;
- case '|':
- if (*eval_text == '|')
- {
- eval_text++;
- return LOR;
- }
- else if (*eval_text == '=')
- return BADOP;
- return OR;
- case '(':
- return LEFTP;
- case ')':
- return RIGHTP;
- default:
- return ERROR;
- }
-}
-
-/*---------------------------------------.
-| Main entry point, called from "eval". |
-`---------------------------------------*/
-
-bool
-evaluate (const char *expr, int32_t *val)
-{
- eval_token et;
- eval_error err;
-
- eval_init_lex (expr);
- et = eval_lex (val);
- err = logical_or_term (et, val);
-
- if (err == NO_ERROR && *eval_text != '\0')
- {
- if (eval_lex (val) == BADOP)
- err = INVALID_OPERATOR;
- else
- err = EXCESS_INPUT;
- }
-
- switch (err)
- {
- case NO_ERROR:
- break;
-
- case MISSING_RIGHT:
- M4ERROR ((warning_status, 0,
- "bad expression in eval (missing right parenthesis): %s",
- expr));
- break;
-
- case SYNTAX_ERROR:
- M4ERROR ((warning_status, 0,
- "bad expression in eval: %s", expr));
- break;
-
- case UNKNOWN_INPUT:
- M4ERROR ((warning_status, 0,
- "bad expression in eval (bad input): %s", expr));
- break;
-
- case EXCESS_INPUT:
- M4ERROR ((warning_status, 0,
- "bad expression in eval (excess input): %s", expr));
- break;
-
- case INVALID_OPERATOR:
- M4ERROR ((warning_status, 0,
- "invalid operator in eval: %s", expr));
- retcode = EXIT_FAILURE;
- break;
-
- case DIVIDE_ZERO:
- M4ERROR ((warning_status, 0,
- "divide by zero in eval: %s", expr));
- break;
-
- case MODULO_ZERO:
- M4ERROR ((warning_status, 0,
- "modulo by zero in eval: %s", expr));
- break;
-
- case NEGATIVE_EXPONENT:
- M4ERROR ((warning_status, 0,
- "negative exponent in eval: %s", expr));
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad error code in evaluate ()"));
- abort ();
- }
-
- return err != NO_ERROR;
-}
-
-/*---------------------------.
-| Recursive descent parser. |
-`---------------------------*/
-
-static eval_error
-logical_or_term (eval_token et, int32_t *v1)
-{
- int32_t v2;
- eval_error er;
-
- if ((er = logical_and_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((et = eval_lex (&v2)) == LOR)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- /* Implement short-circuiting of valid syntax. */
- er = logical_and_term (et, &v2);
- if (er == NO_ERROR)
- *v1 = *v1 || v2;
- else if (*v1 != 0 && er < SYNTAX_ERROR)
- *v1 = 1;
- else
- return er;
- }
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-logical_and_term (eval_token et, int32_t *v1)
-{
- int32_t v2;
- eval_error er;
-
- if ((er = or_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((et = eval_lex (&v2)) == LAND)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- /* Implement short-circuiting of valid syntax. */
- er = or_term (et, &v2);
- if (er == NO_ERROR)
- *v1 = *v1 && v2;
- else if (*v1 == 0 && er < SYNTAX_ERROR)
- ; /* v1 is already 0 */
- else
- return er;
- }
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-or_term (eval_token et, int32_t *v1)
-{
- int32_t v2;
- eval_error er;
-
- if ((er = xor_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((et = eval_lex (&v2)) == OR)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = xor_term (et, &v2)) != NO_ERROR)
- return er;
-
- *v1 |= v2;
- }
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-xor_term (eval_token et, int32_t *v1)
-{
- int32_t v2;
- eval_error er;
-
- if ((er = and_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((et = eval_lex (&v2)) == XOR)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = and_term (et, &v2)) != NO_ERROR)
- return er;
-
- *v1 ^= v2;
- }
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-and_term (eval_token et, int32_t *v1)
-{
- int32_t v2;
- eval_error er;
-
- if ((er = equality_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((et = eval_lex (&v2)) == AND)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = equality_term (et, &v2)) != NO_ERROR)
- return er;
-
- *v1 &= v2;
- }
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-equality_term (eval_token et, int32_t *v1)
-{
- eval_token op;
- int32_t v2;
- eval_error er;
-
- if ((er = cmp_term (et, v1)) != NO_ERROR)
- return er;
-
- /* In the 1.4.x series, we maintain the traditional behavior that
- '=' is a synonym for '=='; however, this is contrary to POSIX and
- we hope to convert '=' to mean assignment in 2.0. */
- while ((op = eval_lex (&v2)) == EQ || op == NOTEQ || op == ASSIGN)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = cmp_term (et, &v2)) != NO_ERROR)
- return er;
-
- if (op == ASSIGN)
- {
- M4ERROR ((warning_status, 0, "\
-Warning: recommend ==, not =, for equality operator"));
- op = EQ;
- }
- *v1 = (op == EQ) == (*v1 == v2);
- }
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-cmp_term (eval_token et, int32_t *v1)
-{
- eval_token op;
- int32_t v2;
- eval_error er;
-
- if ((er = shift_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((op = eval_lex (&v2)) == GT || op == GTEQ
- || op == LS || op == LSEQ)
- {
-
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = shift_term (et, &v2)) != NO_ERROR)
- return er;
-
- switch (op)
- {
- case GT:
- *v1 = *v1 > v2;
- break;
-
- case GTEQ:
- *v1 = *v1 >= v2;
- break;
-
- case LS:
- *v1 = *v1 < v2;
- break;
-
- case LSEQ:
- *v1 = *v1 <= v2;
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad comparison operator in cmp_term ()"));
- abort ();
- }
- }
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-shift_term (eval_token et, int32_t *v1)
-{
- eval_token op;
- int32_t v2;
- uint32_t u1;
- eval_error er;
-
- if ((er = add_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((op = eval_lex (&v2)) == LSHIFT || op == RSHIFT)
- {
-
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = add_term (et, &v2)) != NO_ERROR)
- return er;
-
- /* Minimize undefined C behavior (shifting by a negative number,
- shifting by the width or greater, left shift overflow, or
- right shift of a negative number). Implement Java 32-bit
- wrap-around semantics. This code assumes that the
- implementation-defined overflow when casting unsigned to
- signed is a silent twos-complement wrap-around. */
- switch (op)
- {
- case LSHIFT:
- u1 = *v1;
- u1 <<= (uint32_t) (v2 & 0x1f);
- *v1 = u1;
- break;
-
- case RSHIFT:
- u1 = *v1 < 0 ? ~*v1 : *v1;
- u1 >>= (uint32_t) (v2 & 0x1f);
- *v1 = *v1 < 0 ? ~u1 : u1;
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad shift operator in shift_term ()"));
- abort ();
- }
- }
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-add_term (eval_token et, int32_t *v1)
-{
- eval_token op;
- int32_t v2;
- eval_error er;
-
- if ((er = mult_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((op = eval_lex (&v2)) == PLUS || op == MINUS)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = mult_term (et, &v2)) != NO_ERROR)
- return er;
-
- /* Minimize undefined C behavior on overflow. This code assumes
- that the implementation-defined overflow when casting
- unsigned to signed is a silent twos-complement
- wrap-around. */
- if (op == PLUS)
- *v1 = (int32_t) ((uint32_t) *v1 + (uint32_t) v2);
- else
- *v1 = (int32_t) ((uint32_t) *v1 - (uint32_t) v2);
- }
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-mult_term (eval_token et, int32_t *v1)
-{
- eval_token op;
- int32_t v2;
- eval_error er;
-
- if ((er = exp_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((op = eval_lex (&v2)) == TIMES || op == DIVIDE || op == MODULO)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = exp_term (et, &v2)) != NO_ERROR)
- return er;
-
- /* Minimize undefined C behavior on overflow. This code assumes
- that the implementation-defined overflow when casting
- unsigned to signed is a silent twos-complement
- wrap-around. */
- switch (op)
- {
- case TIMES:
- *v1 = (int32_t) ((uint32_t) *v1 * (uint32_t) v2);
- break;
-
- case DIVIDE:
- if (v2 == 0)
- return DIVIDE_ZERO;
- else if (v2 == -1)
- /* Avoid overflow, and the x86 SIGFPE on INT_MIN / -1. */
- *v1 = (int32_t) -(uint32_t) *v1;
- else
- *v1 /= v2;
- break;
-
- case MODULO:
- if (v2 == 0)
- return MODULO_ZERO;
- else if (v2 == -1)
- /* Avoid the x86 SIGFPE on INT_MIN % -1. */
- *v1 = 0;
- else
- *v1 %= v2;
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad operator in mult_term ()"));
- abort ();
- }
- }
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-exp_term (eval_token et, int32_t *v1)
-{
- uint32_t result;
- int32_t v2;
- eval_error er;
-
- if ((er = unary_term (et, v1)) != NO_ERROR)
- return er;
-
- while ((et = eval_lex (&v2)) == EXPONENT)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = exp_term (et, &v2)) != NO_ERROR)
- return er;
-
- /* Minimize undefined C behavior on overflow. This code assumes
- that the implementation-defined overflow when casting
- unsigned to signed is a silent twos-complement
- wrap-around. */
- result = 1;
- if (v2 < 0)
- return NEGATIVE_EXPONENT;
- if (*v1 == 0 && v2 == 0)
- return DIVIDE_ZERO;
- while (v2-- > 0)
- result *= (uint32_t) *v1;
- *v1 = result;
- }
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-unary_term (eval_token et, int32_t *v1)
-{
- eval_error er;
-
- if (et == PLUS || et == MINUS || et == NOT || et == LNOT)
- {
- eval_token et2 = eval_lex (v1);
- if (et2 == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = unary_term (et2, v1)) != NO_ERROR)
- return er;
-
- /* Minimize undefined C behavior on overflow. This code assumes
- that the implementation-defined overflow when casting
- unsigned to signed is a silent twos-complement
- wrap-around. */
- if (et == MINUS)
- *v1 = (int32_t) -(uint32_t) *v1;
- else if (et == NOT)
- *v1 = ~*v1;
- else if (et == LNOT)
- *v1 = *v1 == 0 ? 1 : 0;
- }
- else if ((er = simple_term (et, v1)) != NO_ERROR)
- return er;
-
- return NO_ERROR;
-}
-
-static eval_error
-simple_term (eval_token et, int32_t *v1)
-{
- int32_t v2;
- eval_error er;
-
- switch (et)
- {
- case LEFTP:
- et = eval_lex (v1);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = logical_or_term (et, v1)) != NO_ERROR)
- return er;
-
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if (et != RIGHTP)
- return MISSING_RIGHT;
-
- break;
-
- case NUMBER:
- break;
-
- case BADOP:
- return INVALID_OPERATOR;
-
- default:
- return SYNTAX_ERROR;
- }
- return NO_ERROR;
-}
diff --git a/contrib/tools/bison/m4/src/format.c b/contrib/tools/bison/m4/src/format.c
deleted file mode 100644
index fd8830ed7c..0000000000
--- a/contrib/tools/bison/m4/src/format.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2006-2013 Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* printf like formatting for m4. */
-
-#include "m4.h"
-#include "xvasprintf.h"
-
-/* Simple varargs substitute. We assume int and unsigned int are the
- same size; likewise for long and unsigned long. */
-
-/* Parse STR as an integer, reporting warnings. */
-static int
-arg_int (const char *str)
-{
- char *endp;
- long value;
- size_t len = strlen (str);
-
- if (!len)
- {
- M4ERROR ((warning_status, 0, _("empty string treated as 0")));
- return 0;
- }
- errno = 0;
- value = strtol (str, &endp, 10);
- if (endp - str - len)
- M4ERROR ((warning_status, 0, _("non-numeric argument %s"), str));
- else if (isspace (to_uchar (*str)))
- M4ERROR ((warning_status, 0, _("leading whitespace ignored")));
- else if (errno == ERANGE || (int) value != value)
- M4ERROR ((warning_status, 0, _("numeric overflow detected")));
- return value;
-}
-
-/* Parse STR as a long, reporting warnings. */
-static long
-arg_long (const char *str)
-{
- char *endp;
- long value;
- size_t len = strlen (str);
-
- if (!len)
- {
- M4ERROR ((warning_status, 0, _("empty string treated as 0")));
- return 0L;
- }
- errno = 0;
- value = strtol (str, &endp, 10);
- if (endp - str - len)
- M4ERROR ((warning_status, 0, _("non-numeric argument %s"), str));
- else if (isspace (to_uchar (*str)))
- M4ERROR ((warning_status, 0, _("leading whitespace ignored")));
- else if (errno == ERANGE)
- M4ERROR ((warning_status, 0, _("numeric overflow detected")));
- return value;
-}
-
-/* Parse STR as a double, reporting warnings. */
-static double
-arg_double (const char *str)
-{
- char *endp;
- double value;
- size_t len = strlen (str);
-
- if (!len)
- {
- M4ERROR ((warning_status, 0, _("empty string treated as 0")));
- return 0.0;
- }
- errno = 0;
- value = strtod (str, &endp);
- if (endp - str - len)
- M4ERROR ((warning_status, 0, _("non-numeric argument %s"), str));
- else if (isspace (to_uchar (*str)))
- M4ERROR ((warning_status, 0, _("leading whitespace ignored")));
- else if (errno == ERANGE)
- M4ERROR ((warning_status, 0, _("numeric overflow detected")));
- return value;
-}
-
-#define ARG_INT(argc, argv) \
- ((argc == 0) ? 0 : \
- (--argc, argv++, arg_int (TOKEN_DATA_TEXT (argv[-1]))))
-
-#define ARG_LONG(argc, argv) \
- ((argc == 0) ? 0 : \
- (--argc, argv++, arg_long (TOKEN_DATA_TEXT (argv[-1]))))
-
-#define ARG_STR(argc, argv) \
- ((argc == 0) ? "" : \
- (--argc, argv++, TOKEN_DATA_TEXT (argv[-1])))
-
-#define ARG_DOUBLE(argc, argv) \
- ((argc == 0) ? 0 : \
- (--argc, argv++, arg_double (TOKEN_DATA_TEXT (argv[-1]))))
-
-
-/*------------------------------------------------------------------.
-| The main formatting function. Output is placed on the obstack |
-| OBS, the first argument in ARGV is the formatting string, and the |
-| rest is arguments for the string. Warn rather than invoke |
-| unspecified behavior in the underlying printf when we do not |
-| recognize a format. |
-`------------------------------------------------------------------*/
-
-void
-expand_format (struct obstack *obs, int argc, token_data **argv)
-{
- 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 */
-
- /* Flags. */
- char flags; /* flags to use in fstart */
- enum {
- THOUSANDS = 0x01, /* ' */
- PLUS = 0x02, /* + */
- MINUS = 0x04, /* - */
- SPACE = 0x08, /* */
- ZERO = 0x10, /* 0 */
- ALT = 0x20, /* # */
- DONE = 0x40 /* no more flags */
- };
-
- /* Precision specifiers. */
- int width; /* minimum field width */
- int prec; /* precision */
- char lflag; /* long flag */
-
- /* Specifiers we are willing to accept. ok['x'] implies %x is ok.
- Various modifiers reduce the set, in order to avoid undefined
- behavior in printf. */
- char ok[128];
-
- /* Buffer and stuff. */
- char *str; /* malloc'd buffer of formatted text */
- enum {CHAR, INT, LONG, DOUBLE, STR} datatype;
-
- f = fmt = ARG_STR (argc, argv);
- memset (ok, 0, sizeof ok);
- while (1)
- {
- const char *percent = strchr (fmt, '%');
- if (!percent)
- {
- obstack_grow (obs, fmt, strlen (fmt));
- return;
- }
- obstack_grow (obs, fmt, percent - fmt);
- fmt = percent + 1;
-
- if (*fmt == '%')
- {
- obstack_1grow (obs, '%');
- fmt++;
- continue;
- }
-
- p = fstart + 1; /* % */
- lflag = 0;
- ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E']
- = ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o']
- = ok['s'] = ok['u'] = ok['x'] = ok['X'] = 1;
-
- /* Parse flags. */
- flags = 0;
- do
- {
- switch (*fmt)
- {
- case '\'': /* thousands separator */
- ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E']
- = ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
- flags |= THOUSANDS;
- break;
-
- case '+': /* mandatory sign */
- ok['c'] = ok['o'] = ok['s'] = ok['u'] = ok['x'] = ok['X'] = 0;
- flags |= PLUS;
- break;
-
- case ' ': /* space instead of positive sign */
- ok['c'] = ok['o'] = ok['s'] = ok['u'] = ok['x'] = ok['X'] = 0;
- flags |= SPACE;
- break;
-
- case '0': /* zero padding */
- ok['c'] = ok['s'] = 0;
- flags |= ZERO;
- break;
-
- case '#': /* alternate output */
- ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
- flags |= ALT;
- break;
-
- case '-': /* left justification */
- flags |= MINUS;
- break;
-
- default:
- flags |= DONE;
- break;
- }
- }
- while (!(flags & DONE) && fmt++);
- if (flags & THOUSANDS)
- *p++ = '\'';
- if (flags & PLUS)
- *p++ = '+';
- if (flags & MINUS)
- *p++ = '-';
- if (flags & SPACE)
- *p++ = ' ';
- if (flags & ZERO)
- *p++ = '0';
- if (flags & ALT)
- *p++ = '#';
-
- /* Minimum field width; an explicit 0 is the same as not giving
- the width. */
- width = 0;
- *p++ = '*';
- if (*fmt == '*')
- {
- width = ARG_INT (argc, argv);
- fmt++;
- }
- else
- while (isdigit (to_uchar (*fmt)))
- {
- width = 10 * width + *fmt - '0';
- fmt++;
- }
-
- /* Maximum precision; an explicit negative precision is the same
- as not giving the precision. A lone '.' is a precision of 0. */
- prec = -1;
- *p++ = '.';
- *p++ = '*';
- if (*fmt == '.')
- {
- ok['c'] = 0;
- if (*(++fmt) == '*')
- {
- prec = ARG_INT (argc, argv);
- ++fmt;
- }
- else
- {
- prec = 0;
- while (isdigit (to_uchar (*fmt)))
- {
- prec = 10 * prec + *fmt - '0';
- fmt++;
- }
- }
- }
-
- /* Length modifiers. We don't yet recognize ll, j, t, or z. */
- if (*fmt == 'l')
- {
- *p++ = 'l';
- lflag = 1;
- fmt++;
- ok['c'] = ok['s'] = 0;
- }
- else if (*fmt == 'h')
- {
- *p++ = 'h';
- fmt++;
- if (*fmt == 'h')
- {
- *p++ = 'h';
- fmt++;
- }
- ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] = ok['f'] = ok['F']
- = ok['g'] = ok['G'] = ok['s'] = 0;
- }
-
- c = *fmt++;
- if (sizeof ok <= c || !ok[c])
- {
- M4ERROR ((warning_status, 0,
- "Warning: unrecognized specifier in `%s'", f));
- if (c == '\0')
- fmt--;
- continue;
- }
-
- /* Specifiers. We don't yet recognize C, S, n, or p. */
- switch (c)
- {
- case 'c':
- datatype = CHAR;
- p -= 2; /* %.*c is undefined, so undo the '.*'. */
- break;
-
- case 's':
- datatype = STR;
- break;
-
- case 'd':
- case 'i':
- case 'o':
- case 'x':
- case 'X':
- case 'u':
- datatype = lflag ? LONG : INT;
- break;
-
- case 'a':
- case 'A':
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- datatype = DOUBLE;
- break;
-
- default:
- abort ();
- }
- *p++ = c;
- *p = '\0';
-
- /* Our constructed format string in fstart is safe. */
-#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wformat-nonliteral"
-#endif
-
- switch (datatype)
- {
- case CHAR:
- str = xasprintf (fstart, width, ARG_INT(argc, argv));
- break;
-
- case INT:
- str = xasprintf (fstart, width, prec, ARG_INT(argc, argv));
- break;
-
- case LONG:
- str = xasprintf (fstart, width, prec, ARG_LONG(argc, argv));
- break;
-
- case DOUBLE:
- str = xasprintf (fstart, width, prec, ARG_DOUBLE(argc, argv));
- break;
-
- case STR:
- str = xasprintf (fstart, width, prec, ARG_STR(argc, argv));
- break;
-
- default:
- abort();
- }
-#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
-# pragma GCC diagnostic pop
-#endif
-
- /* NULL was returned on failure, such as invalid format string. For
- now, just silently ignore that bad specifier. */
- if (str == NULL)
- continue;
-
- obstack_grow (obs, str, strlen (str));
- free (str);
- }
-}
diff --git a/contrib/tools/bison/m4/src/freeze.c b/contrib/tools/bison/m4/src/freeze.c
deleted file mode 100644
index edc0568b96..0000000000
--- a/contrib/tools/bison/m4/src/freeze.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2006-2013 Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* This module handles frozen files. */
-
-#include "m4.h"
-
-/*-------------------------------------------------------------------.
-| Destructively reverse a symbol list and return the reversed list. |
-`-------------------------------------------------------------------*/
-
-static symbol *
-reverse_symbol_list (symbol *sym)
-{
- symbol *result;
- symbol *next;
-
- result = NULL;
- while (sym)
- {
- next = SYMBOL_NEXT (sym);
- SYMBOL_NEXT (sym) = result;
- result = sym;
- sym = next;
- }
- return result;
-}
-
-/*------------------------------------------------.
-| Produce a frozen state to the given file NAME. |
-`------------------------------------------------*/
-
-void
-produce_frozen_state (const char *name)
-{
- FILE *file;
- size_t h;
- symbol *sym;
- const builtin *bp;
-
- file = fopen (name, O_BINARY ? "wb" : "w");
- if (!file)
- {
- M4ERROR ((EXIT_FAILURE, errno, "cannot open `%s'", name));
- return;
- }
-
- /* Write a recognizable header. */
-
- xfprintf (file, "# This is a frozen state file generated by %s\n",
- PACKAGE_STRING);
- xfprintf (file, "V1\n");
-
- /* Dump quote delimiters. */
-
- if (strcmp (lquote.string, DEF_LQUOTE) || strcmp (rquote.string, DEF_RQUOTE))
- {
- xfprintf (file, "Q%d,%d\n", (int) lquote.length, (int) rquote.length);
- fputs (lquote.string, file);
- fputs (rquote.string, file);
- fputc ('\n', file);
- }
-
- /* Dump comment delimiters. */
-
- if (strcmp (bcomm.string, DEF_BCOMM) || strcmp (ecomm.string, DEF_ECOMM))
- {
- xfprintf (file, "C%d,%d\n", (int) bcomm.length, (int) ecomm.length);
- fputs (bcomm.string, file);
- fputs (ecomm.string, file);
- fputc ('\n', file);
- }
-
- /* Dump all symbols. */
-
- for (h = 0; h < hash_table_size; h++)
- {
-
- /* Process all entries in one bucket, from the last to the first.
- This order ensures that, at reload time, pushdef's will be
- executed with the oldest definitions first. */
-
- symtab[h] = reverse_symbol_list (symtab[h]);
- for (sym = symtab[h]; sym; sym = SYMBOL_NEXT (sym))
- {
- switch (SYMBOL_TYPE (sym))
- {
- case TOKEN_TEXT:
- xfprintf (file, "T%d,%d\n",
- (int) strlen (SYMBOL_NAME (sym)),
- (int) strlen (SYMBOL_TEXT (sym)));
- fputs (SYMBOL_NAME (sym), file);
- fputs (SYMBOL_TEXT (sym), file);
- fputc ('\n', file);
- break;
-
- case TOKEN_FUNC:
- bp = find_builtin_by_addr (SYMBOL_FUNC (sym));
- if (bp == NULL)
- {
- M4ERROR ((warning_status, 0, "\
-INTERNAL ERROR: builtin not found in builtin table!"));
- abort ();
- }
- xfprintf (file, "F%d,%d\n",
- (int) strlen (SYMBOL_NAME (sym)),
- (int) strlen (bp->name));
- fputs (SYMBOL_NAME (sym), file);
- fputs (bp->name, file);
- fputc ('\n', file);
- break;
-
- case TOKEN_VOID:
- /* Ignore placeholder tokens that exist due to traceon. */
- break;
-
- default:
- M4ERROR ((warning_status, 0, "\
-INTERNAL ERROR: bad token data type in freeze_one_symbol ()"));
- abort ();
- break;
- }
- }
-
- /* Reverse the bucket once more, putting it back as it was. */
-
- symtab[h] = reverse_symbol_list (symtab[h]);
- }
-
- /* Let diversions be issued from output.c module, its cleaner to have this
- piece of code there. */
-
- freeze_diversions (file);
-
- /* All done. */
-
- fputs ("# End of frozen state file\n", file);
- if (close_stream (file) != 0)
- M4ERROR ((EXIT_FAILURE, errno, "unable to create frozen state"));
-}
-
-/*----------------------------------------------------------------------.
-| Issue a message saying that some character is an EXPECTED character. |
-`----------------------------------------------------------------------*/
-
-static void
-issue_expect_message (int expected)
-{
- if (expected == '\n')
- M4ERROR ((EXIT_FAILURE, 0, "expecting line feed in frozen file"));
- else
- M4ERROR ((EXIT_FAILURE, 0, "expecting character `%c' in frozen file",
- expected));
-}
-
-/*-------------------------------------------------.
-| Reload a frozen state from the given file NAME. |
-`-------------------------------------------------*/
-
-/* We are seeking speed, here. */
-
-void
-reload_frozen_state (const char *name)
-{
- FILE *file;
- int character;
- int operation;
- char *string[2];
- int allocated[2];
- int number[2];
- const builtin *bp;
- bool advance_line = true;
-
-#define GET_CHARACTER \
- do \
- { \
- if (advance_line) \
- { \
- current_line++; \
- advance_line = false; \
- } \
- (character = getc (file)); \
- if (character == '\n') \
- advance_line = true; \
- } \
- while (0)
-
-#define GET_NUMBER(Number, AllowNeg) \
- do \
- { \
- unsigned int n = 0; \
- while (isdigit (character) && n <= INT_MAX / 10U) \
- { \
- n = 10 * n + character - '0'; \
- GET_CHARACTER; \
- } \
- if (((AllowNeg) ? INT_MIN : INT_MAX) + 0U < n \
- || isdigit (character)) \
- m4_error (EXIT_FAILURE, 0, \
- _("integer overflow in frozen file")); \
- (Number) = n; \
- } \
- while (0)
-
-#define VALIDATE(Expected) \
- do \
- { \
- if (character != (Expected)) \
- issue_expect_message (Expected); \
- } \
- while (0)
-
- /* Skip comments (`#' at beginning of line) and blank lines, setting
- character to the next directive or to EOF. */
-
-#define GET_DIRECTIVE \
- do \
- { \
- GET_CHARACTER; \
- if (character == '#') \
- { \
- while (character != EOF && character != '\n') \
- GET_CHARACTER; \
- VALIDATE ('\n'); \
- } \
- } \
- while (character == '\n')
-
-#define GET_STRING(i) \
- do \
- { \
- void *tmp; \
- char *p; \
- if (number[(i)] + 1 > allocated[(i)]) \
- { \
- free (string[(i)]); \
- allocated[(i)] = number[(i)] + 1; \
- string[(i)] = xcharalloc ((size_t) allocated[(i)]); \
- } \
- if (number[(i)] > 0 \
- && !fread (string[(i)], (size_t) number[(i)], 1, file)) \
- m4_error (EXIT_FAILURE, 0, \
- _("premature end of frozen file")); \
- string[(i)][number[(i)]] = '\0'; \
- p = string[(i)]; \
- while ((tmp = memchr(p, '\n', number[(i)] - (p - string[(i)])))) \
- { \
- current_line++; \
- p = (char *) tmp + 1; \
- } \
- } \
- while (0)
-
- file = m4_path_search (name, NULL);
- if (file == NULL)
- M4ERROR ((EXIT_FAILURE, errno, "cannot open %s", name));
- current_file = name;
-
- allocated[0] = 100;
- string[0] = xcharalloc ((size_t) allocated[0]);
- allocated[1] = 100;
- string[1] = xcharalloc ((size_t) allocated[1]);
-
- /* Validate format version. Only `1' is acceptable for now. */
- GET_DIRECTIVE;
- VALIDATE ('V');
- GET_CHARACTER;
- GET_NUMBER (number[0], false);
- if (number[0] > 1)
- M4ERROR ((EXIT_MISMATCH, 0,
- "frozen file version %d greater than max supported of 1",
- number[0]));
- else if (number[0] < 1)
- M4ERROR ((EXIT_FAILURE, 0,
- "ill-formed frozen file, version directive expected"));
- VALIDATE ('\n');
-
- GET_DIRECTIVE;
- while (character != EOF)
- {
- switch (character)
- {
- default:
- M4ERROR ((EXIT_FAILURE, 0, "ill-formed frozen file"));
-
- case 'C':
- case 'D':
- case 'F':
- case 'T':
- case 'Q':
- operation = character;
- GET_CHARACTER;
-
- /* Get string lengths. Accept a negative diversion number. */
-
- if (operation == 'D' && character == '-')
- {
- GET_CHARACTER;
- GET_NUMBER (number[0], true);
- number[0] = -number[0];
- }
- else
- GET_NUMBER (number[0], false);
- VALIDATE (',');
- GET_CHARACTER;
- GET_NUMBER (number[1], false);
- VALIDATE ('\n');
-
- if (operation != 'D')
- GET_STRING (0);
- GET_STRING (1);
- GET_CHARACTER;
- VALIDATE ('\n');
-
- /* Act according to operation letter. */
-
- switch (operation)
- {
- case 'C':
-
- /* Change comment strings. */
-
- set_comment (string[0], string[1]);
- break;
-
- case 'D':
-
- /* Select a diversion and add a string to it. */
-
- make_diversion (number[0]);
- if (number[1] > 0)
- output_text (string[1], number[1]);
- break;
-
- case 'F':
-
- /* Enter a macro having a builtin function as a definition. */
-
- bp = find_builtin_by_name (string[1]);
- define_builtin (string[0], bp, SYMBOL_PUSHDEF);
- break;
-
- case 'T':
-
- /* Enter a macro having an expansion text as a definition. */
-
- define_user_macro (string[0], string[1], SYMBOL_PUSHDEF);
- break;
-
- case 'Q':
-
- /* Change quote strings. */
-
- set_quotes (string[0], string[1]);
- break;
-
- default:
-
- /* Cannot happen. */
-
- break;
- }
- break;
-
- }
- GET_DIRECTIVE;
- }
-
- free (string[0]);
- free (string[1]);
- if (close_stream (file) != 0)
- m4_error (EXIT_FAILURE, errno, _("unable to read frozen state"));
- current_file = NULL;
- current_line = 0;
-
-#undef GET_CHARACTER
-#undef GET_DIRECTIVE
-#undef GET_NUMBER
-#undef VALIDATE
-#undef GET_STRING
-}
diff --git a/contrib/tools/bison/m4/src/input.c b/contrib/tools/bison/m4/src/input.c
deleted file mode 100644
index 836d706489..0000000000
--- a/contrib/tools/bison/m4/src/input.c
+++ /dev/null
@@ -1,1156 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2004-2013 Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Handling of different input sources, and lexical analysis. */
-
-#include "m4.h"
-
-#include "memchr2.h"
-
-/* Unread input can be either files, that should be read (eg. included
- files), strings, which should be rescanned (eg. macro expansion text),
- or quoted macro definitions (as returned by the builtin "defn").
- Unread input are organised in a stack, implemented with an obstack.
- Each input source is described by a "struct input_block". The obstack
- is "current_input". The top of the input stack is "isp".
-
- The macro "m4wrap" places the text to be saved on another input
- stack, on the obstack "wrapup_stack", whose top is "wsp". When EOF
- is seen on normal input (eg, when "current_input" is empty), input is
- switched over to "wrapup_stack", and the original "current_input" is
- freed. A new stack is allocated for "wrapup_stack", which will
- accept any text produced by calls to "m4wrap" from within the
- wrapped text. This process of shuffling "wrapup_stack" to
- "current_input" can continue indefinitely, even generating infinite
- loops (e.g. "define(`f',`m4wrap(`f')')f"), without memory leaks.
-
- Pushing new input on the input stack is done by push_file (),
- push_string (), push_wrapup () (for wrapup text), and push_macro ()
- (for macro definitions). Because macro expansion needs direct access
- to the current input obstack (for optimisation), push_string () are
- split in two functions, push_string_init (), which returns a pointer
- to the current input stack, and push_string_finish (), which return a
- pointer to the final text. The input_block *next is used to manage
- the coordination between the different push routines.
-
- The current file and line number are stored in two global
- variables, for use by the error handling functions in m4.c. Macro
- expansion wants to report the line where a macro name was detected,
- rather than where it finished collecting arguments. This also
- applies to text resulting from macro expansions. So each input
- block maintains its own notion of the current file and line, and
- swapping between input blocks updates the global variables
- accordingly. */
-
-#ifdef ENABLE_CHANGEWORD
-#include <contrib/tools/bison/gnulib/src/regex.h>
-#endif
-
-enum input_type
-{
- INPUT_STRING, /* String resulting from macro expansion. */
- INPUT_FILE, /* File from command line or include. */
- INPUT_MACRO /* Builtin resulting from defn. */
-};
-
-typedef enum input_type input_type;
-
-struct input_block
-{
- struct input_block *prev; /* previous input_block on the input stack */
- input_type type; /* see enum values */
- const char *file; /* file where this input is from */
- int line; /* line where this input is from */
- union
- {
- struct
- {
- char *string; /* remaining string value */
- char *end; /* terminating NUL of string */
- }
- u_s; /* INPUT_STRING */
- struct
- {
- FILE *fp; /* input file handle */
- bool_bitfield end : 1; /* true if peek has seen EOF */
- bool_bitfield close : 1; /* true if we should close file on pop */
- bool_bitfield advance : 1; /* track previous start_of_input_line */
- }
- u_f; /* INPUT_FILE */
- builtin_func *func; /* pointer to macro's function */
- }
- u;
-};
-
-typedef struct input_block input_block;
-
-
-/* Current input file name. */
-const char *current_file;
-
-/* Current input line number. */
-int current_line;
-
-/* Obstack for storing individual tokens. */
-static struct obstack token_stack;
-
-/* Obstack for storing file names. */
-static struct obstack file_names;
-
-/* Wrapup input stack. */
-static struct obstack *wrapup_stack;
-
-/* Current stack, from input or wrapup. */
-static struct obstack *current_input;
-
-/* Bottom of token_stack, for obstack_free. */
-static void *token_bottom;
-
-/* Pointer to top of current_input. */
-static input_block *isp;
-
-/* Pointer to top of wrapup_stack. */
-static input_block *wsp;
-
-/* Aux. for handling split push_string (). */
-static input_block *next;
-
-/* Flag for next_char () to increment current_line. */
-static bool start_of_input_line;
-
-/* Flag for next_char () to recognize change in input block. */
-static bool input_change;
-
-#define CHAR_EOF 256 /* character return on EOF */
-#define CHAR_MACRO 257 /* character return for MACRO token */
-
-/* Quote chars. */
-STRING rquote;
-STRING lquote;
-
-/* Comment chars. */
-STRING bcomm;
-STRING ecomm;
-
-#ifdef ENABLE_CHANGEWORD
-
-# define DEFAULT_WORD_REGEXP "[_a-zA-Z][_a-zA-Z0-9]*"
-
-static struct re_pattern_buffer word_regexp;
-static int default_word_regexp;
-static struct re_registers regs;
-
-#else /* ! ENABLE_CHANGEWORD */
-# define default_word_regexp 1
-#endif /* ! ENABLE_CHANGEWORD */
-
-#ifdef DEBUG_INPUT
-static const char *token_type_string (token_type);
-#endif
-
-
-/*-------------------------------------------------------------------.
-| push_file () pushes an input file on the input stack, saving the |
-| current file name and line number. If next is non-NULL, this push |
-| invalidates a call to push_string_init (), whose storage is |
-| consequently released. If CLOSE_WHEN_DONE, then close FP after |
-| EOF is detected. |
-`-------------------------------------------------------------------*/
-
-void
-push_file (FILE *fp, const char *title, bool close_when_done)
-{
- input_block *i;
-
- if (next != NULL)
- {
- obstack_free (current_input, next);
- next = NULL;
- }
-
- if (debug_level & DEBUG_TRACE_INPUT)
- DEBUG_MESSAGE1 ("input read from %s", title);
-
- i = (input_block *) obstack_alloc (current_input,
- sizeof (struct input_block));
- i->type = INPUT_FILE;
- i->file = (char *) obstack_copy0 (&file_names, title, strlen (title));
- i->line = 1;
- input_change = true;
-
- i->u.u_f.fp = fp;
- i->u.u_f.end = false;
- i->u.u_f.close = close_when_done;
- i->u.u_f.advance = start_of_input_line;
- output_current_line = -1;
-
- i->prev = isp;
- isp = i;
-}
-
-/*---------------------------------------------------------------.
-| push_macro () pushes a builtin macro's definition on the input |
-| stack. If next is non-NULL, this push invalidates a call to |
-| push_string_init (), whose storage is consequently released. |
-`---------------------------------------------------------------*/
-
-void
-push_macro (builtin_func *func)
-{
- input_block *i;
-
- if (next != NULL)
- {
- obstack_free (current_input, next);
- next = NULL;
- }
-
- i = (input_block *) obstack_alloc (current_input,
- sizeof (struct input_block));
- i->type = INPUT_MACRO;
- i->file = current_file;
- i->line = current_line;
- input_change = true;
-
- i->u.func = func;
- i->prev = isp;
- isp = i;
-}
-
-/*------------------------------------------------------------------.
-| First half of push_string (). The pointer next points to the new |
-| input_block. |
-`------------------------------------------------------------------*/
-
-struct obstack *
-push_string_init (void)
-{
- if (next != NULL)
- {
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: recursive push_string!"));
- abort ();
- }
-
- next = (input_block *) obstack_alloc (current_input,
- sizeof (struct input_block));
- next->type = INPUT_STRING;
- next->file = current_file;
- next->line = current_line;
-
- return current_input;
-}
-
-/*-------------------------------------------------------------------.
-| Last half of push_string (). If next is now NULL, a call to |
-| push_file () has invalidated the previous call to push_string_init |
-| (), so we just give up. If the new object is void, we do not push |
-| it. The function push_string_finish () returns a pointer to the |
-| finished object. This pointer is only for temporary use, since |
-| reading the next token might release the memory used for the |
-| object. |
-`-------------------------------------------------------------------*/
-
-const char *
-push_string_finish (void)
-{
- const char *ret = NULL;
-
- if (next == NULL)
- return NULL;
-
- if (obstack_object_size (current_input) > 0)
- {
- size_t len = obstack_object_size (current_input);
- obstack_1grow (current_input, '\0');
- next->u.u_s.string = (char *) obstack_finish (current_input);
- next->u.u_s.end = next->u.u_s.string + len;
- next->prev = isp;
- isp = next;
- ret = isp->u.u_s.string; /* for immediate use only */
- input_change = true;
- }
- else
- obstack_free (current_input, next); /* people might leave garbage on it. */
- next = NULL;
- return ret;
-}
-
-/*------------------------------------------------------------------.
-| The function push_wrapup () pushes a string on the wrapup stack. |
-| When the normal input stack gets empty, the wrapup stack will |
-| become the input stack, and push_string () and push_file () will |
-| operate on wrapup_stack. Push_wrapup should be done as |
-| push_string (), but this will suffice, as long as arguments to |
-| m4_m4wrap () are moderate in size. |
-`------------------------------------------------------------------*/
-
-void
-push_wrapup (const char *s)
-{
- size_t len = strlen (s);
- input_block *i;
- i = (input_block *) obstack_alloc (wrapup_stack,
- sizeof (struct input_block));
- i->prev = wsp;
- i->type = INPUT_STRING;
- i->file = current_file;
- i->line = current_line;
- i->u.u_s.string = (char *) obstack_copy0 (wrapup_stack, s, len);
- i->u.u_s.end = i->u.u_s.string + len;
- wsp = i;
-}
-
-
-/*-------------------------------------------------------------------.
-| The function pop_input () pops one level of input sources. If the |
-| popped input_block is a file, current_file and current_line are |
-| reset to the saved values before the memory for the input_block is |
-| released. |
-`-------------------------------------------------------------------*/
-
-static void
-pop_input (void)
-{
- input_block *tmp = isp->prev;
-
- switch (isp->type)
- {
- case INPUT_STRING:
- case INPUT_MACRO:
- break;
-
- case INPUT_FILE:
- if (debug_level & DEBUG_TRACE_INPUT)
- {
- if (tmp)
- DEBUG_MESSAGE2 ("input reverted to %s, line %d",
- tmp->file, tmp->line);
- else
- DEBUG_MESSAGE ("input exhausted");
- }
-
- if (ferror (isp->u.u_f.fp))
- {
- M4ERROR ((warning_status, 0, "read error"));
- if (isp->u.u_f.close)
- fclose (isp->u.u_f.fp);
- retcode = EXIT_FAILURE;
- }
- else if (isp->u.u_f.close && fclose (isp->u.u_f.fp) == EOF)
- {
- M4ERROR ((warning_status, errno, "error reading file"));
- retcode = EXIT_FAILURE;
- }
- start_of_input_line = isp->u.u_f.advance;
- output_current_line = -1;
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: input stack botch in pop_input ()"));
- abort ();
- }
- obstack_free (current_input, isp);
- next = NULL; /* might be set in push_string_init () */
-
- isp = tmp;
- input_change = true;
-}
-
-/*-------------------------------------------------------------------.
-| To switch input over to the wrapup stack, main calls pop_wrapup |
-| (). Since wrapup text can install new wrapup text, pop_wrapup () |
-| returns false when there is no wrapup text on the stack, and true |
-| otherwise. |
-`-------------------------------------------------------------------*/
-
-bool
-pop_wrapup (void)
-{
- next = NULL;
- obstack_free (current_input, NULL);
- free (current_input);
-
- if (wsp == NULL)
- {
- /* End of the program. Free all memory even though we are about
- to exit, since it makes leak detection easier. */
- obstack_free (&token_stack, NULL);
- obstack_free (&file_names, NULL);
- obstack_free (wrapup_stack, NULL);
- free (wrapup_stack);
-#ifdef ENABLE_CHANGEWORD
- regfree (&word_regexp);
-#endif /* ENABLE_CHANGEWORD */
- return false;
- }
-
- current_input = wrapup_stack;
- wrapup_stack = (struct obstack *) xmalloc (sizeof (struct obstack));
- obstack_init (wrapup_stack);
-
- isp = wsp;
- wsp = NULL;
- input_change = true;
-
- return true;
-}
-
-/*-------------------------------------------------------------------.
-| When a MACRO token is seen, next_token () uses init_macro_token () |
-| to retrieve the value of the function pointer. |
-`-------------------------------------------------------------------*/
-
-static void
-init_macro_token (token_data *td)
-{
- if (isp->type != INPUT_MACRO)
- {
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad call to init_macro_token ()"));
- abort ();
- }
-
- TOKEN_DATA_TYPE (td) = TOKEN_FUNC;
- TOKEN_DATA_FUNC (td) = isp->u.func;
-}
-
-
-/*-----------------------------------------------------------------.
-| Low level input is done a character at a time. The function |
-| peek_input () is used to look at the next character in the input |
-| stream. At any given time, it reads from the input_block on the |
-| top of the current input stack. |
-`-----------------------------------------------------------------*/
-
-static int
-peek_input (void)
-{
- int ch;
- input_block *block = isp;
-
- while (1)
- {
- if (block == NULL)
- return CHAR_EOF;
-
- switch (block->type)
- {
- case INPUT_STRING:
- ch = to_uchar (block->u.u_s.string[0]);
- if (ch != '\0')
- return ch;
- break;
-
- case INPUT_FILE:
- ch = getc (block->u.u_f.fp);
- if (ch != EOF)
- {
- ungetc (ch, block->u.u_f.fp);
- return ch;
- }
- block->u.u_f.end = true;
- break;
-
- case INPUT_MACRO:
- return CHAR_MACRO;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: input stack botch in peek_input ()"));
- abort ();
- }
- block = block->prev;
- }
-}
-
-/*-------------------------------------------------------------------.
-| The function next_char () is used to read and advance the input to |
-| the next character. It also manages line numbers for error |
-| messages, so they do not get wrong, due to lookahead. The token |
-| consisting of a newline alone is taken as belonging to the line it |
-| ends, and the current line number is not incremented until the |
-| next character is read. 99.9% of all calls will read from a |
-| string, so factor that out into a macro for speed. |
-`-------------------------------------------------------------------*/
-
-#define next_char() \
- (isp && isp->type == INPUT_STRING && isp->u.u_s.string[0] \
- && !input_change \
- ? to_uchar (*isp->u.u_s.string++) \
- : next_char_1 ())
-
-static int
-next_char_1 (void)
-{
- int ch;
-
- while (1)
- {
- if (isp == NULL)
- {
- current_file = "";
- current_line = 0;
- return CHAR_EOF;
- }
-
- if (input_change)
- {
- current_file = isp->file;
- current_line = isp->line;
- input_change = false;
- }
-
- switch (isp->type)
- {
- case INPUT_STRING:
- ch = to_uchar (*isp->u.u_s.string++);
- if (ch != '\0')
- return ch;
- break;
-
- case INPUT_FILE:
- if (start_of_input_line)
- {
- start_of_input_line = false;
- current_line = ++isp->line;
- }
-
- /* If stdin is a terminal, calling getc after peek_input
- already called it would make the user have to hit ^D
- twice to quit. */
- ch = isp->u.u_f.end ? EOF : getc (isp->u.u_f.fp);
- if (ch != EOF)
- {
- if (ch == '\n')
- start_of_input_line = true;
- return ch;
- }
- break;
-
- case INPUT_MACRO:
- pop_input (); /* INPUT_MACRO input sources has only one token */
- return CHAR_MACRO;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: input stack botch in next_char ()"));
- abort ();
- }
-
- /* End of input source --- pop one level. */
- pop_input ();
- }
-}
-
-/*-------------------------------------------------------------------.
-| skip_line () simply discards all immediately following characters, |
-| upto the first newline. It is only used from m4_dnl (). |
-`-------------------------------------------------------------------*/
-
-void
-skip_line (void)
-{
- int ch;
- const char *file = current_file;
- int line = current_line;
-
- while ((ch = next_char ()) != CHAR_EOF && ch != '\n')
- ;
- if (ch == CHAR_EOF)
- /* current_file changed to "" if we see CHAR_EOF, use the
- previous value we stored earlier. */
- M4ERROR_AT_LINE ((warning_status, 0, file, line,
- "Warning: end of file treated as newline"));
- /* On the rare occasion that dnl crosses include file boundaries
- (either the input file did not end in a newline, or changeword
- was used), calling next_char can update current_file and
- current_line, and that update will be undone as we return to
- expand_macro. This informs next_char to fix things again. */
- if (file != current_file || line != current_line)
- input_change = true;
-}
-
-
-/*------------------------------------------------------------------.
-| This function is for matching a string against a prefix of the |
-| input stream. If the string matches the input and consume is |
-| true, the input is discarded; otherwise any characters read are |
-| pushed back again. The function is used only when multicharacter |
-| quotes or comment delimiters are used. |
-`------------------------------------------------------------------*/
-
-static bool
-match_input (const char *s, bool consume)
-{
- int n; /* number of characters matched */
- int ch; /* input character */
- const char *t;
- bool result = false;
-
- ch = peek_input ();
- if (ch != to_uchar (*s))
- return false; /* fail */
-
- if (s[1] == '\0')
- {
- if (consume)
- next_char ();
- return true; /* short match */
- }
-
- next_char ();
- for (n = 1, t = s++; peek_input () == to_uchar (*s++); )
- {
- next_char ();
- n++;
- if (*s == '\0') /* long match */
- {
- if (consume)
- return true;
- result = true;
- break;
- }
- }
-
- /* Failed or shouldn't consume, push back input. */
- {
- struct obstack *h = push_string_init ();
-
- /* `obstack_grow' may be macro evaluating its arg 1 several times. */
- obstack_grow (h, t, n);
- }
- push_string_finish ();
- return result;
-}
-
-/*--------------------------------------------------------------------.
-| The macro MATCH() is used to match a string S against the input. |
-| The first character is handled inline, for speed. Hopefully, this |
-| will not hurt efficiency too much when single character quotes and |
-| comment delimiters are used. If CONSUME, then CH is the result of |
-| next_char, and a successful match will discard the matched string. |
-| Otherwise, CH is the result of peek_char, and the input stream is |
-| effectively unchanged. |
-`--------------------------------------------------------------------*/
-
-#define MATCH(ch, s, consume) \
- (to_uchar ((s)[0]) == (ch) \
- && (ch) != '\0' \
- && ((s)[1] == '\0' || (match_input ((s) + (consume), consume))))
-
-
-/*--------------------------------------------------------.
-| Initialize input stacks, and quote/comment characters. |
-`--------------------------------------------------------*/
-
-void
-input_init (void)
-{
- current_file = "";
- current_line = 0;
-
- current_input = (struct obstack *) xmalloc (sizeof (struct obstack));
- obstack_init (current_input);
- wrapup_stack = (struct obstack *) xmalloc (sizeof (struct obstack));
- obstack_init (wrapup_stack);
-
- obstack_init (&file_names);
-
- /* Allocate an object in the current chunk, so that obstack_free
- will always work even if the first token parsed spills to a new
- chunk. */
- obstack_init (&token_stack);
- obstack_alloc (&token_stack, 1);
- token_bottom = obstack_base (&token_stack);
-
- isp = NULL;
- wsp = NULL;
- next = NULL;
-
- start_of_input_line = false;
-
- lquote.string = xstrdup (DEF_LQUOTE);
- lquote.length = strlen (lquote.string);
- rquote.string = xstrdup (DEF_RQUOTE);
- rquote.length = strlen (rquote.string);
- bcomm.string = xstrdup (DEF_BCOMM);
- bcomm.length = strlen (bcomm.string);
- ecomm.string = xstrdup (DEF_ECOMM);
- ecomm.length = strlen (ecomm.string);
-
-#ifdef ENABLE_CHANGEWORD
- set_word_regexp (user_word_regexp);
-#endif
-}
-
-
-/*------------------------------------------------------------------.
-| Functions for setting quotes and comment delimiters. Used by |
-| m4_changecom () and m4_changequote (). Pass NULL if the argument |
-| was not present, to distinguish from an explicit empty string. |
-`------------------------------------------------------------------*/
-
-void
-set_quotes (const char *lq, const char *rq)
-{
- free (lquote.string);
- free (rquote.string);
-
- /* POSIX states that with 0 arguments, the default quotes are used.
- POSIX XCU ERN 112 states that behavior is implementation-defined
- if there was only one argument, or if there is an empty string in
- either position when there are two arguments. We allow an empty
- left quote to disable quoting, but a non-empty left quote will
- always create a non-empty right quote. See the texinfo for what
- some other implementations do. */
- if (!lq)
- {
- lq = DEF_LQUOTE;
- rq = DEF_RQUOTE;
- }
- else if (!rq || (*lq && !*rq))
- rq = DEF_RQUOTE;
-
- lquote.string = xstrdup (lq);
- lquote.length = strlen (lquote.string);
- rquote.string = xstrdup (rq);
- rquote.length = strlen (rquote.string);
-}
-
-void
-set_comment (const char *bc, const char *ec)
-{
- free (bcomm.string);
- free (ecomm.string);
-
- /* POSIX requires no arguments to disable comments. It requires
- empty arguments to be used as-is, but this is counter to
- traditional behavior, because a non-null begin and null end makes
- it impossible to end a comment. An aardvark has been filed:
- http://www.opengroup.org/austin/mailarchives/ag-review/msg02168.html
- This implementation assumes the aardvark will be approved. See
- the texinfo for what some other implementations do. */
- if (!bc)
- bc = ec = "";
- else if (!ec || (*bc && !*ec))
- ec = DEF_ECOMM;
-
- bcomm.string = xstrdup (bc);
- bcomm.length = strlen (bcomm.string);
- ecomm.string = xstrdup (ec);
- ecomm.length = strlen (ecomm.string);
-}
-
-#ifdef ENABLE_CHANGEWORD
-
-void
-set_word_regexp (const char *regexp)
-{
- const char *msg;
- struct re_pattern_buffer new_word_regexp;
-
- if (!*regexp || STREQ (regexp, DEFAULT_WORD_REGEXP))
- {
- default_word_regexp = true;
- return;
- }
-
- /* Dry run to see whether the new expression is compilable. */
- init_pattern_buffer (&new_word_regexp, NULL);
- msg = re_compile_pattern (regexp, strlen (regexp), &new_word_regexp);
- regfree (&new_word_regexp);
-
- if (msg != NULL)
- {
- M4ERROR ((warning_status, 0,
- "bad regular expression `%s': %s", regexp, msg));
- return;
- }
-
- /* If compilation worked, retry using the word_regexp struct. We
- can't rely on struct assigns working, so redo the compilation.
- The fastmap can be reused between compilations, and will be freed
- by the final regfree. */
- if (!word_regexp.fastmap)
- word_regexp.fastmap = xcharalloc (UCHAR_MAX + 1);
- msg = re_compile_pattern (regexp, strlen (regexp), &word_regexp);
- assert (!msg);
- re_set_registers (&word_regexp, &regs, regs.num_regs, regs.start, regs.end);
- if (re_compile_fastmap (&word_regexp))
- assert (false);
-
- default_word_regexp = false;
-}
-
-#endif /* ENABLE_CHANGEWORD */
-
-
-/*--------------------------------------------------------------------.
-| Parse and return a single token from the input stream. A token |
-| can either be TOKEN_EOF, if the input_stack is empty; it can be |
-| TOKEN_STRING for a quoted string; TOKEN_WORD for something that is |
-| a potential macro name; and TOKEN_SIMPLE for any single character |
-| that is not a part of any of the previous types. If LINE is not |
-| NULL, set *LINE to the line where the token starts. |
-| |
-| Next_token () return the token type, and passes back a pointer to |
-| the token data through TD. The token text is collected on the |
-| obstack token_stack, which never contains more than one token text |
-| at a time. The storage pointed to by the fields in TD is |
-| therefore subject to change the next time next_token () is called. |
-`--------------------------------------------------------------------*/
-
-token_type
-next_token (token_data *td, int *line)
-{
- int ch;
- int quote_level;
- token_type type;
-#ifdef ENABLE_CHANGEWORD
- int startpos;
- char *orig_text = NULL;
-#endif
- const char *file;
- int dummy;
-
- obstack_free (&token_stack, token_bottom);
- if (!line)
- line = &dummy;
-
- /* Can't consume character until after CHAR_MACRO is handled. */
- ch = peek_input ();
- if (ch == CHAR_EOF)
- {
-#ifdef DEBUG_INPUT
- xfprintf (stderr, "next_token -> EOF\n");
-#endif
- next_char ();
- return TOKEN_EOF;
- }
- if (ch == CHAR_MACRO)
- {
- init_macro_token (td);
- next_char ();
-#ifdef DEBUG_INPUT
- xfprintf (stderr, "next_token -> MACDEF (%s)\n",
- find_builtin_by_addr (TOKEN_DATA_FUNC (td))->name);
-#endif
- return TOKEN_MACDEF;
- }
-
- next_char (); /* Consume character we already peeked at. */
- file = current_file;
- *line = current_line;
- if (MATCH (ch, bcomm.string, true))
- {
- obstack_grow (&token_stack, bcomm.string, bcomm.length);
- while ((ch = next_char ()) != CHAR_EOF
- && !MATCH (ch, ecomm.string, true))
- obstack_1grow (&token_stack, ch);
- if (ch != CHAR_EOF)
- obstack_grow (&token_stack, ecomm.string, ecomm.length);
- else
- /* current_file changed to "" if we see CHAR_EOF, use the
- previous value we stored earlier. */
- M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, *line,
- "ERROR: end of file in comment"));
-
- type = TOKEN_STRING;
- }
- else if (default_word_regexp && (isalpha (ch) || ch == '_'))
- {
- obstack_1grow (&token_stack, ch);
- while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_'))
- {
- obstack_1grow (&token_stack, ch);
- next_char ();
- }
- type = TOKEN_WORD;
- }
-
-#ifdef ENABLE_CHANGEWORD
-
- else if (!default_word_regexp && word_regexp.fastmap[ch])
- {
- obstack_1grow (&token_stack, ch);
- while (1)
- {
- ch = peek_input ();
- if (ch == CHAR_EOF)
- break;
- obstack_1grow (&token_stack, ch);
- startpos = re_search (&word_regexp,
- (char *) obstack_base (&token_stack),
- obstack_object_size (&token_stack), 0, 0,
- &regs);
- if (startpos ||
- regs.end [0] != (regoff_t) obstack_object_size (&token_stack))
- {
- *(((char *) obstack_base (&token_stack)
- + obstack_object_size (&token_stack)) - 1) = '\0';
- break;
- }
- next_char ();
- }
-
- obstack_1grow (&token_stack, '\0');
- orig_text = (char *) obstack_finish (&token_stack);
-
- if (regs.start[1] != -1)
- obstack_grow (&token_stack,orig_text + regs.start[1],
- regs.end[1] - regs.start[1]);
- else
- obstack_grow (&token_stack, orig_text,regs.end[0]);
-
- type = TOKEN_WORD;
- }
-
-#endif /* ENABLE_CHANGEWORD */
-
- else if (!MATCH (ch, lquote.string, true))
- {
- switch (ch)
- {
- case '(':
- type = TOKEN_OPEN;
- break;
- case ',':
- type = TOKEN_COMMA;
- break;
- case ')':
- type = TOKEN_CLOSE;
- break;
- default:
- type = TOKEN_SIMPLE;
- break;
- }
- obstack_1grow (&token_stack, ch);
- }
- else
- {
- bool fast = lquote.length == 1 && rquote.length == 1;
- quote_level = 1;
- while (1)
- {
- /* Try scanning a buffer first. */
- const char *buffer = (isp && isp->type == INPUT_STRING
- ? isp->u.u_s.string : NULL);
- if (buffer && *buffer)
- {
- size_t len = isp->u.u_s.end - buffer;
- const char *p = buffer;
- do
- {
- p = (char *) memchr2 (p, *lquote.string, *rquote.string,
- buffer + len - p);
- }
- while (p && fast && (*p++ == *rquote.string
- ? --quote_level : ++quote_level));
- if (p)
- {
- if (fast)
- {
- assert (!quote_level);
- obstack_grow (&token_stack, buffer, p - buffer - 1);
- isp->u.u_s.string += p - buffer;
- break;
- }
- obstack_grow (&token_stack, buffer, p - buffer);
- ch = to_uchar (*p);
- isp->u.u_s.string += p - buffer + 1;
- }
- else
- {
- obstack_grow (&token_stack, buffer, len);
- isp->u.u_s.string += len;
- continue;
- }
- }
- /* Fall back to a byte. */
- else
- ch = next_char ();
- if (ch == CHAR_EOF)
- /* current_file changed to "" if we see CHAR_EOF, use
- the previous value we stored earlier. */
- M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, *line,
- "ERROR: end of file in string"));
-
- if (MATCH (ch, rquote.string, true))
- {
- if (--quote_level == 0)
- break;
- obstack_grow (&token_stack, rquote.string, rquote.length);
- }
- else if (MATCH (ch, lquote.string, true))
- {
- quote_level++;
- obstack_grow (&token_stack, lquote.string, lquote.length);
- }
- else
- obstack_1grow (&token_stack, ch);
- }
- type = TOKEN_STRING;
- }
-
- obstack_1grow (&token_stack, '\0');
-
- TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
- TOKEN_DATA_TEXT (td) = (char *) obstack_finish (&token_stack);
-#ifdef ENABLE_CHANGEWORD
- if (orig_text == NULL)
- orig_text = TOKEN_DATA_TEXT (td);
- TOKEN_DATA_ORIG_TEXT (td) = orig_text;
-#endif
-#ifdef DEBUG_INPUT
- xfprintf (stderr, "next_token -> %s (%s)\n",
- token_type_string (type), TOKEN_DATA_TEXT (td));
-#endif
- return type;
-}
-
-/*-----------------------------------------------.
-| Peek at the next token from the input stream. |
-`-----------------------------------------------*/
-
-token_type
-peek_token (void)
-{
- token_type result;
- int ch = peek_input ();
-
- if (ch == CHAR_EOF)
- {
- result = TOKEN_EOF;
- }
- else if (ch == CHAR_MACRO)
- {
- result = TOKEN_MACDEF;
- }
- else if (MATCH (ch, bcomm.string, false))
- {
- result = TOKEN_STRING;
- }
- else if ((default_word_regexp && (isalpha (ch) || ch == '_'))
-#ifdef ENABLE_CHANGEWORD
- || (! default_word_regexp && word_regexp.fastmap[ch])
-#endif /* ENABLE_CHANGEWORD */
- )
- {
- result = TOKEN_WORD;
- }
- else if (MATCH (ch, lquote.string, false))
- {
- result = TOKEN_STRING;
- }
- else
- switch (ch)
- {
- case '(':
- result = TOKEN_OPEN;
- break;
- case ',':
- result = TOKEN_COMMA;
- break;
- case ')':
- result = TOKEN_CLOSE;
- break;
- default:
- result = TOKEN_SIMPLE;
- }
-
-#ifdef DEBUG_INPUT
- xfprintf (stderr, "peek_token -> %s\n", token_type_string (result));
-#endif /* DEBUG_INPUT */
- return result;
-}
-
-
-#ifdef DEBUG_INPUT
-
-static const char *
-token_type_string (token_type t)
-{
- switch (t)
- { /* TOKSW */
- case TOKEN_EOF:
- return "EOF";
- case TOKEN_STRING:
- return "STRING";
- case TOKEN_WORD:
- return "WORD";
- case TOKEN_OPEN:
- return "OPEN";
- case TOKEN_COMMA:
- return "COMMA";
- case TOKEN_CLOSE:
- return "CLOSE";
- case TOKEN_SIMPLE:
- return "SIMPLE";
- case TOKEN_MACDEF:
- return "MACDEF";
- default:
- abort ();
- }
- }
-
-static void
-print_token (const char *s, token_type t, token_data *td)
-{
- xfprintf (stderr, "%s: ", s);
- switch (t)
- { /* TOKSW */
- case TOKEN_OPEN:
- case TOKEN_COMMA:
- case TOKEN_CLOSE:
- case TOKEN_SIMPLE:
- xfprintf (stderr, "char:");
- break;
-
- case TOKEN_WORD:
- xfprintf (stderr, "word:");
- break;
-
- case TOKEN_STRING:
- xfprintf (stderr, "string:");
- break;
-
- case TOKEN_MACDEF:
- xfprintf (stderr, "macro: %p\n", TOKEN_DATA_FUNC (td));
- break;
-
- case TOKEN_EOF:
- xfprintf (stderr, "eof\n");
- break;
- }
- xfprintf (stderr, "\t\"%s\"\n", TOKEN_DATA_TEXT (td));
-}
-
-static void M4_GNUC_UNUSED
-lex_debug (void)
-{
- token_type t;
- token_data td;
-
- while ((t = next_token (&td, NULL)) != TOKEN_EOF)
- print_token ("lex", t, &td);
-}
-#endif /* DEBUG_INPUT */
diff --git a/contrib/tools/bison/m4/src/m4.c b/contrib/tools/bison/m4/src/m4.c
deleted file mode 100644
index 2c03154471..0000000000
--- a/contrib/tools/bison/m4/src/m4.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2004-2013 Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "m4.h"
-
-#include <getopt.h>
-#include <limits.h>
-#include <signal.h>
-
-#include "c-stack.h"
-#include "ignore-value.h"
-#include "progname.h"
-#include "version-etc.h"
-
-#ifdef DEBUG_STKOVF
-# include "assert.h"
-#endif
-
-#define AUTHORS "Rene' Seindal"
-
-static void usage (int) M4_GNUC_NORETURN;
-
-/* Enable sync output for /lib/cpp (-s). */
-int sync_output = 0;
-
-/* Debug (-d[flags]). */
-int debug_level = 0;
-
-/* Hash table size (should be a prime) (-Hsize). */
-size_t hash_table_size = HASHMAX;
-
-/* Disable GNU extensions (-G). */
-int no_gnu_extensions = 0;
-
-/* Prefix all builtin functions by `m4_'. */
-int prefix_all_builtins = 0;
-
-/* Max length of arguments in trace output (-lsize). */
-int max_debug_argument_length = 0;
-
-/* Suppress warnings about missing arguments. */
-int suppress_warnings = 0;
-
-/* If true, then warnings affect exit status. */
-static bool fatal_warnings = false;
-
-/* If not zero, then value of exit status for warning diagnostics. */
-int warning_status = 0;
-
-/* Artificial limit for expansion_level in macro.c. */
-int nesting_limit = 1024;
-
-#ifdef ENABLE_CHANGEWORD
-/* User provided regexp for describing m4 words. */
-const char *user_word_regexp = "";
-#endif
-
-/* Global catchall for any errors that should affect final error status, but
- where we try to continue execution in the meantime. */
-int retcode;
-
-struct macro_definition
-{
- struct macro_definition *next;
- int code; /* D, U, s, t, '\1', or DEBUGFILE_OPTION. */
- const char *arg;
-};
-typedef struct macro_definition macro_definition;
-
-/* Error handling functions. */
-
-/*-----------------------.
-| Wrapper around error. |
-`-----------------------*/
-
-void
-m4_error (int status, int errnum, const char *format, ...)
-{
- va_list args;
- va_start (args, format);
- verror_at_line (status, errnum, current_line ? current_file : NULL,
- current_line, format, args);
- if (fatal_warnings && ! retcode)
- retcode = EXIT_FAILURE;
- va_end (args);
-}
-
-/*-------------------------------.
-| Wrapper around error_at_line. |
-`-------------------------------*/
-
-void
-m4_error_at_line (int status, int errnum, const char *file, int line,
- const char *format, ...)
-{
- va_list args;
- va_start (args, format);
- verror_at_line (status, errnum, line ? file : NULL, line, format, args);
- if (fatal_warnings && ! retcode)
- retcode = EXIT_FAILURE;
- va_end (args);
-}
-
-#ifndef SIGBUS
-# define SIGBUS SIGILL
-#endif
-
-#ifndef NSIG
-# ifndef MAX
-# define MAX(a,b) ((a) < (b) ? (b) : (a))
-# endif
-# define NSIG (MAX (SIGABRT, MAX (SIGILL, MAX (SIGFPE, \
- MAX (SIGSEGV, SIGBUS)))) + 1)
-#endif
-
-/* Pre-translated messages for program errors. Do not translate in
- the signal handler, since gettext and strsignal are not
- async-signal-safe. */
-static const char * volatile program_error_message;
-static const char * volatile signal_message[NSIG];
-
-/* Print a nicer message about any programmer errors, then exit. This
- must be aysnc-signal safe, since it is executed as a signal
- handler. If SIGNO is zero, this represents a stack overflow; in
- that case, we return to allow c_stack_action to handle things. */
-static void M4_GNUC_PURE
-fault_handler (int signo)
-{
- if (signo)
- {
- /* POSIX states that reading static memory is, in general, not
- async-safe. However, the static variables that we read are
- never modified once this handler is installed, so this
- particular usage is safe. And it seems an oversight that
- POSIX claims strlen is not async-safe. Ignore write
- failures, since we will exit with non-zero status anyway. */
-#define WRITE(f, b, l) ignore_value (write (f, b, l))
- WRITE (STDERR_FILENO, program_name, strlen (program_name));
- WRITE (STDERR_FILENO, ": ", 2);
- WRITE (STDERR_FILENO, program_error_message,
- strlen (program_error_message));
- if (signal_message[signo])
- {
- WRITE (STDERR_FILENO, ": ", 2);
- WRITE (STDERR_FILENO, signal_message[signo],
- strlen (signal_message[signo]));
- }
- WRITE (STDERR_FILENO, "\n", 1);
-#undef WRITE
- _exit (EXIT_INTERNAL_ERROR);
- }
-}
-
-
-/*---------------------------------------------.
-| Print a usage message and exit with STATUS. |
-`---------------------------------------------*/
-
-static void
-usage (int status)
-{
- if (status != EXIT_SUCCESS)
- xfprintf (stderr, "Try `%s --help' for more information.\n", program_name);
- else
- {
- xprintf ("Usage: %s [OPTION]... [FILE]...\n", program_name);
- fputs ("\
-Process macros in FILEs. If no FILE or if FILE is `-', standard input\n\
-is read.\n\
-", stdout);
- fputs ("\
-\n\
-Mandatory or optional arguments to long options are mandatory or optional\n\
-for short options too.\n\
-\n\
-Operation modes:\n\
- --help display this help and exit\n\
- --version output version information and exit\n\
-", stdout);
- xprintf ("\
- -E, --fatal-warnings once: warnings become errors, twice: stop\n\
- execution at first error\n\
- -i, --interactive unbuffer output, ignore interrupts\n\
- -P, --prefix-builtins force a `m4_' prefix to all builtins\n\
- -Q, --quiet, --silent suppress some warnings for builtins\n\
- --warn-macro-sequence[=REGEXP]\n\
- warn if macro definition matches REGEXP,\n\
- default %s\n\
-", DEFAULT_MACRO_SEQUENCE);
-#ifdef ENABLE_CHANGEWORD
- fputs ("\
- -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n\
-", stdout);
-#endif
- fputs ("\
-\n\
-Preprocessor features:\n\
- -D, --define=NAME[=VALUE] define NAME as having VALUE, or empty\n\
- -I, --include=DIRECTORY append DIRECTORY to include path\n\
- -s, --synclines generate `#line NUM \"FILE\"' lines\n\
- -U, --undefine=NAME undefine NAME\n\
-", stdout);
- puts ("");
- xprintf (_("\
-Limits control:\n\
- -g, --gnu override -G to re-enable GNU extensions\n\
- -G, --traditional suppress all GNU extensions\n\
- -H, --hashsize=PRIME set symbol lookup hash table size [509]\n\
- -L, --nesting-limit=NUMBER change nesting limit, 0 for unlimited [%d]\n\
-"), nesting_limit);
- puts ("");
- fputs ("\
-Frozen state files:\n\
- -F, --freeze-state=FILE produce a frozen state on FILE at end\n\
- -R, --reload-state=FILE reload a frozen state from FILE at start\n\
-", stdout);
- fputs ("\
-\n\
-Debugging:\n\
- -d, --debug[=FLAGS] set debug level (no FLAGS implies `aeq')\n\
- --debugfile[=FILE] redirect debug and trace output to FILE\n\
- (default stderr, discard if empty string)\n\
- -l, --arglength=NUM restrict macro tracing size\n\
- -t, --trace=NAME trace NAME when it is defined\n\
-", stdout);
- fputs ("\
-\n\
-FLAGS is any of:\n\
- a show actual arguments\n\
- c show before collect, after collect and after call\n\
- e show expansion\n\
- f say current input file name\n\
- i show changes in input files\n\
- l say current input line number\n\
- p show results of path searches\n\
- q quote values as necessary, with a or e flag\n\
- t trace for all macro calls, not only traceon'ed\n\
- x add a unique macro call id, useful with c flag\n\
- V shorthand for all of the above flags\n\
-", stdout);
- fputs ("\
-\n\
-If defined, the environment variable `M4PATH' is a colon-separated list\n\
-of directories included after any specified by `-I'.\n\
-", stdout);
- fputs ("\
-\n\
-Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
-mismatch, or whatever value was passed to the m4exit macro.\n\
-", stdout);
- emit_bug_reporting_address ();
- }
- exit (status);
-}
-
-/*--------------------------------------.
-| Decode options and launch execution. |
-`--------------------------------------*/
-
-/* For long options that have no equivalent short option, use a
- non-character as a pseudo short option, starting with CHAR_MAX + 1. */
-enum
-{
- DEBUGFILE_OPTION = CHAR_MAX + 1, /* no short opt */
- DIVERSIONS_OPTION, /* not quite -N, because of message */
- WARN_MACRO_SEQUENCE_OPTION, /* no short opt */
-
- HELP_OPTION, /* no short opt */
- VERSION_OPTION /* no short opt */
-};
-
-static const struct option long_options[] =
-{
- {"arglength", required_argument, NULL, 'l'},
- {"debug", optional_argument, NULL, 'd'},
- {"define", required_argument, NULL, 'D'},
- {"error-output", required_argument, NULL, 'o'}, /* FIXME: deprecate in 2.0 */
- {"fatal-warnings", no_argument, NULL, 'E'},
- {"freeze-state", required_argument, NULL, 'F'},
- {"gnu", no_argument, NULL, 'g'},
- {"hashsize", required_argument, NULL, 'H'},
- {"include", required_argument, NULL, 'I'},
- {"interactive", no_argument, NULL, 'i'},
- {"nesting-limit", required_argument, NULL, 'L'},
- {"prefix-builtins", no_argument, NULL, 'P'},
- {"quiet", no_argument, NULL, 'Q'},
- {"reload-state", required_argument, NULL, 'R'},
- {"silent", no_argument, NULL, 'Q'},
- {"synclines", no_argument, NULL, 's'},
- {"trace", required_argument, NULL, 't'},
- {"traditional", no_argument, NULL, 'G'},
- {"undefine", required_argument, NULL, 'U'},
- {"word-regexp", required_argument, NULL, 'W'},
-
- {"debugfile", optional_argument, NULL, DEBUGFILE_OPTION},
- {"diversions", required_argument, NULL, DIVERSIONS_OPTION},
- {"warn-macro-sequence", optional_argument, NULL, WARN_MACRO_SEQUENCE_OPTION},
-
- {"help", no_argument, NULL, HELP_OPTION},
- {"version", no_argument, NULL, VERSION_OPTION},
-
- { NULL, 0, NULL, 0 },
-};
-
-/* Process a command line file NAME, and return true only if it was
- stdin. */
-static void
-process_file (const char *name)
-{
- if (STREQ (name, "-"))
- {
- /* If stdin is a terminal, we want to allow 'm4 - file -'
- to read input from stdin twice, like GNU cat. Besides,
- there is no point closing stdin before wrapped text, to
- minimize bugs in syscmd called from wrapped text. */
- push_file (stdin, "stdin", false);
- }
- else
- {
- char *full_name;
- FILE *fp = m4_path_search (name, &full_name);
- if (fp == NULL)
- {
- error (0, errno, _("cannot open `%s'"), name);
- /* Set the status to EXIT_FAILURE, even though we
- continue to process files after a missing file. */
- retcode = EXIT_FAILURE;
- return;
- }
- push_file (fp, full_name, true);
- free (full_name);
- }
- expand_input ();
-}
-
-/* POSIX requires only -D, -U, and -s; and says that the first two
- must be recognized when interspersed with file names. Traditional
- behavior also handles -s between files. Starting OPTSTRING with
- '-' forces getopt_long to hand back file names as arguments to opt
- '\1', rather than reordering the command line. */
-#ifdef ENABLE_CHANGEWORD
-#define OPTSTRING "-B:D:EF:GH:I:L:N:PQR:S:T:U:W:d::egil:o:st:"
-#else
-#define OPTSTRING "-B:D:EF:GH:I:L:N:PQR:S:T:U:d::egil:o:st:"
-#endif
-
-int
-main (int argc, char *const *argv)
-{
-#if !defined(_WIN32) && !defined(_WIN64)
- struct sigaction act;
-#endif
- macro_definition *head; /* head of deferred argument list */
- macro_definition *tail;
- macro_definition *defn;
- int optchar; /* option character */
-
- macro_definition *defines;
- bool interactive = false;
- bool seen_file = false;
- const char *debugfile = NULL;
- const char *frozen_file_to_read = NULL;
- const char *frozen_file_to_write = NULL;
- const char *macro_sequence = "";
-
- set_program_name (argv[0]);
- retcode = EXIT_SUCCESS;
- atexit (close_stdin);
-
- include_init ();
- debug_init ();
-
- /* Stack overflow and program error handling. Ignore failure to
- install a handler, since this is merely for improved output on
- crash, and we should never crash ;). We install SIGBUS and
- SIGSEGV handlers prior to using the c-stack module; depending on
- the platform, c-stack will then override none, SIGSEGV, or both
- handlers. */
- program_error_message
- = xasprintf (_("internal error detected; please report this bug to <%s>"),
- PACKAGE_BUGREPORT);
- signal_message[SIGSEGV] = xstrdup (strsignal (SIGSEGV));
- signal_message[SIGABRT] = xstrdup (strsignal (SIGABRT));
- signal_message[SIGILL] = xstrdup (strsignal (SIGILL));
- signal_message[SIGFPE] = xstrdup (strsignal (SIGFPE));
- if (SIGBUS != SIGILL && SIGBUS != SIGSEGV)
- signal_message[SIGBUS] = xstrdup (strsignal (SIGBUS));
-#if !defined(_WIN32) && !defined(_WIN64)
- // No such signals on Windows
- sigemptyset(&act.sa_mask);
- /* One-shot - if we fault while handling a fault, we want to revert
- to default signal behavior. */
- act.sa_flags = SA_NODEFER | SA_RESETHAND;
- act.sa_handler = fault_handler;
- sigaction (SIGSEGV, &act, NULL);
- sigaction (SIGABRT, &act, NULL);
- sigaction (SIGILL, &act, NULL);
- sigaction (SIGFPE, &act, NULL);
- sigaction (SIGBUS, &act, NULL);
-#endif
- if (c_stack_action (fault_handler) == 0)
- nesting_limit = 0;
-
-#ifdef DEBUG_STKOVF
- /* Make it easier to test our fault handlers. Exporting M4_CRASH=0
- attempts a SIGSEGV, exporting it as 1 attempts an assertion
- failure with a fallback to abort. */
- {
- char *crash = getenv ("M4_CRASH");
- if (crash)
- {
- if (!strtol (crash, NULL, 10))
- ++*(int *) 8;
- assert (false);
- abort ();
- }
- }
-#endif /* DEBUG_STKOVF */
-
- /* First, we decode the arguments, to size up tables and stuff. */
- head = tail = NULL;
-
- while ((optchar = getopt_long (argc, (char **) argv, OPTSTRING,
- long_options, NULL)) != -1)
- switch (optchar)
- {
- default:
- usage (EXIT_FAILURE);
-
- case 'B':
- case 'S':
- case 'T':
- /* Compatibility junk: options that other implementations
- support, but which we ignore as no-ops and don't list in
- --help. */
- error (0, 0, _("warning: `m4 -%c' may be removed in a future release"),
- optchar);
- break;
-
- case 'N':
- case DIVERSIONS_OPTION:
- /* -N became an obsolete no-op in 1.4.x. */
- error (0, 0, _("warning: `m4 %s' is deprecated"),
- optchar == 'N' ? "-N" : "--diversions");
- break;
-
- case 'D':
- case 'U':
- case 's':
- case 't':
- case '\1':
- case DEBUGFILE_OPTION:
- /* Arguments that cannot be handled until later are accumulated. */
-
- defn = (macro_definition *) xmalloc (sizeof (macro_definition));
- defn->code = optchar;
- defn->arg = optarg;
- defn->next = NULL;
-
- if (head == NULL)
- head = defn;
- else
- tail->next = defn;
- tail = defn;
-
- break;
-
- case 'E':
- if (! fatal_warnings)
- fatal_warnings = true;
- else
- warning_status = EXIT_FAILURE;
- break;
-
- case 'F':
- frozen_file_to_write = optarg;
- break;
-
- case 'G':
- no_gnu_extensions = 1;
- break;
-
- case 'H':
- hash_table_size = strtol (optarg, NULL, 10);
- if (hash_table_size == 0)
- hash_table_size = HASHMAX;
- break;
-
- case 'I':
- add_include_directory (optarg);
- break;
-
- case 'L':
- nesting_limit = strtol (optarg, NULL, 10);
- break;
-
- case 'P':
- prefix_all_builtins = 1;
- break;
-
- case 'Q':
- suppress_warnings = 1;
- break;
-
- case 'R':
- frozen_file_to_read = optarg;
- break;
-
-#ifdef ENABLE_CHANGEWORD
- case 'W':
- user_word_regexp = optarg;
- break;
-#endif
-
- case 'd':
- debug_level = debug_decode (optarg);
- if (debug_level < 0)
- {
- error (0, 0, _("bad debug flags: `%s'"), optarg);
- debug_level = 0;
- }
- break;
-
- case 'e':
- error (0, 0, _("warning: `m4 -e' is deprecated, use `-i' instead"));
- /* fall through */
- case 'i':
- interactive = true;
- break;
-
- case 'g':
- no_gnu_extensions = 0;
- break;
-
- case 'l':
- max_debug_argument_length = strtol (optarg, NULL, 10);
- if (max_debug_argument_length <= 0)
- max_debug_argument_length = 0;
- break;
-
- case 'o':
- /* -o/--error-output are deprecated synonyms of --debugfile,
- but don't issue a deprecation warning until autoconf 2.61
- or later is more widely established, as such a warning
- would interfere with all earlier versions of autoconf. */
- /* Don't call debug_set_output here, as it has side effects. */
- debugfile = optarg;
- break;
-
- case WARN_MACRO_SEQUENCE_OPTION:
- /* Don't call set_macro_sequence here, as it can exit.
- --warn-macro-sequence sets optarg to NULL (which uses the
- default regexp); --warn-macro-sequence= sets optarg to ""
- (which disables these warnings). */
- macro_sequence = optarg;
- break;
-
- case VERSION_OPTION:
- version_etc (stdout, PACKAGE, PACKAGE_NAME, VERSION, AUTHORS, NULL);
- exit (EXIT_SUCCESS);
- break;
-
- case HELP_OPTION:
- usage (EXIT_SUCCESS);
- break;
- }
-
- defines = head;
-
- /* Do the basic initializations. */
- if (debugfile && !debug_set_output (debugfile))
- M4ERROR ((warning_status, errno, "cannot set debug file `%s'", debugfile));
-
- input_init ();
- output_init ();
- symtab_init ();
- set_macro_sequence (macro_sequence);
- include_env_init ();
-
- if (frozen_file_to_read)
- reload_frozen_state (frozen_file_to_read);
- else
- builtin_init ();
-
- /* Interactive mode means unbuffered output, and interrupts ignored. */
-
- if (interactive)
- {
- signal (SIGINT, SIG_IGN);
- setbuf (stdout, (char *) NULL);
- }
-
- /* Handle deferred command line macro definitions. Must come after
- initialization of the symbol table. */
-
- while (defines != NULL)
- {
- macro_definition *next;
- symbol *sym;
-
- switch (defines->code)
- {
- case 'D':
- {
- /* defines->arg is read-only, so we need a copy. */
- char *macro_name = xstrdup (defines->arg);
- char *macro_value = strchr (macro_name, '=');
- if (macro_value)
- *macro_value++ = '\0';
- define_user_macro (macro_name, macro_value, SYMBOL_INSERT);
- free (macro_name);
- }
- break;
-
- case 'U':
- lookup_symbol (defines->arg, SYMBOL_DELETE);
- break;
-
- case 't':
- sym = lookup_symbol (defines->arg, SYMBOL_INSERT);
- SYMBOL_TRACED (sym) = true;
- break;
-
- case 's':
- sync_output = 1;
- break;
-
- case '\1':
- seen_file = true;
- process_file (defines->arg);
- break;
-
- case DEBUGFILE_OPTION:
- if (!debug_set_output (defines->arg))
- M4ERROR ((warning_status, errno, "cannot set debug file `%s'",
- debugfile ? debugfile : _("stderr")));
- break;
-
- default:
- M4ERROR ((0, 0, "INTERNAL ERROR: bad code in deferred arguments"));
- abort ();
- }
-
- next = defines->next;
- free (defines);
- defines = next;
- }
-
- /* Handle remaining input files. Each file is pushed on the input,
- and the input read. Wrapup text is handled separately later. */
-
- if (optind == argc && !seen_file)
- process_file ("-");
- else
- for (; optind < argc; optind++)
- process_file (argv[optind]);
-
- /* Now handle wrapup text. */
-
- while (pop_wrapup ())
- expand_input ();
-
- /* Change debug stream back to stderr, to force flushing the debug
- stream and detect any errors it might have encountered. The
- three standard streams are closed by close_stdin. */
- debug_set_output (NULL);
-
- if (frozen_file_to_write)
- produce_frozen_state (frozen_file_to_write);
- else
- {
- make_diversion (0);
- undivert_all ();
- }
- output_exit ();
- free_macro_sequence ();
- exit (retcode);
-}
diff --git a/contrib/tools/bison/m4/src/m4.h b/contrib/tools/bison/m4/src/m4.h
deleted file mode 100644
index eb2a96784f..0000000000
--- a/contrib/tools/bison/m4/src/m4.h
+++ /dev/null
@@ -1,491 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2004-2013 Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* We use <config.h> instead of "config.h" so that a compilation
- using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
- (which it would do because it found this file in $srcdir). */
-
-#include <config.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "binary-io.h"
-#include "clean-temp.h"
-#include "cloexec.h"
-#include "close-stream.h"
-#include "closein.h"
-#include "dirname.h"
-#include "error.h"
-#include "exitfail.h"
-#include "filenamecat.h"
-#include "obstack.h"
-#include "stdio--.h"
-#include "stdlib--.h"
-#include "unistd--.h"
-#include "verror.h"
-#include "xalloc.h"
-#include "xprintf.h"
-#include "xvasprintf.h"
-
-/* Canonicalize UNIX recognition macros. */
-#if defined unix || defined __unix || defined __unix__ \
- || defined _POSIX_VERSION || defined _POSIX2_VERSION \
- || defined __NetBSD__ || defined __OpenBSD__ \
- || defined __APPLE__ || defined __APPLE_CC__
-# define UNIX 1
-#endif
-
-/* Canonicalize Windows recognition macros. */
-#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
-# define W32_NATIVE 1
-#endif
-
-/* Canonicalize OS/2 recognition macro. */
-#ifdef __EMX__
-# define OS2 1
-# undef UNIX
-#endif
-
-/* Used if any programmer error is detected (not possible, right?) */
-#define EXIT_INTERNAL_ERROR 2
-
-/* Used for version mismatch, when -R detects a frozen file it can't parse. */
-#define EXIT_MISMATCH 63
-
-/* No-op, for future gettext compatibility. */
-#define _(ARG) ARG
-
-/* Various declarations. */
-
-struct string
- {
- char *string; /* characters of the string */
- size_t length; /* length of the string */
- };
-typedef struct string STRING;
-
-/* Memory allocation. */
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-/* Those must come first. */
-typedef struct token_data token_data;
-typedef void builtin_func (struct obstack *, int, token_data **);
-
-/* Gnulib's stdbool doesn't work with bool bitfields. For nicer
- debugging, use bool when we know it works, but use the more
- portable unsigned int elsewhere. */
-#if __GNUC__ > 2
-typedef bool bool_bitfield;
-#else
-typedef unsigned int bool_bitfield;
-#endif /* ! __GNUC__ */
-
-/* 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)
-#else
-# define M4_GNUC_ATTRIBUTE(args)
-#endif /* __GNUC__ */
-
-#define M4_GNUC_UNUSED M4_GNUC_ATTRIBUTE ((__unused__))
-#define M4_GNUC_PRINTF(fmt, arg) \
- M4_GNUC_ATTRIBUTE ((__format__ (__printf__, fmt, arg)))
-#define M4_GNUC_NORETURN M4_GNUC_ATTRIBUTE ((__noreturn__))
-#define M4_GNUC_PURE M4_GNUC_ATTRIBUTE ((__pure__))
-
-/* File: m4.c --- global definitions. */
-
-/* Option flags. */
-extern int sync_output; /* -s */
-extern int debug_level; /* -d */
-extern size_t hash_table_size; /* -H */
-extern int no_gnu_extensions; /* -G */
-extern int prefix_all_builtins; /* -P */
-extern int max_debug_argument_length; /* -l */
-extern int suppress_warnings; /* -Q */
-extern int warning_status; /* -E */
-extern int nesting_limit; /* -L */
-#ifdef ENABLE_CHANGEWORD
-extern const char *user_word_regexp; /* -W */
-#endif
-
-/* Error handling. */
-extern int retcode;
-
-extern void m4_error (int, int, const char *, ...) M4_GNUC_PRINTF(3, 4);
-extern void m4_error_at_line (int, int, const char *, int,
- const char *, ...) M4_GNUC_PRINTF(5, 6);
-
-#define M4ERROR(Arglist) (m4_error Arglist)
-#define M4ERROR_AT_LINE(Arglist) (m4_error_at_line Arglist)
-
-
-/* File: debug.c --- debugging and tracing function. */
-
-extern FILE *debug;
-
-/* The value of debug_level is a bitmask of the following. */
-
-/* a: show arglist in trace output */
-#define DEBUG_TRACE_ARGS 1
-/* e: show expansion in trace output */
-#define DEBUG_TRACE_EXPANSION 2
-/* q: quote args and expansion in trace output */
-#define DEBUG_TRACE_QUOTE 4
-/* t: trace all macros -- overrides trace{on,off} */
-#define DEBUG_TRACE_ALL 8
-/* l: add line numbers to trace output */
-#define DEBUG_TRACE_LINE 16
-/* f: add file name to trace output */
-#define DEBUG_TRACE_FILE 32
-/* p: trace path search of include files */
-#define DEBUG_TRACE_PATH 64
-/* c: show macro call before args collection */
-#define DEBUG_TRACE_CALL 128
-/* i: trace changes of input files */
-#define DEBUG_TRACE_INPUT 256
-/* x: add call id to trace output */
-#define DEBUG_TRACE_CALLID 512
-
-/* V: very verbose -- print everything */
-#define DEBUG_TRACE_VERBOSE 1023
-/* default flags -- equiv: aeq */
-#define DEBUG_TRACE_DEFAULT 7
-
-#define DEBUG_PRINT1(Fmt, Arg1) \
- do \
- { \
- if (debug != NULL) \
- xfprintf (debug, Fmt, Arg1); \
- } \
- while (0)
-
-#define DEBUG_PRINT3(Fmt, Arg1, Arg2, Arg3) \
- do \
- { \
- if (debug != NULL) \
- xfprintf (debug, Fmt, Arg1, Arg2, Arg3); \
- } \
- while (0)
-
-#define DEBUG_MESSAGE(Fmt) \
- do \
- { \
- if (debug != NULL) \
- { \
- debug_message_prefix (); \
- xfprintf (debug, Fmt); \
- putc ('\n', debug); \
- } \
- } \
- while (0)
-
-#define DEBUG_MESSAGE1(Fmt, Arg1) \
- do \
- { \
- if (debug != NULL) \
- { \
- debug_message_prefix (); \
- xfprintf (debug, Fmt, Arg1); \
- putc ('\n', debug); \
- } \
- } \
- while (0)
-
-#define DEBUG_MESSAGE2(Fmt, Arg1, Arg2) \
- do \
- { \
- if (debug != NULL) \
- { \
- debug_message_prefix (); \
- xfprintf (debug, Fmt, Arg1, Arg2); \
- putc ('\n', debug); \
- } \
- } \
- while (0)
-
-extern void debug_init (void);
-extern int debug_decode (const char *);
-extern void debug_flush_files (void);
-extern bool debug_set_output (const char *);
-extern void debug_message_prefix (void);
-
-extern void trace_prepre (const char *, int);
-extern void trace_pre (const char *, int, int, token_data **);
-extern void trace_post (const char *, int, int, const char *);
-
-/* File: input.c --- lexical definitions. */
-
-/* Various different token types. */
-enum token_type
-{
- TOKEN_EOF, /* end of file */
- TOKEN_STRING, /* a quoted string or comment */
- TOKEN_WORD, /* an identifier */
- TOKEN_OPEN, /* ( */
- TOKEN_COMMA, /* , */
- TOKEN_CLOSE, /* ) */
- TOKEN_SIMPLE, /* any other single character */
- TOKEN_MACDEF /* a macro's definition (see "defn") */
-};
-
-/* The data for a token, a macro argument, and a macro definition. */
-enum token_data_type
-{
- TOKEN_VOID,
- TOKEN_TEXT,
- TOKEN_FUNC
-};
-
-struct token_data
-{
- enum token_data_type type;
- union
- {
- struct
- {
- char *text;
-#ifdef ENABLE_CHANGEWORD
- char *original_text;
-#endif
- }
- u_t;
- builtin_func *func;
- }
- u;
-};
-
-#define TOKEN_DATA_TYPE(Td) ((Td)->type)
-#define TOKEN_DATA_TEXT(Td) ((Td)->u.u_t.text)
-#ifdef ENABLE_CHANGEWORD
-# define TOKEN_DATA_ORIG_TEXT(Td) ((Td)->u.u_t.original_text)
-#endif
-#define TOKEN_DATA_FUNC(Td) ((Td)->u.func)
-
-typedef enum token_type token_type;
-typedef enum token_data_type token_data_type;
-
-extern void input_init (void);
-extern token_type peek_token (void);
-extern token_type next_token (token_data *, int *);
-extern void skip_line (void);
-
-/* push back input */
-extern void push_file (FILE *, const char *, bool);
-extern void push_macro (builtin_func *);
-extern struct obstack *push_string_init (void);
-extern const char *push_string_finish (void);
-extern void push_wrapup (const char *);
-extern bool pop_wrapup (void);
-
-/* current input file, and line */
-extern const char *current_file;
-extern int current_line;
-
-/* left and right quote, begin and end comment */
-extern STRING bcomm;
-extern STRING ecomm;
-extern STRING lquote;
-extern STRING rquote;
-
-#define DEF_LQUOTE "`"
-#define DEF_RQUOTE "\'"
-#define DEF_BCOMM "#"
-#define DEF_ECOMM "\n"
-
-extern void set_quotes (const char *, const char *);
-extern void set_comment (const char *, const char *);
-#ifdef ENABLE_CHANGEWORD
-extern void set_word_regexp (const char *);
-#endif
-
-/* File: output.c --- output functions. */
-extern int current_diversion;
-extern int output_current_line;
-
-extern void output_init (void);
-extern void output_exit (void);
-extern void output_text (const char *, int);
-extern void shipout_text (struct obstack *, const char *, int, int);
-extern void make_diversion (int);
-extern void insert_diversion (int);
-extern void insert_file (FILE *);
-extern void freeze_diversions (FILE *);
-
-/* File symtab.c --- symbol table definitions. */
-
-/* Operation modes for lookup_symbol (). */
-enum symbol_lookup
-{
- SYMBOL_LOOKUP,
- SYMBOL_INSERT,
- SYMBOL_DELETE,
- SYMBOL_PUSHDEF,
- SYMBOL_POPDEF
-};
-
-/* Symbol table entry. */
-struct symbol
-{
- struct symbol *next;
- bool_bitfield traced : 1;
- bool_bitfield shadowed : 1;
- bool_bitfield macro_args : 1;
- bool_bitfield blind_no_args : 1;
- bool_bitfield deleted : 1;
- int pending_expansions;
-
- char *name;
- token_data data;
-};
-
-#define SYMBOL_NEXT(S) ((S)->next)
-#define SYMBOL_TRACED(S) ((S)->traced)
-#define SYMBOL_SHADOWED(S) ((S)->shadowed)
-#define SYMBOL_MACRO_ARGS(S) ((S)->macro_args)
-#define SYMBOL_BLIND_NO_ARGS(S) ((S)->blind_no_args)
-#define SYMBOL_DELETED(S) ((S)->deleted)
-#define SYMBOL_PENDING_EXPANSIONS(S) ((S)->pending_expansions)
-#define SYMBOL_NAME(S) ((S)->name)
-#define SYMBOL_TYPE(S) (TOKEN_DATA_TYPE (&(S)->data))
-#define SYMBOL_TEXT(S) (TOKEN_DATA_TEXT (&(S)->data))
-#define SYMBOL_FUNC(S) (TOKEN_DATA_FUNC (&(S)->data))
-
-typedef enum symbol_lookup symbol_lookup;
-typedef struct symbol symbol;
-typedef void hack_symbol (symbol *, void *);
-
-#define HASHMAX 509 /* default, overridden by -Hsize */
-
-extern symbol **symtab;
-
-extern void free_symbol (symbol *sym);
-extern void symtab_init (void);
-extern symbol *lookup_symbol (const char *, symbol_lookup);
-extern void hack_all_symbols (hack_symbol *, void *);
-
-/* File: macro.c --- macro expansion. */
-
-extern int expansion_level;
-
-extern void expand_input (void);
-extern void call_macro (symbol *, int, token_data **, struct obstack *);
-
-/* File: builtin.c --- builtins. */
-
-struct builtin
-{
- const char *name;
- bool_bitfield gnu_extension : 1;
- bool_bitfield groks_macro_args : 1;
- bool_bitfield blind_if_no_args : 1;
- builtin_func *func;
-};
-
-struct predefined
-{
- const char *unix_name;
- const char *gnu_name;
- const char *func;
-};
-
-typedef struct builtin builtin;
-typedef struct predefined predefined;
-struct re_pattern_buffer;
-struct re_registers;
-
-/* The default sequence detects multi-digit parameters (obsolete after
- 1.4.x), and any use of extended arguments with the default ${}
- syntax (new in 2.0). */
-#define DEFAULT_MACRO_SEQUENCE "\\$\\({[^}]*}\\|[0-9][0-9]+\\)"
-
-extern void builtin_init (void);
-extern void define_builtin (const char *, const builtin *, symbol_lookup);
-extern void set_macro_sequence (const char *);
-extern void free_macro_sequence (void);
-extern void define_user_macro (const char *, const char *, symbol_lookup);
-extern void undivert_all (void);
-extern void expand_user_macro (struct obstack *, symbol *, int, token_data **);
-extern void m4_placeholder (struct obstack *, int, token_data **);
-extern void init_pattern_buffer (struct re_pattern_buffer *,
- struct re_registers *);
-extern const char *ntoa (int32_t, int);
-
-extern const builtin *find_builtin_by_addr (builtin_func *);
-extern const builtin *find_builtin_by_name (const char *);
-
-/* File: path.c --- path search for include files. */
-
-extern void include_init (void);
-extern void include_env_init (void);
-extern void add_include_directory (const char *);
-extern FILE *m4_path_search (const char *, char **);
-
-/* File: eval.c --- expression evaluation. */
-
-extern bool evaluate (const char *, int32_t *);
-
-/* File: format.c --- printf like formatting. */
-
-extern void expand_format (struct obstack *, int, token_data **);
-
-/* File: freeze.c --- frozen state files. */
-
-extern void produce_frozen_state (const char *);
-extern void reload_frozen_state (const char *);
-
-/* Debugging the memory allocator. */
-
-#ifdef WITH_DMALLOC
-# define DMALLOC_FUNC_CHECK
-# include <dmalloc.h>
-#endif
-
-/* Other debug stuff. */
-
-#ifdef DEBUG
-# define DEBUG_INCL 1
-# define DEBUG_INPUT 1
-# define DEBUG_MACRO 1
-# define DEBUG_OUTPUT 1
-# define DEBUG_STKOVF 1
-# define DEBUG_SYM 1
-#endif
-
-/* Convert a possibly-signed character to an unsigned character. This is
- a bit safer than casting to unsigned char, since it catches some type
- errors that the cast doesn't. */
-#if HAVE_INLINE
-static inline unsigned char to_uchar (char ch) { return ch; }
-#else
-# define to_uchar(C) ((unsigned char) (C))
-#endif
-
-/* Avoid negative logic when comparing two strings. */
-#define STREQ(a, b) (strcmp (a, b) == 0)
diff --git a/contrib/tools/bison/m4/src/macro.c b/contrib/tools/bison/m4/src/macro.c
deleted file mode 100644
index 0e7624372e..0000000000
--- a/contrib/tools/bison/m4/src/macro.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2006-2007, 2009-2013 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* This file contains the functions, that performs the basic argument
- parsing and macro expansion. */
-
-#include "m4.h"
-
-static void expand_macro (symbol *);
-static void expand_token (struct obstack *, token_type, token_data *, int);
-
-/* Current recursion level in expand_macro (). */
-int expansion_level = 0;
-
-/* The number of the current call of expand_macro (). */
-static int macro_call_id = 0;
-
-/* The shared stack of collected arguments for macro calls; as each
- argument is collected, it is finished and its location stored in
- argv_stack. Normally, this stack can be used simultaneously by
- multiple macro calls; the exception is when an outer macro has
- generated some text, then calls a nested macro, in which case the
- nested macro must use a local stack to leave the unfinished text
- alone. Too bad obstack.h does not provide an easy way to reopen a
- finished object for further growth, but in practice this does not
- hurt us too much. */
-static struct obstack argc_stack;
-
-/* The shared stack of pointers to collected arguments for macro
- calls. This object is never finished; we exploit the fact that
- obstack_blank is documented to take a negative size to reduce the
- size again. */
-static struct obstack argv_stack;
-
-/*----------------------------------------------------------------------.
-| This function read all input, and expands each token, one at a time. |
-`----------------------------------------------------------------------*/
-
-void
-expand_input (void)
-{
- token_type t;
- token_data td;
- int line;
-
- obstack_init (&argc_stack);
- obstack_init (&argv_stack);
-
- while ((t = next_token (&td, &line)) != TOKEN_EOF)
- expand_token ((struct obstack *) NULL, t, &td, line);
-
- obstack_free (&argc_stack, NULL);
- obstack_free (&argv_stack, NULL);
-}
-
-
-/*----------------------------------------------------------------.
-| Expand one token, according to its type. Potential macro names |
-| (TOKEN_WORD) are looked up in the symbol table, to see if they |
-| have a macro definition. If they have, they are expanded as |
-| macros, otherwise the text is just copied to the output. |
-`----------------------------------------------------------------*/
-
-static void
-expand_token (struct obstack *obs, token_type t, token_data *td, int line)
-{
- symbol *sym;
-
- switch (t)
- { /* TOKSW */
- case TOKEN_EOF:
- case TOKEN_MACDEF:
- break;
-
- case TOKEN_OPEN:
- case TOKEN_COMMA:
- case TOKEN_CLOSE:
- case TOKEN_SIMPLE:
- case TOKEN_STRING:
- shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)),
- line);
- break;
-
- case TOKEN_WORD:
- sym = lookup_symbol (TOKEN_DATA_TEXT (td), SYMBOL_LOOKUP);
- if (sym == NULL || SYMBOL_TYPE (sym) == TOKEN_VOID
- || (SYMBOL_TYPE (sym) == TOKEN_FUNC
- && SYMBOL_BLIND_NO_ARGS (sym)
- && peek_token () != TOKEN_OPEN))
- {
-#ifdef ENABLE_CHANGEWORD
- shipout_text (obs, TOKEN_DATA_ORIG_TEXT (td),
- strlen (TOKEN_DATA_ORIG_TEXT (td)), line);
-#else
- shipout_text (obs, TOKEN_DATA_TEXT (td),
- strlen (TOKEN_DATA_TEXT (td)), line);
-#endif
- }
- else
- expand_macro (sym);
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad token type in expand_token ()"));
- abort ();
- }
-}
-
-
-/*-------------------------------------------------------------------.
-| This function parses one argument to a macro call. It expects the |
-| first left parenthesis, or the separating comma, to have been read |
-| by the caller. It skips leading whitespace, and reads and expands |
-| tokens, until it finds a comma or an right parenthesis at the same |
-| level of parentheses. It returns a flag indicating whether the |
-| argument read is the last for the active macro call. The argument |
-| is built on the obstack OBS, indirectly through expand_token (). |
-`-------------------------------------------------------------------*/
-
-static bool
-expand_argument (struct obstack *obs, token_data *argp)
-{
- token_type t;
- token_data td;
- char *text;
- int paren_level;
- const char *file = current_file;
- int line = current_line;
-
- TOKEN_DATA_TYPE (argp) = TOKEN_VOID;
-
- /* Skip leading white space. */
- do
- {
- t = next_token (&td, NULL);
- }
- while (t == TOKEN_SIMPLE && isspace (to_uchar (*TOKEN_DATA_TEXT (&td))));
-
- paren_level = 0;
-
- while (1)
- {
-
- switch (t)
- { /* TOKSW */
- case TOKEN_COMMA:
- case TOKEN_CLOSE:
- if (paren_level == 0)
- {
- /* The argument MUST be finished, whether we want it or not. */
- obstack_1grow (obs, '\0');
- text = (char *) obstack_finish (obs);
-
- if (TOKEN_DATA_TYPE (argp) == TOKEN_VOID)
- {
- TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
- TOKEN_DATA_TEXT (argp) = text;
- }
- return t == TOKEN_COMMA;
- }
- /* fallthru */
- case TOKEN_OPEN:
- case TOKEN_SIMPLE:
- text = TOKEN_DATA_TEXT (&td);
-
- if (*text == '(')
- paren_level++;
- else if (*text == ')')
- paren_level--;
- expand_token (obs, t, &td, line);
- break;
-
- case TOKEN_EOF:
- /* current_file changed to "" if we see TOKEN_EOF, use the
- previous value we stored earlier. */
- M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, line,
- "ERROR: end of file in argument list"));
- break;
-
- case TOKEN_WORD:
- case TOKEN_STRING:
- expand_token (obs, t, &td, line);
- break;
-
- case TOKEN_MACDEF:
- if (obstack_object_size (obs) == 0)
- {
- TOKEN_DATA_TYPE (argp) = TOKEN_FUNC;
- TOKEN_DATA_FUNC (argp) = TOKEN_DATA_FUNC (&td);
- }
- break;
-
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad token type in expand_argument ()"));
- abort ();
- }
-
- t = next_token (&td, NULL);
- }
-}
-
-/*-------------------------------------------------------------.
-| Collect all the arguments to a call of the macro SYM. The |
-| arguments are stored on the obstack ARGUMENTS and a table of |
-| pointers to the arguments on the obstack ARGPTR. |
-`-------------------------------------------------------------*/
-
-static void
-collect_arguments (symbol *sym, struct obstack *argptr,
- struct obstack *arguments)
-{
- token_data td;
- token_data *tdp;
- bool more_args;
- bool groks_macro_args = SYMBOL_MACRO_ARGS (sym);
-
- 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);
-
- if (peek_token () == TOKEN_OPEN)
- {
- next_token (&td, NULL); /* gobble parenthesis */
- do
- {
- more_args = expand_argument (arguments, &td);
-
- if (!groks_macro_args && TOKEN_DATA_TYPE (&td) == TOKEN_FUNC)
- {
- TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
- TOKEN_DATA_TEXT (&td) = (char *) "";
- }
- tdp = (token_data *) obstack_copy (arguments, &td, sizeof td);
- obstack_ptr_grow (argptr, tdp);
- }
- while (more_args);
- }
-}
-
-
-/*-------------------------------------------------------------------.
-| The actual call of a macro is handled by call_macro (). |
-| call_macro () is passed a symbol SYM, whose type is used to call |
-| either a builtin function, or the user macro expansion function |
-| expand_user_macro () (lives in builtin.c). There are ARGC |
-| arguments to the call, stored in the ARGV table. The expansion is |
-| left on the obstack EXPANSION. Macro tracing is also handled |
-| here. |
-`-------------------------------------------------------------------*/
-
-void
-call_macro (symbol *sym, int argc, token_data **argv,
- struct obstack *expansion)
-{
- switch (SYMBOL_TYPE (sym))
- {
- case TOKEN_FUNC:
- (*SYMBOL_FUNC (sym)) (expansion, argc, argv);
- break;
-
- case TOKEN_TEXT:
- expand_user_macro (expansion, sym, argc, argv);
- break;
-
- case TOKEN_VOID:
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: bad symbol type in call_macro ()"));
- abort ();
- }
-}
-
-/*-------------------------------------------------------------------.
-| The macro expansion is handled by expand_macro (). It parses the |
-| arguments, using collect_arguments (), and builds a table of |
-| pointers to the arguments. The arguments themselves are stored on |
-| a local obstack. Expand_macro () uses call_macro () to do the |
-| call of the macro. |
-| |
-| Expand_macro () is potentially recursive, since it calls |
-| expand_argument (), which might call expand_token (), which might |
-| call expand_macro (). |
-`-------------------------------------------------------------------*/
-
-static void
-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;
- int argc;
- struct obstack *expansion;
- const char *expanded;
- bool traced;
- int my_call_id;
-
- /* Report errors at the location where the open parenthesis (if any)
- was found, but after expansion, restore global state back to the
- location of the close parenthesis. This is safe since we
- guarantee that macro expansion does not alter the state of
- current_file/current_line (dnl, include, and sinclude are special
- cased in the input engine to ensure this fact). */
- const char *loc_open_file = current_file;
- int loc_open_line = current_line;
- const char *loc_close_file;
- int loc_close_line;
-
- SYMBOL_PENDING_EXPANSIONS (sym)++;
- expansion_level++;
- if (nesting_limit > 0 && expansion_level > nesting_limit)
- M4ERROR ((EXIT_FAILURE, 0,
- "recursion limit of %d exceeded, use -L<N> to change it",
- nesting_limit));
-
- macro_call_id++;
- my_call_id = macro_call_id;
-
- traced = (debug_level & DEBUG_TRACE_ALL) || SYMBOL_TRACED (sym);
-
- argv_base = obstack_object_size (&argv_stack);
- if (obstack_object_size (&argc_stack) > 0)
- {
- /* We cannot use argc_stack if this is a nested invocation, and an
- outer invocation has an unfinished argument being
- collected. */
- obstack_init (&arguments);
- use_argc_stack = false;
- }
-
- 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);
-
- loc_close_file = current_file;
- loc_close_line = current_line;
- current_file = loc_open_file;
- current_line = loc_open_line;
-
- if (traced)
- trace_pre (SYMBOL_NAME (sym), my_call_id, argc, argv);
-
- expansion = push_string_init ();
- call_macro (sym, argc, argv, expansion);
- expanded = push_string_finish ();
-
- if (traced)
- trace_post (SYMBOL_NAME (sym), my_call_id, argc, expanded);
-
- current_file = loc_close_file;
- current_line = loc_close_line;
-
- --expansion_level;
- --SYMBOL_PENDING_EXPANSIONS (sym);
-
- if (SYMBOL_DELETED (sym))
- free_symbol (sym);
-
- if (use_argc_stack)
- obstack_free (&argc_stack, argv[0]);
- else
- obstack_free (&arguments, NULL);
- obstack_blank (&argv_stack, -argc * sizeof (token_data *));
-}
diff --git a/contrib/tools/bison/m4/src/output.c b/contrib/tools/bison/m4/src/output.c
deleted file mode 100644
index c378afebdb..0000000000
--- a/contrib/tools/bison/m4/src/output.c
+++ /dev/null
@@ -1,1017 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2004-2013 Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "m4.h"
-
-#include <limits.h>
-#include <sys/stat.h>
-
-#include "gl_avltree_oset.h"
-#include "gl_xoset.h"
-
-/* Size of initial in-memory buffer size for diversions. Small diversions
- would usually fit in. */
-#define INITIAL_BUFFER_SIZE 512
-
-/* Maximum value for the total of all in-memory buffer sizes for
- diversions. */
-#define MAXIMUM_TOTAL_SIZE (512 * 1024)
-
-/* Size of buffer size to use while copying files. */
-#define COPY_BUFFER_SIZE (32 * 512)
-
-/* Output functions. Most of the complexity is for handling cpp like
- sync lines.
-
- This code is fairly entangled with the code in input.c, and maybe it
- belongs there? */
-
-typedef struct temp_dir m4_temp_dir;
-
-/* When part of diversion_table, each struct m4_diversion either
- represents an open file (zero size, non-NULL u.file), an in-memory
- buffer (non-zero size, non-NULL u.buffer), or an unused placeholder
- diversion (zero size, u is NULL, non-zero used indicates that a
- file has been created). When not part of diversion_table, u.next
- is a pointer to the free_list chain. */
-
-typedef struct m4_diversion m4_diversion;
-
-struct m4_diversion
- {
- union
- {
- FILE *file; /* Diversion file on disk. */
- char *buffer; /* Malloc'd diversion buffer. */
- m4_diversion *next; /* Free-list pointer */
- } u;
- int divnum; /* Which diversion this represents. */
- int size; /* Usable size before reallocation. */
- int used; /* Used buffer length, or tmp file exists. */
- };
-
-/* Table of diversions 1 through INT_MAX. */
-static gl_oset_t diversion_table;
-
-/* Diversion 0 (not part of diversion_table). */
-static m4_diversion div0;
-
-/* Linked list of reclaimed diversion storage. */
-static m4_diversion *free_list;
-
-/* Obstack from which diversion storage is allocated. */
-static struct obstack diversion_storage;
-
-/* Total size of all in-memory buffer sizes. */
-static int total_buffer_size;
-
-/* The number of the currently active diversion. This variable is
- maintained for the `divnum' builtin function. */
-int current_diversion;
-
-/* Current output diversion, NULL if output is being currently
- discarded. output_diversion->u is guaranteed non-NULL except when
- the diversion has never been used; use size to determine if it is a
- malloc'd buffer or a FILE. output_diversion->used is 0 if u.file
- is stdout, and non-zero if this is a malloc'd buffer or a temporary
- diversion file. */
-static m4_diversion *output_diversion;
-
-/* Cache of output_diversion->u.file, only valid when
- output_diversion->size is 0. */
-static FILE *output_file;
-
-/* Cache of output_diversion->u.buffer + output_diversion->used, only
- valid when output_diversion->size is non-zero. */
-static char *output_cursor;
-
-/* Cache of output_diversion->size - output_diversion->used, only
- valid when output_diversion->size is non-zero. */
-static int output_unused;
-
-/* Number of input line we are generating output for. */
-int output_current_line;
-
-/* Temporary directory holding all spilled diversion files. */
-static m4_temp_dir *output_temp_dir;
-
-/* Cache of most recently used spilled diversion files. */
-static FILE *tmp_file1;
-static FILE *tmp_file2;
-
-/* Diversions that own tmp_file, or 0. */
-static int tmp_file1_owner;
-static int tmp_file2_owner;
-
-/* True if tmp_file2 is more recently used. */
-static bool tmp_file2_recent;
-
-
-/* Internal routines. */
-
-/* Callback for comparing list elements ELT1 and ELT2 for order in
- diversion_table. */
-static int
-cmp_diversion_CB (const void *elt1, const void *elt2)
-{
- const m4_diversion *d1 = (const m4_diversion *) elt1;
- const m4_diversion *d2 = (const m4_diversion *) elt2;
- /* No need to worry about overflow, since we don't create diversions
- with negative divnum. */
- return d1->divnum - d2->divnum;
-}
-
-/* Callback for comparing list element ELT against THRESHOLD. */
-static bool
-threshold_diversion_CB (const void *elt, const void *threshold)
-{
- const m4_diversion *diversion = (const m4_diversion *) elt;
- /* No need to worry about overflow, since we don't create diversions
- with negative divnum. */
- return diversion->divnum >= *(const int *) threshold;
-}
-
-/* Clean up any temporary directory. Designed for use as an atexit
- handler, where it is not safe to call exit() recursively; so this
- calls _exit if a problem is encountered. */
-static void
-cleanup_tmpfile (void)
-{
- /* Close any open diversions. */
- bool fail = false;
-
- if (diversion_table)
- {
- const void *elt;
- gl_oset_iterator_t iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (!diversion->size && diversion->u.file
- && close_stream_temp (diversion->u.file) != 0)
- {
- M4ERROR ((0, errno,
- "cannot clean temporary file for diversion"));
- fail = true;
- }
- }
- gl_oset_iterator_free (&iter);
- }
-
- /* Clean up the temporary directory. */
- if (cleanup_temp_dir (output_temp_dir) != 0)
- fail = true;
- if (fail)
- _exit (exit_failure);
-}
-
-/* Convert DIVNUM into a temporary file name for use in m4_tmp*. */
-static const char *
-m4_tmpname (int divnum)
-{
- static char *buffer;
- static char *tail;
- if (buffer == NULL)
- {
- tail = xasprintf ("%s/m4-%d", output_temp_dir->dir_name, INT_MAX);
- buffer = (char *) obstack_copy0 (&diversion_storage, tail,
- strlen (tail));
- free (tail);
- tail = strrchr (buffer, '-') + 1;
- }
- assert (0 < divnum);
- sprintf (tail, "%d", divnum);
- return buffer;
-}
-
-/* Create a temporary file for diversion DIVNUM open for reading and
- writing in a secure temp directory. The file will be automatically
- closed and deleted on a fatal signal. The file can be closed and
- reopened with m4_tmpclose and m4_tmpopen, or moved with
- m4_tmprename; when finally done with the file, close it with
- m4_tmpremove. Exits on failure, so the return value is always an
- open file. */
-static FILE *
-m4_tmpfile (int divnum)
-{
- const char *name;
- FILE *file;
-
- if (output_temp_dir == NULL)
- {
- output_temp_dir = create_temp_dir ("m4-", NULL, true);
- if (output_temp_dir == NULL)
- M4ERROR ((EXIT_FAILURE, errno,
- "cannot create temporary file for diversion"));
- atexit (cleanup_tmpfile);
- }
- name = m4_tmpname (divnum);
- register_temp_file (output_temp_dir, name);
- file = fopen_temp (name, O_BINARY ? "wb+" : "w+");
- if (file == NULL)
- {
- unregister_temp_file (output_temp_dir, name);
- M4ERROR ((EXIT_FAILURE, errno,
- "cannot create temporary file for diversion"));
- }
- else if (set_cloexec_flag (fileno (file), true) != 0)
- M4ERROR ((warning_status, errno,
- "Warning: cannot protect diversion across forks"));
- return file;
-}
-
-/* Reopen a temporary file for diversion DIVNUM for reading and
- writing in a secure temp directory. If REREAD, the file is
- positioned at offset 0, otherwise the file is positioned at the
- end. Exits on failure, so the return value is always an open
- file. */
-static FILE *
-m4_tmpopen (int divnum, bool reread)
-{
- const char *name;
- FILE *file;
-
- if (tmp_file1_owner == divnum)
- {
- if (reread && fseeko (tmp_file1, 0, SEEK_SET) != 0)
- m4_error (EXIT_FAILURE, errno,
- _("cannot seek within diversion"));
- tmp_file2_recent = false;
- return tmp_file1;
- }
- else if (tmp_file2_owner == divnum)
- {
- if (reread && fseeko (tmp_file2, 0, SEEK_SET) != 0)
- m4_error (EXIT_FAILURE, errno,
- _("cannot seek within diversion"));
- tmp_file2_recent = true;
- return tmp_file2;
- }
- name = m4_tmpname (divnum);
- /* We need update mode, to avoid truncation. */
- file = fopen_temp (name, O_BINARY ? "rb+" : "r+");
- if (file == NULL)
- M4ERROR ((EXIT_FAILURE, errno,
- "cannot create temporary file for diversion"));
- else if (set_cloexec_flag (fileno (file), true) != 0)
- m4_error (0, errno, _("cannot protect diversion across forks"));
- /* Update mode starts at the beginning of the stream, but sometimes
- we want the end. */
- else if (!reread && fseeko (file, 0, SEEK_END) != 0)
- m4_error (EXIT_FAILURE, errno,
- _("cannot seek within diversion"));
- return file;
-}
-
-/* Close, but don't delete, a temporary FILE for diversion DIVNUM. To
- reduce the I/O overhead of repeatedly opening and closing the same
- file, this implementation caches the most recent spilled diversion.
- On the other hand, keeping every spilled diversion open would run
- into EMFILE limits. */
-static int
-m4_tmpclose (FILE *file, int divnum)
-{
- int result = 0;
- if (divnum != tmp_file1_owner && divnum != tmp_file2_owner)
- {
- if (tmp_file2_recent)
- {
- if (tmp_file1_owner)
- result = close_stream_temp (tmp_file1);
- tmp_file1 = file;
- tmp_file1_owner = divnum;
- }
- else
- {
- if (tmp_file2_owner)
- result = close_stream_temp (tmp_file2);
- tmp_file2 = file;
- tmp_file2_owner = divnum;
- }
- }
- return result;
-}
-
-/* Delete a closed temporary FILE for diversion DIVNUM. */
-static int
-m4_tmpremove (int divnum)
-{
- if (divnum == tmp_file1_owner)
- {
- int result = close_stream_temp (tmp_file1);
- if (result)
- return result;
- tmp_file1_owner = 0;
- }
- else if (divnum == tmp_file2_owner)
- {
- int result = close_stream_temp (tmp_file2);
- if (result)
- return result;
- tmp_file2_owner = 0;
- }
- return cleanup_temp_file (output_temp_dir, m4_tmpname (divnum));
-}
-
-/* Transfer the temporary file for diversion OLDNUM to the previously
- unused diversion NEWNUM. Return an open stream visiting the new
- temporary file, positioned at the end, or exit on failure. */
-static FILE*
-m4_tmprename (int oldnum, int newnum)
-{
- /* m4_tmpname reuses its return buffer. */
- char *oldname = xstrdup (m4_tmpname (oldnum));
- const char *newname = m4_tmpname (newnum);
- register_temp_file (output_temp_dir, newname);
- if (oldnum == tmp_file1_owner)
- {
- /* Be careful of mingw, which can't rename an open file. */
- if (RENAME_OPEN_FILE_WORKS)
- tmp_file1_owner = newnum;
- else
- {
- if (close_stream_temp (tmp_file1))
- m4_error (EXIT_FAILURE, errno,
- _("cannot close temporary file for diversion"));
- tmp_file1_owner = 0;
- }
- }
- else if (oldnum == tmp_file2_owner)
- {
- /* Be careful of mingw, which can't rename an open file. */
- if (RENAME_OPEN_FILE_WORKS)
- tmp_file2_owner = newnum;
- else
- {
- if (close_stream_temp (tmp_file2))
- m4_error (EXIT_FAILURE, errno,
- _("cannot close temporary file for diversion"));
- tmp_file2_owner = 0;
- }
- }
- /* Either it is safe to rename an open file, or no one should have
- oldname open at this point. */
- if (rename (oldname, newname))
- m4_error (EXIT_FAILURE, errno,
- _("cannot create temporary file for diversion"));
- unregister_temp_file (output_temp_dir, oldname);
- free (oldname);
- return m4_tmpopen (newnum, false);
-}
-
-
-/*------------------------.
-| Output initialization. |
-`------------------------*/
-
-void
-output_init (void)
-{
- diversion_table = gl_oset_create_empty (GL_AVLTREE_OSET, cmp_diversion_CB,
- NULL);
- div0.u.file = stdout;
- output_diversion = &div0;
- output_file = stdout;
- obstack_init (&diversion_storage);
-}
-
-void
-output_exit (void)
-{
- /* Order is important, since we may have registered cleanup_tmpfile
- as an atexit handler, and it must not traverse stale memory. */
- gl_oset_t table = diversion_table;
- if (tmp_file1_owner)
- m4_tmpremove (tmp_file1_owner);
- if (tmp_file2_owner)
- m4_tmpremove (tmp_file2_owner);
- diversion_table = NULL;
- gl_oset_free (table);
- obstack_free (&diversion_storage, NULL);
-}
-
-/*----------------------------------------------------------------.
-| Reorganize in-memory diversion buffers so the current diversion |
-| can accomodate LENGTH more characters without further |
-| reorganization. The current diversion buffer is made bigger if |
-| possible. But to make room for a bigger buffer, one of the |
-| in-memory diversion buffers might have to be flushed to a newly |
-| created temporary file. This flushed buffer might well be the |
-| current one. |
-`----------------------------------------------------------------*/
-
-static void
-make_room_for (int length)
-{
- int wanted_size;
- m4_diversion *selected_diversion = NULL;
-
- /* Compute needed size for in-memory buffer. Diversions in-memory
- buffers start at 0 bytes, then 512, then keep doubling until it is
- decided to flush them to disk. */
-
- output_diversion->used = output_diversion->size - output_unused;
-
- for (wanted_size = output_diversion->size;
- wanted_size < output_diversion->used + length;
- wanted_size = wanted_size == 0 ? INITIAL_BUFFER_SIZE : wanted_size * 2)
- ;
-
- /* Check if we are exceeding the maximum amount of buffer memory. */
-
- if (total_buffer_size - output_diversion->size + wanted_size
- > MAXIMUM_TOTAL_SIZE)
- {
- int selected_used;
- char *selected_buffer;
- m4_diversion *diversion;
- int count;
- gl_oset_iterator_t iter;
- const void *elt;
-
- /* Find out the buffer having most data, in view of flushing it to
- disk. Fake the current buffer as having already received the
- projected data, while making the selection. So, if it is
- selected indeed, we will flush it smaller, before it grows. */
-
- selected_diversion = output_diversion;
- selected_used = output_diversion->used + length;
-
- iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- diversion = (m4_diversion *) elt;
- if (diversion->used > selected_used)
- {
- selected_diversion = diversion;
- selected_used = diversion->used;
- }
- }
- gl_oset_iterator_free (&iter);
-
- /* Create a temporary file, write the in-memory buffer of the
- diversion to this file, then release the buffer. Zero the
- diversion before doing anything that can exit () (including
- m4_tmpfile), so that the atexit handler doesn't try to close
- a garbage pointer as a file. */
-
- selected_buffer = selected_diversion->u.buffer;
- total_buffer_size -= selected_diversion->size;
- selected_diversion->size = 0;
- selected_diversion->u.file = NULL;
- selected_diversion->u.file = m4_tmpfile (selected_diversion->divnum);
-
- if (selected_diversion->used > 0)
- {
- count = fwrite (selected_buffer, (size_t) selected_diversion->used,
- 1, selected_diversion->u.file);
- if (count != 1)
- M4ERROR ((EXIT_FAILURE, errno,
- "ERROR: cannot flush diversion to temporary file"));
- }
-
- /* Reclaim the buffer space for other diversions. */
-
- free (selected_buffer);
- selected_diversion->used = 1;
- }
-
- /* Reload output_file, just in case the flushed diversion was current. */
-
- if (output_diversion == selected_diversion)
- {
- /* The flushed diversion was current indeed. */
-
- output_file = output_diversion->u.file;
- output_cursor = NULL;
- output_unused = 0;
- }
- else
- {
- /* Close any selected file since it is not the current diversion. */
- if (selected_diversion)
- {
- FILE *file = selected_diversion->u.file;
- selected_diversion->u.file = NULL;
- if (m4_tmpclose (file, selected_diversion->divnum) != 0)
- m4_error (0, errno,
- _("cannot close temporary file for diversion"));
- }
-
- /* The current buffer may be safely reallocated. */
- {
- char *buffer = output_diversion->u.buffer;
- output_diversion->u.buffer = xcharalloc ((size_t) wanted_size);
- memcpy (output_diversion->u.buffer, buffer, output_diversion->used);
- free (buffer);
- }
-
- total_buffer_size += wanted_size - output_diversion->size;
- output_diversion->size = wanted_size;
-
- output_cursor = output_diversion->u.buffer + output_diversion->used;
- output_unused = wanted_size - output_diversion->used;
- }
-}
-
-/*--------------------------------------------------------------.
-| Output one character CHAR, when it is known that it goes to a |
-| diversion file or an in-memory diversion buffer. |
-`--------------------------------------------------------------*/
-
-#define OUTPUT_CHARACTER(Char) \
- if (output_file) \
- putc ((Char), output_file); \
- else if (output_unused == 0) \
- output_character_helper ((Char)); \
- else \
- (output_unused--, *output_cursor++ = (Char))
-
-static void
-output_character_helper (int character)
-{
- make_room_for (1);
-
- if (output_file)
- putc (character, output_file);
- else
- {
- *output_cursor++ = character;
- output_unused--;
- }
-}
-
-/*-------------------------------------------------------------------.
-| Output one TEXT having LENGTH characters, when it is known that it |
-| goes to a diversion file or an in-memory diversion buffer. |
-`-------------------------------------------------------------------*/
-
-void
-output_text (const char *text, int length)
-{
- int count;
-
- if (!output_diversion || !length)
- return;
-
- if (!output_file && length > output_unused)
- make_room_for (length);
-
- if (output_file)
- {
- count = fwrite (text, length, 1, output_file);
- if (count != 1)
- M4ERROR ((EXIT_FAILURE, errno, "ERROR: copying inserted file"));
- }
- else
- {
- memcpy (output_cursor, text, (size_t) length);
- output_cursor += length;
- output_unused -= length;
- }
-}
-
-/*--------------------------------------------------------------------.
-| Add some text into an obstack OBS, taken from TEXT, having LENGTH |
-| characters. If OBS is NULL, output the text to an external file |
-| or an in-memory diversion buffer instead. If OBS is NULL, and |
-| there is no output file, the text is discarded. LINE is the line |
-| where the token starts (not necessarily current_line, in the case |
-| of multiline tokens). |
-| |
-| If we are generating sync lines, the output has to be examined, |
-| because we need to know how much output each input line generates. |
-| In general, sync lines are output whenever a single input lines |
-| generates several output lines, or when several input lines do not |
-| generate any output. |
-`--------------------------------------------------------------------*/
-
-void
-shipout_text (struct obstack *obs, const char *text, int length, int line)
-{
- static bool start_of_output_line = true;
- const char *cursor;
-
- /* If output goes to an obstack, merely add TEXT to it. */
-
- if (obs != NULL)
- {
- obstack_grow (obs, text, length);
- return;
- }
-
- /* Do nothing if TEXT should be discarded. */
-
- if (output_diversion == NULL)
- return;
-
- /* Output TEXT to a file, or in-memory diversion buffer. */
-
- if (!sync_output)
- switch (length)
- {
-
- /* In-line short texts. */
-
- case 8: OUTPUT_CHARACTER (*text); text++;
- case 7: OUTPUT_CHARACTER (*text); text++;
- case 6: OUTPUT_CHARACTER (*text); text++;
- case 5: OUTPUT_CHARACTER (*text); text++;
- case 4: OUTPUT_CHARACTER (*text); text++;
- case 3: OUTPUT_CHARACTER (*text); text++;
- case 2: OUTPUT_CHARACTER (*text); text++;
- case 1: OUTPUT_CHARACTER (*text);
- case 0:
- return;
-
- /* Optimize longer texts. */
-
- default:
- output_text (text, length);
- }
- else
- {
- /* Check for syncline only at the start of a token. Multiline
- tokens, and tokens that are out of sync but in the middle of
- the line, must wait until the next raw newline triggers a
- syncline. */
- if (start_of_output_line)
- {
- start_of_output_line = false;
- output_current_line++;
-#ifdef DEBUG_OUTPUT
- xfprintf (stderr, "DEBUG: line %d, cur %d, cur out %d\n",
- line, current_line, output_current_line);
-#endif
-
- /* Output a `#line NUM' synchronization directive if needed.
- If output_current_line was previously given a negative
- value (invalidated), output `#line NUM "FILE"' instead. */
-
- if (output_current_line != line)
- {
- OUTPUT_CHARACTER ('#');
- OUTPUT_CHARACTER ('l');
- OUTPUT_CHARACTER ('i');
- OUTPUT_CHARACTER ('n');
- OUTPUT_CHARACTER ('e');
- OUTPUT_CHARACTER (' ');
- for (cursor = ntoa (line, 10); *cursor; cursor++)
- OUTPUT_CHARACTER (*cursor);
- if (output_current_line < 1 && current_file[0] != '\0')
- {
- OUTPUT_CHARACTER (' ');
- OUTPUT_CHARACTER ('"');
- for (cursor = current_file; *cursor; cursor++)
- OUTPUT_CHARACTER (*cursor);
- OUTPUT_CHARACTER ('"');
- }
- OUTPUT_CHARACTER ('\n');
- output_current_line = line;
- }
- }
-
- /* Output the token, and track embedded newlines. */
- for (; length-- > 0; text++)
- {
- if (start_of_output_line)
- {
- start_of_output_line = false;
- output_current_line++;
-#ifdef DEBUG_OUTPUT
- xfprintf (stderr, "DEBUG: line %d, cur %d, cur out %d\n",
- line, current_line, output_current_line);
-#endif
- }
- OUTPUT_CHARACTER (*text);
- if (*text == '\n')
- start_of_output_line = true;
- }
- }
-}
-
-/* Functions for use by diversions. */
-
-/*------------------------------------------------------------------.
-| Make a file for diversion DIVNUM, and install it in the diversion |
-| table. Grow the size of the diversion table as needed. |
-`------------------------------------------------------------------*/
-
-/* The number of possible diversions is limited only by memory and
- available file descriptors (each overflowing diversion uses one). */
-
-void
-make_diversion (int divnum)
-{
- m4_diversion *diversion = NULL;
-
- if (current_diversion == divnum)
- return;
-
- if (output_diversion)
- {
- if (!output_diversion->size && !output_diversion->u.file)
- {
- assert (!output_diversion->used);
- if (!gl_oset_remove (diversion_table, output_diversion))
- assert (false);
- output_diversion->u.next = free_list;
- free_list = output_diversion;
- }
- else if (output_diversion->size)
- output_diversion->used = output_diversion->size - output_unused;
- else if (output_diversion->used)
- {
- FILE *file = output_diversion->u.file;
- output_diversion->u.file = NULL;
- if (m4_tmpclose (file, output_diversion->divnum) != 0)
- m4_error (0, errno,
- _("cannot close temporary file for diversion"));
- }
- output_diversion = NULL;
- output_file = NULL;
- output_cursor = NULL;
- output_unused = 0;
- }
-
- current_diversion = divnum;
-
- if (divnum < 0)
- return;
-
- if (divnum == 0)
- diversion = &div0;
- else
- {
- const void *elt;
- if (gl_oset_search_atleast (diversion_table, threshold_diversion_CB,
- &divnum, &elt))
- {
- m4_diversion *temp = (m4_diversion *) elt;
- if (temp->divnum == divnum)
- diversion = temp;
- }
- }
- if (diversion == NULL)
- {
- /* First time visiting this diversion. */
- if (free_list)
- {
- diversion = free_list;
- free_list = diversion->u.next;
- }
- else
- {
- diversion = (m4_diversion *) obstack_alloc (&diversion_storage,
- sizeof *diversion);
- diversion->size = 0;
- diversion->used = 0;
- }
- diversion->u.file = NULL;
- diversion->divnum = divnum;
- gl_oset_add (diversion_table, diversion);
- }
-
- output_diversion = diversion;
- if (output_diversion->size)
- {
- output_cursor = output_diversion->u.buffer + output_diversion->used;
- output_unused = output_diversion->size - output_diversion->used;
- }
- else
- {
- if (!output_diversion->u.file && output_diversion->used)
- output_diversion->u.file = m4_tmpopen (output_diversion->divnum,
- false);
- output_file = output_diversion->u.file;
- }
- output_current_line = -1;
-}
-
-/*-------------------------------------------------------------------.
-| Insert a FILE into the current output file, in the same manner |
-| diversions are handled. This allows files to be included, without |
-| having them rescanned by m4. |
-`-------------------------------------------------------------------*/
-
-void
-insert_file (FILE *file)
-{
- static char buffer[COPY_BUFFER_SIZE];
- size_t length;
-
- /* Optimize out inserting into a sink. */
- if (!output_diversion)
- return;
-
- /* Insert output by big chunks. */
- while (1)
- {
- length = fread (buffer, 1, sizeof buffer, file);
- if (ferror (file))
- M4ERROR ((EXIT_FAILURE, errno, "error reading inserted file"));
- if (length == 0)
- break;
- output_text (buffer, length);
- }
-}
-
-/*-------------------------------------------------------------------.
-| Insert DIVERSION (but not div0) into the current output file. The |
-| diversion is NOT placed on the expansion obstack, because it must |
-| not be rescanned. When the file is closed, it is deleted by the |
-| system. |
-`-------------------------------------------------------------------*/
-
-static void
-insert_diversion_helper (m4_diversion *diversion)
-{
- /* Effectively undivert only if an output stream is active. */
- if (output_diversion)
- {
- if (diversion->size)
- {
- if (!output_diversion->u.file)
- {
- /* Transferring diversion metadata is faster than
- copying contents. */
- assert (!output_diversion->used && output_diversion != &div0
- && !output_file);
- output_diversion->u.buffer = diversion->u.buffer;
- output_diversion->size = diversion->size;
- output_cursor = diversion->u.buffer + diversion->used;
- output_unused = diversion->size - diversion->used;
- diversion->u.buffer = NULL;
- }
- else
- {
- /* Avoid double-charging the total in-memory size when
- transferring from one in-memory diversion to
- another. */
- total_buffer_size -= diversion->size;
- output_text (diversion->u.buffer, diversion->used);
- }
- }
- else if (!output_diversion->u.file)
- {
- /* Transferring diversion metadata is faster than copying
- contents. */
- assert (!output_diversion->used && output_diversion != &div0
- && !output_file);
- output_diversion->u.file = m4_tmprename (diversion->divnum,
- output_diversion->divnum);
- output_diversion->used = 1;
- output_file = output_diversion->u.file;
- diversion->u.file = NULL;
- diversion->size = 1;
- }
- else
- {
- if (!diversion->u.file)
- diversion->u.file = m4_tmpopen (diversion->divnum, true);
- insert_file (diversion->u.file);
- }
-
- output_current_line = -1;
- }
-
- /* Return all space used by the diversion. */
- if (diversion->size)
- {
- if (!output_diversion)
- total_buffer_size -= diversion->size;
- free (diversion->u.buffer);
- diversion->size = 0;
- }
- else
- {
- if (diversion->u.file)
- {
- FILE *file = diversion->u.file;
- diversion->u.file = NULL;
- if (m4_tmpclose (file, diversion->divnum) != 0)
- m4_error (0, errno,
- _("cannot clean temporary file for diversion"));
- }
- if (m4_tmpremove (diversion->divnum) != 0)
- M4ERROR ((0, errno, "cannot clean temporary file for diversion"));
- }
- diversion->used = 0;
- gl_oset_remove (diversion_table, diversion);
- diversion->u.next = free_list;
- free_list = diversion;
-}
-
-/*------------------------------------------------------------------.
-| Insert diversion number DIVNUM into the current output file. The |
-| diversion is NOT placed on the expansion obstack, because it must |
-| not be rescanned. When the file is closed, it is deleted by the |
-| system. |
-`------------------------------------------------------------------*/
-
-void
-insert_diversion (int divnum)
-{
- const void *elt;
-
- /* Do not care about nonexistent diversions, and undiverting stdout
- or self is a no-op. */
- if (divnum <= 0 || current_diversion == divnum)
- return;
- if (gl_oset_search_atleast (diversion_table, threshold_diversion_CB,
- &divnum, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (diversion->divnum == divnum)
- insert_diversion_helper (diversion);
- }
-}
-
-/*----------------------------------------------------------------.
-| Get back all diversions. This is done just before exiting from |
-| main, and from m4_undivert (), if called without arguments. |
-`----------------------------------------------------------------*/
-
-void
-undivert_all (void)
-{
- const void *elt;
- gl_oset_iterator_t iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (diversion->divnum != current_diversion)
- insert_diversion_helper (diversion);
- }
- gl_oset_iterator_free (&iter);
-}
-
-/*-------------------------------------------------------------.
-| Produce all diversion information in frozen format on FILE. |
-`-------------------------------------------------------------*/
-
-void
-freeze_diversions (FILE *file)
-{
- int saved_number;
- int last_inserted;
- gl_oset_iterator_t iter;
- const void *elt;
-
- saved_number = current_diversion;
- last_inserted = 0;
- make_diversion (0);
- output_file = file; /* kludge in the frozen file */
-
- iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (diversion->size || diversion->used)
- {
- if (diversion->size)
- xfprintf (file, "D%d,%d\n", diversion->divnum, diversion->used);
- else
- {
- struct stat file_stat;
- diversion->u.file = m4_tmpopen (diversion->divnum, true);
- if (fstat (fileno (diversion->u.file), &file_stat) < 0)
- M4ERROR ((EXIT_FAILURE, errno, "cannot stat diversion"));
- if (file_stat.st_size < 0
- || (file_stat.st_size + 0UL
- != (unsigned long int) file_stat.st_size))
- M4ERROR ((EXIT_FAILURE, 0, "diversion too large"));
- xfprintf (file, "D%d,%lu\n", diversion->divnum,
- (unsigned long int) file_stat.st_size);
- }
-
- insert_diversion_helper (diversion);
- putc ('\n', file);
-
- last_inserted = diversion->divnum;
- }
- }
- gl_oset_iterator_free (&iter);
-
- /* Save the active diversion number, if not already. */
-
- if (saved_number != last_inserted)
- xfprintf (file, "D%d,0\n\n", saved_number);
-}
diff --git a/contrib/tools/bison/m4/src/path.c b/contrib/tools/bison/m4/src/path.c
deleted file mode 100644
index 278200b782..0000000000
--- a/contrib/tools/bison/m4/src/path.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1993, 2004, 2006-2013 Free Software Foundation,
- Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Handling of path search of included files via the builtins "include"
- and "sinclude". */
-
-#include "m4.h"
-
-struct includes
-{
- struct includes *next; /* next directory to search */
- const char *dir; /* directory */
- int len;
-};
-
-typedef struct includes includes;
-
-static includes *dir_list; /* the list of path directories */
-static includes *dir_list_end; /* the end of same */
-static int dir_max_length; /* length of longest directory name */
-
-
-void
-include_init (void)
-{
- dir_list = NULL;
- dir_list_end = NULL;
- dir_max_length = 0;
-}
-
-void
-include_env_init (void)
-{
- char *path;
- char *path_end;
- char *env_path;
-
- if (no_gnu_extensions)
- return;
-
- env_path = getenv ("M4PATH");
- if (env_path == NULL)
- return;
-
- env_path = xstrdup (env_path);
- path = env_path;
-
- do
- {
- path_end = strchr (path, ':');
- if (path_end)
- *path_end = '\0';
- add_include_directory (path);
- path = path_end + 1;
- }
- while (path_end);
- free (env_path);
-}
-
-void
-add_include_directory (const char *dir)
-{
- includes *incl;
-
- if (no_gnu_extensions)
- return;
-
- if (*dir == '\0')
- dir = ".";
-
- incl = (includes *) xmalloc (sizeof (struct includes));
- incl->next = NULL;
- incl->len = strlen (dir);
- incl->dir = xstrdup (dir);
-
- if (incl->len > dir_max_length) /* remember len of longest directory */
- dir_max_length = incl->len;
-
- if (dir_list_end == NULL)
- dir_list = incl;
- else
- dir_list_end->next = incl;
- dir_list_end = incl;
-
-#ifdef DEBUG_INCL
- xfprintf (stderr, "add_include_directory (%s);\n", dir);
-#endif
-}
-
-/* Attempt to open FILE; if it opens, verify that it is not a
- directory, and ensure it does not leak across execs. */
-static FILE *
-m4_fopen (const char *file)
-{
- FILE *fp = fopen (file, "r");
- if (fp)
- {
- struct stat st;
- int fd = fileno (fp);
- if (fstat (fd, &st) == 0 && S_ISDIR (st.st_mode))
- {
- fclose (fp);
- errno = EISDIR;
- return NULL;
- }
- if (set_cloexec_flag (fd, true) != 0)
- M4ERROR ((warning_status, errno,
- "Warning: cannot protect input file across forks"));
- }
- return fp;
-}
-
-/* Search for FILE, first in `.', then according to -I options. If
- successful, return the open file, and if RESULT is not NULL, set
- *RESULT to a malloc'd string that represents the file found with
- respect to the current working directory. */
-
-FILE *
-m4_path_search (const char *file, char **result)
-{
- FILE *fp;
- includes *incl;
- char *name; /* buffer for constructed name */
- int e;
-
- if (result)
- *result = NULL;
-
- /* Reject empty file. */
- if (!*file)
- {
- errno = ENOENT;
- return NULL;
- }
-
- /* Look in current working directory first. */
- fp = m4_fopen (file);
- if (fp != NULL)
- {
- if (result)
- *result = xstrdup (file);
- return fp;
- }
-
- /* If file not found, and filename absolute, fail. */
- if (IS_ABSOLUTE_FILE_NAME (file) || no_gnu_extensions)
- return NULL;
- e = errno;
-
- for (incl = dir_list; incl != NULL; incl = incl->next)
- {
- name = file_name_concat (incl->dir, file, NULL);
-
-#ifdef DEBUG_INCL
- xfprintf (stderr, "m4_path_search (%s) -- trying %s\n", file, name);
-#endif
-
- fp = m4_fopen (name);
- if (fp != NULL)
- {
- if (debug_level & DEBUG_TRACE_PATH)
- DEBUG_MESSAGE2 ("path search for `%s' found `%s'", file, name);
- if (result)
- *result = name;
- else
- free (name);
- return fp;
- }
- free (name);
- }
- errno = e;
- return fp;
-}
-
-#ifdef DEBUG_INCL
-
-static void M4_GNUC_UNUSED
-include_dump (void)
-{
- includes *incl;
-
- xfprintf (stderr, "include_dump:\n");
- for (incl = dir_list; incl != NULL; incl = incl->next)
- xfprintf (stderr, "\t%s\n", incl->dir);
-}
-
-#endif /* DEBUG_INCL */
diff --git a/contrib/tools/bison/m4/src/symtab.c b/contrib/tools/bison/m4/src/symtab.c
deleted file mode 100644
index 7448c272cc..0000000000
--- a/contrib/tools/bison/m4/src/symtab.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 2003, 2006-2013 Free Software Foundation,
- Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* This file handles all the low level work around the symbol table. The
- symbol table is a simple chained hash table. Each symbol is described
- by a struct symbol, which is placed in the hash table based upon the
- symbol name. Symbols that hash to the same entry in the table are
- kept on a list, sorted by name. As a special case, to facilitate the
- "pushdef" and "popdef" builtins, a symbol can be several times in the
- symbol table, one for each definition. Since the name is the same,
- all the entries for the symbol will be on the same list, and will
- also, because the list is sorted, be adjacent. All the entries for a
- name are simply ordered on the list by age. The current definition
- will then always be the first found. */
-
-#include "m4.h"
-#include <limits.h>
-
-#ifdef DEBUG_SYM
-/* When evaluating hash table performance, this profiling code shows
- how many collisions were encountered. */
-
-struct profile
-{
- int entry; /* Number of times lookup_symbol called with this mode. */
- int comparisons; /* Number of times strcmp was called. */
- int misses; /* Number of times strcmp did not return 0. */
- long long bytes; /* Number of bytes compared. */
-};
-
-static struct profile profiles[5];
-static symbol_lookup current_mode;
-
-/* On exit, show a profile of symbol table performance. */
-static void
-show_profile (void)
-{
- int i;
- for (i = 0; i < 5; i++)
- {
- xfprintf(stderr, "m4: lookup mode %d called %d times, %d compares, "
- "%d misses, %lld bytes\n",
- i, profiles[i].entry, profiles[i].comparisons,
- profiles[i].misses, profiles[i].bytes);
- }
-}
-
-/* Like strcmp (S1, S2), but also track profiling statistics. */
-static int
-profile_strcmp (const char *s1, const char *s2)
-{
- int i = 1;
- int result;
- while (*s1 && *s1 == *s2)
- {
- s1++;
- s2++;
- i++;
- }
- result = (unsigned char) *s1 - (unsigned char) *s2;
- profiles[current_mode].comparisons++;
- if (result != 0)
- profiles[current_mode].misses++;
- profiles[current_mode].bytes += i;
- return result;
-}
-
-# define strcmp profile_strcmp
-#endif /* DEBUG_SYM */
-
-
-/*------------------------------------------------------------------.
-| Initialise the symbol table, by allocating the necessary storage, |
-| and zeroing all the entries. |
-`------------------------------------------------------------------*/
-
-/* Pointer to symbol table. */
-symbol **symtab;
-
-void
-symtab_init (void)
-{
- size_t i;
- symbol **s;
-
- s = symtab = (symbol **) xnmalloc (hash_table_size, sizeof (symbol *));
-
- for (i = 0; i < hash_table_size; i++)
- s[i] = NULL;
-
-#ifdef DEBUG_SYM
- {
- int e = atexit(show_profile);
- if (e != 0)
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: unable to show symtab profile"));
- }
-#endif /* DEBUG_SYM */
-}
-
-/*--------------------------------------------------.
-| Return a hashvalue for a string, from GNU-emacs. |
-`--------------------------------------------------*/
-
-static size_t M4_GNUC_PURE
-hash (const char *s)
-{
- size_t val = 0;
-
- const char *ptr = s;
- char ch;
-
- while ((ch = *ptr++) != '\0')
- val = (val << 7) + (val >> (sizeof (val) * CHAR_BIT - 7)) + ch;
- return val;
-}
-
-/*--------------------------------------------.
-| Free all storage associated with a symbol. |
-`--------------------------------------------*/
-
-void
-free_symbol (symbol *sym)
-{
- if (SYMBOL_PENDING_EXPANSIONS (sym) > 0)
- SYMBOL_DELETED (sym) = true;
- else
- {
- free (SYMBOL_NAME (sym));
- if (SYMBOL_TYPE (sym) == TOKEN_TEXT)
- free (SYMBOL_TEXT (sym));
- free (sym);
- }
-}
-
-/*-------------------------------------------------------------------.
-| Search in, and manipulation of the symbol table, are all done by |
-| lookup_symbol (). It basically hashes NAME to a list in the |
-| symbol table, and searches this list for the first occurrence of a |
-| symbol with the name. |
-| |
-| The MODE parameter determines what lookup_symbol () will do. It |
-| can either just do a lookup, do a lookup and insert if not |
-| present, do an insertion even if the name is already in the list, |
-| delete the first occurrence of the name on the list, or delete all |
-| occurrences of the name on the list. |
-`-------------------------------------------------------------------*/
-
-symbol *
-lookup_symbol (const char *name, symbol_lookup mode)
-{
- size_t h;
- int cmp = 1;
- symbol *sym, *prev;
- symbol **spp;
-
-#if DEBUG_SYM
- current_mode = mode;
- profiles[mode].entry++;
-#endif /* DEBUG_SYM */
-
- h = hash (name);
- sym = symtab[h % hash_table_size];
-
- for (prev = NULL; sym != NULL; prev = sym, sym = sym->next)
- {
- cmp = strcmp (SYMBOL_NAME (sym), name);
- if (cmp >= 0)
- break;
- }
-
- /* If just searching, return status of search. */
-
- if (mode == SYMBOL_LOOKUP)
- return cmp == 0 ? sym : NULL;
-
- /* Symbol not found. */
-
- spp = (prev != NULL) ? &prev->next : &symtab[h % hash_table_size];
-
- switch (mode)
- {
-
- case SYMBOL_INSERT:
-
- /* If the name was found in the table, check whether it is still in
- use by a pending expansion. If so, replace the table element with
- a new one; if not, just return the symbol. If not found, just
- insert the name, and return the new symbol. */
-
- if (cmp == 0 && sym != NULL)
- {
- if (SYMBOL_PENDING_EXPANSIONS (sym) > 0)
- {
- symbol *old = sym;
- SYMBOL_DELETED (old) = true;
-
- sym = (symbol *) xmalloc (sizeof (symbol));
- SYMBOL_TYPE (sym) = TOKEN_VOID;
- SYMBOL_TRACED (sym) = SYMBOL_TRACED (old);
- SYMBOL_NAME (sym) = xstrdup (name);
- SYMBOL_SHADOWED (sym) = false;
- SYMBOL_MACRO_ARGS (sym) = false;
- SYMBOL_BLIND_NO_ARGS (sym) = false;
- SYMBOL_DELETED (sym) = false;
- SYMBOL_PENDING_EXPANSIONS (sym) = 0;
-
- SYMBOL_NEXT (sym) = SYMBOL_NEXT (old);
- SYMBOL_NEXT (old) = NULL;
- (*spp) = sym;
- }
- return sym;
- }
- /* Fall through. */
-
- case SYMBOL_PUSHDEF:
-
- /* Insert a name in the symbol table. If there is already a symbol
- with the name, insert this in front of it, and mark the old
- symbol as "shadowed". */
-
- sym = (symbol *) xmalloc (sizeof (symbol));
- SYMBOL_TYPE (sym) = TOKEN_VOID;
- SYMBOL_TRACED (sym) = false;
- SYMBOL_NAME (sym) = xstrdup (name);
- SYMBOL_SHADOWED (sym) = false;
- SYMBOL_MACRO_ARGS (sym) = false;
- SYMBOL_BLIND_NO_ARGS (sym) = false;
- SYMBOL_DELETED (sym) = false;
- SYMBOL_PENDING_EXPANSIONS (sym) = 0;
-
- SYMBOL_NEXT (sym) = *spp;
- (*spp) = sym;
-
- if (mode == SYMBOL_PUSHDEF && cmp == 0)
- {
- SYMBOL_SHADOWED (SYMBOL_NEXT (sym)) = true;
- SYMBOL_TRACED (sym) = SYMBOL_TRACED (SYMBOL_NEXT (sym));
- }
- return sym;
-
- case SYMBOL_DELETE:
- case SYMBOL_POPDEF:
-
- /* Delete occurrences of symbols with NAME. SYMBOL_DELETE kills
- all definitions, SYMBOL_POPDEF kills only the first.
- However, if the last instance of a symbol is marked for
- tracing, reinsert a placeholder in the table. And if the
- definition is still in use, let the caller free the memory
- after it is done with the symbol. */
-
- if (cmp != 0 || sym == NULL)
- return NULL;
- {
- bool traced = false;
- if (SYMBOL_NEXT (sym) != NULL
- && SYMBOL_SHADOWED (SYMBOL_NEXT (sym))
- && mode == SYMBOL_POPDEF)
- {
- SYMBOL_SHADOWED (SYMBOL_NEXT (sym)) = false;
- SYMBOL_TRACED (SYMBOL_NEXT (sym)) = SYMBOL_TRACED (sym);
- }
- else
- traced = SYMBOL_TRACED (sym);
- do
- {
- *spp = SYMBOL_NEXT (sym);
- free_symbol (sym);
- sym = *spp;
- }
- while (*spp != NULL && SYMBOL_SHADOWED (*spp)
- && mode == SYMBOL_DELETE);
- if (traced)
- {
- sym = (symbol *) xmalloc (sizeof (symbol));
- SYMBOL_TYPE (sym) = TOKEN_VOID;
- SYMBOL_TRACED (sym) = true;
- SYMBOL_NAME (sym) = xstrdup (name);
- SYMBOL_SHADOWED (sym) = false;
- SYMBOL_MACRO_ARGS (sym) = false;
- SYMBOL_BLIND_NO_ARGS (sym) = false;
- SYMBOL_DELETED (sym) = false;
- SYMBOL_PENDING_EXPANSIONS (sym) = 0;
-
- SYMBOL_NEXT (sym) = *spp;
- (*spp) = sym;
- }
- }
- return NULL;
-
- case SYMBOL_LOOKUP:
- default:
- M4ERROR ((warning_status, 0,
- "INTERNAL ERROR: invalid mode to symbol_lookup ()"));
- abort ();
- }
-}
-
-/*-----------------------------------------------------------------.
-| The following function is used for the cases where we want to do |
-| something to each and every symbol in the table. The function |
-| hack_all_symbols () traverses the symbol table, and calls a |
-| specified function FUNC for each symbol in the table. FUNC is |
-| called with a pointer to the symbol, and the DATA argument. |
-| |
-| FUNC may safely call lookup_symbol with mode SYMBOL_POPDEF or |
-| SYMBOL_LOOKUP, but any other mode can break the iteration. |
-`-----------------------------------------------------------------*/
-
-void
-hack_all_symbols (hack_symbol *func, void *data)
-{
- size_t h;
- symbol *sym;
- symbol *next;
-
- for (h = 0; h < hash_table_size; h++)
- {
- /* We allow func to call SYMBOL_POPDEF, which can invalidate
- sym, so we must grab the next element to traverse before
- calling func. */
- for (sym = symtab[h]; sym != NULL; sym = next)
- {
- next = SYMBOL_NEXT (sym);
- func (sym, data);
- }
- }
-}
-
-#ifdef DEBUG_SYM
-
-static void symtab_print_list (int i);
-
-static void M4_GNUC_UNUSED
-symtab_debug (void)
-{
- token_data td;
- const char *text;
- symbol *s;
- int delete;
- static int i;
-
- while (next_token (&td, NULL) == TOKEN_WORD)
- {
- text = TOKEN_DATA_TEXT (&td);
- if (*text == '_')
- {
- delete = 1;
- text++;
- }
- else
- delete = 0;
-
- s = lookup_symbol (text, SYMBOL_LOOKUP);
-
- if (s == NULL)
- xprintf ("Name `%s' is unknown\n", text);
-
- lookup_symbol (text, delete ? SYMBOL_DELETE : SYMBOL_INSERT);
- }
- symtab_print_list (i++);
-}
-
-static void
-symtab_print_list (int i)
-{
- symbol *sym;
- size_t h;
-
- xprintf ("Symbol dump #%d:\n", i);
- for (h = 0; h < hash_table_size; h++)
- for (sym = symtab[h]; sym != NULL; sym = sym->next)
- xprintf ("\tname %s, bucket %lu, addr %p, next %p, "
- "flags%s%s%s, pending %d\n",
- SYMBOL_NAME (sym),
- (unsigned long int) h, sym, SYMBOL_NEXT (sym),
- SYMBOL_TRACED (sym) ? " traced" : "",
- SYMBOL_SHADOWED (sym) ? " shadowed" : "",
- SYMBOL_DELETED (sym) ? " deleted" : "",
- SYMBOL_PENDING_EXPANSIONS (sym));
-}
-
-#endif /* DEBUG_SYM */
diff --git a/contrib/tools/bison/m4/ya.make b/contrib/tools/bison/m4/ya.make
deleted file mode 100644
index f474cbfb71..0000000000
--- a/contrib/tools/bison/m4/ya.make
+++ /dev/null
@@ -1,36 +0,0 @@
-PROGRAM()
-
-LICENSE(GPL-3.0-or-later)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
-NO_RUNTIME()
-
-NO_COMPILER_WARNINGS()
-
-IF (MUSL)
- CFLAGS(
- -DO_BINARY=0
- )
-ENDIF()
-
-SRCS(
- src/builtin.c
- src/debug.c
- src/eval.c
- src/format.c
- src/freeze.c
- src/input.c
- src/m4.c
- src/macro.c
- src/output.c
- src/path.c
- src/symtab.c
- src/cpp.cpp
-)
-
-PEERDIR(
- contrib/tools/bison/gnulib
-)
-
-END()