summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2005-09-19 16:06:40 +0000
committerBruno Haible <bruno@clisp.org>2009-06-23 12:12:50 +0200
commit145763c502191957a4abdc663020198510cf7479 (patch)
treeac4c8e5bc82c691dc9b8594f9a8ce3ccc951d0f2
parent06d3f09a53be3051c6976fac9b182b73e4b08aad (diff)
downloadexternal_gettext-145763c502191957a4abdc663020198510cf7479.zip
external_gettext-145763c502191957a4abdc663020198510cf7479.tar.gz
external_gettext-145763c502191957a4abdc663020198510cf7479.tar.bz2
New, higher-level error and warning message output primitives.
-rw-r--r--gettext-tools/src/ChangeLog62
-rw-r--r--gettext-tools/src/FILES2
-rw-r--r--gettext-tools/src/Makefile.am4
-rw-r--r--gettext-tools/src/msgcmp.c1
-rw-r--r--gettext-tools/src/msgfmt.c399
-rw-r--r--gettext-tools/src/msgl-iconv.c58
-rw-r--r--gettext-tools/src/msgl-iconv.h1
-rw-r--r--gettext-tools/src/msgmerge.c1
-rw-r--r--gettext-tools/src/open-po.c15
-rw-r--r--gettext-tools/src/po-charset.c92
-rw-r--r--gettext-tools/src/po-lex.c59
-rw-r--r--gettext-tools/src/po-lex.h76
-rw-r--r--gettext-tools/src/po-xerror.c199
-rw-r--r--gettext-tools/src/po-xerror.h83
-rw-r--r--gettext-tools/src/read-po-abstract.c12
-rw-r--r--gettext-tools/src/read-po.c11
-rw-r--r--gettext-tools/src/read-properties.c22
-rw-r--r--gettext-tools/src/read-stringtable.c63
-rw-r--r--gettext-tools/src/write-po.c101
-rw-r--r--gettext-tools/src/xgettext.c1
-rw-r--r--gettext-tools/tests/ChangeLog8
-rwxr-xr-xgettext-tools/tests/msgfmt-72
-rwxr-xr-xgettext-tools/tests/msgfmt-82
-rwxr-xr-xgettext-tools/tests/msgfmt-92
-rwxr-xr-xgettext-tools/tests/msgmerge-22
-rwxr-xr-xgettext-tools/tests/msgmerge-92
26 files changed, 851 insertions, 429 deletions
diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog
index 49346ba..c7db86f 100644
--- a/gettext-tools/src/ChangeLog
+++ b/gettext-tools/src/ChangeLog
@@ -1,3 +1,65 @@
+2005-09-17 Bruno Haible <bruno@clisp.org>
+
+ New, higher-level error message output primitives.
+ * po-xerror.h: New file.
+ * po-xerror.c: New file.
+ * open-po.c: Include xerror.h, po-xerror.h, not error.h.
+ (open_po_file): Use po_xerror instead of error.
+ * po-charset.c: Include po-xerror.h, not po-error.h.
+ (po_lex_charset_set): Use po_xerror instead of po_multiline_warning.
+ * po-lex.c: Include xerror.h, po-error.h, po-xerror.h.
+ (po_gram_error, po_gram_error_at_line): Use po_xerror instead of
+ po_error or po_error_at_line. Don't decrement error_message_count;
+ let the caller do this instead.
+ (mbfile_getc, lex_getc): Use po_xerror instead of po_error.
+ * po-lex.h: Don't include po-error.h.
+ (po_gram_error, po_gram_error_at_line): Remove optimized macros.
+ * read-po-abstract.c: Include xerror.h, po-xerror.h.
+ (po_scan): Use po_xerror instead of po_error.
+ * read-po.c: Include po-xerror.h.
+ (default_add_message): Use po_xerror2 instead of po_gram_error_at_line
+ pair.
+ * read-properties.c: Include xerror.h, po-xerror.h, not exit.h.
+ (phase1_getc, phase4_getuc): Use po_xerror instead of error.
+ * read-stringtable.c: Include xerror.h, po-xerror.h, not exit.h.
+ (phase1_getc, read_string, stringtable_parse): Use po_xerror instead of
+ error.
+ * write-po.c: Include po-xerror.h, not exit.h, po-error.h.
+ (wrap): Pass the entire message as argument. Use po_xerror instead of
+ po_error.
+ (message_print, message_print_obsolete): Update. Use po_xerror instead
+ of po_multiline_warning.
+ (msgdomain_list_print): Use po_xerror instead of po_error or
+ po_error_at_line.
+ * msgl-iconv.h (struct conversion_context): Add 'message' field.
+ * msgl-iconv.c: Include xerror.h, po-xerror.h, not error.h, exit.h.
+ (conversion_error): Use po_xerror instead of error.
+ (iconv_message_list): Likewise. Set the entire message in the
+ conversion context before calling convert_*.
+ (iconv_msgdomain_list): Use po_xerror instead of error.
+ * xgettext.c (from_current_source_encoding): Set context.message.
+ * msgfmt.c: Include po-xerror.h.
+ (check_plural_eval): Pass the entire header as argument. Use po_xerror
+ instead of error_at_line.
+ (plural_help): New function, extracted from check_plural.
+ (check_plural): Change type of local variables has_plural, min_pos,
+ max_pos. Use po_xerror2 instead of error_at_line pairs. Use po_xerror
+ instead of error_at_line.
+ (curr_mp): New variable.
+ (formatstring_error_logger): Use po_xerror instead of vfprintf.
+ (check_pair): Take the entire message as argument. Use po_xerror
+ instead of error_at_line. Set curr_mp before calling
+ check_msgid_msgstr_format.
+ (check_header_entry): Take the entire header message as argument. Use
+ po_xerror instead of multiline_error.
+ (msgfmt_frob_new_message): Update.
+ * msgcmp.c (match_domain): Decrement error_message_count between two
+ error messages that belong together.
+ * msgmerge.c (match_domain): Decrement error_message_count between two
+ error messages that belong together.
+ * Makefile.am (noinst_HEADERS): Add po-xerror.h.
+ (COMMON_SOURCE): Add po-xerror.c.
+
2005-09-16 Bruno Haible <bruno@clisp.org>
* gettext-po.c (po_file_read): Set gram_max_allowed_errors to a large
diff --git a/gettext-tools/src/FILES b/gettext-tools/src/FILES
index ceee7cb..0ab3c8f 100644
--- a/gettext-tools/src/FILES
+++ b/gettext-tools/src/FILES
@@ -34,6 +34,8 @@ msgl-ascii.c
po-error.h
po-error.c
+po-xerror.h
+po-xerror.c
Error handling during writing and reading of PO files.
write-po.h
diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am
index b41f07c..46a882c 100644
--- a/gettext-tools/src/Makefile.am
+++ b/gettext-tools/src/Makefile.am
@@ -34,7 +34,7 @@ lib_LTLIBRARIES = libgettextsrc.la libgettextpo.la
include_HEADERS = gettext-po.h
-noinst_HEADERS = pos.h message.h po-error.h po-gram.h po-charset.h \
+noinst_HEADERS = pos.h message.h po-error.h po-xerror.h po-gram.h po-charset.h \
po-lex.h open-po.h \
read-po-abstract.h read-po.h read-properties.h read-stringtable.h \
str-list.h \
@@ -98,7 +98,7 @@ CSHARPCOMPFLAGS = -O -g
# (read-po-abstract.c <--> po-gram-gen.y <--> po-lex.c) -> open-po.c -> dir-list.c -> str-list.c.
# (read-po-abstract.c <--> po-gram-gen.y <--> po-lex.c) -> po-charset.c.
# (read-po-abstract.c <--> po-gram-gen.y <--> po-lex.c) -> message.c -> str-list.c.
-COMMON_SOURCE = message.c po-error.c \
+COMMON_SOURCE = message.c po-error.c po-xerror.c \
read-po-abstract.c po-lex.c po-gram-gen.y po-charset.c \
read-properties.c read-stringtable.c open-po.c dir-list.c str-list.c
diff --git a/gettext-tools/src/msgcmp.c b/gettext-tools/src/msgcmp.c
index 2c5bb0e..6f0962c 100644
--- a/gettext-tools/src/msgcmp.c
+++ b/gettext-tools/src/msgcmp.c
@@ -284,6 +284,7 @@ match_domain (const char *fn1, const char *fn2,
{
po_gram_error_at_line (&refmsg->pos, _("\
this message is used but not defined..."));
+ error_message_count--;
po_gram_error_at_line (&defmsg->pos, _("\
...but this definition is similar"));
defmsg->used = 1;
diff --git a/gettext-tools/src/msgfmt.c b/gettext-tools/src/msgfmt.c
index 7d6c81e..4c5bf8e 100644
--- a/gettext-tools/src/msgfmt.c
+++ b/gettext-tools/src/msgfmt.c
@@ -39,6 +39,7 @@
#include "relocatable.h"
#include "basename.h"
#include "xerror.h"
+#include "po-xerror.h"
#include "format.h"
#include "xalloc.h"
#include "plural-exp.h"
@@ -873,7 +874,7 @@ uninstall_sigfpe_handler ()
static void
check_plural_eval (struct expression *plural_expr,
unsigned long nplurals_value,
- const lex_pos_ty *header_pos)
+ const message_ty *header)
{
if (sigsetjmp (sigfpe_exit, 1) == 0)
{
@@ -891,25 +892,22 @@ check_plural_eval (struct expression *plural_expr,
/* End of protection against arithmetic exceptions. */
uninstall_sigfpe_handler ();
- error_with_progname = false;
- error_at_line (0, 0,
- header_pos->file_name, header_pos->line_number,
- _("plural expression can produce negative values"));
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
+ _("plural expression can produce negative values"));
exit_status = EXIT_FAILURE;
return;
}
else if (val >= nplurals_value)
{
+ char *msg;
+
/* End of protection against arithmetic exceptions. */
uninstall_sigfpe_handler ();
- error_with_progname = false;
- error_at_line (0, 0,
- header_pos->file_name, header_pos->line_number,
- _("nplurals = %lu but plural expression can produce values as large as %lu"),
- nplurals_value, val);
- error_with_progname = true;
+ msg = xasprintf (_("nplurals = %lu but plural expression can produce values as large as %lu"),
+ nplurals_value, val);
+ po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
+ free (msg);
exit_status = EXIT_FAILURE;
return;
}
@@ -933,39 +931,65 @@ check_plural_eval (struct expression *plural_expr,
#if USE_SIGINFO
# ifdef FPE_INTDIV
case FPE_INTDIV:
- /* xgettext: c-format */
msg = _("plural expression can produce division by zero");
break;
# endif
# ifdef FPE_INTOVF
case FPE_INTOVF:
- /* xgettext: c-format */
msg = _("plural expression can produce integer overflow");
break;
# endif
default:
#endif
- /* xgettext: c-format */
msg = _("plural expression can produce arithmetic exceptions, possibly division by zero");
}
- error_with_progname = false;
- error_at_line (0, 0, header_pos->file_name, header_pos->line_number, msg);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
exit_status = EXIT_FAILURE;
}
}
+/* Try to help the translator by looking up the right plural formula for her.
+ Return a freshly allocated multiline help string, or NULL. */
+static char *
+plural_help (const char *nullentry)
+{
+ const char *language;
+ size_t j;
+
+ language = strstr (nullentry, "Language-Team: ");
+ if (language != NULL)
+ {
+ language += 15;
+ for (j = 0; j < plural_table_size; j++)
+ if (strncmp (language,
+ plural_table[j].language,
+ strlen (plural_table[j].language)) == 0)
+ {
+ char *helpline1 =
+ xasprintf (_("Try using the following, valid for %s:"),
+ plural_table[j].language);
+ char *help =
+ xasprintf ("%s\n\"Plural-Forms: %s\\n\"\n",
+ helpline1, plural_table[j].value);
+ free (helpline1);
+ return help;
+ }
+ }
+ return NULL;
+}
+
+
/* Perform plural expression checking. */
static void
check_plural (message_list_ty *mlp)
{
- const lex_pos_ty *has_plural;
+ const message_ty *has_plural;
unsigned long min_nplurals;
- const lex_pos_ty *min_pos;
+ const message_ty *min_pos;
unsigned long max_nplurals;
- const lex_pos_ty *max_pos;
+ const message_ty *max_pos;
size_t j;
message_ty *header;
@@ -986,7 +1010,7 @@ check_plural (message_list_ty *mlp)
unsigned long n;
if (has_plural == NULL)
- has_plural = &mp->pos;
+ has_plural = mp;
n = 0;
for (p = mp->msgstr, p_end = p + mp->msgstr_len;
@@ -996,12 +1020,12 @@ check_plural (message_list_ty *mlp)
if (min_nplurals > n)
{
min_nplurals = n;
- min_pos = &mp->pos;
+ min_pos = mp;
}
if (max_nplurals > n)
{
max_nplurals = n;
- min_pos = &mp->pos;
+ min_pos = mp;
}
}
}
@@ -1014,7 +1038,6 @@ check_plural (message_list_ty *mlp)
const char *nullentry;
const char *plural;
const char *nplurals;
- bool try_to_help = false;
nullentry = header->msgstr;
@@ -1022,26 +1045,50 @@ check_plural (message_list_ty *mlp)
nplurals = strstr (nullentry, "nplurals=");
if (plural == NULL && has_plural != NULL)
{
- error_with_progname = false;
- error_at_line (0, 0, has_plural->file_name, has_plural->line_number,
- _("message catalog has plural form translations..."));
- --error_message_count;
- error_at_line (0, 0, header->pos.file_name, header->pos.line_number,
- _("...but header entry lacks a \"plural=EXPRESSION\" attribute"));
- error_with_progname = true;
- try_to_help = true;
+ const char *msg1 =
+ _("message catalog has plural form translations");
+ const char *msg2 =
+ _("but header entry lacks a \"plural=EXPRESSION\" attribute");
+ char *help = plural_help (nullentry);
+
+ if (help != NULL)
+ {
+ char *msg2ext = xasprintf ("%s\n%s", msg2, help);
+ po_xerror2 (PO_SEVERITY_ERROR,
+ has_plural, NULL, 0, 0, false, msg1,
+ header, NULL, 0, 0, true, msg2ext);
+ free (msg2ext);
+ free (help);
+ }
+ else
+ po_xerror2 (PO_SEVERITY_ERROR,
+ has_plural, NULL, 0, 0, false, msg1,
+ header, NULL, 0, 0, false, msg2);
+
exit_status = EXIT_FAILURE;
}
if (nplurals == NULL && has_plural != NULL)
{
- error_with_progname = false;
- error_at_line (0, 0, has_plural->file_name, has_plural->line_number,
- _("message catalog has plural form translations..."));
- --error_message_count;
- error_at_line (0, 0, header->pos.file_name, header->pos.line_number,
- _("...but header entry lacks a \"nplurals=INTEGER\" attribute"));
- error_with_progname = true;
- try_to_help = true;
+ const char *msg1 =
+ _("message catalog has plural form translations");
+ const char *msg2 =
+ _("but header entry lacks a \"nplurals=INTEGER\" attribute");
+ char *help = plural_help (nullentry);
+
+ if (help != NULL)
+ {
+ char *msg2ext = xasprintf ("%s\n%s", msg2, help);
+ po_xerror2 (PO_SEVERITY_ERROR,
+ has_plural, NULL, 0, 0, false, msg1,
+ header, NULL, 0, 0, true, msg2ext);
+ free (msg2ext);
+ free (help);
+ }
+ else
+ po_xerror2 (PO_SEVERITY_ERROR,
+ has_plural, NULL, 0, 0, false, msg1,
+ header, NULL, 0, 0, false, msg2);
+
exit_status = EXIT_FAILURE;
}
if (plural != NULL && nplurals != NULL)
@@ -1061,12 +1108,20 @@ check_plural (message_list_ty *mlp)
nplurals_value = strtoul (nplurals, (char **) &endp, 10);
if (nplurals == endp)
{
- error_with_progname = false;
- error_at_line (0, 0,
- header->pos.file_name, header->pos.line_number,
- _("invalid nplurals value"));
- error_with_progname = true;
- try_to_help = true;
+ const char *msg = _("invalid nplurals value");
+ char *help = plural_help (nullentry);
+
+ if (help != NULL)
+ {
+ char *msgext = xasprintf ("%s\n%s", msg, help);
+ po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, true,
+ msgext);
+ free (msgext);
+ free (help);
+ }
+ else
+ po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
+
exit_status = EXIT_FAILURE;
}
@@ -1075,51 +1130,61 @@ check_plural (message_list_ty *mlp)
args.cp = plural;
if (parse_plural_expression (&args) != 0)
{
- error_with_progname = false;
- error_at_line (0, 0,
- header->pos.file_name, header->pos.line_number,
- _("invalid plural expression"));
- error_with_progname = true;
- try_to_help = true;
+ const char *msg = _("invalid plural expression");
+ char *help = plural_help (nullentry);
+
+ if (help != NULL)
+ {
+ char *msgext = xasprintf ("%s\n%s", msg, help);
+ po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, true,
+ msgext);
+ free (msgext);
+ free (help);
+ }
+ else
+ po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
+
exit_status = EXIT_FAILURE;
}
plural_expr = args.res;
/* See whether nplurals and plural fit together. */
if (exit_status != EXIT_FAILURE)
- check_plural_eval (plural_expr, nplurals_value, &header->pos);
+ check_plural_eval (plural_expr, nplurals_value, header);
/* Check the number of plurals of the translations. */
if (exit_status != EXIT_FAILURE)
{
if (min_nplurals < nplurals_value)
{
- error_with_progname = false;
- error_at_line (0, 0,
- header->pos.file_name, header->pos.line_number,
- _("nplurals = %lu..."), nplurals_value);
- --error_message_count;
- error_at_line (0, 0, min_pos->file_name, min_pos->line_number,
- ngettext ("...but some messages have only one plural form",
- "...but some messages have only %lu plural forms",
- min_nplurals),
- min_nplurals);
- error_with_progname = true;
+ char *msg1 =
+ xasprintf (_("nplurals = %lu"), nplurals_value);
+ char *msg2 =
+ xasprintf (ngettext ("but some messages have only one plural form",
+ "but some messages have only %lu plural forms",
+ min_nplurals),
+ min_nplurals);
+ po_xerror2 (PO_SEVERITY_ERROR,
+ header, NULL, 0, 0, false, msg1,
+ min_pos, NULL, 0, 0, false, msg2);
+ free (msg2);
+ free (msg1);
exit_status = EXIT_FAILURE;
}
else if (max_nplurals > nplurals_value)
{
- error_with_progname = false;
- error_at_line (0, 0,
- header->pos.file_name, header->pos.line_number,
- _("nplurals = %lu..."), nplurals_value);
- --error_message_count;
- error_at_line (0, 0, max_pos->file_name, max_pos->line_number,
- ngettext ("...but some messages have one plural form",
- "...but some messages have %lu plural forms",
- max_nplurals),
- max_nplurals);
- error_with_progname = true;
+ char *msg1 =
+ xasprintf (_("nplurals = %lu"), nplurals_value);
+ char *msg2 =
+ xasprintf (ngettext ("but some messages have one plural form",
+ "but some messages have %lu plural forms",
+ max_nplurals),
+ max_nplurals);
+ po_xerror2 (PO_SEVERITY_ERROR,
+ header, NULL, 0, 0, false, msg1,
+ max_pos, NULL, 0, 0, false, msg2);
+ free (msg2);
+ free (msg1);
exit_status = EXIT_FAILURE;
}
/* The only valid case is max_nplurals <= n <= min_nplurals,
@@ -1127,70 +1192,45 @@ check_plural (message_list_ty *mlp)
max_nplurals = n = min_nplurals. */
}
}
- /* Try to help the translator by looking up the right plural formula
- for her. */
- if (try_to_help)
- {
- const char *language;
-
- language = strstr (nullentry, "Language-Team: ");
- if (language != NULL)
- {
- language += 15;
- for (j = 0; j < plural_table_size; j++)
- if (strncmp (language,
- plural_table[j].language,
- strlen (plural_table[j].language)) == 0)
- {
- char *recommended =
- xasprintf ("Plural-Forms: %s\\n", plural_table[j].value);
- fprintf (stderr,
- _("Try using the following, valid for %s:\n"),
- plural_table[j].language);
- fprintf (stderr, "\"%s\"\n", recommended);
- free (recommended);
- break;
- }
- }
- }
}
else if (has_plural != NULL)
{
- error_with_progname = false;
- error_at_line (0, 0, has_plural->file_name, has_plural->line_number,
- _("message catalog has plural form translations, but lacks a header entry with \"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\""));
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, has_plural, NULL, 0, 0, false,
+ _("message catalog has plural form translations, but lacks a header entry with \"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\""));
exit_status = EXIT_FAILURE;
}
}
/* Signal an error when checking format strings. */
+static const message_ty *curr_mp;
static lex_pos_ty curr_msgid_pos;
static void
formatstring_error_logger (const char *format, ...)
{
va_list args;
+ char *msg;
va_start (args, format);
- fprintf (stderr, "%s:%lu: ",
- curr_msgid_pos.file_name,
- (unsigned long) curr_msgid_pos.line_number);
- vfprintf (stderr, format, args);
- putc ('\n', stderr);
- fflush (stderr);
+ if (vasprintf (&msg, format, args) < 0)
+ error (EXIT_FAILURE, 0, _("memory exhausted"));
va_end (args);
- ++error_message_count;
+ po_xerror (PO_SEVERITY_ERROR,
+ curr_mp, curr_msgid_pos.file_name, curr_msgid_pos.line_number,
+ (size_t)(-1), false, msg);
+ free (msg);
}
/* Perform miscellaneous checks on a message. */
static void
-check_pair (const char *msgid,
+check_pair (const message_ty *mp,
+ const char *msgid,
const lex_pos_ty *msgid_pos,
const char *msgid_plural,
const char *msgstr, size_t msgstr_len,
- const lex_pos_ty *msgstr_pos, enum is_format is_format[NFORMATS])
+ const lex_pos_ty *msgstr_pos,
+ enum is_format is_format[NFORMATS])
{
int has_newline;
unsigned int j;
@@ -1208,21 +1248,22 @@ check_pair (const char *msgid,
{
if (TEST_NEWLINE(msgid_plural) != has_newline)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("\
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, _("\
`msgid' and `msgid_plural' entries do not both begin with '\\n'"));
- error_with_progname = true;
exit_status = EXIT_FAILURE;
}
for (p = msgstr, j = 0; p < msgstr + msgstr_len; p += strlen (p) + 1, j++)
if (TEST_NEWLINE(p) != has_newline)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("\
+ char *msg =
+ xasprintf (_("\
`msgid' and `msgstr[%u]' entries do not both begin with '\\n'"), j);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, msg);
+ free (msg);
exit_status = EXIT_FAILURE;
}
}
@@ -1230,11 +1271,10 @@ check_pair (const char *msgid,
{
if (TEST_NEWLINE(msgstr) != has_newline)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("\
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, _("\
`msgid' and `msgstr' entries do not both begin with '\\n'"));
- error_with_progname = true;
exit_status = EXIT_FAILURE;
}
}
@@ -1247,21 +1287,22 @@ check_pair (const char *msgid,
{
if (TEST_NEWLINE(msgid_plural) != has_newline)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("\
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, _("\
`msgid' and `msgid_plural' entries do not both end with '\\n'"));
- error_with_progname = true;
exit_status = EXIT_FAILURE;
}
for (p = msgstr, j = 0; p < msgstr + msgstr_len; p += strlen (p) + 1, j++)
if (TEST_NEWLINE(p) != has_newline)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("\
+ char *msg =
+ xasprintf (_("\
`msgid' and `msgstr[%u]' entries do not both end with '\\n'"), j);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, msg);
+ free (msg);
exit_status = EXIT_FAILURE;
}
}
@@ -1269,11 +1310,10 @@ check_pair (const char *msgid,
{
if (TEST_NEWLINE(msgstr) != has_newline)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("\
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, _("\
`msgid' and `msgstr' entries do not both end with '\\n'"));
- error_with_progname = true;
exit_status = EXIT_FAILURE;
}
}
@@ -1281,10 +1321,10 @@ check_pair (const char *msgid,
if (check_compatibility && msgid_plural != NULL)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("plural handling is a GNU gettext extension"));
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, _("\
+plural handling is a GNU gettext extension"));
exit_status = EXIT_FAILURE;
}
@@ -1292,6 +1332,7 @@ check_pair (const char *msgid,
/* Test 3: Check whether both formats strings contain the same number
of format specifications. */
{
+ curr_mp = mp;
curr_msgid_pos = *msgid_pos;
if (check_msgid_msgstr_format (msgid, msgid_plural, msgstr, msgstr_len,
is_format, formatstring_error_logger))
@@ -1322,19 +1363,23 @@ check_pair (const char *msgid,
if (count == 0)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("msgstr lacks the keyboard accelerator mark '%c'"),
- accelerator_char);
- error_with_progname = true;
+ char *msg =
+ xasprintf (_("msgstr lacks the keyboard accelerator mark '%c'"),
+ accelerator_char);
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, msg);
+ free (msg);
}
else if (count > 1)
{
- error_with_progname = false;
- error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number,
- _("msgstr has too many keyboard accelerator marks '%c'"),
- accelerator_char);
- error_with_progname = true;
+ char *msg =
+ xasprintf (_("msgstr has too many keyboard accelerator marks '%c'"),
+ accelerator_char);
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, msg);
+ free (msg);
}
}
}
@@ -1343,7 +1388,7 @@ check_pair (const char *msgid,
/* Perform miscellaneous checks on a header entry. */
static void
-check_header_entry (const char *msgstr_string)
+check_header_entry (const message_ty *mp, const char *msgstr_string)
{
static const char *required_fields[] =
{
@@ -1365,14 +1410,24 @@ check_header_entry (const char *msgstr_string)
char *endp = strstr (msgstr_string, required_fields[cnt]);
if (endp == NULL)
- multiline_error (xasprintf ("%s: ", gram_pos.file_name),
- xasprintf (_("headerfield `%s' missing in header\n"),
- required_fields[cnt]));
+ {
+ char *msg =
+ xasprintf (_("headerfield `%s' missing in header\n"),
+ required_fields[cnt]);
+ po_xerror (PO_SEVERITY_ERROR, mp, gram_pos.file_name, (size_t)(-1),
+ (size_t)(-1), true, msg);
+ free (msg);
+ }
else if (endp != msgstr_string && endp[-1] != '\n')
- multiline_error (xasprintf ("%s: ", gram_pos.file_name),
- xasprintf (_("\
+ {
+ char *msg =
+ xasprintf (_("\
header field `%s' should start at beginning of line\n"),
- required_fields[cnt]));
+ required_fields[cnt]);
+ po_xerror (PO_SEVERITY_ERROR, mp, gram_pos.file_name, (size_t)(-1),
+ (size_t)(-1), true, msg);
+ free (msg);
+ }
else if (default_values[cnt] != NULL
&& strncmp (default_values[cnt],
endp + strlen (required_fields[cnt]) + 2,
@@ -1380,9 +1435,10 @@ header field `%s' should start at beginning of line\n"),
{
if (initial != -1)
{
- multiline_error (xasprintf ("%s: ", gram_pos.file_name),
- xstrdup (_("\
-some header fields still have the initial default value\n")));
+ po_xerror (PO_SEVERITY_ERROR,
+ mp, gram_pos.file_name, (size_t)(-1), (size_t)(-1),
+ true, _("\
+some header fields still have the initial default value\n"));
initial = -1;
break;
}
@@ -1392,10 +1448,14 @@ some header fields still have the initial default value\n")));
}
if (initial != -1)
- multiline_error (xasprintf ("%s: ", gram_pos.file_name),
- xasprintf (_("\
-field `%s' still has initial default value\n"),
- required_fields[initial]));
+ {
+ char *msg =
+ xasprintf (_("field `%s' still has initial default value\n"),
+ required_fields[initial]);
+ po_xerror (PO_SEVERITY_ERROR, mp, gram_pos.file_name, (size_t)(-1),
+ (size_t)(-1), true, msg);
+ free (msg);
+ }
}
@@ -1587,7 +1647,7 @@ msgfmt_frob_new_message (default_po_reader_ty *that, message_ty *mp,
/* Do some more tests on the contents of the header entry. */
if (check_header)
- check_header_entry (mp->msgstr);
+ check_header_entry (mp, mp->msgstr);
}
else
/* We don't count the header entry in the statistic so place
@@ -1598,7 +1658,8 @@ msgfmt_frob_new_message (default_po_reader_ty *that, message_ty *mp,
++msgs_translated;
/* Do some more checks on both strings. */
- check_pair (mp->msgid, msgid_pos, mp->msgid_plural,
+ check_pair (mp,
+ mp->msgid, msgid_pos, mp->msgid_plural,
mp->msgstr, mp->msgstr_len, msgstr_pos,
mp->is_format);
}
diff --git a/gettext-tools/src/msgl-iconv.c b/gettext-tools/src/msgl-iconv.c
index f7aadc3..ad44f0c 100644
--- a/gettext-tools/src/msgl-iconv.c
+++ b/gettext-tools/src/msgl-iconv.c
@@ -34,7 +34,6 @@
# include <iconv.h>
#endif
-#include "error.h"
#include "progname.h"
#include "basename.h"
#include "message.h"
@@ -43,7 +42,8 @@
#include "xalloc.h"
#include "xallocsa.h"
#include "strstr.h"
-#include "exit.h"
+#include "xerror.h"
+#include "po-xerror.h"
#include "gettext.h"
#define _(str) gettext (str)
@@ -181,12 +181,15 @@ conversion_error (const struct conversion_context* context)
{
if (context->to_code == po_charset_utf8)
/* If a conversion to UTF-8 fails, the problem lies in the input. */
- error (EXIT_FAILURE, 0, _("%s: input is not valid in \"%s\" encoding"),
- context->from_filename, context->from_code);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, context->message, NULL, 0, 0, false,
+ xasprintf (_("%s: input is not valid in \"%s\" encoding"),
+ context->from_filename, context->from_code));
else
- error (EXIT_FAILURE, 0,
- _("%s: error while converting from \"%s\" encoding to \"%s\" encoding"),
- context->from_filename, context->from_code, context->to_code);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, context->message, NULL, 0, 0, false,
+ xasprintf (_("\
+%s: error while converting from \"%s\" encoding to \"%s\" encoding"),
+ context->from_filename, context->from_code,
+ context->to_code));
/* NOTREACHED */
abort ();
}
@@ -325,10 +328,10 @@ iconv_message_list (message_list_ty *mlp,
&& strcmp (charset, "CHARSET") == 0)
canon_charset = po_charset_ascii;
else
- error (EXIT_FAILURE, 0,
- _("\
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0,
+ false, xasprintf (_("\
present charset \"%s\" is not a portable encoding name"),
- charset);
+ charset));
}
}
else
@@ -336,10 +339,11 @@ present charset \"%s\" is not a portable encoding name"),
if (canon_from_code == NULL)
canon_from_code = canon_charset;
else if (canon_from_code != canon_charset)
- error (EXIT_FAILURE, 0,
- _("\
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0,
+ false,
+ xasprintf (_("\
two different charsets \"%s\" and \"%s\" in input file"),
- canon_from_code, canon_charset);
+ canon_from_code, canon_charset));
}
freesa (charset);
@@ -360,7 +364,8 @@ two different charsets \"%s\" and \"%s\" in input file"),
if (is_ascii_message_list (mlp))
canon_from_code = po_charset_ascii;
else
- error (EXIT_FAILURE, 0, _("\
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ _("\
input file doesn't contain a header entry with a charset specification"));
}
@@ -380,10 +385,12 @@ input file doesn't contain a header entry with a charset specification"));
# endif
cd = iconv_open (canon_to_code, canon_from_code);
if (cd == (iconv_t)(-1))
- error (EXIT_FAILURE, 0, _("\
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf (_("\
Cannot convert from \"%s\" to \"%s\". %s relies on iconv(), \
and iconv() does not support this conversion."),
- canon_from_code, canon_to_code, basename (program_name));
+ canon_from_code, canon_to_code,
+ basename (program_name)));
context.from_code = canon_from_code;
context.to_code = canon_to_code;
@@ -396,6 +403,7 @@ and iconv() does not support this conversion."),
if (!is_ascii_string (mp->msgid))
msgids_changed = true;
+ context.message = mp;
convert_string_list (cd, mp->comment, &context);
convert_string_list (cd, mp->comment_dot, &context);
convert_msgid (cd, mp, &context);
@@ -406,15 +414,18 @@ and iconv() does not support this conversion."),
if (msgids_changed)
if (message_list_msgids_changed (mlp))
- error (EXIT_FAILURE, 0, _("\
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf (_("\
Conversion from \"%s\" to \"%s\" introduces duplicates: \
some different msgids become equal."),
- canon_from_code, canon_to_code);
+ canon_from_code, canon_to_code));
#else
- error (EXIT_FAILURE, 0, _("\
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf (_("\
Cannot convert from \"%s\" to \"%s\". %s relies on iconv(). \
This version was built without iconv()."),
- canon_from_code, canon_to_code, basename (program_name));
+ canon_from_code, canon_to_code,
+ basename (program_name));
#endif
}
}
@@ -430,9 +441,10 @@ iconv_msgdomain_list (msgdomain_list_ty *mdlp,
/* Canonicalize target encoding. */
canon_to_code = po_charset_canonicalize (to_code);
if (canon_to_code == NULL)
- error (EXIT_FAILURE, 0,
- _("target charset \"%s\" is not a portable encoding name."),
- to_code);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf (_("\
+target charset \"%s\" is not a portable encoding name."),
+ to_code));
for (k = 0; k < mdlp->nitems; k++)
iconv_message_list (mdlp->item[k]->messages, mdlp->encoding, canon_to_code,
diff --git a/gettext-tools/src/msgl-iconv.h b/gettext-tools/src/msgl-iconv.h
index 14f549b..6d4a361 100644
--- a/gettext-tools/src/msgl-iconv.h
+++ b/gettext-tools/src/msgl-iconv.h
@@ -39,6 +39,7 @@ struct conversion_context
const char *from_code; /* canonicalized encoding name for input */
const char *to_code; /* canonicalized encoding name for output */
const char *from_filename; /* file name where the input comes from */
+ const message_ty *message; /* message being converted, or NULL */
};
/* Converts the STRING through the conversion descriptor CD. */
diff --git a/gettext-tools/src/msgmerge.c b/gettext-tools/src/msgmerge.c
index 89d1d3e..0e45221 100644
--- a/gettext-tools/src/msgmerge.c
+++ b/gettext-tools/src/msgmerge.c
@@ -964,6 +964,7 @@ match_domain (const char *fn1, const char *fn2,
{
po_gram_error_at_line (&refmsg->pos, _("\
this message is used but not defined..."));
+ error_message_count--;
po_gram_error_at_line (&defmsg->pos, _("\
...but this definition is similar"));
}
diff --git a/gettext-tools/src/open-po.c b/gettext-tools/src/open-po.c
index 29c2199..079954b 100644
--- a/gettext-tools/src/open-po.c
+++ b/gettext-tools/src/open-po.c
@@ -1,5 +1,5 @@
/* open-po - search for .po file along search path list and open for reading
- Copyright (C) 1995-1996, 2000-2003 Free Software Foundation, Inc.
+ Copyright (C) 1995-1996, 2000-2003, 2005 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, April 1995.
This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,8 @@
#include "dir-list.h"
#include "pathname.h"
#include "xalloc.h"
-#include "error.h"
+#include "xerror.h"
+#include "po-xerror.h"
#include "gettext.h"
#define _(str) gettext (str)
@@ -114,8 +115,14 @@ open_po_file (const char *input_name, char **real_file_name_p,
FILE *fp = try_open_po_file (input_name, real_file_name_p);
if (fp == NULL && exit_on_error)
- error (EXIT_FAILURE, errno,
- _("error while opening \"%s\" for reading"), *real_file_name_p);
+ {
+ const char *errno_description = strerror (errno);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf ("%s: %s",
+ xasprintf (_("error while opening \"%s\" for reading"),
+ *real_file_name_p),
+ errno_description));
+ }
return fp;
}
diff --git a/gettext-tools/src/po-charset.c b/gettext-tools/src/po-charset.c
index 81759c3..cff5826 100644
--- a/gettext-tools/src/po-charset.c
+++ b/gettext-tools/src/po-charset.c
@@ -30,7 +30,7 @@
#include "xallocsa.h"
#include "xerror.h"
-#include "po-error.h"
+#include "po-xerror.h"
#include "basename.h"
#include "progname.h"
#include "strstr.h"
@@ -223,11 +223,17 @@ po_lex_charset_set (const char *header_entry, const char *filename)
if (!(filenamelen >= 4
&& memcmp (filename + filenamelen - 4, ".pot", 4) == 0
&& strcmp (charset, "CHARSET") == 0))
- po_multiline_warning (xasprintf (_("%s: warning: "), filename),
- xasprintf (_("\
+ {
+ char *warning_message =
+ xasprintf (_("\
Charset \"%s\" is not a portable encoding name.\n\
Message conversion to user's charset might not work.\n"),
- charset));
+ charset);
+ po_xerror (PO_SEVERITY_WARNING, NULL,
+ filename, (size_t)(-1), (size_t)(-1), true,
+ warning_message);
+ free (warning_message);
+ }
}
else
{
@@ -280,7 +286,25 @@ Message conversion to user's charset might not work.\n"),
po_lex_iconv = iconv_open ("UTF-8", po_lex_charset);
if (po_lex_iconv == (iconv_t)(-1))
{
+ char *warning_message;
+ const char *recommendation;
const char *note;
+ char *whole_message;
+
+ warning_message =
+ xasprintf (_("\
+Charset \"%s\" is not supported. %s relies on iconv(),\n\
+and iconv() does not support \"%s\".\n"),
+ po_lex_charset, basename (program_name),
+ po_lex_charset);
+
+# if !defined _LIBICONV_VERSION
+ recommendation = _("\
+Installing GNU libiconv and then reinstalling GNU gettext\n\
+would fix this problem.\n");
+# else
+ recommendation = "";
+# endif
/* Test for a charset which has double-byte characters
ending in 0x5C. For these encodings, the string parser
@@ -293,22 +317,16 @@ Message conversion to user's charset might not work.\n"),
else
note = _("Continuing anyway.");
- po_multiline_warning (xasprintf (_("%s: warning: "), filename),
- xasprintf (_("\
-Charset \"%s\" is not supported. %s relies on iconv(),\n\
-and iconv() does not support \"%s\".\n"),
- po_lex_charset,
- basename (program_name),
- po_lex_charset));
+ whole_message =
+ xasprintf ("%s%s%s\n",
+ warning_message, recommendation, note);
-# if !defined _LIBICONV_VERSION
- po_multiline_warning (NULL,
- xasprintf (_("\
-Installing GNU libiconv and then reinstalling GNU gettext\n\
-would fix this problem.\n")));
-# endif
+ po_xerror (PO_SEVERITY_WARNING, NULL,
+ filename, (size_t)(-1), (size_t)(-1), true,
+ whole_message);
- po_multiline_warning (NULL, xasprintf (_("%s\n"), note));
+ free (whole_message);
+ free (warning_message);
}
#else
/* Test for a charset which has double-byte characters
@@ -318,22 +336,33 @@ would fix this problem.\n")));
po_lex_weird_cjk = po_is_charset_weird_cjk (po_lex_charset);
if (po_is_charset_weird (po_lex_charset) && !po_lex_weird_cjk)
{
- const char *note =
- _("Continuing anyway, expect parse errors.");
+ char *warning_message;
+ const char *recommendation;
+ const char *note;
+ char *whole_message;
- po_multiline_warning (xasprintf (_("%s: warning: "), filename),
- xasprintf (_("\
+ warning_message =
+ xasprintf (_("\
Charset \"%s\" is not supported. %s relies on iconv().\n\
This version was built without iconv().\n"),
- po_lex_charset,
- basename (program_name)));
+ po_lex_charset, basename (program_name));
- po_multiline_warning (NULL,
- xasprintf (_("\
+ recommendation = _("\
Installing GNU libiconv and then reinstalling GNU gettext\n\
-would fix this problem.\n")));
+would fix this problem.\n");
+
+ note = _("Continuing anyway, expect parse errors.");
+
+ whole_message =
+ xasprintf ("%s%s%s\n",
+ warning_message, recommendation, note);
+
+ po_xerror (PO_SEVERITY_WARNING, NULL,
+ filename, (size_t)(-1), (size_t)(-1), true,
+ whole_message);
- po_multiline_warning (NULL, xasprintf (_("%s\n"), note));
+ free (whole_message);
+ free (warning_message);
}
#endif
}
@@ -348,10 +377,11 @@ would fix this problem.\n")));
if (!(filenamelen >= 4
&& memcmp (filename + filenamelen - 4, ".pot", 4) == 0))
- po_multiline_warning (xasprintf (_("%s: warning: "), filename),
- xasprintf (_("\
+ po_xerror (PO_SEVERITY_WARNING,
+ NULL, filename, (size_t)(-1), (size_t)(-1), true,
+ _("\
Charset missing in header.\n\
-Message conversion to user's charset will not work.\n")));
+Message conversion to user's charset will not work.\n"));
}
}
diff --git a/gettext-tools/src/po-lex.c b/gettext-tools/src/po-lex.c
index 6a4fee8..9fc38b5 100644
--- a/gettext-tools/src/po-lex.c
+++ b/gettext-tools/src/po-lex.c
@@ -46,6 +46,9 @@
#include "exit.h"
#include "error.h"
#include "error-progname.h"
+#include "xerror.h"
+#include "po-error.h"
+#include "po-xerror.h"
#include "pos.h"
#include "str-list.h"
#include "po-gram-gen2.h"
@@ -70,13 +73,6 @@ int gram_pos_column;
/* Error handling during the parsing of a PO file.
These functions can access gram_pos and gram_pos_column. */
-#if !(__STDC__ && \
- ((defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __DECC) \
- || (defined __GNUC__ && __GNUC__ >= 2 && !(__APPLE_CC__ > 1))))
-
-/* CAUTION: If you change this function, you must also make identical
- changes to the macro of the same name in src/po-lex.h */
-
/* VARARGS1 */
void
po_gram_error (const char *fmt, ...)
@@ -88,24 +84,14 @@ po_gram_error (const char *fmt, ...)
if (vasprintf (&buffer, fmt, ap) < 0)
error (EXIT_FAILURE, 0, _("memory exhausted"));
va_end (ap);
- error_with_progname = false;
- po_error (0, 0, "%s:%lu:%d: %s", gram_pos.file_name,
- (unsigned long) gram_pos.line_number, gram_pos_column + 1, buffer);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, NULL, gram_pos.file_name, gram_pos.line_number,
+ gram_pos_column + 1, false, buffer);
free (buffer);
- /* Some messages need more than one line. Continuation lines are
- indicated by using "..." at the start of the string. We don't
- increment the error counter for these continuation lines. */
- if (*fmt == '.')
- --error_message_count;
- else if (error_message_count >= gram_max_allowed_errors)
+ if (error_message_count >= gram_max_allowed_errors)
po_error (EXIT_FAILURE, 0, _("too many errors, aborting"));
}
-/* CAUTION: If you change this function, you must also make identical
- changes to the macro of the same name in src/po-lex.h */
-
/* VARARGS2 */
void
po_gram_error_at_line (const lex_pos_ty *pp, const char *fmt, ...)
@@ -117,23 +103,14 @@ po_gram_error_at_line (const lex_pos_ty *pp, const char *fmt, ...)
if (vasprintf (&buffer, fmt, ap) < 0)
error (EXIT_FAILURE, 0, _("memory exhausted"));
va_end (ap);
- error_with_progname = false;
- po_error_at_line (0, 0, pp->file_name, pp->line_number, "%s", buffer);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, NULL, pp->file_name, pp->line_number,
+ (size_t)(-1), false, buffer);
free (buffer);
- /* Some messages need more than one line, or more than one location.
- Continuation lines are indicated by using "..." at the start of the
- string. We don't increment the error counter for these
- continuation lines. */
- if (*fmt == '.')
- --error_message_count;
- else if (error_message_count >= gram_max_allowed_errors)
+ if (error_message_count >= gram_max_allowed_errors)
po_error (EXIT_FAILURE, 0, _("too many errors, aborting"));
}
-#endif
-
/* The lowest level of PO file parsing converts bytes to multibyte characters.
This is needed
@@ -505,7 +482,13 @@ incomplete multibyte sequence at end of line"));
}
}
else
- po_error (EXIT_FAILURE, errno, _("iconv failure"));
+ {
+ const char *errno_description = strerror (errno);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf ("%s: %s",
+ _("iconv failure"),
+ errno_description));
+ }
}
else
{
@@ -665,10 +648,14 @@ lex_getc (mbchar_t mbc)
if (mb_iseof (mbc))
{
if (ferror (mbf->fp))
+ bomb:
{
- bomb:
- po_error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
- gram_pos.file_name);
+ const char *errno_description = strerror (errno);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf ("%s: %s",
+ xasprintf (_("error while reading \"%s\""),
+ gram_pos.file_name),
+ errno_description));
}
break;
}
diff --git a/gettext-tools/src/po-lex.h b/gettext-tools/src/po-lex.h
index 185a24c..17adace 100644
--- a/gettext-tools/src/po-lex.h
+++ b/gettext-tools/src/po-lex.h
@@ -26,7 +26,6 @@
#include "error.h"
#include "error-progname.h"
#include "xerror.h"
-#include "po-error.h"
#include "pos.h"
@@ -70,83 +69,8 @@ extern void po_lex_pass_comments (bool flag);
Switch this on or off. */
extern void po_lex_pass_obsolete_entries (bool flag);
-
-/* ISO C 99 is smart enough to allow optimizations like this.
- Note: OpenVMS 7.3 cc pretends to support ISO C 99 but chokes on '...'. */
-#if __STDC__ && (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __DECC)
-
-/* CAUTION: If you change this macro, you must also make identical
- changes to the function of the same name in src/po-lex.c */
-
-# define po_gram_error(fmt, ...) \
- do { \
- char *totalfmt = xasprintf ("%s%s", "%s:%lu:%d: ", fmt); \
- error_with_progname = false; \
- po_error (0, 0, totalfmt, gram_pos.file_name, \
- (unsigned long) gram_pos.line_number, gram_pos_column + 1, \
- __VA_ARGS__ + 0); \
- error_with_progname = true; \
- free (totalfmt); \
- if (*fmt == '.') \
- --error_message_count; \
- else if (error_message_count >= gram_max_allowed_errors) \
- po_error (1, 0, _("too many errors, aborting")); \
- } while (0)
-
-/* CAUTION: If you change this macro, you must also make identical
- changes to the function of the same name in src/po-lex.c */
-
-# define po_gram_error_at_line(pos, fmt, ...) \
- do { \
- error_with_progname = false; \
- po_error_at_line (0, 0, (pos)->file_name, (pos)->line_number, \
- fmt, __VA_ARGS__ + 0); \
- error_with_progname = true; \
- if (*fmt == '.') \
- --error_message_count; \
- else if (error_message_count >= gram_max_allowed_errors) \
- po_error (1, 0, _("too many errors, aborting")); \
- } while (0)
-
-/* GCC is also smart enough to allow optimizations like this. */
-#elif __STDC__ && defined __GNUC__ && __GNUC__ >= 2 && !(__APPLE_CC__ > 1)
-
-/* CAUTION: If you change this macro, you must also make identical
- changes to the function of the same name in src/po-lex.c */
-
-# define po_gram_error(fmt, args...) \
- do { \
- char *totalfmt = xasprintf ("%s%s", "%s:%d:%d: ", fmt); \
- error_with_progname = false; \
- po_error (0, 0, totalfmt, gram_pos.file_name, gram_pos.line_number, \
- gram_pos_column + 1 , ## args); \
- error_with_progname = true; \
- free (totalfmt); \
- if (*fmt == '.') \
- --error_message_count; \
- else if (error_message_count >= gram_max_allowed_errors) \
- po_error (1, 0, _("too many errors, aborting")); \
- } while (0)
-
-/* CAUTION: If you change this macro, you must also make identical
- changes to the function of the same name in src/po-lex.c */
-
-# define po_gram_error_at_line(pos, fmt, args...) \
- do { \
- error_with_progname = false; \
- po_error_at_line (0, 0, (pos)->file_name, (pos)->line_number, \
- fmt , ## args); \
- error_with_progname = true; \
- if (*fmt == '.') \
- --error_message_count; \
- else if (error_message_count >= gram_max_allowed_errors) \
- po_error (1, 0, _("too many errors, aborting")); \
- } while (0)
-
-#else
extern void po_gram_error (const char *fmt, ...);
extern void po_gram_error_at_line (const lex_pos_ty *pos, const char *fmt, ...);
-#endif
/* Contains information about the definition of one translation. */
diff --git a/gettext-tools/src/po-xerror.c b/gettext-tools/src/po-xerror.c
new file mode 100644
index 0000000..0e5de27
--- /dev/null
+++ b/gettext-tools/src/po-xerror.c
@@ -0,0 +1,199 @@
+/* Error handling during reading and writing of PO files.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2005.
+
+ This program 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 2, or (at your option)
+ any later version.
+
+ This program 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, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Specification. */
+#include "po-xerror.h"
+
+#include <error.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "exit.h"
+#include "message.h"
+#include "progname.h"
+#include "error-progname.h"
+#include "xalloc.h"
+#include "xerror.h"
+#include "po-error.h"
+#include "gettext.h"
+
+#define _(str) gettext (str)
+
+
+static void
+xerror (int severity, const char *prefix_tail,
+ const char *filename, size_t lineno, size_t column,
+ int multiline_p, const char *message_text)
+{
+ if (multiline_p)
+ {
+ bool old_error_with_progname = error_with_progname;
+ char *prefix;
+
+ if (filename != NULL)
+ {
+ if (lineno != (size_t)(-1))
+ {
+ if (column != (size_t)(-1))
+ prefix =
+ xasprintf ("%s:%ld:%ld: %s", filename,
+ (long) lineno, (long) column, prefix_tail);
+ else
+ prefix =
+ xasprintf ("%s:%ld: %s", filename,
+ (long) lineno, prefix_tail);
+ }
+ else
+ prefix = xasprintf ("%s: %s", filename, prefix_tail);
+ error_with_progname = false;
+ }
+ else
+ prefix = xasprintf ("%s: %s", program_name, prefix_tail);
+
+ if (severity >= PO_SEVERITY_ERROR)
+ po_multiline_error (prefix, xstrdup (message_text));
+ else
+ po_multiline_warning (prefix, xstrdup (message_text));
+ error_with_progname = old_error_with_progname;
+
+ if (severity == PO_SEVERITY_FATAL_ERROR)
+ exit (EXIT_FAILURE);
+ }
+ else
+ {
+ int exit_status =
+ (severity == PO_SEVERITY_FATAL_ERROR ? EXIT_FAILURE : 0);
+
+ if (filename != NULL)
+ {
+ error_with_progname = false;
+ if (lineno != (size_t)(-1))
+ {
+ if (column != (size_t)(-1))
+ po_error (exit_status, 0, "%s:%ld:%ld: %s%s",
+ filename, (long) lineno, (long) column,
+ prefix_tail, message_text);
+ else
+ po_error_at_line (exit_status, 0, filename, lineno, "%s%s",
+ prefix_tail, message_text);
+ }
+ else
+ po_error (exit_status, 0, "%s: %s%s",
+ filename, prefix_tail, message_text);
+ error_with_progname = true;
+ }
+ else
+ po_error (exit_status, 0, "%s%s", prefix_tail, message_text);
+ if (severity < PO_SEVERITY_ERROR)
+ --error_message_count;
+ }
+}
+
+/* The default error handler is based on the lower-level error handler
+ in po-error.h, so that gettext-po.h can offer to override one or the
+ other. */
+void
+textmode_xerror (int severity,
+ const struct message_ty *message,
+ const char *filename, size_t lineno, size_t column,
+ int multiline_p, const char *message_text)
+{
+ const char *prefix_tail =
+ (severity == PO_SEVERITY_WARNING ? _("warning: ") : "");
+
+ if (message != NULL && (filename == NULL || lineno == (size_t)(-1)))
+ {
+ filename = message->pos.file_name;
+ lineno = message->pos.line_number;
+ column = (size_t)(-1);
+ }
+
+ xerror (severity, prefix_tail, filename, lineno, column,
+ multiline_p, message_text);
+}
+
+void
+textmode_xerror2 (int severity,
+ const struct message_ty *message1,
+ const char *filename1, size_t lineno1, size_t column1,
+ int multiline_p1, const char *message_text1,
+ const struct message_ty *message2,
+ const char *filename2, size_t lineno2, size_t column2,
+ int multiline_p2, const char *message_text2)
+{
+ int severity1 = /* Don't exit before both texts have been output. */
+ (severity == PO_SEVERITY_FATAL_ERROR ? PO_SEVERITY_ERROR : severity);
+ const char *prefix_tail =
+ (severity == PO_SEVERITY_WARNING ? _("warning: ") : "");
+
+ if (message1 != NULL && (filename1 == NULL || lineno1 == (size_t)(-1)))
+ {
+ filename1 = message1->pos.file_name;
+ lineno1 = message1->pos.line_number;
+ column1 = (size_t)(-1);
+ }
+
+ if (message2 != NULL && (filename2 == NULL || lineno2 == (size_t)(-1)))
+ {
+ filename2 = message2->pos.file_name;
+ lineno2 = message2->pos.line_number;
+ column2 = (size_t)(-1);
+ }
+
+ if (multiline_p1)
+ xerror (severity1, prefix_tail, filename1, lineno1, column1, multiline_p1,
+ message_text1);
+ else
+ {
+ char *message_text1_extended = xasprintf ("%s...", message_text1);
+ xerror (severity1, prefix_tail, filename1, lineno1, column1,
+ multiline_p1, message_text1_extended);
+ free (message_text1_extended);
+ }
+
+ {
+ char *message_text2_extended = xasprintf ("...%s", message_text2);
+ xerror (severity, prefix_tail, filename2, lineno2, column2,
+ multiline_p2, message_text2_extended);
+ free (message_text2_extended);
+ }
+
+ if (severity >= PO_SEVERITY_ERROR)
+ /* error_message_count needs to be incremented only by 1, not by 2. */
+ --error_message_count;
+}
+
+void (*po_xerror) (int severity,
+ const struct message_ty *message,
+ const char *filename, size_t lineno, size_t column,
+ int multiline_p, const char *message_text)
+ = textmode_xerror;
+
+void (*po_xerror2) (int severity,
+ const struct message_ty *message1,
+ const char *filename1, size_t lineno1, size_t column1,
+ int multiline_p1, const char *message_text1,
+ const struct message_ty *message2,
+ const char *filename2, size_t lineno2, size_t column2,
+ int multiline_p2, const char *message_text2)
+ = textmode_xerror2;
diff --git a/gettext-tools/src/po-xerror.h b/gettext-tools/src/po-xerror.h
new file mode 100644
index 0000000..03a3438
--- /dev/null
+++ b/gettext-tools/src/po-xerror.h
@@ -0,0 +1,83 @@
+/* Error handling during reading and writing of PO files.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2005.
+
+ This program 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 2, or (at your option)
+ any later version.
+
+ This program 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, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _PO_XERROR_H
+#define _PO_XERROR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+struct message_ty;
+
+
+/* A higher-level error handler than the one in po-error.h. */
+
+/* These values must be the same as those in gettext-po.h. */
+#define PO_SEVERITY_WARNING 0 /* just a warning, tell the user */
+#define PO_SEVERITY_ERROR 1 /* an error, the operation cannot complete */
+#define PO_SEVERITY_FATAL_ERROR 2 /* an error, the operation must be aborted */
+
+/* Signal a problem of the given severity.
+ MESSAGE and/or FILENAME + LINENO indicate where the problem occurred.
+ If FILENAME is NULL, FILENAME and LINENO and COLUMN should be ignored.
+ If LINENO is (size_t)(-1), LINENO and COLUMN should be ignored.
+ If COLUMN is (size_t)(-1), it should be ignored.
+ MESSAGE_TEXT is the problem description (if MULTILINE_P is true,
+ multiple lines of text, each terminated with a newline, otherwise
+ usually a single line).
+ Must not return if SEVERITY is PO_SEVERITY_FATAL_ERROR. */
+extern DLL_VARIABLE
+ void (*po_xerror) (int severity,
+ const struct message_ty *message,
+ const char *filename, size_t lineno, size_t column,
+ int multiline_p, const char *message_text);
+
+/* Signal a problem that refers to two messages.
+ Similar to two calls to po_xerror.
+ If possible, a "..." can be appended to MESSAGE_TEXT1 and prepended to
+ MESSAGE_TEXT2. */
+extern DLL_VARIABLE
+ void (*po_xerror2) (int severity,
+ const struct message_ty *message1,
+ const char *filename1, size_t lineno1, size_t column1,
+ int multiline_p1, const char *message_text1,
+ const struct message_ty *message2,
+ const char *filename2, size_t lineno2, size_t column2,
+ int multiline_p2, const char *message_text2);
+
+/* The default error handler. */
+extern void textmode_xerror (int severity,
+ const struct message_ty *message,
+ const char *filename, size_t lineno, size_t column,
+ int multiline_p, const char *message_text);
+extern void textmode_xerror2 (int severity,
+ const struct message_ty *message1,
+ const char *filename1, size_t lineno1, size_t column1,
+ int multiline_p1, const char *message_text1,
+ const struct message_ty *message2,
+ const char *filename2, size_t lineno2, size_t column2,
+ int multiline_p2, const char *message_text2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PO_XERROR_H */
diff --git a/gettext-tools/src/read-po-abstract.c b/gettext-tools/src/read-po-abstract.c
index 29f0573..bb99740 100644
--- a/gettext-tools/src/read-po-abstract.c
+++ b/gettext-tools/src/read-po-abstract.c
@@ -32,6 +32,8 @@
#include "read-properties.h"
#include "read-stringtable.h"
#include "xalloc.h"
+#include "xerror.h"
+#include "po-xerror.h"
#include "gettext.h"
/* Local variables. */
@@ -187,10 +189,12 @@ po_scan (abstract_po_reader_ty *pop, FILE *fp,
}
if (error_message_count > 0)
- po_error (EXIT_FAILURE, 0,
- ngettext ("found %d fatal error", "found %d fatal errors",
- error_message_count),
- error_message_count);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL,
+ /*real_filename*/ NULL, (size_t)(-1), (size_t)(-1), false,
+ xasprintf (ngettext ("found %d fatal error",
+ "found %d fatal errors",
+ error_message_count),
+ error_message_count));
error_message_count = 0;
}
diff --git a/gettext-tools/src/read-po.c b/gettext-tools/src/read-po.c
index 84a2001..4b37081 100644
--- a/gettext-tools/src/read-po.c
+++ b/gettext-tools/src/read-po.c
@@ -1,5 +1,5 @@
/* Reading PO files.
- Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2003, 2005 Free Software Foundation, Inc.
This file was written by Peter Miller <millerp@canb.auug.org.au>
This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,7 @@
#include "open-po.h"
#include "po-charset.h"
+#include "po-xerror.h"
#include "xalloc.h"
#include "gettext.h"
@@ -354,9 +355,11 @@ default_add_message (default_po_reader_ty *this,
translations are equal or different. This is for consistency
with msgmerge, msgcat and others. The user can use the
msguniq program to get rid of duplicates. */
- po_gram_error_at_line (msgid_pos, _("duplicate message definition"));
- po_gram_error_at_line (&mp->pos, _("\
-...this is the location of the first definition"));
+ po_xerror2 (PO_SEVERITY_ERROR,
+ NULL, msgid_pos->file_name, msgid_pos->line_number,
+ (size_t)(-1), false, _("duplicate message definition"),
+ mp, NULL, 0, 0, false,
+ _("this is the location of the first definition"));
}
/* We don't need the just constructed entries' parameter string
(allocated in po-gram-gen.y). */
diff --git a/gettext-tools/src/read-properties.c b/gettext-tools/src/read-properties.c
index 3a110a8..4e22d9e 100644
--- a/gettext-tools/src/read-properties.c
+++ b/gettext-tools/src/read-properties.c
@@ -1,5 +1,5 @@
/* Reading Java .properties files.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2003.
This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,8 @@
#include "message.h"
#include "read-po-abstract.h"
#include "xalloc.h"
-#include "exit.h"
+#include "xerror.h"
+#include "po-xerror.h"
#include "msgl-ascii.h"
#include "utf16-ucs4.h"
#include "ucs4-utf8.h"
@@ -77,8 +78,14 @@ phase1_getc ()
if (c == EOF)
{
if (ferror (fp))
- error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
- real_file_name);
+ {
+ const char *errno_description = strerror (errno);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf ("%s: %s",
+ xasprintf (_("error while reading \"%s\""),
+ real_file_name),
+ errno_description));
+ }
return EOF;
}
@@ -211,10 +218,9 @@ phase4_getuc ()
else
{
phase3_ungetc (c1);
- error_with_progname = false;
- error (0, 0, _("%s:%lu: warning: invalid \\uxxxx syntax for Unicode character"),
- real_file_name, (unsigned long) gram_pos.line_number);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, NULL,
+ real_file_name, gram_pos.line_number, (size_t)(-1),
+ false, _("warning: invalid \\uxxxx syntax for Unicode character"));
return 'u';
}
}
diff --git a/gettext-tools/src/read-stringtable.c b/gettext-tools/src/read-stringtable.c
index c841c49..081e582 100644
--- a/gettext-tools/src/read-stringtable.c
+++ b/gettext-tools/src/read-stringtable.c
@@ -34,7 +34,8 @@
#include "error-progname.h"
#include "read-po-abstract.h"
#include "xalloc.h"
-#include "exit.h"
+#include "xerror.h"
+#include "po-xerror.h"
#include "utf8-ucs4.h"
#include "ucs4-utf8.h"
#include "gettext.h"
@@ -92,8 +93,14 @@ phase1_getc ()
if (c == EOF)
{
if (ferror (fp))
- error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
- real_file_name);
+ {
+ const char *errno_description = strerror (errno);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf ("%s: %s",
+ xasprintf (_("error while reading \"%s\""),
+ real_file_name),
+ errno_description));
+ }
return EOF;
}
@@ -792,23 +799,17 @@ read_string (lex_pos_ty *pos)
buffer[buflen++] = c;
}
if (c == UEOF)
- {
- error_with_progname = false;
- error (0, 0, _("%s:%lu: warning: unterminated string"),
- real_file_name, (unsigned long) gram_pos.line_number);
- error_with_progname = true;
- }
+ po_xerror (PO_SEVERITY_ERROR, NULL,
+ real_file_name, gram_pos.line_number, (size_t)(-1), false,
+ _("warning: unterminated string"));
}
else
{
/* Read a token outside quotes. */
if (is_quotable (c))
- {
- error_with_progname = false;
- error (0, 0, _("%s:%lu: warning: syntax error"),
- real_file_name, (unsigned long) gram_pos.line_number);
- error_with_progname = true;
- }
+ po_xerror (PO_SEVERITY_ERROR, NULL,
+ real_file_name, gram_pos.line_number, (size_t)(-1), false,
+ _("warning: syntax error"));
for (; c != UEOF && !is_quotable (c); c = phase4_getc ())
{
if (buflen >= bufmax)
@@ -867,10 +868,9 @@ stringtable_parse (abstract_po_reader_ty *pop, FILE *file,
/* Expect a '=' or ';'. */
if (c == UEOF)
{
- error_with_progname = false;
- error (0, 0, _("%s:%lu: warning: unterminated key/value pair"),
- real_file_name, (unsigned long) gram_pos.line_number);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, NULL,
+ real_file_name, gram_pos.line_number, (size_t)(-1), false,
+ _("warning: unterminated key/value pair"));
break;
}
if (c == ';')
@@ -889,10 +889,9 @@ stringtable_parse (abstract_po_reader_ty *pop, FILE *file,
msgstr = read_string (&msgstr_pos);
if (msgstr == NULL)
{
- error_with_progname = false;
- error (0, 0, _("%s:%lu: warning: unterminated key/value pair"),
- real_file_name, (unsigned long) gram_pos.line_number);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, NULL,
+ real_file_name, gram_pos.line_number, (size_t)(-1),
+ false, _("warning: unterminated key/value pair"));
break;
}
@@ -935,21 +934,19 @@ stringtable_parse (abstract_po_reader_ty *pop, FILE *file,
}
else
{
- error_with_progname = false;
- error (0, 0, _("\
-%s:%lu: warning: syntax error, expected ';' after string"),
- real_file_name, (unsigned long) gram_pos.line_number);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, NULL,
+ real_file_name, gram_pos.line_number, (size_t)(-1),
+ false, _("\
+warning: syntax error, expected ';' after string"));
break;
}
}
else
{
- error_with_progname = false;
- error (0, 0, _("\
-%s:%lu: warning: syntax error, expected '=' or ';' after string"),
- real_file_name, (unsigned long) gram_pos.line_number);
- error_with_progname = true;
+ po_xerror (PO_SEVERITY_ERROR, NULL,
+ real_file_name, gram_pos.line_number, (size_t)(-1), false,
+ _("\
+warning: syntax error, expected '=' or ';' after string"));
break;
}
}
diff --git a/gettext-tools/src/write-po.c b/gettext-tools/src/write-po.c
index cebfd6a..b1a0b56 100644
--- a/gettext-tools/src/write-po.c
+++ b/gettext-tools/src/write-po.c
@@ -45,10 +45,9 @@
#include "xallocsa.h"
#include "strstr.h"
#include "fwriteerror.h"
-#include "exit.h"
#include "error-progname.h"
#include "xerror.h"
-#include "po-error.h"
+#include "po-xerror.h"
#include "gettext.h"
/* Our regular abbreviation. */
@@ -419,8 +418,9 @@ memcpy_small (void *dst, const void *src, size_t n)
static void
-wrap (FILE *fp, const char *line_prefix, const char *name, const char *value,
- enum is_wrap do_wrap, const char *charset)
+wrap (const message_ty *mp, FILE *fp, const char *line_prefix,
+ const char *name, const char *value, enum is_wrap do_wrap,
+ const char *charset)
{
const char *canon_charset;
const char *s;
@@ -550,7 +550,8 @@ wrap (FILE *fp, const char *line_prefix, const char *name, const char *value,
{
if (errno == EILSEQ)
{
- po_error (0, 0, _("invalid multibyte sequence"));
+ po_xerror (PO_SEVERITY_ERROR, mp, NULL, 0, 0, false,
+ _("invalid multibyte sequence"));
continue;
}
else
@@ -603,9 +604,15 @@ wrap (FILE *fp, const char *line_prefix, const char *name, const char *value,
/* We warn about any use of escape sequences beside
'\n' and '\t'. */
if (c != 'n' && c != 't')
- po_error (0, 0, _("\
+ {
+ char *error_message =
+ xasprintf (_("\
internationalized messages should not contain the `\\%c' escape sequence"),
- c);
+ c);
+ po_xerror (PO_SEVERITY_ERROR, mp, NULL, 0, 0, false,
+ error_message);
+ free (error_message);
+ }
}
else if (escape && !c_isprint ((unsigned char) c))
{
@@ -658,7 +665,8 @@ internationalized messages should not contain the `\\%c' escape sequence"),
{
if (errno == EILSEQ)
{
- po_error (0, 0, _("invalid multibyte sequence"));
+ po_xerror (PO_SEVERITY_ERROR, mp, NULL, 0, 0,
+ false, _("invalid multibyte sequence"));
continue;
}
else
@@ -848,18 +856,22 @@ message_print (const message_ty *mp, FILE *fp, const char *charset,
this domain, emit an empty string. */
if (!is_ascii_string (mp->msgid)
&& po_charset_canonicalize (charset) != po_charset_utf8)
- po_multiline_warning (xasprintf (_("warning: ")),
- xasprintf (_("\
+ {
+ char *warning_message =
+ xasprintf (_("\
The following msgid contains non-ASCII characters.\n\
This will cause problems to translators who use a character encoding\n\
different from yours. Consider using a pure ASCII msgid instead.\n\
-%s\n"), mp->msgid));
- wrap (fp, NULL, "msgid", mp->msgid, mp->do_wrap, charset);
+%s\n"), mp->msgid);
+ po_xerror (PO_SEVERITY_WARNING, mp, NULL, 0, 0, true, warning_message);
+ free (warning_message);
+ }
+ wrap (mp, fp, NULL, "msgid", mp->msgid, mp->do_wrap, charset);
if (mp->msgid_plural != NULL)
- wrap (fp, NULL, "msgid_plural", mp->msgid_plural, mp->do_wrap, charset);
+ wrap (mp, fp, NULL, "msgid_plural", mp->msgid_plural, mp->do_wrap, charset);
if (mp->msgid_plural == NULL)
- wrap (fp, NULL, "msgstr", mp->msgstr, mp->do_wrap, charset);
+ wrap (mp, fp, NULL, "msgstr", mp->msgstr, mp->do_wrap, charset);
else
{
char prefix_buf[20];
@@ -871,7 +883,7 @@ different from yours. Consider using a pure ASCII msgid instead.\n\
p += strlen (p) + 1, i++)
{
sprintf (prefix_buf, "msgstr[%u]", i);
- wrap (fp, NULL, prefix_buf, p, mp->do_wrap, charset);
+ wrap (mp, fp, NULL, prefix_buf, p, mp->do_wrap, charset);
}
}
}
@@ -914,18 +926,23 @@ message_print_obsolete (const message_ty *mp, FILE *fp, const char *charset,
are as readable as possible. */
if (!is_ascii_string (mp->msgid)
&& po_charset_canonicalize (charset) != po_charset_utf8)
- po_multiline_warning (xasprintf (_("warning: ")),
- xasprintf (_("\
+ {
+ char *warning_message =
+ xasprintf (_("\
The following msgid contains non-ASCII characters.\n\
This will cause problems to translators who use a character encoding\n\
different from yours. Consider using a pure ASCII msgid instead.\n\
-%s\n"), mp->msgid));
- wrap (fp, "#~ ", "msgid", mp->msgid, mp->do_wrap, charset);
+%s\n"), mp->msgid);
+ po_xerror (PO_SEVERITY_WARNING, mp, NULL, 0, 0, true, warning_message);
+ free (warning_message);
+ }
+ wrap (mp, fp, "#~ ", "msgid", mp->msgid, mp->do_wrap, charset);
if (mp->msgid_plural != NULL)
- wrap (fp, "#~ ", "msgid_plural", mp->msgid_plural, mp->do_wrap, charset);
+ wrap (mp, fp, "#~ ", "msgid_plural", mp->msgid_plural, mp->do_wrap,
+ charset);
if (mp->msgid_plural == NULL)
- wrap (fp, "#~ ", "msgstr", mp->msgstr, mp->do_wrap, charset);
+ wrap (mp, fp, "#~ ", "msgstr", mp->msgstr, mp->do_wrap, charset);
else
{
char prefix_buf[20];
@@ -937,7 +954,7 @@ different from yours. Consider using a pure ASCII msgid instead.\n\
p += strlen (p) + 1, i++)
{
sprintf (prefix_buf, "msgstr[%u]", i);
- wrap (fp, "#~ ", prefix_buf, p, mp->do_wrap, charset);
+ wrap (mp, fp, "#~ ", prefix_buf, p, mp->do_wrap, charset);
}
}
}
@@ -1060,9 +1077,11 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename,
if (mdlp->nitems > 1)
{
if (use_syntax_properties)
- po_error (EXIT_FAILURE, 0, _("Cannot output multiple translation domains into a single file with Java .properties syntax. Try using PO file syntax instead."));
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false, _("\
+Cannot output multiple translation domains into a single file with Java .properties syntax. Try using PO file syntax instead."));
if (use_syntax_stringtable)
- po_error (EXIT_FAILURE, 0, _("Cannot output multiple translation domains into a single file with NeXTstep/GNUstep .strings syntax."));
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false, _("\
+Cannot output multiple translation domains into a single file with NeXTstep/GNUstep .strings syntax."));
}
if (mdlp->nitems == 1)
{
@@ -1086,13 +1105,15 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename,
{
error_with_progname = false;
if (use_syntax_properties)
- po_error_at_line (EXIT_FAILURE, 0,
- has_plural->file_name, has_plural->line_number,
- _("message catalog has plural form translations, but the output format does not support them. Try generating a Java class using \"msgfmt --java\", instead of a properties file."));
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL,
+ has_plural->file_name, has_plural->line_number,
+ (size_t)(-1), false, _("\
+message catalog has plural form translations, but the output format does not support them. Try generating a Java class using \"msgfmt --java\", instead of a properties file."));
if (use_syntax_stringtable)
- po_error_at_line (EXIT_FAILURE, 0,
- has_plural->file_name, has_plural->line_number,
- _("message catalog has plural form translations, but the output format does not support them."));
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL,
+ has_plural->file_name, has_plural->line_number,
+ (size_t)(-1), false, _("\
+message catalog has plural form translations, but the output format does not support them."));
error_with_progname = true;
}
}
@@ -1104,8 +1125,14 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename,
{
fp = fopen (filename, "w");
if (fp == NULL)
- po_error (EXIT_FAILURE, errno, _("cannot create output file \"%s\""),
- filename);
+ {
+ const char *errno_description = strerror (errno);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf ("%s: %s",
+ xasprintf (_("cannot create output file \"%s\""),
+ filename),
+ errno_description));
+ }
}
else
{
@@ -1123,8 +1150,14 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename,
/* Make sure nothing went wrong. */
if (fwriteerror (fp))
- po_error (EXIT_FAILURE, errno, _("error while writing \"%s\" file"),
- filename);
+ {
+ const char *errno_description = strerror (errno);
+ po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false,
+ xasprintf ("%s: %s",
+ xasprintf (_("error while writing \"%s\" file"),
+ filename),
+ errno_description));
+ }
}
diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c
index be4d8b3..260577f 100644
--- a/gettext-tools/src/xgettext.c
+++ b/gettext-tools/src/xgettext.c
@@ -1676,6 +1676,7 @@ Please specify the source encoding through --from-code.\n"),
context.from_code = xgettext_current_source_encoding;
context.to_code = po_charset_utf8;
context.from_filename = file_name;
+ context.message = NULL;
string = convert_string (xgettext_current_source_iconv, string, &context);
#else
diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog
index fc88890..aeb2d1c 100644
--- a/gettext-tools/tests/ChangeLog
+++ b/gettext-tools/tests/ChangeLog
@@ -1,3 +1,11 @@
+2005-09-17 Bruno Haible <bruno@clisp.org>
+
+ * msgfmt-7: Update after slight change in error message.
+ * msgfmt-8: Likewise.
+ * msgfmt-9: Likewise.
+ * msgmerge-2: Likewise.
+ * msgmerge-9: Likewise.
+
2005-08-26 Bruno Haible <bruno@clisp.org>
* plural-2: Add test for Romanian plural formula.
diff --git a/gettext-tools/tests/msgfmt-7 b/gettext-tools/tests/msgfmt-7
index 002cf6d..f399d6c 100755
--- a/gettext-tools/tests/msgfmt-7
+++ b/gettext-tools/tests/msgfmt-7
@@ -34,7 +34,7 @@ ${MSGFMT} --verbose --check mf-test7.in1 -o /dev/null \
tmpfiles="$tmpfiles mf-test7.ok"
cat << EOF > mf-test7.ok
-mf-test7.in1:17: duplicate message definition
+mf-test7.in1:17: duplicate message definition...
mf-test7.in1:16: ...this is the location of the first definition
msgfmt: found 1 fatal error
EOF
diff --git a/gettext-tools/tests/msgfmt-8 b/gettext-tools/tests/msgfmt-8
index c5467ed..515ff58 100755
--- a/gettext-tools/tests/msgfmt-8
+++ b/gettext-tools/tests/msgfmt-8
@@ -34,7 +34,7 @@ ${MSGFMT} --verbose --check mf-test8.in1 -o /dev/null \
tmpfiles="$tmpfiles mf-test8.ok"
cat << EOF > mf-test8.ok
-mf-test8.in1:17: duplicate message definition
+mf-test8.in1:17: duplicate message definition...
mf-test8.in1:16: ...this is the location of the first definition
msgfmt: found 1 fatal error
EOF
diff --git a/gettext-tools/tests/msgfmt-9 b/gettext-tools/tests/msgfmt-9
index 1574916..1a897d1 100755
--- a/gettext-tools/tests/msgfmt-9
+++ b/gettext-tools/tests/msgfmt-9
@@ -37,7 +37,7 @@ ${MSGFMT} --verbose --check mf-test9.in1 -o /dev/null \
tmpfiles="$tmpfiles mf-test9.ok"
cat << EOF > mf-test9.ok
-mf-test9.in1:17: duplicate message definition
+mf-test9.in1:17: duplicate message definition...
mf-test9.in1:15: ...this is the location of the first definition
msgfmt: found 1 fatal error
EOF
diff --git a/gettext-tools/tests/msgmerge-2 b/gettext-tools/tests/msgmerge-2
index 9580df5..e79b145 100755
--- a/gettext-tools/tests/msgmerge-2
+++ b/gettext-tools/tests/msgmerge-2
@@ -26,7 +26,7 @@ ${MSGMERGE} -q mm-test2.in1 mm-test2.in2 -o /dev/stdout \
tmpfiles="$tmpfiles mm-test2.ok"
cat << EOF > mm-test2.ok
-mm-test2.in1:3: duplicate message definition
+mm-test2.in1:3: duplicate message definition...
mm-test2.in1:1: ...this is the location of the first definition
msgmerge: found 1 fatal error
EOF
diff --git a/gettext-tools/tests/msgmerge-9 b/gettext-tools/tests/msgmerge-9
index 872dc9f..c2197e9 100755
--- a/gettext-tools/tests/msgmerge-9
+++ b/gettext-tools/tests/msgmerge-9
@@ -29,7 +29,7 @@ ${MSGMERGE} -q mm-test9.in1 mm-test9.in2 -o /dev/null \
tmpfiles="$tmpfiles mm-test9.ok"
cat << EOF > mm-test9.ok
-mm-test9.in1:3: duplicate message definition
+mm-test9.in1:3: duplicate message definition...
mm-test9.in1:1: ...this is the location of the first definition
msgmerge: found 1 fatal error
EOF