Add scanner interface to "struct buf"

Can be used to easily write simple parsers in C.
This commit is contained in:
Lassi Kortela 2019-08-14 13:46:50 +03:00
parent 44a8208d38
commit 7ac23c6f0b
2 changed files with 72 additions and 0 deletions

61
c/buf.c
View File

@ -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));
}

11
c/buf.h
View File

@ -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);