diff options
Diffstat (limited to '')
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | calc-example/calc.c | 36 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | libparser.c | 42 | ||||
-rw-r--r-- | libparser.h | 3 |
5 files changed, 55 insertions, 30 deletions
@@ -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 <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <libparser.h> -#include <libsimple.h> -#include <libsimple-arg.h> - -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; } @@ -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 <libsimple.h> +#include <stdlib.h> +#include <string.h> 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 |