* gettext-tools/src/xgettext.h (xgettext_record_flag): Add more comments.
* gettext-tools/src/xgettext.c (xgettext_record_flag): Parse an optional
'!BACKEND' suffix. When present, limit the effects of c-format related flags to
the specified flag table(s).
* gettext-tools/src/x-vala.c (init_flag_table_vala): Append '!Vala' to all
xgettext_record_flag arguments.
* gettext-tools/tests/xgettext-c-format-6: New file.
* gettext-tools/tests/Makefile.am (TESTS): Add it.
void
init_flag_table_vala ()
{
- xgettext_record_flag ("dgettext:2:pass-c-format");
- xgettext_record_flag ("dcgettext:2:pass-c-format");
- xgettext_record_flag ("ngettext:1:pass-c-format");
- xgettext_record_flag ("ngettext:2:pass-c-format");
- xgettext_record_flag ("dngettext:2:pass-c-format");
- xgettext_record_flag ("dngettext:3:pass-c-format");
- xgettext_record_flag ("dpgettext:2:pass-c-format");
- xgettext_record_flag ("dpgettext2:3:pass-c-format");
- xgettext_record_flag ("_:1:pass-c-format");
- xgettext_record_flag ("Q_:1:pass-c-format");
- xgettext_record_flag ("N_:1:pass-c-format");
- xgettext_record_flag ("NC_:2:pass-c-format");
-
/* Vala leaves string formatting to Glib functions and thus the
format string is exactly same as C. See also
vapi/glib-2.0.vapi. */
- xgettext_record_flag ("printf:1:c-format");
- xgettext_record_flag ("vprintf:1:c-format");
+
+ xgettext_record_flag ("dgettext:2:pass-c-format!Vala");
+ xgettext_record_flag ("dcgettext:2:pass-c-format!Vala");
+ xgettext_record_flag ("ngettext:1:pass-c-format!Vala");
+ xgettext_record_flag ("ngettext:2:pass-c-format!Vala");
+ xgettext_record_flag ("dngettext:2:pass-c-format!Vala");
+ xgettext_record_flag ("dngettext:3:pass-c-format!Vala");
+ xgettext_record_flag ("dpgettext:2:pass-c-format!Vala");
+ xgettext_record_flag ("dpgettext2:3:pass-c-format!Vala");
+ xgettext_record_flag ("_:1:pass-c-format!Vala");
+ xgettext_record_flag ("Q_:1:pass-c-format!Vala");
+ xgettext_record_flag ("N_:1:pass-c-format!Vala");
+ xgettext_record_flag ("NC_:2:pass-c-format!Vala");
+
+ xgettext_record_flag ("printf:1:c-format!Vala");
+ xgettext_record_flag ("vprintf:1:c-format!Vala");
}
const char *name_end = colon1;
const char *argnum_start = colon1 + 1;
const char *argnum_end = colon2;
- const char *flag = colon2 + 1;
+ const char *flag_start = colon2 + 1;
+ const char *flag_end;
+ const char *backend;
int argnum;
/* Check the parts' syntax. */
if (argnum <= 0)
goto err;
+ flag_end = strchr (flag_start, '!');
+ if (flag_end != NULL)
+ backend = flag_end + 1;
+ else
+ {
+ flag_end = flag_start + strlen (flag_start);
+ backend = NULL;
+ }
+
/* Analyze the flag part. */
{
bool pass;
pass = false;
- if (strlen (flag) >= 5 && memcmp (flag, "pass-", 5) == 0)
+ if (flag_end - flag_start >= 5 && memcmp (flag_start, "pass-", 5) == 0)
{
pass = true;
- flag += 5;
+ flag_start += 5;
}
/* Unlike po_parse_comment_special(), we don't accept "fuzzy",
"wrap", or "check" here - it has no sense. */
- if (strlen (flag) >= 7
- && memcmp (flag + strlen (flag) - 7, "-format", 7) == 0)
+ if (flag_end - flag_start >= 7
+ && memcmp (flag_end - 7, "-format", 7) == 0)
{
const char *p;
size_t n;
enum is_format value;
size_t type;
- p = flag;
- n = strlen (flag) - 7;
+ p = flag_start;
+ n = flag_end - flag_start - 7;
if (n >= 3 && memcmp (p, "no-", 3) == 0)
{
switch (type)
{
case format_c:
- flag_context_list_table_insert (&flag_table_c, 0,
- name_start, name_end,
- argnum, value, pass);
- flag_context_list_table_insert (&flag_table_cxx_qt, 0,
- name_start, name_end,
- argnum, value, pass);
- flag_context_list_table_insert (&flag_table_cxx_kde, 0,
- name_start, name_end,
- argnum, value, pass);
- flag_context_list_table_insert (&flag_table_cxx_boost, 0,
- name_start, name_end,
- argnum, value, pass);
- flag_context_list_table_insert (&flag_table_objc, 0,
- name_start, name_end,
- argnum, value, pass);
- flag_context_list_table_insert (&flag_table_vala, 0,
- name_start, name_end,
- argnum, value, pass);
+ if (backend == NULL || strcmp (backend, "C") == 0
+ || strcmp (backend, "C++") == 0)
+ {
+ flag_context_list_table_insert (&flag_table_c, 0,
+ name_start, name_end,
+ argnum, value, pass);
+ }
+ if (backend == NULL || strcmp (backend, "C++") == 0)
+ {
+ flag_context_list_table_insert (&flag_table_cxx_qt, 0,
+ name_start, name_end,
+ argnum, value, pass);
+ flag_context_list_table_insert (&flag_table_cxx_kde, 0,
+ name_start, name_end,
+ argnum, value, pass);
+ flag_context_list_table_insert (&flag_table_cxx_boost, 0,
+ name_start, name_end,
+ argnum, value, pass);
+ }
+ if (backend == NULL || strcmp (backend, "ObjectiveC") == 0)
+ {
+ flag_context_list_table_insert (&flag_table_objc, 0,
+ name_start, name_end,
+ argnum, value, pass);
+ }
+ if (backend == NULL || strcmp (backend, "Vala") == 0)
+ {
+ flag_context_list_table_insert (&flag_table_vala, 0,
+ name_start, name_end,
+ argnum, value, pass);
+ }
break;
case format_objc:
flag_context_list_table_insert (&flag_table_objc, 1,
extern struct formatstring_parser *current_formatstring_parser4;
-/* Record a flag in the appropriate backend's table. */
+/* Record a flag in the appropriate backend's table.
+ OPTIONSTRING has the syntax WORD:ARG:FLAG (as documented)
+ or WORD:ARG:FLAG!BACKEND.
+ The latter syntax is undocumented and only needed for format string types
+ that are used by multiple backends. */
extern void xgettext_record_flag (const char *optionstring);
xgettext-c-comment-4 xgettext-c-comment-5 xgettext-c-comment-6 \
xgettext-c-escape-1 xgettext-c-escape-2 xgettext-c-escape-3 \
xgettext-c-format-1 xgettext-c-format-2 xgettext-c-format-3 \
- xgettext-c-format-4 xgettext-c-format-5 \
+ xgettext-c-format-4 xgettext-c-format-5 xgettext-c-format-6 \
xgettext-c-ctxt-1 xgettext-c-ctxt-2 xgettext-c-ctxt-3 \
xgettext-c-c++-1 xgettext-c-c++-2 \
xgettext-c-stackovfl-1 xgettext-c-stackovfl-2 \
--- /dev/null
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test C support: verify that there are no side effects of the Vala extractor
+# on the C extractor.
+
+cat <<\EOF > xg-c-format-6.c
+/* For the C extractor, Q_ and X_ are unknown identifiers and should therefore
+ behave the same way. */
+printf (Q_("blablaQ %d and %s"), a, b);
+printf (Q_("blablaQ {0} and {1}"), a, b);
+printf (X_("blablaX %d and %s"), a, b);
+printf (X_("blablaX {0} and {1}"), a, b);
+EOF
+
+: ${XGETTEXT=xgettext}
+${XGETTEXT} --omit-header --no-location -kQ_ -kX_ \
+ -d xg-c-format-6.tmp xg-c-format-6.c || Exit 1
+LC_ALL=C tr -d '\r' < xg-c-format-6.tmp.po > xg-c-format-6.po || Exit 1
+
+cat <<EOF > xg-c-format-6.ok
+#, c-format
+msgid "blablaQ %d and %s"
+msgstr ""
+
+msgid "blablaQ {0} and {1}"
+msgstr ""
+
+#, c-format
+msgid "blablaX %d and %s"
+msgstr ""
+
+msgid "blablaX {0} and {1}"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-c-format-6.ok xg-c-format-6.po
+result=$?
+
+exit $result