]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Add xerror-handler.
authorBruno Haible <bruno@clisp.org>
Fri, 2 Aug 2024 22:40:17 +0000 (00:40 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 4 Aug 2024 23:02:31 +0000 (01:02 +0200)
* 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.

gettext-tools/src/FILES
gettext-tools/src/Makefile.am
gettext-tools/src/xerror-handler.c [new file with mode: 0644]
gettext-tools/src/xerror-handler.h [new file with mode: 0644]
gettext-tools/woe32dll/c++xerror-handler.cc [new file with mode: 0644]
gettext-tools/woe32dll/gettextsrc-exports.c

index fb5d38f280997e1d65693a8278aaa8d7254c0b37..8b6f9604af2c439bef8cf37a0915674866df5a7d 100644 (file)
@@ -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
index 5c31e489cb25794cac618fb4ebc0c74a73bb9a2d..c13e412cd86850e0f68a96d1a0d176859bd7e833 100644 (file)
@@ -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 (file)
index 0000000..5423fef
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2024.  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Specification.  */
+#include "xerror-handler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <error.h>
+#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 (file)
index 0000000..13413a4
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2024.  */
+
+#ifndef _XERROR_HANDLER_H
+#define _XERROR_HANDLER_H
+
+#include <stddef.h>
+
+#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 <error.h>, 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 (file)
index 0000000..971043a
--- /dev/null
@@ -0,0 +1 @@
+#include "../src/xerror-handler.c"
index 6b273d04726404a50b1a3b04e71c2676cb1f124b..79cbac622089ea20c9db027a1ba307d2bb0b63cf 100644 (file)
@@ -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)