diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-08-18 09:05:28 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-08-18 09:05:28 -0400 |
commit | be1f2bc848e9c4386437fe4a6147a0a8d7f000ff (patch) | |
tree | 0e104447439e9ecd85d0b1921006101ce82291a8 /util | |
parent | 895be6655cb86e06811e92247b34d2262b13caa0 (diff) |
Added string constants and improved tokenization
Diffstat (limited to 'util')
-rw-r--r-- | util/arr.c | 28 | ||||
-rw-r--r-- | util/colored_text.c | 10 | ||||
-rw-r--r-- | util/err.c | 60 |
3 files changed, 84 insertions, 14 deletions
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 @@ -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("<end of file>"); + 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) { |