* 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.
* 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.
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;
}
return;
+ case ';':
+ /* Semicolon. */
+ tp->type = token_type_semicolon;
+ return;
+
default:
/* Misc. operator. */
tp->type = token_type_other;
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;
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);
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 \
--- /dev/null
+#! /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
--- /dev/null
+#! /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