poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] pkl: Add support for %% in format string


From: Mohammad-Reza Nabipoor
Subject: [PATCH] pkl: Add support for %% in format string
Date: Sun, 5 Dec 2021 01:20:20 +0330

2021-12-04  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>

        * libpoke/pkl-trans.c (pkl_trans1_ps_format): Add support for `%%`
        in format string of `printf` and `format`.
        * testsuite/poke.pkl/printf-36.pk: New test.
        * testsuite/poke.pkl/format-36.pk: Likewise.
        * testsuite/Makefile.am (EXTRA_DIST): Update.
---
 ChangeLog                       |   8 +++
 libpoke/pkl-trans.c             | 119 +++++++++++++++++++-------------
 testsuite/Makefile.am           |   2 +
 testsuite/poke.pkl/format-36.pk |   5 ++
 testsuite/poke.pkl/printf-36.pk |   3 +
 5 files changed, 88 insertions(+), 49 deletions(-)
 create mode 100644 testsuite/poke.pkl/format-36.pk
 create mode 100644 testsuite/poke.pkl/printf-36.pk

diff --git a/ChangeLog b/ChangeLog
index 7fb5e42c..a3a82394 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2021-12-04  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * libpoke/pkl-trans.c (pkl_trans1_ps_format): Add support for `%%`
+       in format string of `printf` and `format`.
+       * testsuite/poke.pkl/printf-36.pk: New test.
+       * testsuite/poke.pkl/format-36.pk: Likewise.
+       * testsuite/Makefile.am (EXTRA_DIST): Update.
+
 2021-12-04  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
 
        * libpoke/libpoke.h (pk_map_decl_fn): Add new param (`pk_val value`).
diff --git a/libpoke/pkl-trans.c b/libpoke/pkl-trans.c
index 9943e22d..27d8fa73 100644
--- a/libpoke/pkl-trans.c
+++ b/libpoke/pkl-trans.c
@@ -659,6 +659,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_format)
 #define MAX_CLASS_TAGS 32
   int nclasses = 0;
   char *classes[MAX_CLASS_TAGS];
+  int add_new_percent_arg_p = 0;
+  int add_new_style_arg_p = 0;
+  char *new_style_class = NULL;
 
   /* Calculate the number of arguments.  */
   for (t = args; t; t = PKL_AST_CHAIN (t))
@@ -692,7 +695,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_format)
       int prefix = -1;
 
       assert (*p == '%');
-      if (ntag >= nargs && p[1] != '>' && p[1] != '<')
+      if (ntag >= nargs && p[1] != '%' && p[1] != '>' && p[1] != '<')
         {
           PKL_ERROR (PKL_AST_LOC (format), "not enough format arguments");
           PKL_TRANS_PAYLOAD->errors++;
@@ -728,6 +731,10 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_format)
       /* Now process the rest of the tag.  */
       switch (p[1])
         {
+        case '%':
+          p += 2;
+          add_new_percent_arg_p = 1;
+          break;
         case 'v':
           p += 2;
           PKL_AST_FORMAT_ARG_BASE (arg) = 0; /* Arbitrary.  */
@@ -850,7 +857,6 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_format)
             int end_sc = 0;
             char *class = xmalloc (strlen (fmt) + 1);
             size_t j;
-            pkl_ast_node new_arg;
 
             end_sc = (p[1] == '>');
             p += 2;
@@ -897,53 +903,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_format)
                 class = classes[--nclasses];
               }
 
-            /* Create the new arg and add it to the list of
-               arguments.  */
-            new_arg = pkl_ast_make_format_arg (PKL_PASS_AST,
-                                                   NULL);
-            PKL_AST_LOC (new_arg) = PKL_AST_LOC (format_fmt);
-
-            if (end_sc)
-              PKL_AST_FORMAT_ARG_END_SC (new_arg) = xstrdup (class);
-            else
-              PKL_AST_FORMAT_ARG_BEGIN_SC (new_arg) = class;
-
-            if (arg)
-              {
-                if (arg == PKL_AST_FORMAT_ARGS (format))
-                  {
-                    /* Prepend.  */
-                    PKL_AST_CHAIN (new_arg) = arg;
-                    PKL_AST_FORMAT_ARGS (format)
-                      = ASTREF (new_arg);
-                  }
-                else
-                  {
-                    /* Add after.  */
-                    PKL_AST_CHAIN (new_arg) = PKL_AST_CHAIN (prev_arg);
-                    PKL_AST_CHAIN (prev_arg) = ASTREF (new_arg);
-                  }
-              }
-            else
-              {
-                /* Append.  */
-                if (!PKL_AST_FORMAT_ARGS (format))
-                  PKL_AST_FORMAT_ARGS (format)
-                    = ASTREF (new_arg);
-                else
-                  PKL_AST_FORMAT_ARGS (format)
-                    = pkl_ast_chainon (PKL_AST_FORMAT_ARGS (format),
-                                       new_arg);
-              }
-
-            arg = new_arg;
-
-            /* The type corresponding to a styling class format
-               directive is `void'.  */
-            atype = pkl_ast_make_void_type (PKL_PASS_AST);
-            PKL_AST_LOC (atype) = PKL_AST_LOC (format_fmt);
-            types = pkl_ast_chainon (types, atype);
-
+            assert (new_style_class == NULL);
+            new_style_class = end_sc ? xstrdup (class) : class;
+            add_new_style_arg_p = 1;
             break;
           }
         default:
@@ -951,6 +913,65 @@ PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_format)
           goto invalid_tag;
         }
 
+      assert (!(add_new_percent_arg_p && add_new_style_arg_p));
+      if (add_new_percent_arg_p || add_new_style_arg_p)
+        {
+          pkl_ast_node new_arg;
+
+          /* Create the new arg and add it to the list of arguments.  */
+          new_arg = pkl_ast_make_format_arg (PKL_PASS_AST, NULL);
+          PKL_AST_LOC (new_arg) = PKL_AST_LOC (format_fmt);
+
+          if (add_new_percent_arg_p)
+            PKL_AST_FORMAT_ARG_SUFFIX (new_arg) = xstrdup ("%");
+          else if (add_new_style_arg_p)
+            {
+              int end_sc = p[-1] == '>';
+
+              assert (new_style_class != NULL);
+              if (end_sc)
+                PKL_AST_FORMAT_ARG_END_SC (new_arg) = new_style_class;
+              else
+                PKL_AST_FORMAT_ARG_BEGIN_SC (new_arg) = new_style_class;
+              new_style_class = NULL;
+            }
+
+          if (arg)
+            {
+              if (arg == PKL_AST_FORMAT_ARGS (format))
+                {
+                  /* Prepend.  */
+                  PKL_AST_CHAIN (new_arg) = arg;
+                  PKL_AST_FORMAT_ARGS (format) = ASTREF (new_arg);
+                }
+              else
+                {
+                  /* Add after.  */
+                  PKL_AST_CHAIN (new_arg) = PKL_AST_CHAIN (prev_arg);
+                  PKL_AST_CHAIN (prev_arg) = ASTREF (new_arg);
+                }
+            }
+          else
+            {
+              /* Append.  */
+              if (!PKL_AST_FORMAT_ARGS (format))
+                PKL_AST_FORMAT_ARGS (format) = ASTREF (new_arg);
+              else
+                PKL_AST_FORMAT_ARGS (format)
+                  = pkl_ast_chainon (PKL_AST_FORMAT_ARGS (format), new_arg);
+            }
+
+          arg = new_arg;
+
+          /* The type corresponding to new arg is `void'.  */
+          atype = pkl_ast_make_void_type (PKL_PASS_AST);
+          PKL_AST_LOC (atype) = PKL_AST_LOC (format_fmt);
+          types = pkl_ast_chainon (types, atype);
+
+          add_new_percent_arg_p = 0;
+          add_new_style_arg_p = 0;
+        }
+
       /* Add the optional suffix to the argument.  */
       if (*p != '\0' && *p != '%')
         {
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index aadbbddd..add9f58c 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -1065,6 +1065,7 @@ EXTRA_DIST = \
   poke.pkl/format-33.pk \
   poke.pkl/format-34.pk \
   poke.pkl/format-35.pk \
+  poke.pkl/format-36.pk \
   poke.pkl/format-diag-1.pk \
   poke.pkl/formfeedchar.pk \
   poke.pkl/fun-types-1.pk \
@@ -1525,6 +1526,7 @@ EXTRA_DIST = \
   poke.pkl/printf-33.pk \
   poke.pkl/printf-34.pk \
   poke.pkl/printf-35.pk \
+  poke.pkl/printf-36.pk \
   poke.pkl/printf-binary-1.pk \
   poke.pkl/printf-binary-2.pk \
   poke.pkl/printf-binary-3.pk \
diff --git a/testsuite/poke.pkl/format-36.pk b/testsuite/poke.pkl/format-36.pk
new file mode 100644
index 00000000..b2df3211
--- /dev/null
+++ b/testsuite/poke.pkl/format-36.pk
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+
+/* { dg-command {.set obase 10} } */
+/* { dg-command {format("%%%i32d%%", 23)} } */
+/* { dg-output {"%23%"} } */
diff --git a/testsuite/poke.pkl/printf-36.pk b/testsuite/poke.pkl/printf-36.pk
new file mode 100644
index 00000000..c9231abf
--- /dev/null
+++ b/testsuite/poke.pkl/printf-36.pk
@@ -0,0 +1,3 @@
+/* { dg-do run } */
+
+printf "%%%i45o%%", -1;          /* { dg-output "%777777777777777%" } */
-- 
2.34.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]