summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2016-03-23 15:17:21 +0900
committerDaiki Ueno <ueno@gnu.org>2016-03-23 15:25:24 +0900
commitb4220c509a90186931a69575981c1b0e80ffc1f6 (patch)
treead4c7322b29c85b2c598ae34b26afd9545e0af2b
parent009c1218593a5f5a6d132b3694e4e679572eff9f (diff)
downloadexternal_gettext-b4220c509a90186931a69575981c1b0e80ffc1f6.zip
external_gettext-b4220c509a90186931a69575981c1b0e80ffc1f6.tar.gz
external_gettext-b4220c509a90186931a69575981c1b0e80ffc1f6.tar.bz2
format-python-brace: Support chained expression
* gettext-tools/src/format-python-brace.c (parse_directive): Recognize chained getattr/getitem expressions. * gettext-tools/tests/format-python-brace-1: Add test for the case where both getattr and getitem are used. Reported by Paul Franklin in: https://lists.gnu.org/archive/html/bug-gettext/2016-03/msg00017.html
-rw-r--r--gettext-tools/src/format-python-brace.c67
-rwxr-xr-xgettext-tools/tests/format-python-brace-12
2 files changed, 39 insertions, 30 deletions
diff --git a/gettext-tools/src/format-python-brace.c b/gettext-tools/src/format-python-brace.c
index a212707..c76088c 100644
--- a/gettext-tools/src/format-python-brace.c
+++ b/gettext-tools/src/format-python-brace.c
@@ -140,42 +140,49 @@ parse_directive (struct spec *spec,
return false;
}
- c = *format;
- if (c == '.')
+ /* Parse '.' (getattr) or '[..]' (getitem) operators followed by a
+ name. If must not recurse, but can be specifed in a chain, such
+ as "foo.bar.baz[0]". */
+ for (;;)
{
- format++;
- if (!parse_named_field (spec, &format, translated, fdi,
- invalid_reason))
- {
- *invalid_reason =
- xasprintf (_("In the directive number %u, '%c' cannot start a getattr argument."), spec->directives, *format);
- FDI_SET (format, FMTDIR_ERROR);
- return false;
- }
c = *format;
- }
- else if (c == '[')
- {
- format++;
- if (!parse_named_field (spec, &format, translated, fdi,
- invalid_reason)
- && !parse_numeric_field (spec, &format, translated, fdi,
- invalid_reason))
+
+ if (c == '.')
{
- *invalid_reason =
- xasprintf (_("In the directive number %u, '%c' cannot start a getitem argument."), spec->directives, *format);
- FDI_SET (format, FMTDIR_ERROR);
- return false;
+ format++;
+ if (!parse_named_field (spec, &format, translated, fdi,
+ invalid_reason))
+ {
+ *invalid_reason =
+ xasprintf (_("In the directive number %u, '%c' cannot start a getattr argument."), spec->directives, *format);
+ FDI_SET (format, FMTDIR_ERROR);
+ return false;
+ }
}
-
- c = *format++;
- if (c != ']')
+ else if (c == '[')
{
- *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
- FDI_SET (format, FMTDIR_ERROR);
- return false;
+ format++;
+ if (!parse_named_field (spec, &format, translated, fdi,
+ invalid_reason)
+ && !parse_numeric_field (spec, &format, translated, fdi,
+ invalid_reason))
+ {
+ *invalid_reason =
+ xasprintf (_("In the directive number %u, '%c' cannot start a getitem argument."), spec->directives, *format);
+ FDI_SET (format, FMTDIR_ERROR);
+ return false;
+ }
+
+ c = *format++;
+ if (c != ']')
+ {
+ *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
+ FDI_SET (format, FMTDIR_ERROR);
+ return false;
+ }
}
- c = *format;
+ else
+ break;
}
if (c == ':')
diff --git a/gettext-tools/tests/format-python-brace-1 b/gettext-tools/tests/format-python-brace-1
index 601b023..3a1f9ea 100755
--- a/gettext-tools/tests/format-python-brace-1
+++ b/gettext-tools/tests/format-python-brace-1
@@ -30,6 +30,8 @@ cat <<\EOF > f-pyb-1.data
"abc{value[0}"
# Invalid: unknown character in getitem operator
"abc{value[!]}"
+# Valid: use of both getattr and getitem operators
+"abc{value.v[name]}"
# Valid: format specifier
"abc{value:0}"
# Valid: standard format specifier