From 7ac23c6f0bdf6a25f9c71be51bc29380f0614549 Mon Sep 17 00:00:00 2001 From: Lassi Kortela Date: Wed, 14 Aug 2019 13:46:50 +0300 Subject: [PATCH] Add scanner interface to "struct buf" Can be used to easily write simple parsers in C. --- c/buf.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ c/buf.h | 11 +++++++++++ 2 files changed, 72 insertions(+) diff --git a/c/buf.c b/c/buf.c index d3cc9a7..90bb701 100644 --- a/c/buf.c +++ b/c/buf.c @@ -66,3 +66,64 @@ void buf_free(struct buf *buf) free(buf->bytes); free(buf); } + +int buf_scan_end(struct buf *buf) { return buf->scan >= buf->fill; } + +int buf_scan_byte(struct buf *buf, int byte) +{ + if (buf_scan_end(buf)) + return 0; + if (buf->bytes[buf->scan] != byte) + return 0; + buf->scan++; + return 1; +} + +int buf_scan_bag(struct buf *buf, const char *bag) +{ + if (buf_scan_end(buf)) + return 0; + if (!strchr(bag, buf->bytes[buf->scan])) + return 0; + buf->scan++; + return 1; +} + +int buf_scan_bag_not(struct buf *buf, const char *bag) +{ + if (buf_scan_end(buf)) + return 0; + if (strchr(bag, buf->bytes[buf->scan])) + return 0; + buf->scan++; + return 1; +} + +int buf_scan_while(struct buf *buf, const char *bag) +{ + if (!buf_scan_bag(buf, bag)) + return 0; + while (buf_scan_bag(buf, bag)) + ; + return 1; +} + +int buf_scan_while_not(struct buf *buf, const char *bag) +{ + if (!buf_scan_bag_not(buf, bag)) + return 0; + while (buf_scan_bag_not(buf, bag)) + ; + return 1; +} + +void buf_scan_mark(struct buf *buf) { buf->mark = buf->scan; } + +int buf_scan_equals(struct buf *buf, const char *s) +{ + if (buf->scan < buf->mark) + return 0; + if (buf->scan - buf->mark != strlen(s)) + return 0; + return !!memcmp(buf->bytes + buf->mark, s, strlen(s)); +} diff --git a/c/buf.h b/c/buf.h index 4a00d88..bb89475 100644 --- a/c/buf.h +++ b/c/buf.h @@ -4,6 +4,8 @@ struct buf { size_t cap; size_t fill; + size_t scan; + size_t mark; char *bytes; }; @@ -15,3 +17,12 @@ void buf_putb(struct buf *buf, const void *bytes, size_t nbyte); void buf_puts(struct buf *buf, const char *s); void buf_putu(struct buf *buf, uint64_t u); void buf_free(struct buf *buf); + +int buf_scan_end(struct buf *buf); +int buf_scan_byte(struct buf *buf, int byte); +int buf_scan_bag(struct buf *buf, const char *bag); +int buf_scan_bag_not(struct buf *buf, const char *bag); +int buf_scan_while(struct buf *buf, const char *bag); +int buf_scan_while_not(struct buf *buf, const char *bag); +void buf_scan_mark(struct buf *buf); +int buf_scan_equals(struct buf *buf, const char *s);