diff options
author | David Robillard <d@drobilla.net> | 2011-01-20 20:40:43 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-01-20 20:40:43 +0000 |
commit | ec2991ce8c75390a227de2d21a532de1dff0fdfd (patch) | |
tree | 695fd1b44e217ca9a592b85bc46c691e32973572 | |
parent | 3433e155c739f6a081209ea7422b9fdc7f87a555 (diff) | |
download | serd-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.h | 6 | ||||
-rw-r--r-- | src/serdi.c | 51 | ||||
-rw-r--r-- | src/uri.c | 14 | ||||
-rw-r--r-- | src/write.c | 2 |
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( @@ -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; |