From be1f2bc848e9c4386437fe4a6147a0a8d7f000ff Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 18 Aug 2019 09:05:28 -0400 Subject: Added string constants and improved tokenization --- util/arr.c | 28 +++++++++++++++++++++++++ util/colored_text.c | 10 --------- util/err.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 util/arr.c delete mode 100644 util/colored_text.c (limited to 'util') diff --git a/util/arr.c b/util/arr.c new file mode 100644 index 0000000..7595b4b --- /dev/null +++ b/util/arr.c @@ -0,0 +1,28 @@ +#define arr_declaration(arr_type, type, prefix) typedef struct { \ + type *data; \ + size_t cap; \ + size_t len; \ + } arr_type; \ + static void prefix##create(arr_type *arr) { \ + arr->data = NULL; \ + arr->cap = 0; \ + arr->len = 0; \ + } \ + static void prefix##reserve(arr_type *arr, size_t n) { \ + arr->data = err_realloc(arr->data, n * sizeof(*arr->data)); \ + arr->cap = n; \ + } \ + static void prefix##add(arr_type *arr, type *item) { \ + if (arr->len >= arr->cap) { \ + prefix##reserve(arr, 2 * arr->len + 2); \ + } \ + arr->data[arr->len++] = *item; \ + } \ + static void prefix##clear(arr_type *arr) { \ + free(arr->data); \ + arr->data = NULL; \ + arr->cap = 0; \ + arr->len = 0; \ + } + +#define arr_foreach(arr, type, var) for (type *var = (arr).data, *arr_iterate_last_ = (arr).data + ((arr).len - 1); var; (var == arr_iterate_last_) ? var = NULL : var++) diff --git a/util/colored_text.c b/util/colored_text.c deleted file mode 100644 index 836f357..0000000 --- a/util/colored_text.c +++ /dev/null @@ -1,10 +0,0 @@ - -#define USE_COLORED_TEXT 1 - -#if USE_COLORED_TEXT -#define TEXT_ERROR(x) "\x1b[91m" x "\x1b[0m" -#define TEXT_IMPORTANT(x) "\x1b[1m" x "\x1b[0m" -#else -#define TEXT_ERROR(x) x -#define TEXT_IMPORTANT(x) x -#endif diff --git a/util/err.c b/util/err.c index 6fd2ac3..5e296da 100644 --- a/util/err.c +++ b/util/err.c @@ -1,13 +1,65 @@ +#define USE_COLORED_TEXT 1 + +#if USE_COLORED_TEXT +#define TEXT_ERROR(x) "\x1b[91m" x "\x1b[0m" +#define TEXT_IMPORTANT(x) "\x1b[1m" x "\x1b[0m" +#else +#define TEXT_ERROR(x) x +#define TEXT_IMPORTANT(x) x +#endif + typedef uint32_t LineNo; -static void err_print(LineNo line, LineNo col, const char *fmt, ...) { - /* TODO: Color */ +/* file name of file being processed */ +static const char *err_filename; + +/* Write directly to the error file */ +static void err_fwrite(const void *data, size_t size, size_t n) { + fwrite(data, size, n, stderr); +} + +static void err_fprint(const char *fmt, ...) { va_list args; - fprintf(stderr, TEXT_ERROR("error:") " at line %lu col %lu:\n", (unsigned long)line, (unsigned long)col); va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); - fprintf(stderr, "\n"); +} + +static void err_vfprint(const char *fmt, va_list args) { + vfprintf(stderr, fmt, args); +} + +static void err_print_header_(LineNo line) { + err_fprint(TEXT_ERROR("error:") " at line %lu of %s:\n", (unsigned long)line, err_filename); +} + +static void err_print_footer_(const char *context) { + err_fprint("\n\there --> "); + const char *end = strchr(context, '\n'); + int has_newline = end != NULL; + if (!has_newline) + end = strchr(context, '\0'); + assert(end); + err_fwrite(context, 1, (size_t)(end - context)); + if (!has_newline) + err_fprint(""); + err_fprint("\n"); +} + +/* Write nicely-formatted errors to the error file */ +static void err_print(LineNo line, const char *context, const char *fmt, ...) { + err_print_header_(line); + va_list args; + va_start(args, fmt); + err_vfprint(fmt, args); + va_end(args); + err_print_footer_(context); +} + +static void err_vprint(LineNo line, const char *context, const char *fmt, va_list args) { + err_print_header_(line); + err_vfprint(fmt, args); + err_print_footer_(context); } static void *err_malloc(size_t size) { -- cgit v1.2.3