aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-07-09 20:23:41 -0400
committerDavid Robillard <d@drobilla.net>2022-01-13 23:03:53 -0500
commitbf72cc408db5244881143619236aee20156f4ffd (patch)
treed8f12781c8050e2ee9c0e9d83488838968480f00 /src
parenta1c18e5585a1b3edbe62f53e768d270e54e4cac5 (diff)
downloadserd-bf72cc408db5244881143619236aee20156f4ffd.tar.gz
serd-bf72cc408db5244881143619236aee20156f4ffd.tar.bz2
serd-bf72cc408db5244881143619236aee20156f4ffd.zip
Add SerdCaret
Diffstat (limited to 'src')
-rw-r--r--src/byte_source.c27
-rw-r--r--src/byte_source.h23
-rw-r--r--src/caret.c75
-rw-r--r--src/caret.h28
-rw-r--r--src/reader.c30
-rw-r--r--src/serdi.c12
-rw-r--r--src/world.c14
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;