Index: ChangeLog =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/ChangeLog,v retrieving revision 1.161 diff -u -u -r1.161 ChangeLog --- ChangeLog 23 Jun 2004 13:29:26 -0000 1.161 +++ ChangeLog 12 Aug 2004 13:07:49 -0000 @@ -1,3 +1,15 @@ +2004-08-12 Ross Golder + + * read-po-abstract.[ch]: Added 'report_error' callback, which + applications can set to obtain parser error messages. + * read-po.[ch]: Implement 'default_report_error' handler, to report + errors using libc 'error(_at_line)' calls, as before. + * po-lex.[ch]: Added hooks into po_gram_error(_at_line) to call + po_callback_report_error. Removed ability to call exit (except on + memory exhaustion) within the parser. + * msgmft.c, x-po.c: Use 'default_report_error' handler for parser + errors, and to exit on fatal error. + 2004-06-23 Bruno Haible * x-c.c (phase1_getc): Fix phase0_getc invocation. Index: read-po-abstract.c =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/read-po-abstract.c,v retrieving revision 1.6 diff -u -u -r1.6 read-po-abstract.c --- read-po-abstract.c 22 Oct 2003 10:49:09 -0000 1.6 +++ read-po-abstract.c 12 Aug 2004 13:07:49 -0000 @@ -134,6 +134,14 @@ } +static inline void +call_report_error (abstract_po_reader_ty *pop, lex_pos_ty *pos, char *s) +{ + if (pop->methods->report_error != NULL) + pop->methods->report_error (pop, pos, s); +} + + /* ========================================================================= */ /* Exported functions. */ @@ -158,11 +166,13 @@ } -void +int po_scan (abstract_po_reader_ty *pop, FILE *fp, const char *real_filename, const char *logical_filename, input_syntax_ty syntax) { + int err_msg_count = 0; + /* Parse the stream's content. */ switch (syntax) { @@ -187,12 +197,9 @@ abort (); } - if (error_message_count > 0) - error (EXIT_FAILURE, 0, - ngettext ("found %d fatal error", "found %d fatal errors", - error_message_count), - error_message_count); + err_msg_count = error_message_count; error_message_count = 0; + return err_msg_count; } @@ -397,3 +404,16 @@ po_callback_comment (s); } } + + +/* Handle errors nicely. By default, does the same as po_gram_error. + Intended to be replaced by calling applications (e.g. GUIs) to + receive the errors into some kind of dialog. */ +void +po_callback_report_error (lex_pos_ty *pos, char *s) +{ + /* assert(callback_arg); */ + call_report_error (callback_arg, pos, s); +} + + Index: read-po-abstract.h =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/read-po-abstract.h,v retrieving revision 1.5 diff -u -u -r1.5 read-po-abstract.h --- read-po-abstract.h 22 Oct 2003 10:49:09 -0000 1.5 +++ read-po-abstract.h 12 Aug 2004 13:07:49 -0000 @@ -103,6 +103,10 @@ special comment. One of the possible uses is to indicate a inexact translation. */ void (*comment_special) (struct abstract_po_reader_ty *pop, const char *s); + + /* How to report parser errors back to the calling program */ + void (*report_error) (struct abstract_po_reader_ty *pop, lex_pos_ty *pos, char *s); + }; @@ -139,8 +143,9 @@ typedef enum input_syntax_ty input_syntax_ty; /* Read a PO file from a stream, and dispatch to the various - abstract_po_reader_class_ty methods. */ -extern void + abstract_po_reader_class_ty methods. Returns the number of errors + encountered */ +extern int po_scan (abstract_po_reader_ty *pop, FILE *fp, const char *real_filename, const char *logical_filename, input_syntax_ty syntax); @@ -164,6 +169,7 @@ extern void po_callback_comment_filepos (const char *s, size_t line); extern void po_callback_comment_special (const char *s); extern void po_callback_comment_dispatcher (const char *s); +extern void po_callback_report_error (lex_pos_ty *pos, char *s); /* Parse a special comment and put the result in *fuzzyp, formatp, *wrapp. */ extern void po_parse_comment_special (const char *s, bool *fuzzyp, Index: read-po.c =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/read-po.c,v retrieving revision 1.8 diff -u -u -r1.8 read-po.c --- read-po.c 22 Oct 2003 10:49:09 -0000 1.8 +++ read-po.c 12 Aug 2004 13:07:49 -0000 @@ -31,6 +31,9 @@ #include "po-charset.h" #include "xalloc.h" #include "gettext.h" +#include "exit.h" +#include "error.h" +#include "error-progname.h" #define _(str) gettext (str) @@ -384,6 +387,19 @@ } } +/* Attempt to handle errors as before (using GNU libc's 'error' function) */ +void +default_report_error (abstract_po_reader_ty *that, lex_pos_ty *pos, char *s) +{ + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, s); + error_with_progname = true; + + /* Handle continuation messages */ + if (*s == '.') + --error_message_count; +} + /* So that the one parser can be used for multiple programs, and also use good data hiding and encapsulation practices, an object @@ -441,6 +457,7 @@ { default_po_reader_ty *pop; msgdomain_list_ty *mdlp; + int err_msg_count = 0; pop = default_po_reader_alloc (&default_methods); pop->handle_comments = true; @@ -455,10 +472,17 @@ convert strings to UTF-8. */ pop->mdlp->encoding = po_charset_utf8; po_lex_pass_obsolete_entries (true); - po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, logical_filename, - input_syntax); + err_msg_count = po_scan ((abstract_po_reader_ty *) pop, fp, + real_filename, logical_filename, input_syntax); mdlp = pop->mdlp; po_reader_free ((abstract_po_reader_ty *) pop); + + if (err_msg_count > 0) + error (EXIT_FAILURE, 0, + ngettext ("found %d fatal error", "found %d fatal errors", + err_msg_count), + err_msg_count); + return mdlp; } Index: read-po.h =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/read-po.h,v retrieving revision 1.5 diff -u -u -r1.5 read-po.h --- read-po.h 24 Aug 2003 17:56:37 -0000 1.5 +++ read-po.h 12 Aug 2004 13:07:49 -0000 @@ -142,6 +142,8 @@ char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos, bool force_fuzzy, bool obsolete); +extern void default_report_error (abstract_po_reader_ty *that, + lex_pos_ty *pas, char *s); /* Allocate a fresh default_po_reader_ty (or derived class) instance and call its constructor. */ Index: po-lex.c =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/po-lex.c,v retrieving revision 1.14 diff -u -u -r1.14 po-lex.c --- po-lex.c 17 Oct 2003 10:37:12 -0000 1.14 +++ po-lex.c 12 Aug 2004 13:07:49 -0000 @@ -43,12 +43,10 @@ #include "gettext.h" #include "po-charset.h" #include "xalloc.h" -#include "exit.h" -#include "error.h" -#include "error-progname.h" #include "pos.h" #include "str-list.h" #include "po-gram-gen2.h" +#include "read-po-abstract.h" #define _(str) gettext(str) @@ -88,19 +86,8 @@ if (vasprintf (&buffer, fmt, ap) < 0) error (EXIT_FAILURE, 0, _("memory exhausted")); va_end (ap); - error_with_progname = false; - 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_callback_report_error (&gram_pos, 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) - error (EXIT_FAILURE, 0, _("too many errors, aborting")); } /* CAUTION: If you change this function, you must also make identical @@ -117,19 +104,8 @@ if (vasprintf (&buffer, fmt, ap) < 0) error (EXIT_FAILURE, 0, _("memory exhausted")); va_end (ap); - error_with_progname = false; - error_at_line (0, 0, pp->file_name, pp->line_number, "%s", buffer); - error_with_progname = true; + po_callback_report_error (pp, 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) - error (EXIT_FAILURE, 0, _("too many errors, aborting")); } #endif Index: po-lex.h =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/po-lex.h,v retrieving revision 1.7 diff -u -u -r1.7 po-lex.h --- po-lex.h 24 Aug 2003 17:56:37 -0000 1.7 +++ po-lex.h 12 Aug 2004 13:07:49 -0000 @@ -79,17 +79,9 @@ # define po_gram_error(fmt, ...) \ do { \ - char *totalfmt = xasprintf ("%s%s", "%s:%lu:%d: ", fmt); \ - error_with_progname = false; \ - 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) \ - error (1, 0, _("too many errors, aborting")); \ + char *errmsg = xasprintf (fmt, __VA_ARGS__ + 0); \ + po_callback_report_error (&gram_pos, errmsg); \ + free (errmsg); \ } while (0) /* CAUTION: If you change this macro, you must also make identical @@ -97,14 +89,9 @@ # define po_gram_error_at_line(pos, fmt, ...) \ do { \ - error_with_progname = false; \ - 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) \ - error (1, 0, _("too many errors, aborting")); \ + char *errmsg = xasprintf (fmt, __VA_ARGS__ + 0); \ + po_callback_report_error (pos, errmsg); \ + free (errmsg); \ } while (0) /* GCC is also smart enough to allow optimizations like this. */ @@ -115,16 +102,9 @@ # define po_gram_error(fmt, args...) \ do { \ - char *totalfmt = xasprintf ("%s%s", "%s:%d:%d: ", fmt); \ - error_with_progname = false; \ - 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) \ - error (1, 0, _("too many errors, aborting")); \ + char *errmsg = xasprintf (fmt, ## args); \ + po_callback_report_error (&gram_pos, errmsg); \ + free (errmsg); \ } while (0) /* CAUTION: If you change this macro, you must also make identical @@ -132,14 +112,9 @@ # define po_gram_error_at_line(pos, fmt, args...) \ do { \ - error_with_progname = false; \ - 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) \ - error (1, 0, _("too many errors, aborting")); \ + char *errmsg = xasprintf (fmt, ## args); \ + po_callback_report_error (pos, errmsg); \ + free (errmsg); \ } while (0) #else Index: msgfmt.c =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/msgfmt.c,v retrieving revision 1.19 diff -u -u -r1.19 msgfmt.c --- msgfmt.c 15 Jan 2004 11:36:38 -0000 1.19 +++ msgfmt.c 12 Aug 2004 13:07:50 -0000 @@ -1676,7 +1676,8 @@ default_comment, default_comment_dot, default_comment_filepos, - msgfmt_comment_special + msgfmt_comment_special, + default_report_error }, msgfmt_set_domain, /* set_domain */ msgfmt_add_message, /* add_message */ @@ -1691,6 +1692,7 @@ char *real_filename; FILE *fp = open_po_file (filename, &real_filename, true); default_po_reader_ty *pop; + int err_msg_count = 0; pop = default_po_reader_alloc (&msgfmt_methods); pop->handle_comments = false; @@ -1707,10 +1709,16 @@ pop->mlp = current_domain->mlp; } po_lex_pass_obsolete_entries (true); - po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, filename, - input_syntax); + err_msg_count = po_scan ((abstract_po_reader_ty *) pop, fp, + real_filename, filename, input_syntax); po_reader_free ((abstract_po_reader_ty *) pop); if (fp != stdin) fclose (fp); + + if (err_msg_count > 0) + error (EXIT_FAILURE, 0, + ngettext ("found %d fatal error", "found %d fatal errors", + err_msg_count), + err_msg_count); } Index: x-po.c =================================================================== RCS file: /cvs/gettext/gettext/gettext-tools/src/x-po.c,v retrieving revision 1.8 diff -u -u -r1.8 x-po.c --- x-po.c 22 Oct 2003 10:49:09 -0000 1.8 +++ x-po.c 12 Aug 2004 13:07:50 -0000 @@ -92,7 +92,8 @@ default_comment, default_comment_dot, default_comment_filepos, - default_comment_special + default_comment_special, + default_report_error }, default_set_domain, /* set_domain */ extract_add_message, /* add_message */ @@ -107,6 +108,7 @@ msgdomain_list_ty *mdlp) { default_po_reader_ty *pop; + int err_msg_count = 0; pop = default_po_reader_alloc (&extract_methods); pop->handle_comments = true; @@ -116,9 +118,15 @@ pop->allow_duplicates_if_same_msgstr = true; pop->mdlp = NULL; pop->mlp = mdlp->item[0]->messages; - po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, logical_filename, - syntax); + err_msg_count = po_scan ((abstract_po_reader_ty *) pop, fp, + real_filename, logical_filename, syntax); po_reader_free ((abstract_po_reader_ty *) pop); + + if (err_msg_count > 0) + error (EXIT_FAILURE, 0, + ngettext ("found %d fatal error", "found %d fatal errors", + err_msg_count), + err_msg_count); }