diff options
author | David Robillard <d@drobilla.net> | 2019-05-05 16:12:38 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-12-20 10:26:55 -0500 |
commit | c55d1fd13c2f49c8ef1b4e2060f846ecd4eabbc1 (patch) | |
tree | d5877facdaad01f3dd0998a21c5f4631cd9d0fc2 | |
parent | 48003ea5959c56a3204a2222a147d2bf1ecd96c9 (diff) | |
download | serd-c55d1fd13c2f49c8ef1b4e2060f846ecd4eabbc1.tar.gz serd-c55d1fd13c2f49c8ef1b4e2060f846ecd4eabbc1.tar.bz2 serd-c55d1fd13c2f49c8ef1b4e2060f846ecd4eabbc1.zip |
Add support for reading multiple files at once
-rw-r--r-- | doc/serdi.1 | 4 | ||||
-rw-r--r-- | src/serdi.c | 123 | ||||
-rw-r--r-- | tests/multifile/input1.ttl | 2 | ||||
-rw-r--r-- | tests/multifile/input2.trig | 7 | ||||
-rw-r--r-- | tests/multifile/output.nq | 3 | ||||
-rw-r--r-- | wscript | 9 |
6 files changed, 112 insertions, 36 deletions
diff --git a/doc/serdi.1 b/doc/serdi.1 index 3e1d2ebd..2bef4922 100644 --- a/doc/serdi.1 +++ b/doc/serdi.1 @@ -1,10 +1,10 @@ -.TH SERDI 1 "06 Jan 2019" +.TH SERDI 1 "05 May 2019" .SH NAME .B serdi \- Read and write RDF syntax .SH SYNOPSIS -serdi [\fIOPTION\fR]... \fIINPUT\fR +serdi [\fIOPTION\fR]... \fIINPUT\fR... .SH OPTIONS diff --git a/src/serdi.c b/src/serdi.c index 81b4dc1f..763f495e 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -89,6 +89,45 @@ quiet_error_func(void* handle, const SerdLogEntry* entry) return SERD_SUCCESS; } +static SerdStatus +read_file(SerdWorld* const world, + SerdSyntax syntax, + const SerdReaderFlags flags, + const SerdSink* const sink, + const size_t stack_size, + const char* filename, + const char* add_prefix, + bool bulk_read) +{ + syntax = syntax ? syntax : serd_guess_syntax(filename); + syntax = syntax ? syntax : SERD_TRIG; + + SerdStatus st = SERD_SUCCESS; + SerdReader* reader = + serd_reader_new(world, syntax, flags, sink, stack_size); + + serd_reader_add_blank_prefix(reader, add_prefix); + + if (!strcmp(filename, "-")) { + SerdNode* name = serd_new_string("stdin"); + st = serd_reader_start_stream(reader, + serd_file_read_byte, + (SerdStreamErrorFunc)ferror, + stdin, + name, + 1); + serd_node_free(name); + } else { + st = serd_reader_start_file(reader, filename, bulk_read); + } + + st = st ? st : serd_reader_read_document(reader); + + serd_reader_free(reader); + + return st; +} + int main(int argc, char** argv) { @@ -101,7 +140,6 @@ main(int argc, char** argv) SerdSyntax output_syntax = SERD_SYNTAX_EMPTY; SerdReaderFlags reader_flags = 0; SerdWriterFlags writer_flags = 0; - bool from_stdin = false; bool bulk_read = true; bool bulk_write = false; bool no_inline = false; @@ -110,13 +148,12 @@ main(int argc, char** argv) bool quiet = false; size_t stack_size = 4194304; const char* input_string = NULL; - const char* add_prefix = NULL; + const char* add_prefix = ""; const char* chop_prefix = NULL; const char* root_uri = NULL; int a = 1; for (; a < argc && argv[a][0] == '-'; ++a) { if (argv[a][1] == '\0') { - from_stdin = true; break; } else if (argv[a][1] == 'I') { if (++a == argc) { @@ -206,21 +243,18 @@ main(int argc, char** argv) _setmode(_fileno(stdout), _O_BINARY); #endif - const char* input = argv[a++]; - - if (!input_syntax && !input || !(input_syntax = serd_guess_syntax(input))) { - input_syntax = SERD_TRIG; + bool input_has_graphs = serd_syntax_has_graphs(input_syntax); + for (int i = a; i < argc; ++i) { + if (serd_syntax_has_graphs(serd_guess_syntax(argv[i]))) { + input_has_graphs = true; + break; + } } - const bool input_has_graphs = serd_syntax_has_graphs(input_syntax); if (!output_syntax && !osyntax_set) { output_syntax = input_has_graphs ? SERD_NQUADS : SERD_NTRIPLES; } - if (!base && input) { - base = serd_new_file_uri(input, NULL); - } - FILE* out_fd = stdout; SerdWorld* world = serd_world_new(); SerdEnv* env = serd_env_new(base); @@ -238,7 +272,6 @@ main(int argc, char** argv) (SerdWriteFunc)serd_byte_sink_write, byte_sink); - SerdReader* reader = NULL; SerdModel* model = NULL; SerdInserter* inserter = NULL; const SerdSink* sink = NULL; @@ -253,9 +286,6 @@ main(int argc, char** argv) sink = serd_writer_get_sink(writer); } - reader = serd_reader_new( - world, input_syntax, reader_flags, sink, stack_size); - if (quiet) { serd_world_set_log_func(world, quiet_error_func, NULL); } @@ -263,31 +293,59 @@ main(int argc, char** argv) SerdNode* root = serd_new_uri(root_uri); serd_writer_set_root_uri(writer, root); serd_writer_chop_blank_prefix(writer, chop_prefix); - serd_reader_add_blank_prefix(reader, add_prefix); serd_node_free(root); SerdStatus st = SERD_SUCCESS; SerdNode* input_name = NULL; if (input_string) { - input_name = serd_new_string("string"); - st = serd_reader_start_string(reader, input_string, input_name); - } else if (from_stdin) { - input_name = serd_new_string("stdin"); - st = serd_reader_start_stream(reader, - serd_file_read_byte, - (SerdStreamErrorFunc)ferror, - stdin, - input_name, - 1); - } else { - st = serd_reader_start_file(reader, input, bulk_read); + SerdReader* reader = + serd_reader_new(world, + input_syntax ? input_syntax : SERD_TRIG, + reader_flags, + sink, + stack_size); + serd_reader_add_blank_prefix(reader, add_prefix); + + SerdNode* name = serd_new_string("string"); + if (!(st = serd_reader_start_string(reader, input_string, name))) { + st = serd_reader_read_document(reader); + } + serd_node_free(name); + serd_reader_free(reader); } - if (!st) { - st = serd_reader_read_document(reader); + char** inputs = argv + a; + int n_inputs = argc - a; + size_t prefix_len = 0; + char* prefix = NULL; + if (n_inputs > 1) { + prefix_len = 8 + strlen(add_prefix); + prefix = (char*)calloc(1, prefix_len); } - serd_reader_finish(reader); + for (int i = 0; i < n_inputs; ++i) { + if (!base) { + SerdNode* file_uri = serd_new_file_uri(inputs[i], NULL); + serd_env_set_base_uri(env, file_uri); + serd_node_free(file_uri); + } + + if (n_inputs > 1) { + snprintf(prefix, prefix_len, "f%d%s", i, add_prefix); + } + + if ((st = read_file(world, + input_syntax, + reader_flags, + sink, + stack_size, + inputs[i], + n_inputs > 1 ? prefix : add_prefix, + bulk_read))) { + break; + } + } + free(prefix); if (st <= SERD_FAILURE && use_model) { const SerdSink* wsink = serd_writer_get_sink(writer); @@ -301,7 +359,6 @@ main(int argc, char** argv) serd_node_free(input_name); serd_inserter_free(inserter); serd_model_free(model); - serd_reader_free(reader); serd_writer_free(writer); serd_byte_sink_free(byte_sink); serd_env_free(env); diff --git a/tests/multifile/input1.ttl b/tests/multifile/input1.ttl new file mode 100644 index 00000000..88c3f8e9 --- /dev/null +++ b/tests/multifile/input1.ttl @@ -0,0 +1,2 @@ +[] + a <http://example.org/Type> . diff --git a/tests/multifile/input2.trig b/tests/multifile/input2.trig new file mode 100644 index 00000000..260080a8 --- /dev/null +++ b/tests/multifile/input2.trig @@ -0,0 +1,7 @@ +[] + a <http://example.org/Type> . + +<http://example.org/graph> { + [] + a <http://example.org/OtherType> . +} diff --git a/tests/multifile/output.nq b/tests/multifile/output.nq new file mode 100644 index 00000000..dd35dc4d --- /dev/null +++ b/tests/multifile/output.nq @@ -0,0 +1,3 @@ +_:f0b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Type> . +_:f1b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Type> . +_:f1b2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/OtherType> <http://example.org/graph> . @@ -493,7 +493,7 @@ def test(tst): import tempfile # Create test output directories - for i in ['bad', 'good', 'lax', 'terse', + for i in ['bad', 'good', 'lax', 'terse', 'multifile', 'TurtleTests', 'NTriplesTests', 'NQuadsTests', 'TriGTests']: try: test_dir = os.path.join('tests', i) @@ -547,6 +547,13 @@ def test(tst): stdout.seek(0, 2) # Seek to end check(lambda: stdout.tell() == 0, name='empty output') + with tst.group('MultiFile') as check: + path = '%s/tests/multifile' % srcdir + check([serdi, '%s/input1.ttl' % path, '%s/input2.trig' % path], + stdout='tests/multifile/output.out.nq') + check.file_equals('%s/tests/multifile/output.nq' % srcdir, + 'tests/multifile/output.out.nq') + with tst.group('BadCommands', expected=1, stderr=autowaf.NONEMPTY) as check: check([serdi]) check([serdi, '/no/such/file']) |