summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2023-03-12 13:11:58 +0100
committerBruno Haible <bruno@clisp.org>2023-03-14 02:57:28 +0100
commit3396633eb956e024589147031956b4b0392b3ba0 (patch)
tree258d76990f8bde652e6d1624330c55308645258b
parentc8bf9978901a484516a0181c581bfe8915defbbc (diff)
downloadgettext-3396633eb956e024589147031956b4b0392b3ba0.tar.gz
Fix python-brace-format: Fix placement of FMTDIR_ERROR marker.
* gettext-tools/src/format-python-brace.c (parse_directive): Simplify. Fix placement of FMTDIR_ERROR marker and improve error message in one case. * gettext-tools/tests/format-python-brace-1: Add more test cases.
-rw-r--r--gettext-tools/src/format-python-brace.c39
-rwxr-xr-xgettext-tools/tests/format-python-brace-16
2 files changed, 24 insertions, 21 deletions
diff --git a/gettext-tools/src/format-python-brace.c b/gettext-tools/src/format-python-brace.c
index c5c0a076e..cd5307721 100644
--- a/gettext-tools/src/format-python-brace.c
+++ b/gettext-tools/src/format-python-brace.c
@@ -128,6 +128,12 @@ parse_numeric_field (struct spec *spec,
return false;
}
+/* Parses a directive.
+ When this function is invoked, *formatp points to the start of the directive,
+ i.e. to the '{' character.
+ When this function returns true, *formatp points to the first character after
+ the directive, i.e. in most cases to the character after the '}' character.
+ */
static bool
parse_directive (struct spec *spec,
const char **formatp, bool is_toplevel,
@@ -141,6 +147,7 @@ parse_directive (struct spec *spec,
c = *++format;
if (c == '{')
{
+ /* An escaped '{'. */
*formatp = ++format;
return true;
}
@@ -191,18 +198,21 @@ parse_directive (struct spec *spec,
return false;
}
- c = *format++;
- if (c != ']')
+ if (*format != ']')
{
- *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
+ *invalid_reason =
+ xasprintf (_("In the directive number %u, there is an unterminated getitem argument."),
+ spec->directives);
FDI_SET (format, FMTDIR_ERROR);
return false;
}
+ format++;
}
else
break;
}
+ /* Here c == *format. */
if (c == ':')
{
if (!is_toplevel)
@@ -214,6 +224,8 @@ parse_directive (struct spec *spec,
return false;
}
+ format++;
+
/* Format specifiers. Although a format specifier can be any
string in theory, we can only recognize two types of format
specifiers below, because otherwise we would need to evaluate
@@ -222,7 +234,6 @@ parse_directive (struct spec *spec,
- A nested format directive expanding to an argument
- The Standard Format Specifiers, as described in PEP3101,
not including a nested format directive */
- format++;
if (*format == '{')
{
/* Nested format directive. */
@@ -233,13 +244,6 @@ parse_directive (struct spec *spec,
parse_directive. */
return false;
}
-
- if (*format != '}')
- {
- *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
- FDI_SET (format, FMTDIR_ERROR);
- return false;
- }
}
else
{
@@ -300,21 +304,14 @@ parse_directive (struct spec *spec,
default:
break;
}
-
- if (*format != '}')
- {
- *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
- FDI_SET (format, FMTDIR_ERROR);
- return false;
- }
}
- c = *format;
}
- if (c != '}')
+ if (*format != '}')
{
*invalid_reason =
- xasprintf (_("In the directive number %u, there is an unterminated format directive."), spec->directives);
+ xasprintf (_("In the directive number %u, there is an unterminated format directive."),
+ spec->directives);
FDI_SET (format, FMTDIR_ERROR);
return false;
}
diff --git a/gettext-tools/tests/format-python-brace-1 b/gettext-tools/tests/format-python-brace-1
index 4c7b1b35d..0028f7fdb 100755
--- a/gettext-tools/tests/format-python-brace-1
+++ b/gettext-tools/tests/format-python-brace-1
@@ -32,8 +32,14 @@ cat <<\EOF > f-pyb-1.data
"abc{value[!]}"
# Valid: use of both getattr and getitem operators
"abc{value.v[name]}"
+# Valid: use of both getitem and getattr operators
+"abc{value[name].v}"
# Valid: format specifier
"abc{value:0}"
+# Valid: format specifier after getattr operator
+"abc{value.name:0}"
+# Valid: format specifier after getitem operator
+"abc{value[name]:0}"
# Valid: standard format specifier
"abc{value:<<-#012.34e}"
# Invalid: empty precision