aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/man/serd-pipe.164
-rw-r--r--test/meson.build9
-rwxr-xr-xtest/run_suite.py9
-rw-r--r--test/test_writer.c2
-rw-r--r--tools/serd-pipe.c13
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;
}