From: Bruno Haible Date: Fri, 2 Aug 2024 22:40:17 +0000 (+0200) Subject: Add xerror-handler. X-Git-Tag: v0.23~190 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=579e12bff569924ed69e8758880e720199e652ea;p=thirdparty%2Fgettext.git Add xerror-handler. * gettext-tools/src/xerror-handler.h: New file, based on gettext-tools/src/po-xerror.h. * gettext-tools/src/xerror-handler.c: New file, based on gettext-tools/src/po-xerror.c. * gettext-tools/src/Makefile.am (noinst_HEADERS): Add xerror-handler.h. (COMMON_SOURCE): Add xerror-handler.c. * gettext-tools/src/FILES: Update. * gettext-tools/woe32dll/gettextsrc-exports.c (textmode_xerror_handler_struct): New export. --- diff --git a/gettext-tools/src/FILES b/gettext-tools/src/FILES index fb5d38f28..8b6f9604a 100644 --- a/gettext-tools/src/FILES +++ b/gettext-tools/src/FILES @@ -45,6 +45,8 @@ po-error.h po-error.c po-xerror.h po-xerror.c +xerror-handler.h +xerror-handler.c Error handling during writing and reading of PO files. +-------------- Writing PO files diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am index 5c31e489c..c13e412cd 100644 --- a/gettext-tools/src/Makefile.am +++ b/gettext-tools/src/Makefile.am @@ -42,8 +42,9 @@ noinst_LTLIBRARIES = libgettextsrc.la endif noinst_HEADERS = \ - pos.h message.h po-error.h po-xerror.h read-po-internal.h po-charset.h \ - read-po-lex.h open-catalog.h read-catalog-special.h \ + pos.h message.h po-error.h po-xerror.h xerror-handler.h \ + read-po-internal.h po-charset.h read-po-lex.h \ + open-catalog.h read-catalog-special.h \ read-catalog-abstract.h read-catalog.h read-catalog-file.h \ read-po.h read-properties.h read-stringtable.h \ str-list.h \ @@ -142,10 +143,27 @@ CSHARPCOMPFLAGS = @CSHARPCOMPFLAGS@ # (read-catalog-abstract.c <--> read-po-gram.y <--> read-po-lex.c) -> po-charset.c. # (read-catalog-abstract.c <--> read-po-gram.y <--> read-po-lex.c) -> message.c -> str-list.c. # read-catalog-file.c -> open-catalog.c -> dir-list.c -> str-list.c. -COMMON_SOURCE = message.c pos.c po-error.c po-xerror.c \ -read-catalog-abstract.c read-po-lex.c read-po-gram.y po-charset.c \ -read-po.c read-properties.c read-stringtable.c open-catalog.c \ -dir-list.c str-list.c +COMMON_SOURCE = \ + message.c \ + pos.c \ + po-error.c \ + po-xerror.c +if !WOE32DLL +COMMON_SOURCE += xerror-handler.c +else +COMMON_SOURCE += ../woe32dll/c++xerror-handler.cc +endif +COMMON_SOURCE += \ + read-catalog-abstract.c \ + read-po-lex.c \ + read-po-gram.y \ + po-charset.c \ + read-po.c \ + read-properties.c \ + read-stringtable.c \ + open-catalog.c \ + dir-list.c \ + str-list.c # xgettext and msgfmt deal with format strings. if !WOE32DLL diff --git a/gettext-tools/src/xerror-handler.c b/gettext-tools/src/xerror-handler.c new file mode 100644 index 000000000..5423fefa7 --- /dev/null +++ b/gettext-tools/src/xerror-handler.c @@ -0,0 +1,189 @@ +/* Error handling during reading and writing of textual message catalogs. + Copyright (C) 2005-2024 Free Software Foundation, Inc. + + 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 3 of the License, 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, see . */ + +/* Written by Bruno Haible , 2024. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* Specification. */ +#include "xerror-handler.h" + +#include +#include + +#include +#include "message.h" +#include "error-progname.h" +#include "xalloc.h" +#include "xerror.h" +#include "xvasprintf.h" +#include "po-error.h" +#include "progname.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 >= CAT_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 == CAT_SEVERITY_FATAL_ERROR) + exit (EXIT_FAILURE); + } + else + { + int exit_status = + (severity == CAT_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 < CAT_SEVERITY_ERROR) + --error_message_count; + } +} + +/* The default error handler is based on the lower-level error handler + in po-error.h. */ +static 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 == CAT_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); +} + +static 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 == CAT_SEVERITY_FATAL_ERROR ? CAT_SEVERITY_ERROR : severity); + const char *prefix_tail = + (severity == CAT_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 >= CAT_SEVERITY_ERROR) + /* error_message_count needs to be incremented only by 1, not by 2. */ + --error_message_count; +} + +const struct xerror_handler textmode_xerror_handler_struct = +{ + textmode_xerror, /* xerror */ + textmode_xerror2, /* xerror2 */ + &error_message_count /* error_message_count_p */ +}; diff --git a/gettext-tools/src/xerror-handler.h b/gettext-tools/src/xerror-handler.h new file mode 100644 index 000000000..13413a4fe --- /dev/null +++ b/gettext-tools/src/xerror-handler.h @@ -0,0 +1,81 @@ +/* Error handling during reading and writing of textual message catalogs. + Copyright (C) 2005-2024 Free Software Foundation, Inc. + + 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 3 of the License, 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, see . */ + +/* Written by Bruno Haible , 2024. */ + +#ifndef _XERROR_HANDLER_H +#define _XERROR_HANDLER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct message_ty; + + +/* These values must be the same as those in gettext-po.h. */ +#define CAT_SEVERITY_WARNING 0 /* just a warning, tell the user */ +#define CAT_SEVERITY_ERROR 1 /* an error, the operation cannot complete */ +#define CAT_SEVERITY_FATAL_ERROR 2 /* an error, the operation must be aborted */ + +/* An xerror_handler handles error situations. + This one is higher-level than the one in po-error.h. */ +struct xerror_handler +{ + /* Signals 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 CAT_SEVERITY_FATAL_ERROR. */ + void (*xerror) (int severity, + const struct message_ty *message, + const char *filename, size_t lineno, size_t column, + int multiline_p, const char *message_text); + + /* Signals 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, + 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); + + /* Points to an error_message_count variable or field. */ + unsigned int *error_message_count_p; +}; +typedef const struct xerror_handler *xerror_handler_ty; + +/* The default xerror_handler, that uses the global variable error_message_count + from , and therefore is not multithread-safe. */ +extern DLL_VARIABLE const struct xerror_handler textmode_xerror_handler_struct; +#define textmode_xerror_handler (&textmode_xerror_handler_struct) + + +#ifdef __cplusplus +} +#endif + +#endif /* _XERROR_HANDLER_H */ diff --git a/gettext-tools/woe32dll/c++xerror-handler.cc b/gettext-tools/woe32dll/c++xerror-handler.cc new file mode 100644 index 000000000..971043ad3 --- /dev/null +++ b/gettext-tools/woe32dll/c++xerror-handler.cc @@ -0,0 +1 @@ +#include "../src/xerror-handler.c" diff --git a/gettext-tools/woe32dll/gettextsrc-exports.c b/gettext-tools/woe32dll/gettextsrc-exports.c index 6b273d047..79cbac622 100644 --- a/gettext-tools/woe32dll/gettextsrc-exports.c +++ b/gettext-tools/woe32dll/gettextsrc-exports.c @@ -78,4 +78,5 @@ VARIABLE(po_multiline_warning) VARIABLE(po_xerror) VARIABLE(po_xerror2) VARIABLE(syntax_check_name) +VARIABLE(textmode_xerror_handler_struct) VARIABLE(use_first)