]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Java: Flag strings on which the method 'formatted' is used as java-printf...
authorBruno Haible <bruno@clisp.org>
Tue, 5 Dec 2023 15:07:38 +0000 (16:07 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 5 Dec 2023 15:07:38 +0000 (16:07 +0100)
* gettext-tools/src/x-java.c (token_type_semicolon): New enum item.
(phase5_get): Recognize semicolon tokens.
(extract_parenthesized): Handle method invocation .formatted. Return when a
semicolon was seen.
* gettext-tools/tests/xgettext-java-8: New file, based on
gettext-tools/tests/xgettext-vala-6.
* gettext-tools/tests/xgettext-java-9: New file, based on
gettext-tools/tests/xgettext-vala-7.
* gettext-tools/tests/Makefile.am (TESTS): Add them.
* NEWS: Mention the change.

NEWS
gettext-tools/src/x-java.c
gettext-tools/tests/Makefile.am
gettext-tools/tests/xgettext-java-8 [new file with mode: 0644]
gettext-tools/tests/xgettext-java-9 [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index a99ecc85fb56ba233ffd1a6f43fafa06e28bdc40..2e96a61208d17ce0a079e2b93b68db0306d0c0a5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ Version 0.23 - December 2023
 
 * Programming languages support:
   - Python: xgettext now recognizes the f-string syntax.
+  - Java: Improved recognition of format strings when the String.formatted
+    method is used.
   - Vala: Improved recognition of format strings when the string.printf method
     is used.
   - Glade: xgettext has improved support for GtkBuilder 4.
index 37a9f54ddd6a4affe96f2bdbc33dade7d5349a6d..469c036c45f770d1f2c2533e464196bb1bc98bbd 100644 (file)
@@ -574,6 +574,7 @@ enum token_type_ty
   token_type_number,            /* 1.23 */
   token_type_symbol,            /* identifier, keyword, null */
   token_type_plus,              /* + */
+  token_type_semicolon,         /* ; */
   token_type_other              /* character literal, misc. operator */
 };
 typedef enum token_type_ty token_type_ty;
@@ -1312,6 +1313,11 @@ phase5_get (token_ty *tp)
             }
           return;
 
+        case ';':
+          /* Semicolon.  */
+          tp->type = token_type_semicolon;
+          return;
+
         default:
           /* Misc. operator.  */
           tp->type = token_type_other;
@@ -1586,6 +1592,34 @@ extract_parenthesized (message_list_ty *mlp, token_type_ty terminator,
               return true;
             }
           paren_nesting_depth--;
+          /* Test whether the next tokens are '.' and 'formatted'.  */
+          {
+            token_ty token2;
+            x_java_lex (&token2);
+            if (token2.type == token_type_dot)
+              {
+                token_ty token3;
+                x_java_lex (&token3);
+                if (token3.type == token_type_symbol
+                    && strcmp (token3.string, "formatted") == 0)
+                  {
+                    /* Mark the messages found in the region as java-printf-format
+                       a posteriori.  */
+                    inner_region->for_formatstring[XFORMAT_SECONDARY].is_format = yes_according_to_context;
+                    struct remembered_message_list_ty *rmlp =
+                      inner_region->for_formatstring[XFORMAT_SECONDARY].remembered;
+                    size_t i;
+                    for (i = 0; i < rmlp->nitems; i++)
+                      {
+                        struct remembered_message_ty *rmp = &rmlp->item[i];
+                        set_format_flag_from_context (rmp->mp, rmp->plural, &rmp->pos,
+                                                      XFORMAT_SECONDARY, inner_region);
+                      }
+                  }
+                x_java_unlex (&token3);
+              }
+            x_java_unlex (&token2);
+          }
           next_context_iter = null_context_list_iterator;
           state = 0;
           continue;
@@ -1676,6 +1710,11 @@ extract_parenthesized (message_list_ty *mlp, token_type_ty terminator,
           state = 0;
           continue;
 
+        case token_type_semicolon:
+          arglist_parser_done (argparser, arg);
+          unref_region (inner_region);
+          return false;
+
         case token_type_eof:
           arglist_parser_done (argparser, arg);
           unref_region (inner_region);
index 9e37ff14294b49484914bfa05e5c578d0d155979..d5dd1131a1e1df01971b98922ffd50cbd0934b96 100644 (file)
@@ -110,7 +110,8 @@ TESTS = gettext-1 gettext-2 \
        xgettext-gsettings-1 \
        xgettext-its-1 xgettext-its-2 \
        xgettext-java-1 xgettext-java-2 xgettext-java-3 xgettext-java-4 \
-       xgettext-java-5 xgettext-java-6 xgettext-java-7 \
+       xgettext-java-5 xgettext-java-6 xgettext-java-7 xgettext-java-8 \
+       xgettext-java-9 \
        xgettext-java-stackovfl-1 xgettext-java-stackovfl-2 \
        xgettext-java-stackovfl-3 xgettext-java-stackovfl-4 \
        xgettext-javascript-1 xgettext-javascript-2 xgettext-javascript-3 \
diff --git a/gettext-tools/tests/xgettext-java-8 b/gettext-tools/tests/xgettext-java-8
new file mode 100644 (file)
index 0000000..15cd7bc
--- /dev/null
@@ -0,0 +1,53 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test Java support: formatted and format strings.
+
+: ${XGETTEXT=xgettext}
+
+cat <<\EOF > xg-j-8.java
+"<b>%s</b>".formatted(_("Hello 1"));
+_("Explanation: %s").formatted(_("Hello 2"));
+_("No error 1");
+_("No error 2").formatted();
+(_("No error 3")).formatted();
+foo(_("No error 4")).formatted();
+EOF
+
+${XGETTEXT} --omit-header --no-location \
+            -k_ --flag=_:1:pass-java-format --flag=_:1:pass-java-printf-format \
+            -o xg-j-8.tmp xg-j-8.java \
+  || Exit 1
+func_filter_POT_Creation_Date xg-j-8.tmp xg-j-8.po
+
+cat <<\EOF > xg-j-8.ok
+msgid "Hello 1"
+msgstr ""
+
+#, java-printf-format
+msgid "Explanation: %s"
+msgstr ""
+
+msgid "Hello 2"
+msgstr ""
+
+msgid "No error 1"
+msgstr ""
+
+#, java-printf-format
+msgid "No error 2"
+msgstr ""
+
+#, java-printf-format
+msgid "No error 3"
+msgstr ""
+
+msgid "No error 4"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-j-8.ok xg-j-8.po
+result=$?
+
+exit $result
diff --git a/gettext-tools/tests/xgettext-java-9 b/gettext-tools/tests/xgettext-java-9
new file mode 100644 (file)
index 0000000..81cc1f4
--- /dev/null
@@ -0,0 +1,30 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test Java support: diagnostics for invalid format strings.
+
+: ${XGETTEXT=xgettext}
+
+cat <<\EOF > xg-j-9.java
+_("Invalid Java format %z").formatted();
+EOF
+
+LANGUAGE= LC_ALL=C \
+${XGETTEXT} --omit-header --no-location \
+            -k_ --flag=_:1:pass-java-format --flag=_:1:pass-java-printf-format \
+            -o xg-j-9.tmp xg-j-9.java 2>xg-j-9.err \
+  || Exit 1
+cat xg-j-9.err
+grep 'warning: Although being used in a format string position, the msgid is not a valid Java printf format string.' xg-j-9.err >/dev/null || Exit 1
+func_filter_POT_Creation_Date xg-j-9.tmp xg-j-9.po
+
+cat <<\EOF > xg-j-9.ok
+msgid "Invalid Java format %z"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-j-9.ok xg-j-9.po
+result=$?
+
+exit $result