]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Fix python-brace-format: Fix placement of FMTDIR_ERROR marker.
authorBruno Haible <bruno@clisp.org>
Sun, 12 Mar 2023 12:11:58 +0000 (13:11 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 14 Mar 2023 01:57:28 +0000 (02:57 +0100)
* 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.

gettext-tools/src/format-python-brace.c
gettext-tools/tests/format-python-brace-1

index c5c0a076e412cf476d3960cd5e93fdd07a35cd5a..cd53077214b774459bcb2712e16ccfe40adef28a 100644 (file)
@@ -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;
     }
index 4c7b1b35df089ae9020749d46b4a53e4c239ee8b..0028f7fdb5ac5164dbd9c3da570322319f33ac25 100755 (executable)
@@ -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