diff options
author | David Robillard <d@drobilla.net> | 2018-06-03 22:15:53 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-12-31 11:37:47 -0500 |
commit | 5246440bc489b9b8168d0e26700cf5f343895169 (patch) | |
tree | 345fd9e2916a0e92205186e011721d9c8459c047 | |
parent | c10db88a4eac181e83acff319e77308291c59645 (diff) | |
download | serd-5246440bc489b9b8168d0e26700cf5f343895169.tar.gz serd-5246440bc489b9b8168d0e26700cf5f343895169.tar.bz2 serd-5246440bc489b9b8168d0e26700cf5f343895169.zip |
Add SerdCursor to public API
-rw-r--r-- | serd/serd.h | 51 | ||||
-rw-r--r-- | src/byte_source.c | 23 | ||||
-rw-r--r-- | src/byte_source.h | 17 | ||||
-rw-r--r-- | src/cursor.c | 35 | ||||
-rw-r--r-- | src/cursor.h | 28 | ||||
-rw-r--r-- | src/reader.c | 18 | ||||
-rw-r--r-- | src/serdi.c | 9 | ||||
-rw-r--r-- | src/world.c | 12 | ||||
-rw-r--r-- | wscript | 1 |
9 files changed, 157 insertions, 37 deletions
diff --git a/serd/serd.h b/serd/serd.h index 73acf9d6..6f8dece4 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -69,6 +69,11 @@ typedef struct SerdWorldImpl SerdWorld; typedef struct SerdStatementImpl SerdStatement; /** + Cursor, the origin of a statement in a document. +*/ +typedef struct SerdCursorImpl SerdCursor; + +/** Environment. Represents the state required to resolve a CURIE or relative URI, e.g. the @@ -262,12 +267,10 @@ typedef struct { An error description. */ typedef struct { - SerdStatus status; /**< Error code */ - const char* filename; /**< File where error was encountered, or NULL */ - unsigned line; /**< Line where error was encountered, or 0 */ - unsigned col; /**< Column where error was encountered */ - const char* fmt; /**< Message format string (printf style) */ - va_list* args; /**< Arguments for fmt */ + SerdStatus status; /**< Error code */ + const SerdCursor* cursor; /**< Origin of error, or NULL */ + const char* fmt; /**< Message format string (printf style) */ + va_list* args; /**< Arguments for fmt */ } SerdError; /** @@ -1071,7 +1074,7 @@ serd_reader_start_stream(SerdReader* reader, SerdReadFunc read_func, SerdStreamErrorFunc error_func, void* stream, - const char* name, + const SerdNode* name, size_t page_size); /** @@ -1079,7 +1082,9 @@ serd_reader_start_stream(SerdReader* reader, */ SERD_API SerdStatus -serd_reader_start_string(SerdReader* reader, const char* utf8); +serd_reader_start_string(SerdReader* reader, + const char* utf8, + const SerdNode* name); /** Read a single "chunk" of data during an incremental read. @@ -1262,6 +1267,36 @@ serd_statement_get_graph(const SerdStatement* statement); /** @} + @name Cursor + @{ +*/ + +/** + Return the document name. + + This is typically a file URI, but may be a descriptive string node for + statements that originate from streams. +*/ +SERD_API +const SerdNode* +serd_cursor_get_name(const SerdCursor* cursor); + +/** + Return the one-relative line number in the document. +*/ +SERD_API +unsigned +serd_cursor_get_line(const SerdCursor* cursor); + +/** + Return the zero-relative column number in the line. +*/ +SERD_API +unsigned +serd_cursor_get_column(const SerdCursor* cursor); + +/** + @} @} */ diff --git a/src/byte_source.c b/src/byte_source.c index a3f50a14..93ba972f 100644 --- a/src/byte_source.c +++ b/src/byte_source.c @@ -46,20 +46,21 @@ 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) { - const Cursor cur = { name, 1, 1 }; - memset(source, '\0', sizeof(*source)); source->read_func = read_func; source->error_func = error_func; source->close_func = close_func; source->stream = stream; source->page_size = page_size; - source->cur = cur; + source->name = serd_node_copy(name); source->from_stream = true; + const SerdCursor cur = { source->name, 1, 1 }; + source->cur = cur; + if (page_size > 1) { source->file_buf = (uint8_t*)serd_allocate_buffer(page_size); source->read_buf = source->file_buf; @@ -86,13 +87,18 @@ serd_byte_source_prepare(SerdByteSource* source) } SerdStatus -serd_byte_source_open_string(SerdByteSource* source, const char* utf8) +serd_byte_source_open_string(SerdByteSource* source, + const char* utf8, + const SerdNode* name) { - const Cursor cur = { "(string)", 1, 1 }; - memset(source, '\0', sizeof(*source)); - source->cur = cur; + + source->name = name ? serd_node_copy(name) : serd_new_string("string"); source->read_buf = (const uint8_t*)utf8; + + const SerdCursor cur = {source->name, 1, 1}; + source->cur = cur; + return SERD_SUCCESS; } @@ -107,6 +113,7 @@ serd_byte_source_close(SerdByteSource* source) if (source->page_size > 1) { free(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 0edfd75c..f88fa6c9 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 "cursor.h" + #include "serd/serd.h" #include <assert.h> @@ -27,18 +29,13 @@ 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 - Cursor cur; ///< Cursor for error reporting + SerdNode* name; ///< Name of stream (referenced by cur) + SerdCursor cur; ///< Cursor 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 @@ -49,7 +46,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, @@ -57,7 +56,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 diff --git a/src/cursor.c b/src/cursor.c new file mode 100644 index 00000000..7d72954b --- /dev/null +++ b/src/cursor.c @@ -0,0 +1,35 @@ +/* + Copyright 2018 David Robillard <http://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 "cursor.h" + +const SerdNode* +serd_cursor_get_name(const SerdCursor* cursor) +{ + return cursor->file; +} + +unsigned +serd_cursor_get_line(const SerdCursor* cursor) +{ + return cursor->line; +} + +unsigned +serd_cursor_get_column(const SerdCursor* cursor) +{ + return cursor->col; +} diff --git a/src/cursor.h b/src/cursor.h new file mode 100644 index 00000000..51fbf6e8 --- /dev/null +++ b/src/cursor.h @@ -0,0 +1,28 @@ +/* + Copyright 2018 David Robillard <http://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_CURSOR_H +#define SERD_CURSOR_H + +#include "serd/serd.h" + +struct SerdCursorImpl { + const SerdNode* file; + unsigned line; + unsigned col; +}; + +#endif // SERD_CURSOR_H diff --git a/src/reader.c b/src/reader.c index 40c48a41..79e2315e 100644 --- a/src/reader.c +++ b/src/reader.c @@ -39,8 +39,7 @@ r_err(SerdReader* reader, SerdStatus st, const char* 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.cur, fmt, &args }; serd_world_error(reader->world, &e); va_end(args); return st; @@ -246,7 +245,7 @@ serd_reader_start_stream(SerdReader* reader, SerdReadFunc read_func, SerdStreamErrorFunc error_func, void* stream, - const char* name, + const SerdNode* name, 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( + SerdNode* const name = serd_new_uri(uri); + const SerdStatus st = serd_byte_source_open_source( &reader->source, bulk ? (SerdReadFunc)fread : serd_file_read_byte, (SerdStreamErrorFunc)ferror, (SerdStreamCloseFunc)fclose, fd, - uri, + name, bulk ? SERD_PAGE_SIZE : 1); + serd_node_free(name); + return st; } SerdStatus -serd_reader_start_string(SerdReader* reader, const char* utf8) +serd_reader_start_string(SerdReader* reader, + const char* utf8, + const SerdNode* 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 b0c3eb3a..204d381a 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -238,15 +238,18 @@ main(int argc, char** argv) serd_reader_add_blank_prefix(reader, add_prefix); serd_node_free(root); - SerdStatus status = SERD_SUCCESS; + SerdStatus status = SERD_SUCCESS; + SerdNode* input_name = NULL; if (from_string) { - status = serd_reader_start_string(reader, input); + input_name = serd_new_string("string"); + status = serd_reader_start_string(reader, input, input_name); } else if (from_stdin) { + input_name = serd_new_string("stdin"); status = serd_reader_start_stream(reader, serd_file_read_byte, (SerdStreamErrorFunc)ferror, stdin, - "(stdin)", + input_name, 1); } else { status = serd_reader_start_file(reader, input, bulk_read); diff --git a/src/world.c b/src/world.c index 27feeac6..d43a2909 100644 --- a/src/world.c +++ b/src/world.c @@ -18,6 +18,7 @@ #include "world.h" +#include "cursor.h" #include "node.h" #include "serd_config.h" @@ -54,7 +55,14 @@ serd_world_error(const SerdWorld* world, const SerdError* e) if (world->error_sink) { world->error_sink(world->error_handle, e); } else { - fprintf(stderr, "error: %s:%u:%u: ", e->filename, e->line, e->col); + fprintf(stderr, "error: "); + if (e->cursor) { + fprintf(stderr, + "%s:%u:%u: ", + serd_node_get_string(e->cursor->file), + e->cursor->line, + e->cursor->col); + } vfprintf(stderr, e->fmt, *e->args); } return e->status; @@ -65,7 +73,7 @@ serd_world_errorf(const SerdWorld* world, SerdStatus st, const char* fmt, ...) { 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; @@ -76,6 +76,7 @@ def configure(conf): lib_source = ['src/base64.c', 'src/byte_source.c', + 'src/cursor.c', 'src/env.c', 'src/n3.c', 'src/node.c', |