aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-01-20 20:40:43 +0000
committerDavid Robillard <d@drobilla.net>2011-01-20 20:40:43 +0000
commitec2991ce8c75390a227de2d21a532de1dff0fdfd (patch)
tree695fd1b44e217ca9a592b85bc46c691e32973572
parent3433e155c739f6a081209ea7422b9fdc7f87a555 (diff)
downloadserd-ec2991ce8c75390a227de2d21a532de1dff0fdfd.tar.gz
serd-ec2991ce8c75390a227de2d21a532de1dff0fdfd.tar.bz2
serd-ec2991ce8c75390a227de2d21a532de1dff0fdfd.zip
Support passing no base URI on command line (use filename as base URI).
Decent usage output. git-svn-id: http://svn.drobilla.net/serd/trunk@15 490d8e77-9747-427b-9fa3-0b8f29cee8a0
-rw-r--r--serd/serd.h6
-rw-r--r--src/serdi.c51
-rw-r--r--src/uri.c14
-rw-r--r--src/write.c2
4 files changed, 49 insertions, 24 deletions
diff --git a/serd/serd.h b/serd/serd.h
index 1dd49c65..822b4b10 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -96,10 +96,12 @@ typedef struct {
SerdChunk fragment; ///< Fragment
} SerdURI;
-/** Return true iff @a utf8 is a relative URI string. */
+static const SerdURI SERD_URI_NULL = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
+
+/** Return true iff @a utf8 starts with a valid URI scheme. */
SERD_API
bool
-serd_uri_string_is_relative(const uint8_t* utf8);
+serd_uri_string_has_scheme(const uint8_t* utf8);
/** Parse @a utf8, writing result to @a out. */
SERD_API
diff --git a/src/serdi.c b/src/serdi.c
index abac1010..d9554679 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -39,7 +39,7 @@ event_base(void* handle,
return false;
}
- SerdURI base_uri = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
+ SerdURI base_uri = SERD_URI_NULL;
SerdString* base_uri_str;
if (!uri.scheme.len) {
// URI has no scheme (relative by definition), resolve
@@ -74,7 +74,7 @@ event_prefix(void* handle,
const SerdString* uri_string)
{
State* const state = (State*)handle;
- if (serd_uri_string_is_relative(uri_string->buf)) {
+ if (!serd_uri_string_has_scheme(uri_string->buf)) {
SerdURI uri;
if (!serd_uri_parse(uri_string->buf, &uri)) {
return false;
@@ -115,25 +115,50 @@ event_statement(void* handle,
}
int
+print_usage(const char* name, bool error)
+{
+ FILE* const os = error ? stderr : stdout;
+ fprintf(os, "Usage: %s INPUT [BASE_URI]\n", name);
+ fprintf(os, "Read and write RDF syntax.\n");
+ return error ? 1 : 0;
+}
+
+int
main(int argc, char** argv)
{
- if (/*argc != 2 && */argc != 3) {
- fprintf(stderr, "Bad parameters\n");
- return 1;
+ if (argc != 2 && argc != 3) {
+ return print_usage(argv[0], true);
}
- const uint8_t* const in_filename = (uint8_t*)argv[1];
- const uint8_t* base_uri_str = in_filename;
+ const uint8_t* in_filename = (const uint8_t*)argv[1];
- SerdURI base_uri;
- if (argc > 2) {
- base_uri_str = (const uint8_t*)argv[2];
- if (!serd_uri_parse(base_uri_str, &base_uri)) {
- fprintf(stderr, "invalid base uri: %s\n", base_uri_str);
+ if (serd_uri_string_has_scheme(in_filename)) {
+ // Input is an absolute URI, ensure it's a file: URI and chop scheme
+ if (strncmp((const char*)in_filename, "file:", 5)) {
+ fprintf(stderr, "unsupported URI scheme `%s'\n", in_filename);
return 1;
+ } else if (!strncmp((const char*)in_filename, "file:///", 7)) {
+ in_filename += 7;
+ } else {
+ in_filename += 5;
}
}
+ SerdString* base_uri_str = NULL;
+ SerdURI base_uri;
+ if (argc > 2) { // Base URI given on command line
+ const uint8_t* const in_base_uri = (const uint8_t*)argv[2];
+ if (!serd_uri_parse((const uint8_t*)in_base_uri, &base_uri)) {
+ fprintf(stderr, "invalid base URI `%s'\n", argv[2]);
+ return 1;
+ }
+ base_uri_str = serd_string_new(in_base_uri);
+ } else { // Use input file URI
+ base_uri_str = serd_string_new(in_filename);
+ }
+
+ serd_uri_parse(base_uri_str->buf, &base_uri);
+
FILE* const in_fd = fopen((const char*)in_filename, "r");
FILE* out_fd = stdout;
@@ -145,7 +170,7 @@ main(int argc, char** argv)
SerdNamespaces ns = serd_namespaces_new();
State state = { serd_writer_new(SERD_NTRIPLES, ns, out_fd, &base_uri),
ns,
- serd_string_new(base_uri_str),
+ base_uri_str,
base_uri };
SerdReader reader = serd_reader_new(
diff --git a/src/uri.c b/src/uri.c
index a7e7178c..2d4fdc9f 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -44,29 +44,28 @@ is_digit(const uint8_t c)
return in_range(c, '0', '9');
}
-/** Return true if @a uri is relative (i.e. does not start with a scheme) */
SERD_API
bool
-serd_uri_string_is_relative(const uint8_t* utf8)
+serd_uri_string_has_scheme(const uint8_t* utf8)
{
// RFC3986: scheme ::= ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
if (!is_alpha(utf8[0])) {
- return true; // Invalid scheme initial character, URI is relative
+ return false; // Invalid scheme initial character, URI is relative
}
for (uint8_t c = *++utf8; (c = *utf8) != '\0'; ++utf8) {
switch (c) {
case ':':
- return false; // End of scheme, URI is absolute
+ return true; // End of scheme
case '+': case '-': case '.':
break; // Valid scheme character, continue
default:
if (!is_alpha(c) && !is_digit(c)) {
- return true; // Invalid scheme character, URI is relative
+ return false; // Invalid scheme character
}
}
}
- return true;
+ return false;
}
#ifdef URI_DEBUG
@@ -93,8 +92,7 @@ SERD_API
bool
serd_uri_parse(const uint8_t* utf8, SerdURI* uri)
{
- static const SerdURI null_uri = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
- *uri = null_uri;
+ *uri = SERD_URI_NULL;
assert(uri->path_base.buf == NULL);
assert(uri->path_base.len == 0);
assert(uri->authority.len == 0);
diff --git a/src/write.c b/src/write.c
index 893062ef..95b2c2f2 100644
--- a/src/write.c
+++ b/src/write.c
@@ -142,7 +142,7 @@ serd_write_node(SerdWriter writer,
fwrite(">", 1, 1, fd);
break;
case URI:
- if (serd_uri_string_is_relative(str->buf)) {
+ if (!serd_uri_string_has_scheme(str->buf)) {
SerdURI uri;
if (serd_uri_parse(str->buf, &uri)) {
SerdURI abs_uri;