diff options
author | Daiki Ueno <ueno@gnu.org> | 2016-03-23 15:17:21 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2016-03-23 15:25:24 +0900 |
commit | b4220c509a90186931a69575981c1b0e80ffc1f6 (patch) | |
tree | ad4c7322b29c85b2c598ae34b26afd9545e0af2b | |
parent | 009c1218593a5f5a6d132b3694e4e679572eff9f (diff) | |
download | external_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.c | 67 | ||||
-rwxr-xr-x | gettext-tools/tests/format-python-brace-1 | 2 |
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 |