From 29086b1d12a2c28cffdbfbf0b3990a7bd75506b9 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Thu, 20 Apr 2017 16:49:35 +0300 Subject: work in progress --- src/ragel/ragel.h | 244 +++++------------------------------------------------- 1 file changed, 19 insertions(+), 225 deletions(-) (limited to 'src/ragel/ragel.h') diff --git a/src/ragel/ragel.h b/src/ragel/ragel.h index af06f4a..b2c7572 100644 --- a/src/ragel/ragel.h +++ b/src/ragel/ragel.h @@ -1,236 +1,30 @@ #pragma once -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -struct ragel { - struct { - uint8_t *data; // data\0another_data\0 - const uint8_t *cur; // data\0another_data\0cursor - size_t written, size; // amount of data written / size of data - } mem; +struct ragel_mem { + const char *data, *end; + bool binary; // binary input bit +}; - char buf[4096]; // block of input data +struct ragel { + struct ragel_mem input; // block of input data + uint64_t lineno; // current line const char *p, *pe, *eof; // see ragel doc - size_t lineno; // current line + const char *cl; // current line start + const char *name; // may be current file name for example + bool error; // error thrown bit }; -static inline void -ragel_get_current_line(const struct ragel *ragel, size_t *out_lineno, size_t *out_ls, size_t *out_le, size_t *out_ws, size_t *out_we) -{ - assert(out_ls && out_le && out_ws && out_we); - assert(ragel->p >= ragel->buf && ragel->pe >= ragel->p); - - size_t ls, le, ws, we; - size_t off = ragel->p - ragel->buf; - size_t lineno = ragel->lineno; - const size_t end = ragel->pe - ragel->buf; - - // rewind to first non-space - for (; off > 0 && (isspace(ragel->buf[off]) || !ragel->buf[off]); --off) { - if (lineno > 0 && ragel->buf[off] == '\n') - --lineno; - } - - for (ls = off; ls > 0 && ragel->buf[ls] != '\n'; --ls); // beginning of line - for (le = off; le < end && ragel->buf[le] != '\n'; ++le); // end of line - for (; ls < le && isspace(ragel->buf[ls]); ++ls); // strip leading whitespace - for (ws = off; ws > ls && isspace(ragel->buf[ws]); --ws); // rewind to first non-space - for (; ws > 0 && ws > ls && !isspace(ragel->buf[ws - 1]); --ws); // find word start - for (we = ws; we < le && !isspace(ragel->buf[we]); ++we); // find word ending - - assert(we >= ws && ws >= ls && le >= ls && le >= we); - *out_lineno = lineno; - *out_ls = ls; - *out_le = le; - *out_ws = ws; - *out_we = we; -} - -__attribute__((format(printf, 2, 3))) -static inline void -ragel_throw_error(const struct ragel *ragel, const char *fmt, ...) -{ - assert(ragel && fmt); - - size_t lineno, ls, le, ws, we; - ragel_get_current_line(ragel, &lineno, &ls, &le, &ws, &we); - assert(le - ls <= INT_MAX && ws - ls <= INT_MAX); - - char msg[255]; - va_list args; - va_start(args, fmt); - vsnprintf(msg, sizeof(msg), fmt, args); - va_end(args); - - const int indent = 8; - const size_t mark = (we - ws ? we - ws : 1), cur = (ragel->p - ragel->buf) - ws; - warnx("\x1b[37m%zu: \x1b[31merror: \x1b[0m%s\n%*s%.*s", lineno, msg, indent, "", (int)(le - ls), ragel->buf + ls); - fprintf(stderr, "%*s%*s\x1b[31m", indent, "", (int)(ws - ls), ""); - for (size_t i = 0; i < mark; ++i) fputs((i == cur ? "^" : "~"), stderr); - fputs("\x1b[0m\n", stderr); - - exit(EXIT_FAILURE); -} - -static inline void -ragel_bounds_check_data(const struct ragel *ragel, const size_t nmemb) -{ - assert(ragel); - - if (ragel->mem.size < nmemb || ragel->mem.written >= ragel->mem.size - nmemb) - ragel_throw_error(ragel, "data storage limit exceeded: %zu bytes exceeds the maximum store size of %zu bytes", ragel->mem.written, ragel->mem.size); -} - -static inline void -ragel_replace_data(struct ragel *ragel, const size_t nmemb, char replacement) -{ - assert(ragel); - - if (ragel->mem.written < nmemb) - ragel_throw_error(ragel, "parse error: received escape conversion with mem.written of %zu, expected >= %zu", ragel->mem.written, nmemb); - - ragel->mem.data[(ragel->mem.written -= nmemb)] = replacement; - ragel->mem.data[++ragel->mem.written] = 0; -} - -static inline void -ragel_convert_escape(struct ragel *ragel) -{ - assert(ragel); - - if (ragel->mem.written < 2) - ragel_throw_error(ragel, "parse error: received escape conversion with mem.written of %zu, expected >= 2", ragel->mem.written); - - const struct { - const char *e; - const char v, b; - } map[] = { - { .e = "\\a", .v = '\a' }, - { .e = "\\b", .v = '\b' }, - { .e = "\\f", .v = '\f' }, - { .e = "\\n", .v = '\n' }, - { .e = "\\r", .v = '\r' }, - { .e = "\\t", .v = '\t' }, - { .e = "\\v", .v = '\v' }, - { .e = "\\\\", .v = '\\' }, - { .e = "\\'", .v = '\'' }, - { .e = "\\\"", .v = '"' }, - { .e = "\\e", .v = '\e' }, - { .e = "\\x", .b = 16 }, - { .e = "\\", .b = 8 }, - }; - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - const char *cur = (char*)ragel->mem.cur; - const size_t cur_sz = strlen(cur); - for (size_t i = 0; i < ARRAY_SIZE(map); ++i) { - if (!strncmp(cur, map[i].e, strlen(map[i].e))) { - const char v = (!map[i].b ? map[i].v : strtol(cur + strlen(map[i].e), NULL, map[i].b)); - assert((map[i].b == 8 && cur_sz >= 2) || (map[i].b == 16 && cur_sz >= 2) || (map[i].b == 0 && cur_sz == 2)); - assert(map[i].b != 8 || isdigit(cur[1])); - ragel_replace_data(ragel, cur_sz, v); - return; - } - } -#undef ARRAY_SIZE - - ragel_throw_error(ragel, "parse error: received unknown escape conversion"); -} - -static inline void -ragel_dump_data(struct ragel *ragel, const size_t offset) -{ - const uint8_t *end = ragel->mem.data + ragel->mem.written; - for (const uint8_t *p = ragel->mem.data + offset; p && p < end; p = (uint8_t*)memchr(p, 0, end - p), p += !!p) - printf("%s\n", p); -} - -static inline const uint8_t* -ragel_search_data(const struct ragel *ragel, const size_t offset, const uint8_t *data, const size_t size) -{ - assert(ragel && data); - - const uint8_t *end = ragel->mem.data + ragel->mem.written; - for (const uint8_t *p = ragel->mem.data + offset; p && p < end && (size_t)(end - p) >= size; p = (uint8_t*)memchr(p, 0, end - p), p += !!p) { - if (!memcmp(data, p, size)) - return p; - } - - return NULL; -} - -static inline const uint8_t* -ragel_search_str(const struct ragel *ragel, const size_t offset, const char *str) -{ - return ragel_search_data(ragel, offset, (const uint8_t*)str, strlen(str) + 1); -} - -static inline void -ragel_remove_last_data(struct ragel *ragel) -{ - assert(ragel); - const uint8_t *end = ragel->mem.data + ragel->mem.written; - const size_t size = end - ragel->mem.cur + 1; - assert(ragel->mem.written >= size); - ragel->mem.written -= size; - ragel->mem.data[ragel->mem.written] = 0; -} - -static inline void -ragel_finish_data(struct ragel *ragel) -{ - assert(ragel); - - const uint8_t *end = ragel->mem.data + ragel->mem.written, *p; - if ((p = ragel_search_data(ragel, 0, ragel->mem.cur, end - ragel->mem.cur + 1))) { - ragel_remove_last_data(ragel); - ragel->mem.cur = p; - } -} - -static inline void -ragel_store_data(struct ragel *ragel) -{ - ragel_bounds_check_data(ragel, 1); - ragel->mem.data[ragel->mem.written++] = *ragel->p; - ragel->mem.data[ragel->mem.written] = 0; -} - -static inline void -ragel_begin_data(struct ragel *ragel) -{ - ragel_bounds_check_data(ragel, 1); - ragel->mem.written += (ragel->mem.written > 0); - ragel->mem.cur = ragel->mem.data + ragel->mem.written; -} - -static inline void -ragel_advance_line(struct ragel *ragel) -{ - assert(ragel); - ++ragel->lineno; -} +__attribute__((format(printf, 2, 3))) void +ragel_throw_error(struct ragel *ragel, const char *fmt, ...); -static inline bool -ragel_confirm_input(struct ragel *ragel, const size_t bytes) -{ - assert(ragel); +void +ragel_set_name(struct ragel *ragel, const char *name); - if (bytes > sizeof(ragel->buf)) - errx(EXIT_FAILURE, "%s: gave larger buffer than %zu", __func__, sizeof(ragel->buf)); +void +ragel_advance_line(struct ragel *ragel); - const bool in_eof = (bytes < sizeof(ragel->buf)); - ragel->p = ragel->buf; - ragel->pe = ragel->p + bytes; - ragel->eof = (in_eof ? ragel->pe : NULL); - return !in_eof; -} +void +ragel_feed_input(struct ragel *ragel, const bool eof, const struct ragel_mem *input); -- cgit v1.2.3