/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2000, 2004, 2006-2013 Free Software
- Foundation, Inc.
+ Copyright (C) 1989-1994, 2000, 2004, 2006-2014, 2016-2017, 2020-2021
+ Free Software Foundation, Inc.
This file is part of GNU M4.
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/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* Code for all builtin macros, initialization of symbol table, and
| Find the builtin, which lives on ADDR. |
`----------------------------------------*/
-const builtin * M4_GNUC_PURE
+const builtin * ATTRIBUTE_PURE
find_builtin_by_addr (builtin_func *func)
{
const builtin *bp;
| placeholder builtin. |
`----------------------------------------------------------*/
-const builtin * M4_GNUC_PURE
+const builtin * ATTRIBUTE_PURE
find_builtin_by_name (const char *name)
{
const builtin *bp;
msg = re_compile_pattern (regexp, strlen (regexp), ¯o_sequence_buf);
if (msg != NULL)
- {
- M4ERROR ((EXIT_FAILURE, 0,
- "--warn-macro-sequence: bad regular expression `%s': %s",
- regexp, msg));
- }
+ m4_failure (0, _("--warn-macro-sequence: bad regular expression `%s': %s"),
+ regexp, msg);
re_set_registers (¯o_sequence_buf, ¯o_sequence_regs,
macro_sequence_regs.num_regs,
macro_sequence_regs.start, macro_sequence_regs.end);
tmp = defn[offset];
defn[offset] = '\0';
M4ERROR ((warning_status, 0,
- "Warning: definition of `%s' contains sequence `%s'",
+ _("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'",
+ _("error checking --warn-macro-sequence for macro `%s'"),
name));
}
}
{
if (!suppress_warnings)
M4ERROR ((warning_status, 0,
- "Warning: too few arguments to builtin `%s'",
+ _("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",
+ _("Warning: excess arguments to builtin `%s' ignored"),
TOKEN_DATA_TEXT (name)));
return isbad;
{
*valuep = 0;
M4ERROR ((warning_status, 0,
- "empty string treated as 0 in builtin `%s'",
+ _("empty string treated as 0 in builtin `%s'"),
TOKEN_DATA_TEXT (macro)));
}
else
if (*endp != '\0')
{
M4ERROR ((warning_status, 0,
- "non-numeric argument to builtin `%s'",
+ _("non-numeric argument to builtin `%s'"),
TOKEN_DATA_TEXT (macro)));
return false;
}
- if (isspace (to_uchar (*arg)))
+ if (c_isspace (*arg))
M4ERROR ((warning_status, 0,
- "leading whitespace ignored in builtin `%s'",
+ _("leading whitespace ignored in builtin `%s'"),
TOKEN_DATA_TEXT (macro)));
else if (errno == ERANGE)
M4ERROR ((warning_status, 0,
- "numeric overflow detected in builtin `%s'",
+ _("numeric overflow detected in builtin `%s'"),
TOKEN_DATA_TEXT (macro)));
}
return true;
if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
{
M4ERROR ((warning_status, 0,
- "Warning: %s: invalid macro name ignored", ARG (0)));
+ _("Warning: %s: invalid macro name ignored"), ARG (0)));
return;
}
}
static void
-m4_define (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_define (struct obstack *obs MAYBE_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)
+m4_undefine (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
int i;
if (bad_argc (argv[0], argc, 2, -1))
}
static void
-m4_pushdef (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_pushdef (struct obstack *obs MAYBE_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)
+m4_popdef (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
int i;
if (bad_argc (argv[0], argc, 2, -1))
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)
+ if (SYMBOL_TYPE (sym) != TOKEN_VOID)
{
obstack_blank (data->obs, sizeof (symbol *));
data->base = (symbol **) obstack_base (data->obs);
dump_symbol (s, &data);
else
M4ERROR ((warning_status, 0,
- "undefined macro `%s'", TOKEN_DATA_TEXT (argv[i])));
+ _("undefined macro `%s'"), TOKEN_DATA_TEXT (argv[i])));
}
}
if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
{
M4ERROR ((warning_status, 0,
- "Warning: %s: invalid macro name ignored", ARG (0)));
+ _("Warning: %s: invalid macro name ignored"), ARG (0)));
return;
}
bp = find_builtin_by_name (name);
if (bp->func == m4_placeholder)
M4ERROR ((warning_status, 0,
- "undefined builtin `%s'", name));
+ _("undefined builtin `%s'"), name));
else
{
int i;
if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
{
M4ERROR ((warning_status, 0,
- "Warning: %s: invalid macro name ignored", ARG (0)));
+ _("Warning: %s: invalid macro name ignored"), ARG (0)));
return;
}
s = lookup_symbol (name, SYMBOL_LOOKUP);
if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
M4ERROR ((warning_status, 0,
- "undefined macro `%s'", name));
+ _("undefined macro `%s'"), name));
else
{
int i;
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));
+ 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'",
+ _("Warning: cannot concatenate builtin `%s'"),
arg));
else
push_macro (b);
static int sysval;
static void
-m4_syscmd (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_syscmd (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
const char *cmd = ARG (1);
int status;
#endif
prog_args[2] = cmd;
errno = 0;
- status = execute (ARG (0), SYSCMD_SHELL, (char **) prog_args, false,
+ status = execute (ARG (0), SYSCMD_SHELL, prog_args, NULL, false,
false, false, false, true, false, &sig_status);
if (sig_status)
{
else
{
if (status == 127 && errno)
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
+ M4ERROR ((warning_status, errno, _("cannot run command `%s'"), cmd));
sysval = status;
}
}
#endif
prog_args[2] = cmd;
errno = 0;
- child = create_pipe_in (ARG (0), SYSCMD_SHELL, (char **) prog_args,
+ child = create_pipe_in (ARG (0), SYSCMD_SHELL, prog_args, NULL,
NULL, false, true, false, &fd);
if (child == -1)
{
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
+ M4ERROR ((warning_status, errno, _("cannot run command `%s'"), cmd));
sysval = 127;
return;
}
+#if OS2
+ /* On OS/2 kLIBC, fdopen() creates a stream in a mode of a file descriptor.
+ So include "t" to open a stream in a text mode explicitly on OS/2. */
+ pin = fdopen (fd, "rt");
+#else
pin = fdopen (fd, "r");
+#endif
if (pin == NULL)
{
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
+ M4ERROR ((warning_status, errno, _("cannot run command `%s'"), cmd));
sysval = 127;
close (fd);
return;
obstack_blank_fast (obs, len);
}
if (ferror (pin) || fclose (pin))
- M4ERROR ((EXIT_FAILURE, errno, "cannot read pipe"));
+ m4_failure (errno, _("cannot read pipe"));
errno = 0;
status = wait_subprocess (child, ARG (0), false, true, true, false,
&sig_status);
else
{
if (status == 127 && errno)
- M4ERROR ((warning_status, errno, "cannot run command `%s'", cmd));
+ 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)
+m4_sysval (struct obstack *obs, int argc MAYBE_UNUSED,
+ token_data **argv MAYBE_UNUSED)
{
shipout_int (obs, sysval);
}
if (radix < 1 || radix > (int) strlen (digits))
{
M4ERROR ((warning_status, 0,
- "radix %d in builtin `%s' out of range",
+ _("radix %d in builtin `%s' out of range"),
radix, ARG (0)));
return;
}
if (min < 0)
{
M4ERROR ((warning_status, 0,
- "negative width to builtin `%s'", ARG (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)));
+ _("empty string treated as 0 in builtin `%s'"), ARG (0)));
else if (evaluate (ARG (1), &value))
return;
if (!numeric_arg (argv[0], ARG (1), &value))
return;
- shipout_int (obs, value + 1);
+ /* 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. */
+ uint32_t v = value;
+ int32_t w = v + 1;
+ shipout_int (obs, w);
}
static void
if (!numeric_arg (argv[0], ARG (1), &value))
return;
- shipout_int (obs, value - 1);
+ /* 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. */
+ uint32_t v = value;
+ int32_t w = v - 1;
+ shipout_int (obs, w);
}
\f
/* This section contains the macros "divert", "undivert" and "divnum" for
`-----------------------------------------------------------------*/
static void
-m4_divert (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_divert (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
int i = 0;
`------------------------------------------------------------------*/
static void
-m4_undivert (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_undivert (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
int i, file;
FILE *fp;
for (i = 1; i < argc; i++)
{
file = strtol (ARG (i), &endp, 10);
- if (*endp == '\0' && !isspace (to_uchar (*ARG (i))))
+ if (*endp == '\0' && !c_isspace (*ARG (i)))
insert_diversion (file);
else if (no_gnu_extensions)
M4ERROR ((warning_status, 0,
- "non-numeric argument to builtin `%s'", ARG (0)));
+ _("non-numeric argument to builtin `%s'"), ARG (0)));
else
{
fp = m4_path_search (ARG (i), NULL);
insert_file (fp);
if (fclose (fp) == EOF)
M4ERROR ((warning_status, errno,
- "error undiverting `%s'", ARG (i)));
+ _("error undiverting `%s'"), ARG (i)));
}
else
M4ERROR ((warning_status, errno,
- "cannot undivert `%s'", ARG (i)));
+ _("cannot undivert `%s'"), ARG (i)));
}
}
}
`-----------------------------------------------------------*/
static void
-m4_dnl (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_dnl (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
if (bad_argc (argv[0], argc, 1, 1))
return;
`--------------------------------------------------------------------------*/
static void
-m4_changequote (struct obstack *obs M4_GNUC_UNUSED, int argc,
+m4_changequote (struct obstack *obs MAYBE_UNUSED, int argc,
token_data **argv)
{
if (bad_argc (argv[0], argc, 1, 3))
`-----------------------------------------------------------------*/
static void
-m4_changecom (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_changecom (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
if (bad_argc (argv[0], argc, 1, 3))
return;
`---------------------------------------------------------------*/
static void
-m4_changeword (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_changeword (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
if (bad_argc (argv[0], argc, 2, 2))
return;
{
if (!silent)
{
- M4ERROR ((warning_status, errno, "cannot open `%s'", ARG (1)));
+ M4ERROR ((warning_status, errno, _("cannot open `%s'"), ARG (1)));
retcode = EXIT_FAILURE;
}
return;
`------------------------------------------------*/
static void
-m4_include (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_include (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
include (argc, argv, false);
}
`----------------------------------*/
static void
-m4_sinclude (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_sinclude (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
include (argc, argv, true);
}
fd = mkstemp (name);
if (fd < 0)
{
- M4ERROR ((0, errno, "%s: cannot create tempfile `%s'", me, pattern));
+ 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_blank_fast (obs, -1);
obstack_grow (obs, rquote.string, rquote.length);
}
}
int i;
int len2;
- M4ERROR ((warning_status, 0, "recommend using mkstemp instead"));
+ M4ERROR ((warning_status, 0, _("recommend using mkstemp instead")));
for (i = len; i > 1; i--)
if (str[i - 1] != 'X')
break;
| 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)
+static void
+m4_m4exit (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
int exit_code = EXIT_SUCCESS;
if (exit_code < 0 || exit_code > 255)
{
M4ERROR ((warning_status, 0,
- "exit status out of range: `%d'", exit_code));
+ _("exit status out of range: `%d'"), exit_code));
exit_code = EXIT_FAILURE;
}
/* Change debug stream back to stderr, to force flushing debug stream and
`------------------------------------------------------------------------*/
static void
-m4_traceoff (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_traceoff (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
symbol *s;
int i;
`------------------------------------------------------------------*/
static void
-m4_debugmode (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_debugmode (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
int new_debug_level;
int change_flag;
if (new_debug_level < 0)
M4ERROR ((warning_status, 0,
- "Debugmode: bad debug flags: `%s'", ARG (1)));
+ _("Debugmode: bad debug flags: `%s'"), ARG (1)));
else
{
switch (change_flag)
`-------------------------------------------------------------------------*/
static void
-m4_debugfile (struct obstack *obs M4_GNUC_UNUSED, int argc, token_data **argv)
+m4_debugfile (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv)
{
if (bad_argc (argv[0], argc, 1, 2))
return;
debug_set_output (NULL);
else if (!debug_set_output (ARG (1)))
M4ERROR ((warning_status, errno,
- "cannot set debug file `%s'", ARG (1)));
+ _("cannot set debug file `%s'"), ARG (1)));
}
\f
/* This section contains text processing macros: "len", "index",
case '0':
if (!substitute_warned)
{
- M4ERROR ((warning_status, 0, "\
-Warning: \\0 will disappear, use \\& instead in replacements"));
+ M4ERROR ((warning_status, 0, _("\
+Warning: \\0 will disappear, use \\& instead in replacements")));
substitute_warned = 1;
}
- /* Fall through. */
-
+ FALLTHROUGH;
case '&':
obstack_grow (obs, victim + regs->start[0],
regs->end[0] - regs->start[0]);
ind = ch -= '0';
if (regs->num_regs - 1 <= ind)
M4ERROR ((warning_status, 0,
- "Warning: sub-expression %d not present", ch));
+ _("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]);
case '\0':
M4ERROR ((warning_status, 0,
- "Warning: trailing \\ ignored in replacement"));
+ _("Warning: trailing \\ ignored in replacement")));
return;
default:
if (msg != NULL)
{
M4ERROR ((warning_status, 0,
- "bad regular expression: `%s': %s", regexp, msg));
+ _("bad regular expression: `%s': %s"), regexp, msg));
free_pattern_buffer (&buf, ®s);
return;
}
if (startpos == -2)
M4ERROR ((warning_status, 0,
- "error matching regular expression `%s'", regexp));
+ _("error matching regular expression `%s'"), regexp));
else if (argc == 3)
shipout_int (obs, startpos);
else if (startpos >= 0)
if (msg != NULL)
{
M4ERROR ((warning_status, 0,
- "bad regular expression `%s': %s", regexp, msg));
+ _("bad regular expression `%s': %s"), regexp, msg));
free (buf.buffer);
return;
}
if (matchpos == -2)
M4ERROR ((warning_status, 0,
- "error matching regular expression `%s'", regexp));
+ _("error matching regular expression `%s'"), regexp));
else if (offset < length)
obstack_grow (obs, victim + offset, length - offset);
break;
`--------------------------------------------------------------------*/
void
-m4_placeholder (struct obstack *obs M4_GNUC_UNUSED, int argc,
+m4_placeholder (struct obstack *obs MAYBE_UNUSED, int argc,
token_data **argv)
{
- M4ERROR ((warning_status, 0, "\
-builtin `%s' requested by frozen file is not supported", ARG (0)));
+ M4ERROR ((warning_status, 0, _("\
+builtin `%s' requested by frozen file is not supported"), ARG (0)));
}
\f
/*-------------------------------------------------------------------.
}
else
{
- for (i = 0; isdigit (to_uchar (*text)); text++)
+ for (i = 0; c_isdigit (*text); text++)
i = i*10 + (*text - '0');
}
if (i < argc)