]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Protect file names with spaces through Unicode U+2068, U+2069.
authorBruno Haible <bruno@clisp.org>
Sun, 4 Apr 2021 14:19:11 +0000 (16:19 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 4 Apr 2021 18:48:41 +0000 (20:48 +0200)
* gettext-tools/src/pos.h: Include <stdbool.h>.
(pos_filename_has_spaces): New declaration.
* gettext-tools/src/pos.c: New file.
* gettext-tools/src/msgl-ofn.h: New file.
* gettext-tools/src/msgl-ofn.c: New file.
* gettext-tools/src/FILES: Update.
* gettext-tools/src/Makefile.am (noinst_HEADERS): Add msgl-ofn.h.
(COMMON_SOURCE): Add pos.c.
(libgettextsrc_la_SOURCES): Add msgl-ofn.c.
* gettext-tools/libgettextpo/Makefile.am (libgettextpo_la_AUXSOURCES): Likewise.
* gettext-tools/src/write-catalog.h (struct catalog_output_format): Add field
requires_utf8_for_filenames_with_spaces.
* gettext-tools/src/xgettext.c: Include pos.h, msgl-ofn.h.
(finalize_header): Convert the message domain to UTF-8 also when some message
has file names with spaces.
* gettext-tools/src/write-po.h (message_print_comment_filepos): Add charset
parameter.
* gettext-tools/src/write-po.c: Include pos.h.
(message_print_comment_filepos): Add charset parameter. If a file name has
spaces, enclose it in U+2068 and U+2069 characters.
(message_print, message_print_obsolete, output_format_po): Update.
* gettext-tools/src/write-properties.c (write_message,
output_format_properties): Update.
* gettext-tools/src/write-stringtable.c (output_format_stringtable): Update.
* gettext-tools/tests/xgettext-17: New file.
* gettext-tools/tests/Makefile.am (TESTS): Add it.

15 files changed:
gettext-tools/libgettextpo/Makefile.am
gettext-tools/src/FILES
gettext-tools/src/Makefile.am
gettext-tools/src/msgl-ofn.c [new file with mode: 0644]
gettext-tools/src/msgl-ofn.h [new file with mode: 0644]
gettext-tools/src/pos.c [new file with mode: 0644]
gettext-tools/src/pos.h
gettext-tools/src/write-catalog.h
gettext-tools/src/write-po.c
gettext-tools/src/write-po.h
gettext-tools/src/write-properties.c
gettext-tools/src/write-stringtable.c
gettext-tools/src/xgettext.c
gettext-tools/tests/Makefile.am
gettext-tools/tests/xgettext-17 [new file with mode: 0755]

index a5ba8398fdeb324311c89074a422eb0799a8f831..f5e96027bbf2dacd89a46bf5c54ab1aba6a1289b 100644 (file)
@@ -1,5 +1,5 @@
 ## Makefile for the gettext-tools/libgettextpo subdirectory of GNU gettext
-## Copyright (C) 1995-1998, 2000-2016, 2019-2020 Free Software Foundation, Inc.
+## Copyright (C) 1995-1998, 2000-2016, 2019-2021 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
@@ -51,6 +51,7 @@ libgettextpo_la_AUXSOURCES = \
   ../src/str-list.c \
   ../src/dir-list.c \
   ../src/message.c \
+  ../src/pos.c \
   ../src/msgl-ascii.c \
   ../src/po-error.c \
   ../src/po-xerror.c \
index 8d3e7d1f31d34b7461f9f5d731310331c6fb4fe6..90471bccdc0b7ff9e11ed0e2afdf1bc46366cc2a 100644 (file)
@@ -24,6 +24,7 @@ lang-table.c
                 Language names according to ISO 639.
 
 pos.h
+pos.c
                 Source file positions.
 
 message.h
@@ -36,6 +37,10 @@ msgl-ascii.h
 msgl-ascii.c
                 Message list test for ASCII character set.
 
+msgl-ofn.h
+msgl-ofn.c
+                Message list test for ordinary file names.
+
 po-error.h
 po-error.c
 po-xerror.h
index 510ab2a08f8ae5b473b87f8c9a1790c8cfb97684..1024992f0a3b294a8f0c1069b3134eb0c2082a78 100644 (file)
@@ -1,5 +1,5 @@
 ## Makefile for the gettext-tools/src subdirectory of GNU gettext
-## Copyright (C) 1995-1998, 2000-2020 Free Software Foundation, Inc.
+## Copyright (C) 1995-1998, 2000-2021 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
@@ -43,8 +43,8 @@ noinst_HEADERS = \
   write-catalog.h write-po.h write-properties.h write-stringtable.h \
   dir-list.h file-list.h po-gram-gen.h po-gram-gen2.h cldr-plural.h \
   cldr-plural-exp.h locating-rule.h its.h search-path.h \
-  msgl-charset.h msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-header.h \
-  msgl-english.h msgl-check.h msgl-fsearch.h msgfmt.h msgunfmt.h \
+  msgl-charset.h msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-ofn.h msgl-cat.h \
+  msgl-header.h msgl-english.h msgl-check.h msgl-fsearch.h msgfmt.h msgunfmt.h \
   plural-count.h plural-eval.h plural-distrib.h \
   read-mo.h write-mo.h \
   read-java.h write-java.h \
@@ -127,7 +127,7 @@ CSHARPCOMPFLAGS = @CSHARPCOMPFLAGS@
 # (read-catalog-abstract.c <--> po-gram-gen.y <--> po-lex.c) -> open-catalog.c -> dir-list.c -> str-list.c.
 # (read-catalog-abstract.c <--> po-gram-gen.y <--> po-lex.c) -> po-charset.c.
 # (read-catalog-abstract.c <--> po-gram-gen.y <--> po-lex.c) -> message.c -> str-list.c.
-COMMON_SOURCE = message.c po-error.c po-xerror.c \
+COMMON_SOURCE = message.c pos.c po-error.c po-xerror.c \
 read-catalog-abstract.c po-lex.c po-gram-gen.y po-charset.c \
 read-po.c read-properties.c read-stringtable.c open-catalog.c \
 dir-list.c str-list.c
@@ -171,13 +171,27 @@ FORMAT_SOURCE += \
 
 # libgettextsrc contains all code that is needed by at least two programs.
 libgettextsrc_la_SOURCES = \
-$(COMMON_SOURCE) read-catalog.c \
-write-catalog.c write-properties.c write-stringtable.c write-po.c \
-msgl-ascii.c msgl-iconv.c msgl-equal.c msgl-cat.c msgl-header.c msgl-english.c \
-msgl-check.c file-list.c msgl-charset.c po-time.c plural-exp.c plural-eval.c \
-plural-table.c quote.h sentence.h sentence.c \
-$(FORMAT_SOURCE) \
-read-desktop.c locating-rule.c its.c search-path.c
+  $(COMMON_SOURCE) \
+  read-catalog.c \
+  write-catalog.c write-properties.c write-stringtable.c write-po.c \
+  msgl-ascii.c \
+  msgl-ofn.c \
+  msgl-iconv.c \
+  msgl-equal.c \
+  msgl-cat.c \
+  msgl-header.c \
+  msgl-english.c \
+  msgl-check.c \
+  file-list.c \
+  msgl-charset.c \
+  po-time.c \
+  plural-exp.c plural-eval.c plural-table.c \
+  quote.h \
+  sentence.h sentence.c \
+  $(FORMAT_SOURCE) \
+  read-desktop.c \
+  locating-rule.c its.c \
+  search-path.c
 
 # msggrep needs pattern matching.
 LIBGREP = ../libgrep/libgrep.a
diff --git a/gettext-tools/src/msgl-ofn.c b/gettext-tools/src/msgl-ofn.c
new file mode 100644 (file)
index 0000000..a58dfed
--- /dev/null
@@ -0,0 +1,65 @@
+/* Message list test for ordinary file names.
+   Copyright (C) 2021 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>, 2021.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Specification.  */
+#include "msgl-ofn.h"
+
+#include "pos.h"
+
+
+bool
+message_has_filenames_with_spaces (message_ty *mp)
+{
+  size_t n = mp->filepos_count;
+  size_t i;
+
+  for (i = 0; i < n; i++)
+    if (pos_filename_has_spaces (&mp->filepos[i]))
+      return true;
+
+  return false;
+}
+
+bool
+message_list_has_filenames_with_spaces (message_list_ty *mlp)
+{
+  size_t j;
+
+  for (j = 0; j < mlp->nitems; j++)
+    if (message_has_filenames_with_spaces (mlp->item[j]))
+      return true;
+
+  return false;
+}
+
+bool
+msgdomain_list_has_filenames_with_spaces (msgdomain_list_ty *mdlp)
+{
+  size_t k;
+
+  for (k = 0; k < mdlp->nitems; k++)
+    if (message_list_has_filenames_with_spaces (mdlp->item[k]->messages))
+      return true;
+
+  return false;
+}
diff --git a/gettext-tools/src/msgl-ofn.h b/gettext-tools/src/msgl-ofn.h
new file mode 100644 (file)
index 0000000..8e83de2
--- /dev/null
@@ -0,0 +1,46 @@
+/* Message list test for ordinary file names.
+   Copyright (C) 2021 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>, 2021.  */
+
+#ifndef _MSGL_OFN_H
+#define _MSGL_OFN_H
+
+#include "message.h"
+
+#include <stdbool.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Tests whether some of the file names in the message locations has spaces.  */
+
+extern bool
+       message_has_filenames_with_spaces (message_ty *mp);
+extern bool
+       message_list_has_filenames_with_spaces (message_list_ty *mlp);
+extern bool
+       msgdomain_list_has_filenames_with_spaces (msgdomain_list_ty *mdlp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _MSGL_OFN_H */
diff --git a/gettext-tools/src/pos.c b/gettext-tools/src/pos.c
new file mode 100644 (file)
index 0000000..ffa1bd3
--- /dev/null
@@ -0,0 +1,32 @@
+/* Source file positions.
+   Copyright (C) 2021 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/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification.  */
+#include "pos.h"
+
+#include <string.h>
+
+bool
+pos_filename_has_spaces (const struct lex_pos_ty *pos)
+{
+  const char *filename = pos->file_name;
+
+  return strchr (filename, ' ') != NULL || strchr (filename, '\t') != NULL;
+}
index c5acf6ec32967d9d6519d58cdf00576de47985cf..ce2b002b31980257c0e668c01bd0c40d31b2209b 100644 (file)
@@ -1,5 +1,5 @@
 /* Source file positions.
-   Copyright (C) 1995-1998, 2000-2001 Free Software Foundation, Inc.
+   Copyright (C) 1995-1998, 2000-2001, 2021 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
@@ -20,6 +20,9 @@
 /* Get size_t.  */
 #include <stddef.h>
 
+/* Get bool.  */
+#include <stdbool.h>
+
 /* Position of a message within a source file.
    Used for error reporting purposes.  */
 typedef struct lex_pos_ty lex_pos_ty;
@@ -29,4 +32,8 @@ struct lex_pos_ty
   size_t line_number;
 };
 
+/* Determines whether the file name in the position has spaces.
+   Such spaces need special protection in PO files and .properties files.  */
+extern bool pos_filename_has_spaces (const struct lex_pos_ty *pos);
+
 #endif /* _POS_H */
index 5813429fb0ed851388101271a83a34ce23834204..d9bbece344b4c8760d8d7a5529164b6219af1829 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995-1998, 2000-2003, 2006, 2008, 2019 Free Software Foundation, Inc.
+   Copyright (C) 1995-1998, 2000-2003, 2006, 2008, 2019, 2021 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
@@ -39,6 +39,10 @@ struct catalog_output_format
      encoding.  */
   bool requires_utf8;
 
+  /* Whether the print function uses Unicode control characters to protect
+     against filenames with spaces.  */
+  bool requires_utf8_for_filenames_with_spaces;
+
   /* Whether the print function supports styled output.  */
   bool supports_color;
 
index 4338e8ef404e96660b85c3afb0f71803a0488aea..c307ca5d0e5cde50029909abf5ff9b5a3c5a924d 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995-1998, 2000-2010, 2012, 2014-2015, 2018-2020 Free Software
+   Copyright (C) 1995-1998, 2000-2010, 2012, 2014-2015, 2018-2021 Free Software
    Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
@@ -43,6 +43,7 @@
 #include "format.h"
 #include "unilbrk.h"
 #include "msgl-ascii.h"
+#include "pos.h"
 #include "write-catalog.h"
 #include "xalloc.h"
 #include "xmalloca.h"
@@ -311,7 +312,8 @@ static enum filepos_comment_type filepos_comment_type = filepos_comment_full;
 
 void
 message_print_comment_filepos (const message_ty *mp, ostream_t stream,
-                               bool uniforum, size_t page_width)
+                               const char *charset, bool uniforum,
+                               size_t page_width)
 {
   if (filepos_comment_type != filepos_comment_none
       && mp->filepos_count != 0)
@@ -377,9 +379,12 @@ message_print_comment_filepos (const message_ty *mp, ostream_t stream,
         }
       else
         {
+          const char *canon_charset;
           size_t column;
           size_t j;
 
+          canon_charset = po_charset_canonicalize (charset);
+
           ostream_write_str (stream, "#:");
           column = 2;
           for (j = 0; j < filepos_count; ++j)
@@ -387,7 +392,7 @@ message_print_comment_filepos (const message_ty *mp, ostream_t stream,
               lex_pos_ty *pp;
               char buffer[21];
               const char *cp;
-              size_t len;
+              size_t width;
 
               pp = &filepos[j];
               cp = pp->file_name;
@@ -400,18 +405,41 @@ message_print_comment_filepos (const message_ty *mp, ostream_t stream,
                 buffer[0] = '\0';
               else
                 sprintf (buffer, ":%ld", (long) pp->line_number);
-              len = strlen (cp) + strlen (buffer) + 1;
-              if (column > 2 && column + len > page_width)
+              /* File names are usually entirely ASCII.  Therefore strlen is
+                 sufficient to determine their printed width.  */
+              width = strlen (cp) + strlen (buffer) + 1;
+              if (column > 2 && column + width > page_width)
                 {
                   ostream_write_str (stream, "\n#:");
                   column = 2;
                 }
               ostream_write_str (stream, " ");
               begin_css_class (stream, class_reference);
-              ostream_write_str (stream, cp);
+              if (pos_filename_has_spaces (pp))
+                {
+                  /* Enclose the file name within U+2068 and U+2069 characters,
+                     so that it can be parsed unambiguously.  */
+                  if (canon_charset == po_charset_utf8)
+                    {
+                      ostream_write_str (stream, "\xE2\x81\xA8"); /* U+2068 */
+                      ostream_write_str (stream, cp);
+                      ostream_write_str (stream, "\xE2\x81\xA9"); /* U+2069 */
+                    }
+                  else if (canon_charset != NULL
+                           && strcmp (canon_charset, "GB18030") == 0)
+                    {
+                      ostream_write_str (stream, "\x81\x36\xAC\x34"); /* U+2068 */
+                      ostream_write_str (stream, cp);
+                      ostream_write_str (stream, "\x81\x36\xAC\x35"); /* U+2069 */
+                    }
+                  else
+                    abort ();
+                }
+              else
+                ostream_write_str (stream, cp);
               ostream_write_str (stream, buffer);
               end_css_class (stream, class_reference);
-              column += len;
+              column += width;
             }
           ostream_write_str (stream, "\n");
         }
@@ -1300,7 +1328,7 @@ message_print (const message_ty *mp, ostream_t stream,
   /* Print the file position comments.  This will help a human who is
      trying to navigate the sources.  There is no problem of getting
      repeated positions, because duplicates are checked for.  */
-  message_print_comment_filepos (mp, stream, uniforum, page_width);
+  message_print_comment_filepos (mp, stream, charset, uniforum, page_width);
 
   /* Print flag information in special comment.  */
   message_print_comment_flags (mp, stream, debug);
@@ -1418,7 +1446,7 @@ message_print_obsolete (const message_ty *mp, ostream_t stream,
   message_print_comment_dot (mp, stream);
 
   /* Print the file position comments (normally empty).  */
-  message_print_comment_filepos (mp, stream, uniforum, page_width);
+  message_print_comment_filepos (mp, stream, charset, uniforum, page_width);
 
   /* Print flag information in special comment.
      Preserve only
@@ -1654,6 +1682,7 @@ const struct catalog_output_format output_format_po =
 {
   msgdomain_list_print_po,              /* print */
   false,                                /* requires_utf8 */
+  true,                                 /* requires_utf8_for_filenames_with_spaces */
   true,                                 /* supports_color */
   true,                                 /* supports_multiple_domains */
   true,                                 /* supports_contexts */
index fdebd061e73d6f487a1c1c575afae6c3247de57e..6d32e6578cf41f6662e1795bdf87e094351ebdc3 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995-1998, 2000-2003, 2006, 2008, 2014, 2018-2019 Free Software
+   Copyright (C) 1995-1998, 2000-2003, 2006, 2008, 2014, 2018-2019, 2021 Free Software
    Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
@@ -56,7 +56,8 @@ extern void
        message_print_comment_dot (const message_ty *mp, ostream_t stream);
 extern void
        message_print_comment_filepos (const message_ty *mp, ostream_t stream,
-                                      bool uniforum, size_t page_width);
+                                      const char *charset, bool uniforum,
+                                      size_t page_width);
 extern void
        message_print_comment_flags (const message_ty *mp, ostream_t stream,
                                     bool debug);
index 19eb228c3e8d15b6e51bc056ddccc3c4ffd8fb77..4da161efaf0986f4d25eaa1bf48e065725256edb 100644 (file)
@@ -1,5 +1,5 @@
 /* Writing Java .properties files.
-   Copyright (C) 2003, 2005-2009, 2019 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005-2009, 2019, 2021 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -217,7 +217,8 @@ write_message (ostream_t stream, const message_ty *mp,
   message_print_comment_dot (mp, stream);
 
   /* Print the file position comments.  */
-  message_print_comment_filepos (mp, stream, false, page_width);
+  message_print_comment_filepos (mp, stream, po_charset_utf8, false,
+                                 page_width);
 
   /* Print flag information in special comment.  */
   message_print_comment_flags (mp, stream, debug);
@@ -296,6 +297,7 @@ const struct catalog_output_format output_format_properties =
 {
   msgdomain_list_print_properties,      /* print */
   true,                                 /* requires_utf8 */
+  true,                                 /* requires_utf8_for_filenames_with_spaces */
   false,                                /* supports_color */
   false,                                /* supports_multiple_domains */
   false,                                /* supports_contexts */
index bf0f63de2ccd548020c48e7ba835522704bc1336..bff51818f917bab74c53453fe8c48492126cce2a 100644 (file)
@@ -1,5 +1,5 @@
 /* Writing NeXTstep/GNUstep .strings files.
-   Copyright (C) 2003, 2006-2008, 2019 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006-2008, 2019, 2021 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -326,6 +326,7 @@ const struct catalog_output_format output_format_stringtable =
 {
   msgdomain_list_print_stringtable,     /* print */
   true,                                 /* requires_utf8 */
+  false,                                /* requires_utf8_for_filenames_with_spaces */
   false,                                /* supports_color */
   false,                                /* supports_multiple_domains */
   false,                                /* supports_contexts */
index 1dce01efb1d5f1c7ec6d684c69f841906989ec9c..e9fb4a0abcca2fd34691c7d82358dc15156ca165 100644 (file)
@@ -1,5 +1,5 @@
 /* Extracts strings from C source file to Uniforum style .po file.
-   Copyright (C) 1995-1998, 2000-2016, 2018-2020 Free Software Foundation, Inc.
+   Copyright (C) 1995-1998, 2000-2016, 2018-2021 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
 #include "read-catalog-abstract.h"
 #include "read-po.h"
 #include "message.h"
+#include "pos.h"
 #include "po-charset.h"
 #include "msgl-iconv.h"
 #include "msgl-ascii.h"
+#include "msgl-ofn.h"
 #include "msgl-check.h"
 #include "po-time.h"
 #include "write-catalog.h"
@@ -2111,18 +2113,14 @@ finalize_header (msgdomain_list_ty *mdlp)
      All messages have already been converted to UTF-8 in remember_a_message
      and remember_a_message_plural.  */
   {
-    bool has_nonascii = false;
-    size_t i;
-
-    for (i = 0; i < mdlp->nitems; i++)
-      {
-        message_list_ty *mlp = mdlp->item[i]->messages;
-
-        if (!is_ascii_message_list (mlp))
-          has_nonascii = true;
-      }
-
-    if (has_nonascii || output_syntax->requires_utf8)
+    bool has_nonascii = ! is_ascii_msgdomain_list (mdlp);
+    bool has_filenames_with_spaces =
+      msgdomain_list_has_filenames_with_spaces (mdlp);
+
+    if (has_nonascii
+        || (has_filenames_with_spaces
+            && output_syntax->requires_utf8_for_filenames_with_spaces)
+        || output_syntax->requires_utf8)
       {
         message_list_ty *mlp = mdlp->item[0]->messages;
 
index 5e13775942fbf75fb9a5caead0c93685983f34f4..181288a0cd30c9a7a470f1634048634e4e8e7fdd 100644 (file)
@@ -1,5 +1,5 @@
 ## Makefile for the gettext-tools/tests subdirectory of GNU gettext
-## Copyright (C) 1995-1997, 2001-2010, 2012-2016, 2018-2020 Free Software Foundation, Inc.
+## Copyright (C) 1995-1997, 2001-2010, 2012-2016, 2018-2021 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
@@ -77,7 +77,7 @@ TESTS = gettext-1 gettext-2 \
        recode-sr-latin-1 recode-sr-latin-2 \
        xgettext-2 xgettext-3 xgettext-4 xgettext-5 xgettext-6 \
        xgettext-7 xgettext-8 xgettext-9 xgettext-10 xgettext-11 xgettext-12 \
-       xgettext-13 xgettext-14 xgettext-15 xgettext-16 \
+       xgettext-13 xgettext-14 xgettext-15 xgettext-16 xgettext-17 \
        xgettext-appdata-1 \
        xgettext-awk-1 xgettext-awk-2 \
        xgettext-c-2 xgettext-c-3 xgettext-c-4 xgettext-c-5 xgettext-c-6 \
diff --git a/gettext-tools/tests/xgettext-17 b/gettext-tools/tests/xgettext-17
new file mode 100755 (executable)
index 0000000..0b0dd5d
--- /dev/null
@@ -0,0 +1,59 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test file locations with file names that contain spaces.
+
+cat <<\EOF > 'xg-test17 a.c'
+gettext ("foo");
+EOF
+
+cat <<\EOF > 'xg-test17 x y.c'
+gettext ("foo");
+gettext ("bar");
+EOF
+
+cat <<\EOF > 'xg-test17z.c'
+gettext ("bar");
+EOF
+
+: ${XGETTEXT=xgettext}
+${XGETTEXT} 'xg-test17 a.c' 'xg-test17 x y.c' 'xg-test17z.c' \
+            -o xg-test17.out >xg-test17.err 2>&1
+result=$?
+cat xg-test17.err | grep -v '^ '
+test $result = 0 || { Exit 1; }
+sed -e '/\"POT-Creation-Date:.*/d' < xg-test17.out | LC_ALL=C tr -d '\r' > xg-test17.po
+
+cat <<\EOF > xg-test17.ok
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ⁨xg-test17 a.c⁩:1 ⁨xg-test17 x y.c⁩:1
+msgid "foo"
+msgstr ""
+
+#: ⁨xg-test17 x y.c⁩:2 xg-test17z.c:1
+msgid "bar"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-test17.ok xg-test17.po
+result=$?
+
+exit $result