diff options
-rw-r--r-- | doc/man/serd-pipe.1 | 64 | ||||
-rw-r--r-- | test/meson.build | 9 | ||||
-rwxr-xr-x | test/run_suite.py | 9 | ||||
-rw-r--r-- | test/test_writer.c | 2 | ||||
-rw-r--r-- | tools/serd-pipe.c | 13 |
5 files changed, 75 insertions, 22 deletions
diff --git a/doc/man/serd-pipe.1 b/doc/man/serd-pipe.1 index ae3e6620..793737f9 100644 --- a/doc/man/serd-pipe.1 +++ b/doc/man/serd-pipe.1 @@ -18,21 +18,46 @@ .Op Fl p Ar prefix .Op Fl r Ar root .Op Fl s Ar string +.Op Fl w Ar filename .Op Ar input ... .Sh DESCRIPTION .Nm -is a fast command-line utility for streaming and processing RDF data. -It reads one or more RDF documents and writes the data to stdout, -possibly transformed and/or in a different syntax. +is a fast command-line utility for streaming RDF data. +It reads one or more files and writes the data again, +possibly in a different form. +.Pp +.Nm +writes statements immediately as they are read, +so it uses little memory and is suitable for use in pipelines and with huge files. +Typical uses include checking syntax, +converting to another syntax, +pretty-printing, +merging files, +expanding URIs, +and so on. +.Pp By default, -the input syntax is guessed from the file extension, -and output is written in NTriples or NQuads. +syntaxes are guessed from file extensions where possible, +making use with filenames most convenient. +For example, +most common tasks can be accomplished with simple commands like: +.Pp +.Dl $ serd-pipe -o pretty.ttl input.nt .Pp +The +.Ar input +operands are processed in command-line order. +If +.Ar input +is +.Ar - +or absent, .Nm -can be used to check for syntax errors, -convert from one syntax to another, -pretty-print documents, -or transform URIs and blank node IDs. +reads from standard input. +Similarly, output defaults to standard output. +If syntax isn't given and can't be determined from filenames, +then input is read as TriG and output is written as NQuads +(which will function properly with Turtle and NTriples, respectively). .Pp The options are as follows: .Bl -tag -width 3n @@ -158,6 +183,10 @@ as input. Write terser output without newlines. .It Fl v Display version information and exit. +.It Fl w Ar filename +Write output to the given +.Ar filename +instead of stdout. .It Fl x Support parsing variable nodes. Variables can be written in SPARQL style, for example @@ -182,16 +211,23 @@ If set to anything other than 0, color is forced on. exits with a status of 0, or non-zero if an error occurred. .Sh EXAMPLES .Bl -tag -width 3n -.It Pretty-print a document: -.Nm Fl o +.It Format a Turtle file to stdout: +.Nm Fl O .Ar turtle -.Pa file.ttl -> -.Pa out.ttl +.Pa input.ttl .It Print only errors and discard the output: .Nm Fl O .Ar empty .Pa input.ttl +.It Convert an NTriples file to Turtle: +.Nm Fl o +.Ar output.ttl +.Pa input.nt +.It Merge two files: +.Nm Fl o +.Pa merged.ttl +.Pa header.ttl +.Pa body.ttl .El .Sh SEE ALSO .Bl -item -compact diff --git a/test/meson.build b/test/meson.build index b01dde81..08fb3200 100644 --- a/test/meson.build +++ b/test/meson.build @@ -197,6 +197,7 @@ simple_command_tests = { ['-r'], ['-s', '<foo> a <Bar> .'], ['-s'], + ['-w'], ['-z'], ], 'good': [ @@ -351,6 +352,14 @@ if is_variable('serd_pipe') env: test_env, suite: 'io', ) + test( + 'missing_output', + serd_pipe, + args: ['-o', '/does/not/exist.ttl', serd_ttl], + env: test_env, + should_fail: true, + suite: 'io', + ) if host_machine.system() == 'linux' test( diff --git a/test/run_suite.py b/test/run_suite.py index ffc616a3..cee9d88e 100755 --- a/test/run_suite.py +++ b/test/run_suite.py @@ -41,13 +41,12 @@ def run_eval_test(command, in_path, good_path, out_path): """Run a positive eval test and return whether the output matches.""" syntax = util.syntax_from_path(out_path) - command = command + ["-o", syntax, in_path] - - with subprocess.Popen(command, stdout=PIPE, encoding="utf-8") as proc: - out = list(proc.stdout) + command = command + ["-o", syntax, "-w", out_path, in_path] + subprocess.check_call(command, encoding="utf-8") with open(good_path, "r", encoding="utf-8") as good: - return util.lines_equal(list(good), out, good_path, out_path) + with open(out_path, "r", encoding="utf-8") as out: + return util.lines_equal(list(good), list(out), good_path, out_path) def run_positive_test(command, in_path): diff --git a/test/test_writer.c b/test/test_writer.c index 655f79e9..47350031 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -417,7 +417,7 @@ test_write_bad_uri(void) SerdBuffer buffer = {NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = - serd_writer_new(world, SERD_NTRIPLES, 0U, env, &output, 1); + serd_writer_new(world, SERD_NTRIPLES, 0U, env, &output, 1U); assert(writer); diff --git a/tools/serd-pipe.c b/tools/serd-pipe.c index 080fc9a1..84893506 100644 --- a/tools/serd-pipe.c +++ b/tools/serd-pipe.c @@ -52,6 +52,7 @@ print_usage(const char* const name, const bool error) " -s STRING Parse STRING as input.\n" " -t Write terser output without newlines.\n" " -v Display version information and exit.\n" + " -w FILENAME Write output to FILENAME instead of stdout.\n" " -x Support parsing variable nodes like \"?x\".\n"; FILE* const os = error ? stderr : stdout; @@ -121,6 +122,7 @@ main(int argc, char** argv) const char* add_prefix = ""; const char* chop_prefix = NULL; const char* root_uri = NULL; + const char* out_filename = NULL; int a = 1; for (; a < argc && argv[a][0] == '-'; ++a) { if (argv[a][1] == '\0') { @@ -238,6 +240,13 @@ main(int argc, char** argv) input_string = argv[a]; break; + } else if (opt == 'w') { + if (argv[a][o + 1] || ++a == argc) { + return missing_arg(argv[0], 'w'); + } + + out_filename = argv[a]; + break; } else { SERDI_ERRORF("invalid option -- '%s'\n", argv[a] + 1); return print_usage(prog, true); @@ -285,7 +294,7 @@ main(int argc, char** argv) SerdEnv* const env = serd_env_new(base ? serd_node_string_view(base) : serd_empty_string()); - SerdOutputStream out = serd_open_tool_output("-"); + SerdOutputStream out = serd_open_tool_output(out_filename); if (!out.stream) { perror("serdi: error opening output file"); return 1; @@ -366,7 +375,7 @@ main(int argc, char** argv) serd_node_free(base); serd_world_free(world); - if (fclose(stdout)) { + if (serd_close_output(&out)) { perror("serd-pipe: write error"); st = SERD_BAD_STREAM; } |