]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
format-python-brace: Support chained expression
authorDaiki Ueno <ueno@gnu.org>
Wed, 23 Mar 2016 06:17:21 +0000 (15:17 +0900)
committerDaiki Ueno <ueno@gnu.org>
Wed, 23 Mar 2016 06:25:24 +0000 (15:25 +0900)
* 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

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

index a212707c6f830dd4fdc0a125d98cff076598073f..c76088c95596a3be136882c95bb8793416c7053f 100644 (file)
@@ -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 == ':')
index 601b0239a4dc2104f7e94583ee3b4b00dca13b94..3a1f9eab6055fc6f48781944db648c10858342d1 100755 (executable)
@@ -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