diff options
author | David Robillard <d@drobilla.net> | 2018-11-25 18:08:54 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-04-13 19:48:23 +0200 |
commit | 5443876d8e15c6ad011ede7d46ed36325a6cb282 (patch) | |
tree | 69fbb26e35f44a6d49d60c4a8969e6d2cca63a3e | |
parent | 3b1252125ca66387f904ce107fb4c6130d5c582d (diff) | |
download | serd-5443876d8e15c6ad011ede7d46ed36325a6cb282.tar.gz serd-5443876d8e15c6ad011ede7d46ed36325a6cb282.tar.bz2 serd-5443876d8e15c6ad011ede7d46ed36325a6cb282.zip |
Remove reader status and handle errors more precisely
-rw-r--r-- | serd/serd.h | 3 | ||||
-rw-r--r-- | src/byte_source.h | 5 | ||||
-rw-r--r-- | src/n3.c | 53 | ||||
-rw-r--r-- | src/reader.c | 13 | ||||
-rw-r--r-- | src/reader.h | 8 | ||||
-rw-r--r-- | src/string.c | 1 | ||||
-rw-r--r-- | tests/serd_test.c | 2 |
7 files changed, 40 insertions, 45 deletions
diff --git a/serd/serd.h b/serd/serd.h index 0b798abc..145a424a 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -110,7 +110,8 @@ typedef enum { SERD_ERR_BAD_CURIE, ///< Invalid CURIE (e.g. prefix does not exist) SERD_ERR_INTERNAL, ///< Unexpected internal error (should not happen) SERD_ERR_OVERFLOW, ///< Stack overflow - SERD_ERR_INVALID ///< Invalid data + SERD_ERR_INVALID, ///< Invalid data + SERD_ERR_NO_DATA ///< Unexpected end of input } SerdStatus; /// RDF syntax type diff --git a/src/byte_source.h b/src/byte_source.h index f88fa6c9..4dfff70f 100644 --- a/src/byte_source.h +++ b/src/byte_source.h @@ -87,13 +87,14 @@ serd_byte_source_advance(SerdByteSource* source) } if (source->from_stream) { - source->eof = false; if (source->page_size > 1) { if (++source->read_head == source->page_size) { + source->eof = false; st = serd_byte_source_page(source); } } else { if (!source->read_func(&source->read_byte, 1, 1, source->stream)) { + source->eof = true; st = source->error_func(source->stream) ? SERD_ERR_UNKNOWN : SERD_FAILURE; } @@ -102,7 +103,7 @@ serd_byte_source_advance(SerdByteSource* source) ++source->read_head; // Move to next character in string } - return source->eof ? SERD_FAILURE : st; + return st ? st : source->eof ? SERD_FAILURE : SERD_SUCCESS; } #endif // SERD_BYTE_SOURCE_H @@ -199,9 +199,10 @@ read_utf8_character(SerdReader* reader, SerdNode* dest, uint8_t c) uint32_t size; uint8_t bytes[4]; SerdStatus st = read_utf8_bytes(reader, bytes, &size, c); - if (st) { - push_bytes(reader, dest, replacement_char, 3); + if (st && reader->strict) { return st; + } else if (st) { + return push_bytes(reader, dest, replacement_char, 3); } return push_bytes(reader, dest, bytes, size); @@ -213,9 +214,10 @@ read_utf8_code(SerdReader* reader, SerdNode* dest, uint32_t* code, uint8_t c) uint32_t size; uint8_t bytes[4] = { 0, 0, 0, 0 }; SerdStatus st = read_utf8_bytes(reader, bytes, &size, c); - if (st) { - push_bytes(reader, dest, replacement_char, 3); + if (st && reader->strict) { return st; + } else if (st) { + return push_bytes(reader, dest, replacement_char, 3); } if (!(st = push_bytes(reader, dest, bytes, size))) { @@ -303,7 +305,7 @@ static SerdStatus read_STRING_LITERAL_LONG(SerdReader* reader, SerdNode* dest, uint8_t q) { SerdStatus st = SERD_SUCCESS; - while (!reader->status && !(st && reader->strict)) { + while (!st || (st == SERD_ERR_BAD_SYNTAX && !reader->strict)) { const uint8_t c = peek_byte(reader); if (c == '\\') { eat_byte_safe(reader, c); @@ -316,6 +318,9 @@ read_STRING_LITERAL_LONG(SerdReader* reader, SerdNode* dest, uint8_t q) peek_byte(reader)); return SERD_ERR_BAD_SYNTAX; } + } else if (reader->source.eof) { + st = r_err(reader, SERD_ERR_NO_DATA, + "unexpected end of file\n"); } else if (c == q) { eat_byte_safe(reader, q); const uint8_t q2 = eat_byte_safe(reader, peek_byte(reader)); @@ -332,6 +337,7 @@ read_STRING_LITERAL_LONG(SerdReader* reader, SerdNode* dest, uint8_t q) reader, dest, &dest->flags, eat_byte_safe(reader, c)); } } + return st; } @@ -341,24 +347,25 @@ static SerdStatus read_STRING_LITERAL(SerdReader* reader, SerdNode* dest, uint8_t q) { SerdStatus st = SERD_SUCCESS; - while (!reader->status && !(st && reader->strict)) { + while (!st || (st == SERD_ERR_BAD_SYNTAX && !reader->strict)) { const uint8_t c = peek_byte(reader); uint32_t code = 0; switch (c) { case '\n': case '\r': - r_err(reader, SERD_ERR_BAD_SYNTAX, "line end in short string\n"); - return SERD_ERR_BAD_SYNTAX; + st = r_err(reader, SERD_ERR_NO_DATA, + "line end in short string\n"); + break; case '\\': eat_byte_safe(reader, c); if ((st = read_ECHAR(reader, dest, &dest->flags)) && (st = read_UCHAR(reader, dest, &code))) { - return r_err(reader, st, - "invalid escape `\\%c'\n", peek_byte(reader)); + st = r_err(reader, st, + "invalid escape `\\%c'\n", peek_byte(reader)); } break; default: if (c == q) { - eat_byte_check(reader, q); + eat_byte_safe(reader, q); return SERD_SUCCESS; } else { st = read_character( @@ -367,8 +374,7 @@ read_STRING_LITERAL(SerdReader* reader, SerdNode* dest, uint8_t q) } } - return st ? st - : eat_byte_check(reader, q) ? SERD_SUCCESS : SERD_ERR_BAD_SYNTAX; + return st; } static SerdStatus @@ -671,10 +677,7 @@ read_IRIREF(SerdReader* reader, SerdNode** dest) } else if (!(c & 0x80)) { push_byte(reader, *dest, c); } else if (read_utf8_character(reader, *dest, c)) { - if (reader->strict) { - return SERD_ERR_BAD_SYNTAX; - } - st = SERD_FAILURE; + st = reader->strict ? SERD_ERR_BAD_SYNTAX : SERD_FAILURE; } } } @@ -1437,8 +1440,6 @@ read_n3_statement(SerdReader* reader) ctx.subject = subj = 0; TRY(st, read_wrappedGraph(reader, &ctx)); read_ws_star(reader); - } else if (!ctx.subject) { - st = r_err(reader, SERD_ERR_BAD_SYNTAX, "bad subject\n"); } else if ((st = read_triples(reader, ctx, &ate_dot))) { if (st == SERD_FAILURE && s_type == '[') { return SERD_SUCCESS; @@ -1473,23 +1474,22 @@ read_turtleTrigDoc(SerdReader* reader) const size_t orig_stack_size = reader->stack.size; const SerdStatus st = read_n3_statement(reader); if (st > SERD_FAILURE) { - if (reader->strict) { + if (reader->strict || reader->source.eof) { serd_stack_pop_to(&reader->stack, orig_stack_size); return st; } skip_until(reader, '\n'); - reader->status = SERD_SUCCESS; } serd_stack_pop_to(&reader->stack, orig_stack_size); } - return reader->status; + return SERD_SUCCESS; } SerdStatus read_nquadsDoc(SerdReader* reader) { SerdStatus st = SERD_SUCCESS; - while (!reader->source.eof) { + while (!st && !reader->source.eof) { const size_t orig_stack_size = reader->stack.size; SerdStatementFlags flags = 0; @@ -1534,11 +1534,8 @@ read_nquadsDoc(SerdReader* reader) } } - if (emit_statement(reader, ctx, ctx.object)) { - break; - } - + st = emit_statement(reader, ctx, ctx.object); serd_stack_pop_to(&reader->stack, orig_stack_size); } - return reader->status; + return st; } diff --git a/src/reader.c b/src/reader.c index 4235168a..2d1fbd7e 100644 --- a/src/reader.c +++ b/src/reader.c @@ -87,7 +87,6 @@ push_node_padded(SerdReader* reader, size_t maxlen, &reader->stack, sizeof(SerdNode) + maxlen + 1, sizeof(SerdNode)); if (!mem) { - reader->status = SERD_ERR_OVERFLOW; return NULL; } @@ -283,15 +282,15 @@ serd_reader_start_string(SerdReader* reader, static SerdStatus serd_reader_prepare(SerdReader* reader) { - reader->status = serd_byte_source_prepare(&reader->source); - if (reader->status == SERD_SUCCESS) { - reader->status = skip_bom(reader); - } else if (reader->status == SERD_FAILURE) { + SerdStatus st = serd_byte_source_prepare(&reader->source); + if (st == SERD_SUCCESS) { + st = skip_bom(reader); + } else if (st == SERD_FAILURE) { reader->source.eof = true; } else { - r_err(reader, reader->status, "read error: %s\n", strerror(errno)); + r_err(reader, st, "error preparing read: %s\n", strerror(errno)); } - return reader->status; + return st; } SerdStatus diff --git a/src/reader.h b/src/reader.h index 62373fc4..88d2d864 100644 --- a/src/reader.h +++ b/src/reader.h @@ -55,7 +55,6 @@ struct SerdReaderImpl { SerdStack stack; SerdSyntax syntax; unsigned next_id; - SerdStatus status; uint8_t* buf; char* bprefix; size_t bprefix_len; @@ -99,11 +98,8 @@ peek_byte(SerdReader* reader) static inline uint8_t eat_byte(SerdReader* reader) { - const uint8_t c = peek_byte(reader); - const SerdStatus st = serd_byte_source_advance(&reader->source); - if (st) { - reader->status = st; - } + const uint8_t c = peek_byte(reader); + serd_byte_source_advance(&reader->source); return c; } diff --git a/src/string.c b/src/string.c index c2466c48..6a433cdb 100644 --- a/src/string.c +++ b/src/string.c @@ -46,6 +46,7 @@ serd_strerror(SerdStatus status) case SERD_ERR_INTERNAL: return "Internal error"; case SERD_ERR_OVERFLOW: return "Stack overflow"; case SERD_ERR_INVALID: return "Invalid data"; + case SERD_ERR_NO_DATA: return "Unexpectd end of input"; } return "Unknown error"; // never reached } diff --git a/tests/serd_test.c b/tests/serd_test.c index 933ea9a5..e3289a17 100644 --- a/tests/serd_test.c +++ b/tests/serd_test.c @@ -247,7 +247,7 @@ main(void) const char* msg = NULL; assert(!strcmp((msg = serd_strerror(SERD_SUCCESS)), "Success")); - for (int i = SERD_FAILURE; i <= SERD_ERR_INVALID; ++i) { + for (int i = SERD_FAILURE; i <= SERD_ERR_NO_DATA; ++i) { msg = serd_strerror((SerdStatus)i); assert(strcmp(msg, "Success")); } |