[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
- [PATCH] pkl: Add support for %% in format string,
Mohammad-Reza Nabipoor <=