aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile2
-rw-r--r--calc-example/calc.c36
-rw-r--r--config.mk2
-rw-r--r--libparser.c42
-rw-r--r--libparser.h3
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 <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;
}
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 <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