]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Allow plural extraction from a single argument function
authorDaiki Ueno <ueno@gnu.org>
Tue, 28 Oct 2014 07:38:40 +0000 (16:38 +0900)
committerDaiki Ueno <ueno@gnu.org>
Thu, 30 Oct 2014 01:22:29 +0000 (10:22 +0900)
The commit 8137d2b4 was a wrong fix since both singular/plural
msgids may point to the same address for Qt4 plural forms.  This
reverts the commit and fix the original double-free problem in the
right way.  Thanks to Jesper Fehrlund for suggestions.
* gettext-tools/src/xgettext.c (arglist_parser_remember_literal):
Don't ignore plural argument even if ARGNUM1 equals to ARGNUM2.
(arglist_parser_done): Make a copy of best_cp->msgid_plural when
passing it to remember_a_message_plural, if it equals to
best_cp->msgid.  Also move code conversion logic earlier taking into
account of the ownership transfer of best_cp->msgid.
* gettext-tools/src/xgettext-12: Test a single argument function.

gettext-tools/src/ChangeLog
gettext-tools/src/xgettext.c
gettext-tools/tests/ChangeLog
gettext-tools/tests/xgettext-12

index e5ff794817546025d59a804e415cbf4b012059e2..d392ba7d439be4a55d45bdf61a663a09c7036ad0 100644 (file)
@@ -1,3 +1,17 @@
+2014-10-28  Daiki Ueno  <ueno@gnu.org>
+
+       xgettext: Allow plural extraction from a single argument function
+       The commit 8137d2b4 was a wrong fix since both singular/plural msgids
+       may point to the same address for Qt4 plural forms.  This reverts
+       the commit and fix the original double-free problem in the right
+       way.  Thanks to Jesper Fehrlund for suggestions.
+       * xgettext.c (arglist_parser_remember_literal): Don't ignore
+       plural argument even if ARGNUM1 equals to ARGNUM2.
+       (arglist_parser_done): Make a copy of best_cp->msgid_plural when
+       passing it to remember_a_message_plural, if it equals to
+       best_cp->msgid.  Also move code conversion logic earlier taking
+       into account of the ownership transfer of best_cp->msgid.
+
 2014-10-28  Daiki Ueno  <ueno@gnu.org>
 
        xgettext: Fix double-free in singular/plural argument extraction
index a8f3af69924111e9c29851d3143d129be918da63..7a4f71a25395677e6f4ef1d56d26ae4dfc48e6a6 100644 (file)
@@ -2791,7 +2791,7 @@ arglist_parser_remember_literal (struct arglist_parser *ap,
               /* Mark msgid as done.  */
               cp->argnum1 = 0;
             }
-          else if (argnum == cp->argnum2)
+          if (argnum == cp->argnum2)
             {
               cp->msgid_plural = string;
               cp->msgid_plural_escape = type;
@@ -3099,9 +3099,9 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
                 char *msgid = parser->parse (best_cp->msgid,
                                              &best_cp->msgid_pos,
                                              best_cp->msgid_escape);
-                free (best_cp->msgid);
                 if (best_cp->msgid_plural == best_cp->msgid)
                   best_cp->msgid_plural = msgid;
+                free (best_cp->msgid);
                 best_cp->msgid = msgid;
               }
             else
@@ -3110,26 +3110,7 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
                 CONVERT_STRING (best_cp->msgid, lc_string);
               }
 
-            if (best_cp->msgid_comment != NULL)
-              {
-                refcounted_string_list_ty *msgid_comment =
-                  savable_comment_convert_encoding (best_cp->msgid_comment,
-                                                    &best_cp->msgid_pos);
-                drop_reference (best_cp->msgid_comment);
-                best_cp->msgid_comment = msgid_comment;
-              }
-
-            /* best_cp->msgctxt and best_cp->msgid are already in
-               UTF-8.  Prevent further conversion in remember_a_message.  */
-            encoding = xgettext_current_source_encoding;
-            xgettext_current_source_encoding = po_charset_utf8;
-            mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid,
-                                     msgid_context,
-                                     &best_cp->msgid_pos,
-                                     NULL, best_cp->msgid_comment);
-            xgettext_current_source_encoding = encoding;
-
-            if (mp != NULL && best_cp->msgid_plural != NULL)
+            if (best_cp->msgid_plural)
               {
                 /* best_cp->msgid_plural may point to best_cp->msgid.
                    In that case, it is already interpreted and converted.  */
@@ -3152,14 +3133,41 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
                       }
                   }
 
-                encoding = xgettext_current_source_encoding;
-                xgettext_current_source_encoding = po_charset_utf8;
-                remember_a_message_plural (mp, best_cp->msgid_plural,
-                                           msgid_plural_context,
-                                           &best_cp->msgid_plural_pos,
-                                           NULL);
-                xgettext_current_source_encoding = encoding;
+                /* If best_cp->msgid_plural equals to best_cp->msgid,
+                   the ownership will be transferred to
+                   remember_a_message before it is passed to
+                   remember_a_message_plural.
+
+                   Make a copy of the string in that case.  */
+                if (best_cp->msgid_plural == best_cp->msgid)
+                  best_cp->msgid_plural = xstrdup (best_cp->msgid);
+              }
+
+            if (best_cp->msgid_comment != NULL)
+              {
+                refcounted_string_list_ty *msgid_comment =
+                  savable_comment_convert_encoding (best_cp->msgid_comment,
+                                                    &best_cp->msgid_pos);
+                drop_reference (best_cp->msgid_comment);
+                best_cp->msgid_comment = msgid_comment;
               }
+
+            /* best_cp->msgctxt, best_cp->msgid, and best_cp->msgid_plural
+               are already in UTF-8.  Prevent further conversion in
+               remember_a_message.  */
+            encoding = xgettext_current_source_encoding;
+            xgettext_current_source_encoding = po_charset_utf8;
+            mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid,
+                                     msgid_context,
+                                     &best_cp->msgid_pos,
+                                     NULL, best_cp->msgid_comment);
+            if (mp != NULL && best_cp->msgid_plural != NULL)
+              remember_a_message_plural (mp,
+                                         best_cp->msgid_plural,
+                                         msgid_plural_context,
+                                         &best_cp->msgid_plural_pos,
+                                         NULL);
+            xgettext_current_source_encoding = encoding;
           }
 
           if (best_cp->xcomments.nitems > 0)
index 8fb2051509999cf9ea3f8ced723f37b88830799e..d6d6788b72b94557787d130b6cb439340bda5b49 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-28  Daiki Ueno  <ueno@gnu.org>
+
+       xgettext: Allow plural extraction from a single argument function
+       * xgettext-12: Test a single argument function.
+
 2014-10-28  Daiki Ueno  <ueno@gnu.org>
 
        tests: Add test for same ARGNUM1/ARGNUM2 given to xgettext -k
index 0438ca7b2ed90291533402c1795dd943a888ca01..fe76f1aad20b8c0fd46c32d4af24a99d3b706ccc 100755 (executable)
@@ -7,10 +7,15 @@
 cat <<\EOF > xg-test12.c
 ngettext ("abc", "abc", 1);
 ngettext ("abc", "abc", 1);
+
+/* Hypothetical case: plural extraction from a function
+   with a single argument.  */
+xngettext ("def", 1);
+xngettext ("def", 1);
 EOF
 
 : ${XGETTEXT=xgettext}
-${XGETTEXT} --omit-header --add-comments -kngettext:1,1 -d xg-test12.tmp xg-test12.c || exit 1
+${XGETTEXT} --omit-header --add-comments -kngettext:1,1 -kxngettext:1,1 -d xg-test12.tmp xg-test12.c || exit 1
 LC_ALL=C tr -d '\r' < xg-test12.tmp.po > xg-test12.po || exit 1
 
 cat <<\EOF > xg-test12.ok
@@ -19,6 +24,14 @@ msgid "abc"
 msgid_plural "abc"
 msgstr[0] ""
 msgstr[1] ""
+
+#. Hypothetical case: plural extraction from a function
+#. with a single argument.
+#: xg-test12.c:6 xg-test12.c:7
+msgid "def"
+msgid_plural "def"
+msgstr[0] ""
+msgstr[1] ""
 EOF
 
 : ${DIFF=diff}