From: Bruno Haible Date: Mon, 19 Sep 2005 16:08:11 +0000 (+0000) Subject: Use new error handlers in libgettextpo. X-Git-Tag: v0.15~399 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b182bdae471ae83cb55e35bb46e9541cc9995e3c;p=thirdparty%2Fgettext.git Use new error handlers in libgettextpo. --- diff --git a/NEWS b/NEWS index a7fa6d033..440e99872 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,11 @@ +* libgettextpo library: + - The error handler type passed to po_file_read(), po_file_write(), + po_message_check_format() has changed. + This is an incompatible change: Programs using the library *must* update + their code. + Binary compatibility is guaranteed, however. + * Portability to mingw. Version 0.14.5 - May 2005 diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 5bf429a5e..76a410dab 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,20 @@ +2005-09-17 Bruno Haible + + Use new error handlers in libgettextpo. + * gettext-po.h (PO_SEVERITY_WARNING, PO_SEVERITY_ERROR, + PO_SEVERITY_FATAL_ERROR): New macros. + (po_xerror_handler): New structure type. + (po_xerror_handler_t): New type. + (po_file_read): Change signature; version 3. + (po_file_write): Change signature; version 2. + (po_message_check_format): Change signature; version 2. + * gettext-po.c: Include po-xerror.h. + (po_file_read): New implementation. Renamed old implementation to + po_file_read_v2. + (po_file_write): New implementation. Keep old implementation. + (po_xerror_logger): New function. + (po_message_check_format): New implementation. Keep old implementation. + 2005-09-17 Bruno Haible * msgfmt.c (check_plural): Fix broken determination of max_nplurals. diff --git a/gettext-tools/src/gettext-po.c b/gettext-tools/src/gettext-po.c index 90099a33f..5efcdd584 100644 --- a/gettext-tools/src/gettext-po.c +++ b/gettext-tools/src/gettext-po.c @@ -37,6 +37,7 @@ #include "error.h" #include "xerror.h" #include "po-error.h" +#include "po-xerror.h" #include "vasprintf.h" #include "format.h" #include "gettext.h" @@ -89,7 +90,51 @@ po_file_create (void) Return its contents. Upon failure, return NULL and set errno. */ po_file_t -po_file_read (const char *filename, po_error_handler_t handler) +po_file_read (const char *filename, po_xerror_handler_t handler) +{ + FILE *fp; + po_file_t file; + + if (strcmp (filename, "-") == 0 || strcmp (filename, "/dev/stdin") == 0) + { + filename = _(""); + fp = stdin; + } + else + { + fp = fopen (filename, "r"); + if (fp == NULL) + return NULL; + } + + /* Establish error handler around read_po(). */ + po_xerror = + (void (*) (int, const message_ty *, const char *, size_t, size_t, int, const char *)) + handler->xerror; + po_xerror2 = + (void (*) (int, const message_ty *, const char *, size_t, size_t, int, const char *, const message_ty *, const char *, size_t, size_t, int, const char *)) + handler->xerror2; + gram_max_allowed_errors = UINT_MAX; + + file = (struct po_file *) xmalloc (sizeof (struct po_file)); + file->real_filename = filename; + file->logical_filename = filename; + file->mdlp = read_po (fp, file->real_filename, file->logical_filename); + file->domains = NULL; + + /* Restore error handler. */ + po_xerror = textmode_xerror; + po_xerror2 = textmode_xerror2; + gram_max_allowed_errors = 20; + + if (fp != stdin) + fclose (fp); + return file; +} +#undef po_file_read + +po_file_t +po_file_read_v2 (const char *filename, po_error_handler_t handler) { FILE *fp; po_file_t file; @@ -130,7 +175,6 @@ po_file_read (const char *filename, po_error_handler_t handler) fclose (fp); return file; } -#undef po_file_read /* Older version for binary backward compatibility. */ po_file_t @@ -166,6 +210,28 @@ po_file_read (const char *filename) /* Write an in-memory PO file to a file. Upon failure, return NULL and set errno. */ +po_file_t +po_file_write (po_file_t file, const char *filename, po_xerror_handler_t handler) +{ + /* Establish error handler around msgdomain_list_print(). */ + po_xerror = + (void (*) (int, const message_ty *, const char *, size_t, size_t, int, const char *)) + handler->xerror; + po_xerror2 = + (void (*) (int, const message_ty *, const char *, size_t, size_t, int, const char *, const message_ty *, const char *, size_t, size_t, int, const char *)) + handler->xerror2; + + msgdomain_list_print (file->mdlp, filename, true, false); + + /* Restore error handler. */ + po_xerror = textmode_xerror; + po_xerror2 = textmode_xerror2; + + return file; +} +#undef po_file_write + +/* Older version for binary backward compatibility. */ po_file_t po_file_write (po_file_t file, const char *filename, po_error_handler_t handler) { @@ -892,6 +958,45 @@ po_message_set_format (po_message_t message, const char *format_type, /*bool*/in } +/* An error logger based on the po_xerror function pointer. */ +static void +po_xerror_logger (const char *format, ...) +{ + va_list args; + char *error_message; + + va_start (args, format); + if (vasprintf (&error_message, format, args) < 0) + error (EXIT_FAILURE, 0, _("memory exhausted")); + va_end (args); + po_xerror (PO_SEVERITY_ERROR, NULL, NULL, 0, 0, false, error_message); + free (error_message); +} + +/* Test whether the message translation is a valid format string if the message + is marked as being a format string. If it is invalid, pass the reasons to + the handler. */ +void +po_message_check_format (po_message_t message, po_xerror_handler_t handler) +{ + message_ty *mp = (message_ty *) message; + + /* Establish error handler for po_xerror_logger(). */ + po_xerror = + (void (*) (int, const message_ty *, const char *, size_t, size_t, int, const char *)) + handler->xerror; + + check_msgid_msgstr_format (mp->msgid, mp->msgid_plural, + mp->msgstr, mp->msgstr_len, + mp->is_format, po_xerror_logger); + + /* Restore error handler. */ + po_xerror = textmode_xerror; +} +#undef po_message_check_format + +/* Older version for binary backward compatibility. */ + /* An error logger based on the po_error function pointer. */ static void po_error_logger (const char *format, ...) diff --git a/gettext-tools/src/gettext-po.h b/gettext-tools/src/gettext-po.h index 944c30ec0..c3927be01 100644 --- a/gettext-tools/src/gettext-po.h +++ b/gettext-tools/src/gettext-po.h @@ -78,6 +78,39 @@ struct po_error_handler }; typedef const struct po_error_handler *po_error_handler_t; +/* A po_xerror_handler handles warnings, error and fatal error situations. */ +#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 */ +struct po_xerror_handler +{ + /* 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. */ + void (*xerror) (int severity, + po_message_t 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 xerror. + If possible, a "..." can be appended to MESSAGE_TEXT1 and prepended to + MESSAGE_TEXT2. */ + void (*xerror2) (int severity, + po_message_t message1, + const char *filename1, size_t lineno1, size_t column1, + int multiline_p1, const char *message_text1, + po_message_t message2, + const char *filename2, size_t lineno2, size_t column2, + int multiline_p2, const char *message_text2); +}; +typedef const struct po_xerror_handler *po_xerror_handler_t; + /* Memory allocation: The memory allocations performed by these functions use xmalloc(), therefore will cause a program exit if memory is exhausted. @@ -92,14 +125,15 @@ extern po_file_t po_file_create (void); /* Read a PO file into memory. Return its contents. Upon failure, return NULL and set errno. */ -#define po_file_read po_file_read_v2 +#define po_file_read po_file_read_v3 extern po_file_t po_file_read (const char *filename, - po_error_handler_t handler); + po_xerror_handler_t handler); /* Write an in-memory PO file to a file. Upon failure, return NULL and set errno. */ +#define po_file_write po_file_write_v2 extern po_file_t po_file_write (po_file_t file, const char *filename, - po_error_handler_t handler); + po_xerror_handler_t handler); /* Free a PO file from memory. */ extern void po_file_free (po_file_t file); @@ -233,7 +267,8 @@ extern void po_message_set_format (po_message_t message, const char *format_type /* Test whether the message translation is a valid format string if the message is marked as being a format string. If it is invalid, pass the reasons to the handler. */ -extern void po_message_check_format (po_message_t message, po_error_handler_t handler); +#define po_message_check_format po_message_check_format_v2 +extern void po_message_check_format (po_message_t message, po_xerror_handler_t handler); /* =========================== po_filepos_t API ============================ */