From d37d1f54c986ff67af0e5edc62af60a4a1a21324 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 17 Apr 2021 12:24:36 +0200 Subject: Do not use libsimple outside of the generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 2 +- calc-example/calc.c | 36 ++++++++++++++++++------------------ config.mk | 2 +- libparser.c | 42 ++++++++++++++++++++++++++++++++++-------- libparser.h | 3 +-- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index c8628b0..9d3fc05 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ calc-example/calc-syntax.o: calc-example/calc-syntax.c libparser.h $(CC) -fPIC -c -o $@ $< $(CPPFLAGS) $(CFLAGS) libparser-generate: libparser-generate.o - $(CC) -o $@ libparser-generate.o $(LDFLAGS) + $(CC) -o $@ libparser-generate.o $(LDFLAGS) -lsimple libparser.a: libparser.o $(AR) rc $@ libparser.o diff --git a/calc-example/calc.c b/calc-example/calc.c index adda2ba..c5f6396 100644 --- a/calc-example/calc.c +++ b/calc-example/calc.c @@ -1,9 +1,9 @@ /* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include #include -#include -#include - -USAGE(""); static void @@ -107,29 +107,29 @@ main(int argc, char *argv[]) size_t size = 0; ssize_t len; intmax_t res; - int exception; + int r; - ARGBEGIN { - default: - usage(); - } ARGEND; - if (argc) - usage(); + if (argc == 2 ? strcmp(argv[1], "--") : argc > 2) { + fprintf(stderr, "usage: %s\n", argv[0]); + return 1; + } while ((len = getline(&line, &size, stdin)) >= 0) { if (len && line[len - 1] == '\n') line[--len] = '\0'; - input = libparser_parse_file(libparser_rule_table, line, (size_t)len, &exception); - if (!input) { - weprintf("didn't find anything to parse\n"); - free_input(input); + r = libparser_parse_file(libparser_rule_table, line, (size_t)len, &input); + if (r < 0) { + perror("libparser_parse_file"); + continue; + } else if (!input) { + fprintf(stderr, "didn't find anything to parse\n"); continue; } else if (input->end != (size_t)len) { - weprintf("line could not be parsed, stopped at column %zu\n", input->end); + fprintf(stderr, "line could not be parsed, stopped at column %zu\n", input->end); free_input(input); continue; - } else if (exception) { - weprintf("premature end of line\n"); + } else if (!r) { + fprintf(stderr, "premature end of line\n"); free_input(input); continue; } diff --git a/config.mk b/config.mk index ac056a6..accd17b 100644 --- a/config.mk +++ b/config.mk @@ -5,4 +5,4 @@ CC = cc CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -I"$$(pwd)" CFLAGS = -std=c99 -Wall -O2 -LDFLAGS = -s -lsimple +LDFLAGS = -s diff --git a/libparser.c b/libparser.c index 9ee22a1..36b662d 100644 --- a/libparser.c +++ b/libparser.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include "libparser.h" -#include +#include +#include struct context { @@ -9,8 +10,9 @@ struct context { const char *data; size_t length; size_t position; - int done; - int exception; + char done; + char exception; + char error; }; @@ -28,6 +30,18 @@ free_unit(struct libparser_unit *unit, struct context *ctx) } +static void +dealloc_unit(struct libparser_unit *unit) +{ + struct libparser_unit *next; + for (; unit; unit = next) { + dealloc_unit(unit->in); + next = unit->next; + free(unit); + } +} + + static struct libparser_unit * try_match(const char *rule, const union libparser_sentence *sentence, struct context *ctx) { @@ -37,7 +51,12 @@ try_match(const char *rule, const union libparser_sentence *sentence, struct con size_t i; if (!ctx->cache) { - unit = ecalloc(1, sizeof(*unit)); + unit = calloc(1, sizeof(*unit)); + if (!unit) { + ctx->done = 1; + ctx->error = 1; + return NULL; + } } else { unit = ctx->cache; ctx->cache = unit->next; @@ -168,8 +187,8 @@ mismatch: } -struct libparser_unit * -libparser_parse_file(const struct libparser_rule *const rules[], const char *data, size_t length, int *exceptionp) +int +libparser_parse_file(const struct libparser_rule *const rules[], const char *data, size_t length, struct libparser_unit **rootp) { struct libparser_unit *ret, *t; struct context ctx; @@ -181,6 +200,7 @@ libparser_parse_file(const struct libparser_rule *const rules[], const char *dat ctx.length = length; ctx.position = 0; ctx.done = 0; + ctx.error = 0; ctx.exception = 0; for (i = 0; rules[i]; i++) @@ -190,7 +210,6 @@ libparser_parse_file(const struct libparser_rule *const rules[], const char *dat abort(); ret = try_match(rules[i]->name, rules[i]->sentence, &ctx); - *exceptionp = ctx.exception; while (ctx.cache) { t = ctx.cache; @@ -198,5 +217,12 @@ libparser_parse_file(const struct libparser_rule *const rules[], const char *dat free(t); } - return ret; + if (ctx.error) { + dealloc_unit(ret); + *rootp = NULL; + return -1; + } + + *rootp = ret; + return !ctx.exception; } diff --git a/libparser.h b/libparser.h index 31d29b6..ed7f0f7 100644 --- a/libparser.h +++ b/libparser.h @@ -72,7 +72,6 @@ struct libparser_unit { extern const struct libparser_rule *const libparser_rule_table[]; -struct libparser_unit *libparser_parse_file(const struct libparser_rule *const rules[], - const char *data, size_t length, int *exceptionp); +int libparser_parse_file(const struct libparser_rule *const rules[], const char *data, size_t length, struct libparser_unit **rootp); #endif -- cgit v1.2.3-70-g09d2