aboutsummaryrefslogtreecommitdiffstats
path: root/libparser.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-05 15:18:50 +0100
committerMattias Andrée <m@maandree.se>2026-02-23 07:53:09 +0100
commit28b0a361363acbd9a2d291d82e145fb3757ed9f8 (patch)
treeb86f7c42410ada38631bbdd4ada2a3d4120660f6 /libparser.c
parentMake deterministic the default (diff)
downloadlibparser-28b0a361363acbd9a2d291d82e145fb3757ed9f8.tar.gz
libparser-28b0a361363acbd9a2d291d82e145fb3757ed9f8.tar.bz2
libparser-28b0a361363acbd9a2d291d82e145fb3757ed9f8.tar.xz
Add \t and improve printing of text, and print the input text when PRINT_ACTIONS used
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libparser.c')
-rw-r--r--libparser.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/libparser.c b/libparser.c
index 5ecb7ee..2a925b7 100644
--- a/libparser.c
+++ b/libparser.c
@@ -363,6 +363,54 @@ print_state(struct context *ctx)
static int
+print_text(const char *text, size_t textlen)
+{
+ size_t off = 0, n = 0;
+ int len, ret = 0;
+
+ while (off + n < textlen) {
+ if (!text[off + n])
+ break;
+ if (text[off + n] < ' ' || text[off + n] >= 0x7F ||
+ text[off + n] == '"' || text[off + n] == '\\') {
+ fprintf(stderr, "%.*s%n", (int)n, &text[off], &len);
+ ret += len;
+ off += n;
+ n = 0;
+ switch (text[off]) {
+ case '\\': fprintf(stderr, "\\\\%n", &len); break;
+ case '\"': fprintf(stderr, "\\\"%n", &len); break;
+ case '\a': fprintf(stderr, "\\a%n", &len); break;
+ case '\b': fprintf(stderr, "\\b%n", &len); break;
+ case '\f': fprintf(stderr, "\\f%n", &len); break;
+ case '\n': fprintf(stderr, "\\n%n", &len); break;
+ case '\r': fprintf(stderr, "\\r%n", &len); break;
+ case '\t': fprintf(stderr, "\\t%n", &len); break;
+ case '\v': fprintf(stderr, "\\v%n", &len); break;
+ default:
+ fprintf(stderr, "\\x%02X%n", +(unsigned char)text[off], &len);
+ break;
+ }
+ off++;
+ } else if (n == 4096U) {
+ fprintf(stderr, "%.*s%n", (int)n, &text[off], &len);
+ ret += len;
+ off += n;
+ n = 0;
+ } else {
+ n++;
+ }
+ }
+ if (n) {
+ fprintf(stderr, "%.*s%n", (int)n, &text[off], &len);
+ ret += len;
+ }
+
+ return ret;
+}
+
+
+static int
print_sentence(const union libparser_sentence *sentence, int indent)
{
unsigned char low, high;
@@ -431,7 +479,9 @@ print_sentence(const union libparser_sentence *sentence, int indent)
break;
case LIBPARSER_SENTENCE_TYPE_STRING:
- fprintf(stderr, "\"%.*s\"%n", (int)sentence->string.length, sentence->string.string, &len);
+ fprintf(stderr, "\"%n", &len);
+ indent += len + print_text(sentence->string.string, sentence->string.length);
+ fprintf(stderr, "\"%n", &len);
indent += len;
break;
@@ -1200,6 +1250,9 @@ libparser_parse_file(const struct libparser_rule *const rules[], const char *dat
#if PRINT_ACTIONS
print_grammar(rules);
+ fprintf(stderr, "Input text: \"");
+ print_text(ctx.data, ctx.length);
+ fprintf(stderr, "\"\n");
#endif
/* TODO guard against left-side recursion */