summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2022-12-18 18:11:29 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2022-12-19 12:33:57 -0800
commit2aa368b97046554c5841ef69d05458854a753252 (patch)
tree828c4581f068450d853e6847add24920e94ef49c
parent3bb0a12761f5f98348dfa4f3eb31b6fe57bb466f (diff)
downloadsed-2aa368b97046554c5841ef69d05458854a753252.tar.gz
sed: simplify how diagnostics are translated
* basicdefs.h, sed/regexp.c (N_): Remove; no longer used. * bootstrap.conf (XGETTEXT_OPTIONS): Treat bad_prog as a function that translates its first arg. Omit unnecessary flags. * sed/compile.c, sed/regexp.c (errors): Remove this array of concatenated strings, and associated macros. All users of these macros now simply call bad_prog ("diagnostic") instead of bad_prog (_(DIAGNOSTIC_MACRO)). This is easier to read and maintain, and made it easy to catch two diagnostics that were never properly translated before: "cannot specify modifiers on empty regexp", "missing filename in r/R/w/W commands". * sed/compile.c (bad_command): Remove; no longer used. (vbad_prog): New function, with most of the old bad_prog contents. (bad_prog): Now variadic, like printf. Always translate WHY. All callers changed. (bad_prog_notranslate): New function.
-rw-r--r--basicdefs.h1
-rw-r--r--bootstrap.conf8
-rw-r--r--sed/compile.c220
-rw-r--r--sed/regexp.c27
-rw-r--r--sed/sed.h5
5 files changed, 80 insertions, 181 deletions
diff --git a/basicdefs.h b/basicdefs.h
index 2ccfb79..df759fc 100644
--- a/basicdefs.h
+++ b/basicdefs.h
@@ -24,7 +24,6 @@
#include <stdbool.h>
#include <gettext.h>
-#define N_(String) gettext_noop(String)
#define _(String) gettext(String)
/* type countT is used to keep track of line numbers, etc. */
diff --git a/bootstrap.conf b/bootstrap.conf
index ea5c2f9..9753f53 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -75,13 +75,7 @@ MSGID_BUGS_ADDRESS=bug-gnu-utils@gnu.org
# Additional xgettext options to use. Use "\\\newline" to break lines.
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
- --flag=asnprintf:3:c-format\\\
- --flag=asprintf:2:c-format\\\
- --flag=error:3:c-format\\\
- --flag=error_at_line:5:c-format\\\
- --flag=vasnprintf:3:c-format\\\
- --flag=vasprintf:2:c-format\\\
- --flag=wrapf:1:c-format\\\
+ --keyword=bad_prog --flag=bad_prog:1:c-format\\\
--from-code=UTF-8\\\
'
diff --git a/sed/compile.c b/sed/compile.c
index f96fbca..79b6390 100644
--- a/sed/compile.c
+++ b/sed/compile.c
@@ -109,122 +109,44 @@ static struct sed_label *blocks = NULL;
/* Use an obstack for compilation. */
static struct obstack obs;
-/* Various error messages we may want to print */
-static const char errors[] =
- "multiple `!'s\0"
- "unexpected `,'\0"
- "invalid usage of +N or ~N as first address\0"
- "unmatched `{'\0"
- "unexpected `}'\0"
- "extra characters after command\0"
- "expected \\ after `a', `c' or `i'\0"
- "`}' doesn't want any addresses\0"
- ": doesn't want any addresses\0"
- "comments don't accept any addresses\0"
- "missing command\0"
- "command only uses one address\0"
- "unterminated address regex\0"
- "unterminated `s' command\0"
- "unterminated `y' command\0"
- "unknown option to `s'\0"
- "multiple `p' options to `s' command\0"
- "multiple `g' options to `s' command\0"
- "multiple number options to `s' command\0"
- "number option to `s' command may not be zero\0"
- "strings for `y' command are different lengths\0"
- "delimiter character is not a single-byte character\0"
- "expected newer version of sed\0"
- "invalid usage of line address 0\0"
- "unknown command: `%c'\0"
- "incomplete command\0"
- "\":\" lacks a label\0"
- "recursive escaping after \\c not allowed\0"
- "e/r/w commands disabled in sandbox mode\0"
- "missing filename in r/R/w/W commands";
-
-#define BAD_BANG (errors)
-#define BAD_COMMA (BAD_BANG + sizeof (N_("multiple `!'s")))
-#define BAD_STEP (BAD_COMMA + sizeof (N_("unexpected `,'")))
-#define EXCESS_OPEN_BRACE (BAD_STEP \
- + sizeof (N_("invalid usage of +N or ~N as first address")))
-#define EXCESS_CLOSE_BRACE (EXCESS_OPEN_BRACE + sizeof (N_("unmatched `{'")))
-#define EXCESS_JUNK (EXCESS_CLOSE_BRACE + sizeof (N_("unexpected `}'")))
-#define EXPECTED_SLASH (EXCESS_JUNK \
- + sizeof (N_("extra characters after command")))
-#define NO_CLOSE_BRACE_ADDR (EXPECTED_SLASH \
- + sizeof (N_("expected \\ after `a', `c' or `i'")))
-#define NO_COLON_ADDR (NO_CLOSE_BRACE_ADDR \
- + sizeof (N_("`}' doesn't want any addresses")))
-#define NO_SHARP_ADDR (NO_COLON_ADDR \
- + sizeof (N_(": doesn't want any addresses")))
-#define NO_COMMAND (NO_SHARP_ADDR \
- + sizeof (N_("comments don't accept any addresses")))
-#define ONE_ADDR (NO_COMMAND + sizeof (N_("missing command")))
-#define UNTERM_ADDR_RE (ONE_ADDR + sizeof (N_("command only uses one address")))
-#define UNTERM_S_CMD (UNTERM_ADDR_RE \
- + sizeof (N_("unterminated address regex")))
-#define UNTERM_Y_CMD (UNTERM_S_CMD + sizeof (N_("unterminated `s' command")))
-#define UNKNOWN_S_OPT (UNTERM_Y_CMD + sizeof (N_("unterminated `y' command")))
-#define EXCESS_P_OPT (UNKNOWN_S_OPT + sizeof (N_("unknown option to `s'")))
-#define EXCESS_G_OPT (EXCESS_P_OPT \
- + sizeof (N_("multiple `p' options to `s' command")))
-#define EXCESS_N_OPT (EXCESS_G_OPT \
- + sizeof (N_("multiple `g' options to `s' command")))
-#define ZERO_N_OPT (EXCESS_N_OPT \
- + sizeof (N_("multiple number options to `s' command")))
-#define Y_CMD_LEN (ZERO_N_OPT \
- + sizeof (N_("number option to `s' command may not be zero")))
-#define BAD_DELIM (Y_CMD_LEN \
- + sizeof (N_("strings for `y' command are different lengths")))
-#define ANCIENT_VERSION (BAD_DELIM \
- + sizeof (N_("delimiter character is not a single-byte character")))
-#define INVALID_LINE_0 (ANCIENT_VERSION \
- + sizeof (N_("expected newer version of sed")))
-#define UNKNOWN_CMD (INVALID_LINE_0 \
- + sizeof (N_("invalid usage of line address 0")))
-#define INCOMPLETE_CMD (UNKNOWN_CMD + sizeof (N_("unknown command: `%c'")))
-#define COLON_LACKS_LABEL (INCOMPLETE_CMD \
- + sizeof (N_("incomplete command")))
-#define RECURSIVE_ESCAPE_C (COLON_LACKS_LABEL \
- + sizeof (N_("\":\" lacks a label")))
-#define DISALLOWED_CMD (RECURSIVE_ESCAPE_C \
- + sizeof (N_("recursive escaping after \\c not allowed")))
-#define MISSING_FILENAME (DISALLOWED_CMD \
- + sizeof (N_( "e/r/w commands disabled in sandbox mode")))
-/* #define END_ERRORS (DISALLOWED_CMD \
- + sizeof (N_( "e/r/w commands disabled in sandbox mode"))) */
-
static struct output *file_read = NULL;
static struct output *file_write = NULL;
-/* Complain about an unknown command and exit. */
-static void
-bad_command (char ch)
-{
- const char *msg = _(UNKNOWN_CMD);
- char *unknown_cmd = xmalloc (strlen (msg));
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
- sprintf (unknown_cmd, msg, ch);
-#pragma GCC diagnostic pop
- bad_prog (unknown_cmd);
-}
-
-/* Complain about a programming error and exit. */
-void
-bad_prog (const char *why)
+/* Complain about a programming error and exit.
+ bad_prog translates WHY, bad_prog_notranslate does not. */
+static _Noreturn void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0)
+vbad_prog (char const *why, va_list ap)
{
if (cur_input.name)
- fprintf (stderr, _("%s: file %s line %lu: %s\n"), program_name,
- cur_input.name, (unsigned long)cur_input.line, why);
+ fprintf (stderr, _("%s: file %s line %lu: "), program_name,
+ cur_input.name, (unsigned long) cur_input.line);
else
- fprintf (stderr, _("%s: -e expression #%lu, char %lu: %s\n"),
+ fprintf (stderr, _("%s: -e expression #%lu, char %lu: "),
program_name,
(unsigned long)cur_input.string_expr_count,
- (unsigned long)(prog.cur-prog.base),
- why);
+ (unsigned long)(prog.cur-prog.base));
+
+ vfprintf (stderr, why, ap);
+ fputc ('\n', stderr);
+
exit (EXIT_BAD_USAGE);
}
+void
+bad_prog (char const *why, ...)
+{
+ va_list ap;
+ va_start (ap, why);
+ vbad_prog (gettext (why), ap);
+ va_end (ap);
+}
+void
+bad_prog_notranslate (const char *why, ...)
+{
+ va_list ap;
+ va_start (ap, why);
+ vbad_prog (why, ap);
+ va_end (ap);
+}
/* Read the next character from the program. Return EOF if there isn't
anything to read. Keep cur_input.line up to date, so error messages
@@ -290,7 +212,7 @@ read_end_of_cmd (void)
if (ch == CLOSE_BRACE || ch == '#')
savchar (ch);
else if (ch != EOF && ch != '\n' && ch != ';')
- bad_prog (_(EXCESS_JUNK));
+ bad_prog ("extra characters after command");
}
/* Read an integer value from the program. */
@@ -363,7 +285,7 @@ read_filename (void)
int ch;
if (sandbox)
- bad_prog (_(DISALLOWED_CMD));
+ bad_prog ("e/r/w commands disabled in sandbox mode");
b = init_buffer ();
ch = in_nonblank ();
@@ -393,7 +315,7 @@ get_openfile (struct output **file_ptrs, const char *mode, int fail)
b = read_filename ();
file_name = get_buffer (b);
if (strlen (file_name) == 0)
- bad_prog (_(MISSING_FILENAME));
+ bad_prog ("missing filename in r/R/w/W commands");
for (p=*file_ptrs; p; p=p->link)
if (strcmp (p->name, file_name) == 0)
@@ -539,7 +461,7 @@ match_slash (int slash, int regex)
/* We allow only 1 byte characters for a slash. */
if (IS_MB_CHAR (slash, &cur_stat))
- bad_prog (BAD_DELIM);
+ bad_prog ("delimiter character is not a single-byte character");
memset (&cur_stat, 0, sizeof cur_stat);
@@ -596,32 +518,32 @@ mark_subst_opts (struct subst *cmd)
case 'i': /* GNU extension */
case 'I': /* GNU extension */
if (posixicity == POSIXLY_BASIC)
- bad_prog (_(UNKNOWN_S_OPT));
+ bad_prog ("unknown option to `s'");
flags |= REG_ICASE;
break;
case 'm': /* GNU extension */
case 'M': /* GNU extension */
if (posixicity == POSIXLY_BASIC)
- bad_prog (_(UNKNOWN_S_OPT));
+ bad_prog ("unknown option to `s'");
flags |= REG_NEWLINE;
break;
case 'e':
if (posixicity == POSIXLY_BASIC)
- bad_prog (_(UNKNOWN_S_OPT));
+ bad_prog ("unknown option to `s'");
cmd->eval = true;
break;
case 'p':
if (cmd->print)
- bad_prog (_(EXCESS_P_OPT));
+ bad_prog ("multiple `p' options to `s' command");
cmd->print |= (1 << cmd->eval); /* 1=before eval, 2=after */
break;
case 'g':
if (cmd->global)
- bad_prog (_(EXCESS_G_OPT));
+ bad_prog ("multiple `g' options to `s' command");
cmd->global = true;
break;
@@ -632,10 +554,10 @@ mark_subst_opts (struct subst *cmd)
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (cmd->numb)
- bad_prog (_(EXCESS_N_OPT));
+ bad_prog ("multiple number options to `s' command");
cmd->numb = in_integer (ch);
if (!cmd->numb)
- bad_prog (_(ZERO_N_OPT));
+ bad_prog ("number option to `s' command may not be zero");
break;
case CLOSE_BRACE:
@@ -653,7 +575,7 @@ mark_subst_opts (struct subst *cmd)
FALLTHROUGH;
default:
- bad_prog (_(UNKNOWN_S_OPT));
+ bad_prog ("unknown option to `s'");
/*NOTREACHED*/
}
}
@@ -904,7 +826,7 @@ compile_address (struct addr *addr, int ch)
if (ch == '\\')
ch = inchar ();
if ( !(b = match_slash (ch, true)) )
- bad_prog (_(UNTERM_ADDR_RE));
+ bad_prog ("unterminated address regex");
for (;;)
{
@@ -1004,14 +926,14 @@ compile_program (struct vector *vector)
{
if (a.addr_type == ADDR_IS_STEP
|| a.addr_type == ADDR_IS_STEP_MOD)
- bad_prog (_(BAD_STEP));
+ bad_prog ("invalid usage of +N or ~N as first address");
cur_cmd->a1 = MEMDUP (&a, 1, struct addr);
ch = in_nonblank ();
if (ch == ',')
{
if (!compile_address (&a, in_nonblank ()))
- bad_prog (_(BAD_COMMA));
+ bad_prog ("unexpected `,'");
cur_cmd->a2 = MEMDUP (&a, 1, struct addr);
ch = in_nonblank ();
@@ -1022,14 +944,14 @@ compile_program (struct vector *vector)
&& ((!cur_cmd->a2 && ch != 'r')
|| (cur_cmd->a2 && cur_cmd->a2->addr_type != ADDR_IS_REGEX)
|| posixicity == POSIXLY_BASIC))
- bad_prog (_(INVALID_LINE_0));
+ bad_prog ("invalid usage of line address 0");
}
if (ch == '!')
{
cur_cmd->addr_bang = true;
ch = in_nonblank ();
if (ch == '!')
- bad_prog (_(BAD_BANG));
+ bad_prog ("multiple `!'s");
}
/* Do not accept extended commands in --posix mode. Also,
@@ -1039,13 +961,13 @@ compile_program (struct vector *vector)
{
case 'e': case 'F': case 'v': case 'z': case 'L':
case 'Q': case 'T': case 'R': case 'W':
- bad_command (ch);
+ bad_prog ("unknown command: `%c'", ch);
FALLTHROUGH;
case 'a': case 'i': case 'l':
case '=': case 'r':
if (cur_cmd->a2)
- bad_prog (_(ONE_ADDR));
+ bad_prog ("command only uses one address");
}
cur_cmd->cmd = ch;
@@ -1053,7 +975,7 @@ compile_program (struct vector *vector)
{
case '#':
if (cur_cmd->a1)
- bad_prog (_(NO_SHARP_ADDR));
+ bad_prog ("comments don't accept any addresses");
ch = inchar ();
if (ch=='n' && first_script && cur_input.line < 2)
if ( (prog.base && prog.cur==2+prog.base)
@@ -1073,7 +995,7 @@ compile_program (struct vector *vector)
char const *compared_version;
compared_version = (*version == '\0') ? "4.0" : version;
if (strverscmp (compared_version, PACKAGE_VERSION) > 0)
- bad_prog (_(ANCIENT_VERSION));
+ bad_prog ("expected newer version of sed");
free (version);
posixicity = POSIXLY_EXTENDED;
@@ -1087,9 +1009,9 @@ compile_program (struct vector *vector)
case '}':
if (!blocks)
- bad_prog (_(EXCESS_CLOSE_BRACE));
+ bad_prog ("unexpected `}'");
if (cur_cmd->a1)
- bad_prog (_(NO_CLOSE_BRACE_ADDR));
+ bad_prog ("`}' doesn't want any addresses");
read_end_of_cmd ();
@@ -1099,7 +1021,7 @@ compile_program (struct vector *vector)
case 'e':
if (sandbox)
- bad_prog (_(DISALLOWED_CMD));
+ bad_prog ("e/r/w commands disabled in sandbox mode");
ch = in_nonblank ();
if (ch == EOF || ch == '\n')
@@ -1117,14 +1039,14 @@ compile_program (struct vector *vector)
read_text_to_slash:
if (ch == EOF)
- bad_prog (_(EXPECTED_SLASH));
+ bad_prog ("expected \\ after `a', `c' or `i'");
if (ch == '\\')
ch = inchar ();
else
{
if (posixicity == POSIXLY_BASIC)
- bad_prog (_(EXPECTED_SLASH));
+ bad_prog ("expected \\ after `a', `c' or `i'");
savchar (ch);
ch = '\n';
}
@@ -1134,11 +1056,11 @@ compile_program (struct vector *vector)
case ':':
if (cur_cmd->a1)
- bad_prog (_(NO_COLON_ADDR));
+ bad_prog (": doesn't want any addresses");
{
char *label = read_label ();
if (!*label)
- bad_prog (_(COLON_LACKS_LABEL));
+ bad_prog ("\":\" lacks a label");
labels = setup_label (labels, vector->v_length, label, NULL);
if (debug)
@@ -1155,7 +1077,7 @@ compile_program (struct vector *vector)
case 'Q':
case 'q':
if (cur_cmd->a2)
- bad_prog (_(ONE_ADDR));
+ bad_prog ("command only uses one address");
FALLTHROUGH;
case 'L':
@@ -1194,7 +1116,7 @@ compile_program (struct vector *vector)
case 'r':
b = read_filename ();
if (strlen (get_buffer (b)) == 0)
- bad_prog (_(MISSING_FILENAME));
+ bad_prog ("missing filename in r/R/w/W commands");
cur_cmd->x.readcmd.fname = xstrdup (get_buffer (b));
/* Adjust '0rFILE' command to '1rFILE' in prepend mode */
@@ -1230,9 +1152,9 @@ compile_program (struct vector *vector)
slash = inchar ();
if ( !(b = match_slash (slash, true)) )
- bad_prog (_(UNTERM_S_CMD));
+ bad_prog ("unterminated `s' command");
if ( !(b2 = match_slash (slash, false)) )
- bad_prog (_(UNTERM_S_CMD));
+ bad_prog ("unterminated `s' command");
cur_cmd->x.cmd_subst = OB_MALLOC (&obs, 1, struct subst);
setup_replacement (cur_cmd->x.cmd_subst,
@@ -1245,7 +1167,7 @@ compile_program (struct vector *vector)
free_buffer (b);
if (cur_cmd->x.cmd_subst->eval && sandbox)
- bad_prog (_(DISALLOWED_CMD));
+ bad_prog ("e/r/w commands disabled in sandbox mode");
}
break;
@@ -1258,12 +1180,12 @@ compile_program (struct vector *vector)
slash = inchar ();
if ( !(b = match_slash (slash, false)) )
- bad_prog (_(UNTERM_Y_CMD));
+ bad_prog ("unterminated `y' command");
src_buf = get_buffer (b);
len = normalize_text (src_buf, size_buffer (b), TEXT_BUFFER);
if ( !(b2 = match_slash (slash, false)) )
- bad_prog (_(UNTERM_Y_CMD));
+ bad_prog ("unterminated `y' command");
dest_buf = get_buffer (b2);
dest_len = normalize_text (dest_buf, size_buffer (b2), TEXT_BUFFER);
@@ -1301,7 +1223,7 @@ compile_program (struct vector *vector)
for (i = 0; i < src_char_num; i++)
{
if (idx >= dest_len)
- bad_prog (_(Y_CMD_LEN));
+ bad_prog ("strings for `y' command are different lengths");
/* Set the i-th source character. */
trans_pairs[2 * i] = XCALLOC (src_lens[i] + 1, char);
@@ -1325,7 +1247,7 @@ compile_program (struct vector *vector)
}
trans_pairs[2 * i] = NULL;
if (idx != dest_len)
- bad_prog (_(Y_CMD_LEN));
+ bad_prog ("strings for `y' command are different lengths");
IF_LINT (free (src_lens));
}
@@ -1336,7 +1258,7 @@ compile_program (struct vector *vector)
unsigned char *ustring = (unsigned char *)src_buf;
if (len != dest_len)
- bad_prog (_(Y_CMD_LEN));
+ bad_prog ("strings for `y' command are different lengths");
for (len = 0; len < YMAP_LENGTH; len++)
translate[len] = len;
@@ -1355,11 +1277,11 @@ compile_program (struct vector *vector)
break;
case EOF:
- bad_prog (_(NO_COMMAND));
+ bad_prog ("missing command");
/*NOTREACHED*/
default:
- bad_command (ch);
+ bad_prog ("unknown command: `%c'", ch);
/*NOTREACHED*/
}
@@ -1367,7 +1289,7 @@ compile_program (struct vector *vector)
++vector->v_length;
}
if (posixicity == POSIXLY_BASIC && pending_text)
- bad_prog (_(INCOMPLETE_CMD));
+ bad_prog ("incomplete command");
return vector;
}
@@ -1451,7 +1373,7 @@ convert:
{
p++;
if (*p != '\\')
- bad_prog (RECURSIVE_ESCAPE_C);
+ bad_prog ("recursive escaping after \\c not allowed");
}
p++;
continue;
@@ -1594,7 +1516,7 @@ check_final_program (struct vector *program)
{
/* update info for error reporting: */
memcpy (&cur_input, &blocks->err_info, sizeof (cur_input));
- bad_prog (_(EXCESS_OPEN_BRACE));
+ bad_prog ("unmatched `{'");
}
/* was the final command an unterminated a/c/i command? */
diff --git a/sed/regexp.c b/sed/regexp.c
index 2b88de1..a80b2f6 100644
--- a/sed/regexp.c
+++ b/sed/regexp.c
@@ -24,22 +24,8 @@
#include "xalloc.h"
-#ifdef gettext_noop
-# define N_(String) gettext_noop(String)
-#else
-# define N_(String) (String)
-#endif
-
extern bool use_extended_syntax_p;
-static const char errors[] =
- "no previous regular expression\0"
- "cannot specify modifiers on empty regexp";
-
-#define NO_REGEX (errors)
-#define BAD_MODIF (NO_REGEX + sizeof(N_("no previous regular expression")))
-
-
void
dfaerror (char const *mesg)
{
@@ -114,18 +100,13 @@ compile_regex_1 (struct regex *new_regex, int needed_sub)
#endif
if (error)
- bad_prog (error);
+ bad_prog_notranslate ("%s", error);
/* Just to be sure, I mark this as not POSIXLY_CORRECT behavior */
if (needed_sub
&& new_regex->pattern.re_nsub < needed_sub - 1
&& posixicity == POSIXLY_EXTENDED)
- {
- char buf[200];
- sprintf (buf, _("invalid reference \\%d on `s' command's RHS"),
- needed_sub - 1);
- bad_prog (buf);
- }
+ bad_prog ("invalid reference \\%d on `s' command's RHS", needed_sub - 1);
int dfaopts = buffer_delimiter == '\n' ? 0 : DFA_EOL_NUL;
new_regex->dfa = dfaalloc ();
@@ -155,7 +136,7 @@ compile_regex (struct buffer *b, int flags, int needed_sub)
if (size_buffer (b) == 0)
{
if (flags > 0)
- bad_prog (_(BAD_MODIF));
+ bad_prog ("cannot specify modifiers on empty regexp");
return NULL;
}
@@ -186,7 +167,7 @@ match_regex (struct regex *regex, char *buf, size_t buflen,
{
regex = regex_last;
if (!regex_last)
- bad_prog (_(NO_REGEX));
+ bad_prog ("no previous regular expression");
}
else
regex_last = regex;
diff --git a/sed/sed.h b/sed/sed.h
index 1c96bc5..8be9955 100644
--- a/sed/sed.h
+++ b/sed/sed.h
@@ -185,7 +185,10 @@ struct sed_cmd {
};
-_Noreturn void bad_prog (const char *why);
+_Noreturn void bad_prog (char const *why, ...)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2);
+_Noreturn void bad_prog_notranslate (char const *why, ...)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2);
size_t normalize_text (char *text, size_t len, enum text_types buftype);
struct vector *compile_string (struct vector *, char *str, size_t len);
struct vector *compile_file (struct vector *, const char *cmdfile);