]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
msgcat: Handle protected file names with spaces.
authorBruno Haible <bruno@clisp.org>
Sun, 4 Apr 2021 17:23:47 +0000 (19:23 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 4 Apr 2021 18:48:52 +0000 (20:48 +0200)
* gettext-tools/src/msgl-cat.c: Include msgl-ofn.h.
(catenate_msgdomain_list): Handle references that contain file names with
spaces.
* gettext-tools/tests/msgcat-22: New file, based on
gettext-tools/tests/msgconv-8.
* gettext-tools/tests/Makefile.am (TESTS): Add it.

gettext-tools/src/msgl-cat.c
gettext-tools/tests/Makefile.am
gettext-tools/tests/msgcat-22 [new file with mode: 0755]

index 990d39e925db928741bf096937b3e4257af0f7b5..965cc8cf8d2d50870c886ffd7e9292d70a9a2b27 100644 (file)
@@ -1,5 +1,5 @@
 /* Message list concatenation and duplicate handling.
-   Copyright (C) 2001-2003, 2005-2008, 2012, 2015, 2019-2020 Free Software
+   Copyright (C) 2001-2003, 2005-2008, 2012, 2015, 2019-2021 Free Software
    Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
@@ -38,6 +38,7 @@
 #include "read-catalog.h"
 #include "po-charset.h"
 #include "msgl-ascii.h"
+#include "msgl-ofn.h"
 #include "msgl-equal.h"
 #include "msgl-iconv.h"
 #include "xalloc.h"
@@ -393,6 +394,16 @@ catenate_msgdomain_list (string_list_ty *file_list,
         total_mdlp->encoding = mdlps[0]->encoding;
     }
 
+  /* Determine whether we need a target encoding that contains the control
+     characters needed for escaping file names with spaces.  */
+  bool has_filenames_with_spaces = false;
+  for (n = 0; n < nfiles; n++)
+    {
+      has_filenames_with_spaces =
+        has_filenames_with_spaces
+        || msgdomain_list_has_filenames_with_spaces (mdlps[n]);
+    }
+
   /* Determine the target encoding for the remaining messages.  */
   if (to_code != NULL)
     {
@@ -402,11 +413,20 @@ catenate_msgdomain_list (string_list_ty *file_list,
         error (EXIT_FAILURE, 0,
                _("target charset \"%s\" is not a portable encoding name."),
                to_code);
+      /* Test whether the control characters required for escaping file names
+         with spaces are present in the target encoding.  */
+      if (has_filenames_with_spaces
+          && !(canon_to_code == po_charset_utf8
+               || strcmp (canon_to_code, "GB18030") == 0))
+        error (EXIT_FAILURE, 0,
+               _("Cannot write the control characters that protect file names with spaces in the %s encoding"),
+               canon_to_code);
     }
   else
     {
       /* No target encoding was specified.  Test whether the messages are
-         all in a single encoding.  If so, conversion is not needed.  */
+         all in a single encoding.  If so and if !has_filenames_with_spaces,
+         conversion is not needed.  */
       const char *first = NULL;
       const char *second = NULL;
       bool with_ASCII = false;
@@ -465,6 +485,22 @@ To select a different output encoding, use the --to-code option.\n\
 "), first, second));
           canon_to_code = po_charset_utf8;
         }
+      else if (has_filenames_with_spaces)
+        {
+          /* A conversion is needed.  Warn the user since he hasn't asked
+             for it and might be surprised.  */
+          if (first != NULL
+              && (first == po_charset_utf8 || strcmp (first, "GB18030") == 0))
+            canon_to_code = first;
+          else
+            canon_to_code = po_charset_utf8;
+          multiline_warning (xasprintf (_("warning: ")),
+                             xasprintf (_("\
+Input files contain messages referenced in file names with spaces.\n\
+Converting the output to %s.\n\
+"),
+                                        canon_to_code));
+        }
       else if (first != NULL && with_ASCII && all_ASCII_compatible)
         {
           /* The conversion is a no-op conversion.  Don't warn the user,
@@ -479,7 +515,7 @@ To select a different output encoding, use the --to-code option.\n\
         }
     }
 
-  /* Now convert the remaining messages to to_code.  */
+  /* Now convert the remaining messages to canon_to_code.  */
   if (canon_to_code != NULL)
     for (n = 0; n < nfiles; n++)
       {
index 4cf3be2afbf7de8679f74b4b9e01cf862e6b2b6c..04db0554f869df89cee189fab6a1bd4265b0498c 100644 (file)
@@ -33,6 +33,7 @@ TESTS = gettext-1 gettext-2 \
        msgcat-1 msgcat-2 msgcat-3 msgcat-4 msgcat-5 msgcat-6 msgcat-7 \
        msgcat-8 msgcat-9 msgcat-10 msgcat-11 msgcat-12 msgcat-13 msgcat-14 \
        msgcat-15 msgcat-16 msgcat-17 msgcat-18 msgcat-19 msgcat-20 msgcat-21 \
+       msgcat-22 \
        msgcat-properties-1 msgcat-properties-2 \
        msgcat-stringtable-1 \
        msgcmp-1 msgcmp-2 msgcmp-3 msgcmp-4 \
diff --git a/gettext-tools/tests/msgcat-22 b/gettext-tools/tests/msgcat-22
new file mode 100755 (executable)
index 0000000..6051bf8
--- /dev/null
@@ -0,0 +1,71 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test file locations with file names that contain spaces.
+
+cat <<\EOF > mcat-test22.po
+msgid ""
+msgstr ""
+"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
+
+: ${MSGCAT=msgcat}
+${MSGCAT} --to-code=UTF-8 \
+          -o mcat-test22.out1 mcat-test22.po || Exit 1
+
+: ${DIFF=diff}
+${DIFF} mcat-test22.po mcat-test22.out1 || Exit 1
+
+: ${MSGCAT=msgcat}
+${MSGCAT} --to-code=GB18030 \
+          -o mcat-test22.2.po mcat-test22.po || Exit 1
+
+cat <<\EOF > mcat-test22.ok
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=GB18030\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: \816¬4xg-test17 a.c\816¬5:1 \816¬4xg-test17 x y.c\816¬5:1
+msgid "foo"
+msgstr ""
+
+#: \816¬4xg-test17 x y.c\816¬5:2 xg-test17z.c:1
+msgid "bar"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} mcat-test22.ok mcat-test22.2.po || Exit 1
+
+: ${MSGCAT=msgcat}
+${MSGCAT} --to-code=GB18030 \
+          -o mcat-test22.out2 mcat-test22.2.po || Exit 1
+
+: ${DIFF=diff}
+${DIFF} mcat-test22.2.po mcat-test22.out2 || Exit 1
+
+: ${MSGCAT=msgcat}
+${MSGCAT} --to-code=UTF-8 \
+          -o mcat-test22.out3 mcat-test22.2.po || Exit 1
+
+: ${DIFF=diff}
+${DIFF} mcat-test22.po mcat-test22.out3 || Exit 1
+
+: ${MSGCAT=msgcat}
+${MSGCAT} --to-code=ISO-8859-1 \
+          -o mcat-test22.out4 mcat-test22.po 2>/dev/null
+test $? = 1 || Exit 1
+
+exit 0