Initial commit
This commit is contained in:
81
src/spp.c
Normal file
81
src/spp.c
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "../include/spp.h"
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool spp_is(const struct Stream s, const char *list) {
|
||||
assert(list != NULL);
|
||||
assert(s.content != NULL && *s.content != NULL);
|
||||
|
||||
return strchr(list, **s.content);
|
||||
}
|
||||
|
||||
bool spp_eof(const struct Stream s) {
|
||||
assert(s.content != NULL && *s.content != NULL);
|
||||
|
||||
return **s.content == 0;
|
||||
}
|
||||
|
||||
char spp_take(const struct Stream s, const char *list) {
|
||||
if (!spp_is(s, list))
|
||||
return 0;
|
||||
|
||||
const char p = **s.content;
|
||||
(*s.content)++;
|
||||
return p;
|
||||
}
|
||||
|
||||
uintptr_t spp_skip(const struct Stream s, const char *list) {
|
||||
uintptr_t size = 0;
|
||||
for (; !spp_eof(s) && spp_is(s, list); size++) {
|
||||
(*s.content)++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
uintptr_t spp_until(const struct Stream s, const char *list) {
|
||||
uintptr_t size = 0;
|
||||
for (; !spp_eof(s) && !spp_is(s, list); size++) {
|
||||
(*s.content)++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
const char *spp_cursor(struct Stream s) {
|
||||
return *s.content;
|
||||
}
|
||||
|
||||
uintptr_t spp_parse(struct Stream s, parse fn, const char *buf[], ptrdiff_t cnt[], uintptr_t cap) {
|
||||
assert(fn != NULL);
|
||||
assert(buf != NULL);
|
||||
assert(cnt != NULL);
|
||||
|
||||
uintptr_t n = 0;
|
||||
|
||||
while (!spp_eof(s) && n < cap) {
|
||||
const char *start = NULL;
|
||||
ptrdiff_t len = 0;
|
||||
|
||||
const char *before = spp_cursor(s);
|
||||
|
||||
if (!fn(s, &start, &len)) {
|
||||
// Prevent infinite loop if callback fails to consume
|
||||
if (spp_cursor(s) == before) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
buf[n] = start;
|
||||
cnt[n] = len;
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user