diff options
author | David Robillard <d@drobilla.net> | 2021-07-09 20:23:41 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-01-13 23:03:53 -0500 |
commit | bf72cc408db5244881143619236aee20156f4ffd (patch) | |
tree | d8f12781c8050e2ee9c0e9d83488838968480f00 /src | |
parent | a1c18e5585a1b3edbe62f53e768d270e54e4cac5 (diff) | |
download | serd-bf72cc408db5244881143619236aee20156f4ffd.tar.gz serd-bf72cc408db5244881143619236aee20156f4ffd.tar.bz2 serd-bf72cc408db5244881143619236aee20156f4ffd.zip |
Add SerdCaret
Diffstat (limited to 'src')
-rw-r--r-- | src/byte_source.c | 27 | ||||
-rw-r--r-- | src/byte_source.h | 23 | ||||
-rw-r--r-- | src/caret.c | 75 | ||||
-rw-r--r-- | src/caret.h | 28 | ||||
-rw-r--r-- | src/reader.c | 30 | ||||
-rw-r--r-- | src/serdi.c | 12 | ||||
-rw-r--r-- | src/world.c | 14 |
7 files changed, 166 insertions, 43 deletions
diff --git a/src/byte_source.c b/src/byte_source.c index 727c655f..0e6ae2be 100644 --- a/src/byte_source.c +++ b/src/byte_source.c @@ -16,6 +16,7 @@ #include "byte_source.h" +#include "caret.h" #include "system.h" #include "serd/serd.h" @@ -52,11 +53,9 @@ serd_byte_source_open_source(SerdByteSource* const source, const SerdStreamErrorFunc error_func, const SerdStreamCloseFunc close_func, void* const stream, - const char* const name, + const SerdNode* const name, const size_t page_size) { - const Cursor cur = {name, 1, 1}; - memset(source, '\0', sizeof(*source)); source->read_func = read_func; source->error_func = error_func; @@ -64,7 +63,10 @@ serd_byte_source_open_source(SerdByteSource* const source, source->stream = stream; source->page_size = page_size; source->buf_size = page_size; - source->cur = cur; + source->name = serd_node_copy(name); + source->caret.file = source->name; + source->caret.line = 1u; + source->caret.col = 1u; source->from_stream = true; if (page_size > 1) { @@ -93,13 +95,19 @@ serd_byte_source_prepare(SerdByteSource* const source) SerdStatus serd_byte_source_open_string(SerdByteSource* const source, - const char* const utf8) + const char* const utf8, + const SerdNode* const name) { - const Cursor cur = {"(string)", 1, 1}; - memset(source, '\0', sizeof(*source)); - source->cur = cur; - source->read_buf = (const uint8_t*)utf8; + + source->name = + name ? serd_node_copy(name) : serd_new_string(SERD_STRING("string")); + + source->read_buf = (const uint8_t*)utf8; + source->caret.file = source->name; + source->caret.line = 1u; + source->caret.col = 1u; + return SERD_SUCCESS; } @@ -115,6 +123,7 @@ serd_byte_source_close(SerdByteSource* const source) serd_free_aligned(source->file_buf); } + serd_node_free(source->name); memset(source, '\0', sizeof(*source)); return st; } diff --git a/src/byte_source.h b/src/byte_source.h index 69f92295..6469ba95 100644 --- a/src/byte_source.h +++ b/src/byte_source.h @@ -17,6 +17,8 @@ #ifndef SERD_BYTE_SOURCE_H #define SERD_BYTE_SOURCE_H +#include "caret.h" + #include "serd/serd.h" #include <assert.h> @@ -27,19 +29,14 @@ typedef int (*SerdStreamCloseFunc)(void*); typedef struct { - const char* filename; - unsigned line; - unsigned col; -} Cursor; - -typedef struct { SerdReadFunc read_func; ///< Read function (e.g. fread) SerdStreamErrorFunc error_func; ///< Error function (e.g. ferror) SerdStreamCloseFunc close_func; ///< Function for closing stream void* stream; ///< Stream (e.g. FILE) size_t page_size; ///< Number of bytes to read at a time size_t buf_size; ///< Number of bytes in file_buf - Cursor cur; ///< Cursor for error reporting + SerdNode* name; ///< Name of stream (referenced by cur) + SerdCaret caret; ///< Caret for error reporting uint8_t* file_buf; ///< Buffer iff reading pages from a file const uint8_t* read_buf; ///< Pointer to file_buf or read_byte size_t read_head; ///< Offset into read_buf @@ -50,7 +47,9 @@ typedef struct { } SerdByteSource; SerdStatus -serd_byte_source_open_string(SerdByteSource* source, const char* utf8); +serd_byte_source_open_string(SerdByteSource* source, + const char* utf8, + const SerdNode* name); SerdStatus serd_byte_source_open_source(SerdByteSource* source, @@ -58,7 +57,7 @@ serd_byte_source_open_source(SerdByteSource* source, SerdStreamErrorFunc error_func, SerdStreamCloseFunc close_func, void* stream, - const char* name, + const SerdNode* name, size_t page_size); SerdStatus @@ -85,11 +84,11 @@ serd_byte_source_advance(SerdByteSource* source) switch (serd_byte_source_peek(source)) { case '\n': - ++source->cur.line; - source->cur.col = 0; + ++source->caret.line; + source->caret.col = 0; break; default: - ++source->cur.col; + ++source->caret.col; } const bool was_eof = source->eof; diff --git a/src/caret.c b/src/caret.c new file mode 100644 index 00000000..2fe92f94 --- /dev/null +++ b/src/caret.c @@ -0,0 +1,75 @@ +/* + Copyright 2018-2020 David Robillard <d@drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "caret.h" + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +SerdCaret* +serd_caret_new(const SerdNode* name, unsigned line, unsigned col) +{ + SerdCaret* caret = (SerdCaret*)malloc(sizeof(SerdCaret)); + + caret->file = name; + caret->line = line; + caret->col = col; + return caret; +} + +SerdCaret* +serd_caret_copy(const SerdCaret* caret) +{ + if (!caret) { + return NULL; + } + + SerdCaret* copy = (SerdCaret*)malloc(sizeof(SerdCaret)); + memcpy(copy, caret, sizeof(SerdCaret)); + return copy; +} + +void +serd_caret_free(SerdCaret* caret) +{ + free(caret); +} + +bool +serd_caret_equals(const SerdCaret* l, const SerdCaret* r) +{ + return (l == r || (l && r && serd_node_equals(l->file, r->file) && + l->line == r->line && l->col == r->col)); +} + +const SerdNode* +serd_caret_name(const SerdCaret* caret) +{ + return caret->file; +} + +unsigned +serd_caret_line(const SerdCaret* caret) +{ + return caret->line; +} + +unsigned +serd_caret_column(const SerdCaret* caret) +{ + return caret->col; +} diff --git a/src/caret.h b/src/caret.h new file mode 100644 index 00000000..3add78a7 --- /dev/null +++ b/src/caret.h @@ -0,0 +1,28 @@ +/* + Copyright 2018-2020 David Robillard <d@drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef SERD_CARET_H +#define SERD_CARET_H + +#include "serd/serd.h" + +struct SerdCaretImpl { + const SerdNode* file; + unsigned line; + unsigned col; +}; + +#endif // SERD_CARET_H diff --git a/src/reader.c b/src/reader.c index 2cdf18c6..9957e55c 100644 --- a/src/reader.c +++ b/src/reader.c @@ -37,8 +37,7 @@ r_err(SerdReader* const reader, const SerdStatus st, const char* const fmt, ...) { va_list args; va_start(args, fmt); - const Cursor* const cur = &reader->source.cur; - const SerdError e = {st, cur->filename, cur->line, cur->col, fmt, &args}; + const SerdError e = {st, &reader->source.caret, fmt, &args}; serd_world_error(reader->world, &e); va_end(args); return st; @@ -246,7 +245,7 @@ serd_reader_start_stream(SerdReader* const reader, const SerdReadFunc read_func, const SerdStreamErrorFunc error_func, void* const stream, - const char* const name, + const SerdNode* const name, const size_t page_size) { return serd_byte_source_open_source( @@ -267,20 +266,25 @@ serd_reader_start_file(SerdReader* reader, const char* uri, bool bulk) return SERD_ERR_UNKNOWN; } - return serd_byte_source_open_source(&reader->source, - bulk ? (SerdReadFunc)fread - : serd_file_read_byte, - (SerdStreamErrorFunc)ferror, - (SerdStreamCloseFunc)fclose, - fd, - uri, - bulk ? SERD_PAGE_SIZE : 1); + SerdNode* const name = serd_new_uri(SERD_STRING(uri)); + const SerdStatus st = serd_byte_source_open_source( + &reader->source, + bulk ? (SerdReadFunc)fread : serd_file_read_byte, + (SerdStreamErrorFunc)ferror, + (SerdStreamCloseFunc)fclose, + fd, + name, + bulk ? SERD_PAGE_SIZE : 1u); + serd_node_free(name); + return st; } SerdStatus -serd_reader_start_string(SerdReader* const reader, const char* const utf8) +serd_reader_start_string(SerdReader* const reader, + const char* const utf8, + const SerdNode* const name) { - return serd_byte_source_open_string(&reader->source, utf8); + return serd_byte_source_open_string(&reader->source, utf8, name); } static SerdStatus diff --git a/src/serdi.c b/src/serdi.c index fcddac6c..a94051bc 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -283,15 +283,18 @@ main(int argc, char** argv) serd_writer_chop_blank_prefix(writer, chop_prefix); serd_reader_add_blank_prefix(reader, add_prefix); - SerdStatus st = SERD_SUCCESS; + SerdStatus st = SERD_SUCCESS; + SerdNode* input_name = NULL; if (from_string) { - st = serd_reader_start_string(reader, input); + input_name = serd_new_string(SERD_STRING("string")); + st = serd_reader_start_string(reader, input, input_name); } else if (from_stdin) { - st = serd_reader_start_stream(reader, + input_name = serd_new_string(SERD_STRING("stdin")); + st = serd_reader_start_stream(reader, serd_file_read_byte, (SerdStreamErrorFunc)ferror, stdin, - "(stdin)", + input_name, 1); } else { st = serd_reader_start_file(reader, input, bulk_read); @@ -305,6 +308,7 @@ main(int argc, char** argv) serd_reader_free(reader); serd_writer_finish(writer); serd_writer_free(writer); + serd_node_free(input_name); serd_env_free(env); serd_node_free(base); serd_world_free(world); diff --git a/src/world.c b/src/world.c index 4413f433..4230448a 100644 --- a/src/world.c +++ b/src/world.c @@ -16,6 +16,7 @@ #include "world.h" +#include "caret.h" #include "node.h" #include "serd_config.h" #include "system.h" @@ -58,10 +59,13 @@ serd_world_error(const SerdWorld* const world, const SerdError* const e) if (world->error_func) { world->error_func(world->error_handle, e); } else { - if (e->filename) { - fprintf(stderr, "error: %s:%u:%u: ", e->filename, e->line, e->col); - } else { - fprintf(stderr, "error: "); + fprintf(stderr, "error: "); + if (e->caret) { + fprintf(stderr, + "%s:%u:%u: ", + serd_node_string(e->caret->file), + e->caret->line, + e->caret->col); } vfprintf(stderr, e->fmt, *e->args); } @@ -76,7 +80,7 @@ serd_world_errorf(const SerdWorld* const world, { va_list args; va_start(args, fmt); - const SerdError e = {st, NULL, 0, 0, fmt, &args}; + const SerdError e = {st, NULL, fmt, &args}; serd_world_error(world, &e); va_end(args); return st; |