Hello community, here is the log from the commit of package serd for openSUSE:Factory checked in at 2015-11-26 17:04:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/serd (Old) and /work/SRC/openSUSE:Factory/.serd.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "serd" Changes: -------- --- /work/SRC/openSUSE:Factory/serd/serd.changes 2015-03-25 10:01:13.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.serd.new/serd.changes 2015-11-26 17:04:39.000000000 +0100 @@ -1,0 +2,17 @@ +Tue Nov 24 18:45:34 UTC 2015 - [email protected] + +- Update to version 0.22.0 + * Remove dependence on fmax() to avoid portability issues + * Fix serd_reader_read_file() for URIs with escaped characters (spaces) + * Add serd_reader_set_strict() and -l (lax) option to serdi to tolerate + parsing URIs with escaped characters + * Fix reading statements ending with a blank then dot with no space + * Fix clash resolution when a blank node ID prefix is set + * Fix serializing fractional decimals that would round up + * Add support for Turtle named inline nodes extension + * Report errors for invalid IRI characters and missing terminators + * Show serdi errors in standard format + * Fix warnings when building with ISO C++ compilers + * Upgrade to waf 1.8.14 + +------------------------------------------------------------------- Old: ---- serd-0.20.0.tar.bz2 New: ---- serd-0.22.0.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ serd.spec ++++++ --- /var/tmp/diff_new_pack.u4mu6s/_old 2015-11-26 17:04:40.000000000 +0100 +++ /var/tmp/diff_new_pack.u4mu6s/_new 2015-11-26 17:04:40.000000000 +0100 @@ -19,7 +19,7 @@ %define soname 0 Name: serd -Version: 0.20.0 +Version: 0.22.0 Release: 0 Summary: A lightweight C library for RDF syntax License: ISC @@ -92,7 +92,7 @@ %{_libdir}/libserd-0.so %{_includedir}/serd-0/ %{_libdir}/pkgconfig/serd-0.pc -%{_defaultdocdir}/serd-0/ -%{_mandir}/man3/* +#%{_defaultdocdir}/serd-0/ +#%{_mandir}/man3/* %changelog ++++++ serd-0.20.0.tar.bz2 -> serd-0.22.0.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/COPYING new/serd-0.22.0/COPYING --- old/serd-0.20.0/COPYING 2014-08-08 07:47:20.000000000 +0200 +++ new/serd-0.22.0/COPYING 2015-10-07 03:59:57.000000000 +0200 @@ -1,4 +1,4 @@ -Copyright 2011-2014 David Robillard <http://drobilla.net> +Copyright 2011-2015 David Robillard <http://drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/INSTALL new/serd-0.22.0/INSTALL --- old/serd-0.20.0/INSTALL 2012-07-09 05:43:14.000000000 +0200 +++ new/serd-0.22.0/INSTALL 2015-10-07 04:13:53.000000000 +0200 @@ -8,11 +8,7 @@ ./waf configure ./waf - ./waf install - -You may need to become root for the install stage, for example: - - sudo ./waf install + ./waf install # or sudo ./waf install Configuration Options --------------------- @@ -40,12 +36,20 @@ * CPPFLAGS: C preprocessor options * LINKFLAGS: Linker options -Installation Directories ------------------------- +Library Versioning +------------------ + +This library uses semantic versioning <http://semver.org/>. -The --prefix option (or the PREFIX environment variable) can be used to change -the prefix which all files are installed under. There are also several options -allowing for more fine-tuned control, see the --help output for details. +Several major versions can be installed in parallel. The shared library name, +include directory, and pkg-config file are suffixed with the major version +number. For example, a library named "foo" at version 1.x.y might install: + + /usr/include/foo-1/foo/foo.h + /usr/lib/foo-1.so.1.x.y + /usr/lib/pkgconfig/foo-1.pc + +Dependencies can check for the package "foo-1" with pkg-config. Packaging --------- @@ -57,3 +61,6 @@ ./waf configure --prefix=/usr ./waf ./waf install --destdir=/tmp/package + +Packages should allow parallel installation of several major versions. For +example, the above would be packaged as "foo-1". \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/NEWS new/serd-0.22.0/NEWS --- old/serd-0.20.0/NEWS 2014-08-09 00:03:44.000000000 +0200 +++ new/serd-0.22.0/NEWS 2015-10-08 21:34:20.000000000 +0200 @@ -1,3 +1,20 @@ +serd (0.22.0) stable; + + * Remove dependence on fmax() to avoid portability issues + * Fix serd_reader_read_file() for URIs with escaped characters (spaces) + * Add serd_reader_set_strict() and -l (lax) option to serdi to tolerate + parsing URIs with escaped characters + * Fix reading statements ending with a blank then dot with no space + * Fix clash resolution when a blank node ID prefix is set + * Fix serializing fractional decimals that would round up + * Add support for Turtle named inline nodes extension + * Report errors for invalid IRI characters and missing terminators + * Show serdi errors in standard format + * Fix warnings when building with ISO C++ compilers + * Upgrade to waf 1.8.14 + + -- David Robillard <[email protected]> Thu, 08 Oct 2015 15:34:18 -0400 + serd (0.20.0) stable; * Support new RDF 1.1 Turtle diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/PACKAGING new/serd-0.22.0/PACKAGING --- old/serd-0.20.0/PACKAGING 2011-12-06 21:07:43.000000000 +0100 +++ new/serd-0.22.0/PACKAGING 1970-01-01 01:00:00.000000000 +0100 @@ -1,29 +0,0 @@ -This library is designed to allow parallel installation of different major -versions. To facilitate this, the shared library name, include directory, and -pkg-config file are suffixed with the major version number of the library. - -For example, if this library was named "foo" and at version 1.x.y: - -/usr/include/foo-1/foo/foo.h -/usr/lib/foo-1.so.1.x.y -/usr/lib/pkgconfig/foo-1.pc - -Dependencies check for pkg-config name "foo-1" and will build -against a compatible version 1, regardless any other installed versions. - -*** IMPORTANT GUIDELINES FOR PACKAGERS *** - -Packages should follow the same conventions as above, i.e. include the major -version (and only the major version) in the name of the package. Continuing the -example above, the package(s) would be named foo-1 and foo-1-dev. This way, -if/when version 2 comes out, it may be installed at the same time as version 1 -without breaking anything. - -Please do not create packages of this library that do not follow these -guidelines, you will break things and cause unnecessary headaches. Please do -not use any number as a suffix other than the actual major version number of the -upstream source package. - -Because program and documentation names are not versioned, these should be -included in separate packages which may replace previous versions, since -there is little use in having parallel installations of them. \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/serd/serd.h new/serd-0.22.0/serd/serd.h --- old/serd-0.20.0/serd/serd.h 2014-08-08 16:40:02.000000000 +0200 +++ new/serd-0.22.0/serd/serd.h 2015-10-08 21:32:14.000000000 +0200 @@ -1,5 +1,5 @@ /* - Copyright 2011-2014 David Robillard <http://drobilla.net> + Copyright 2011-2015 David Robillard <http://drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -183,7 +183,7 @@ @see <a href="http://www.w3.org/TeamSubmission/turtle#nodeID">Turtle <tt>nodeID</tt></a> */ - SERD_BLANK = 4, + SERD_BLANK = 4 } SerdType; @@ -336,8 +336,7 @@ @param hostname If non-NULL, set to the hostname, if present. @return The path component of the URI. - Both the returned path and `hostname` (if applicable) are owned by the - caller and must be freed with free(). + The returned path and `*hostname` must be freed with free(). */ SERD_API uint8_t* @@ -689,6 +688,17 @@ SerdEndSink end_sink); /** + Enable or disable strict parsing. + + The reader is non-strict (lax) by default, which will tolerate URIs with + invalid characters. Setting strict will fail when parsing such files. An + error is printed for invalid input in either case. +*/ +SERD_API +void +serd_reader_set_strict(SerdReader* reader, bool strict); + +/** Set a function to be called when errors occur during reading. The `error_sink` will be called with `handle` as its first argument. If Files old/serd-0.20.0/serd-0.20.0.tar.bz2.sig and new/serd-0.22.0/serd-0.20.0.tar.bz2.sig differ Files old/serd-0.20.0/serd.o and new/serd-0.22.0/serd.o differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/src/node.c new/serd-0.22.0/src/node.c --- old/serd-0.20.0/src/node.c 2014-08-08 07:14:04.000000000 +0200 +++ new/serd-0.22.0/src/node.c 2015-10-08 21:32:14.000000000 +0200 @@ -1,5 +1,5 @@ /* - Copyright 2011-2014 David Robillard <http://drobilla.net> + Copyright 2011-2015 David Robillard <http://drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -216,6 +216,13 @@ return node; } +static inline unsigned +serd_digits(double abs) +{ + const double lg = ceil(log10(floor(abs) + 1.0)); + return lg < 1.0 ? 1U : (unsigned)lg; +} + SERD_API SerdNode serd_node_new_decimal(double d, unsigned frac_digits) @@ -225,7 +232,7 @@ } const double abs_d = fabs(d); - const unsigned int_digits = (unsigned)fmax(1.0, ceil(log10(abs_d + 1))); + const unsigned int_digits = serd_digits(abs_d); char* buf = (char*)calloc(int_digits + frac_digits + 3, 1); SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL }; const double int_part = floor(abs_d); @@ -276,7 +283,7 @@ serd_node_new_integer(int64_t i) { int64_t abs_i = (i < 0) ? -i : i; - const unsigned digits = fmax(1.0, ceil(log10((double)abs_i + 1))); + const unsigned digits = serd_digits(abs_i); char* buf = (char*)calloc(digits + 2, 1); SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/src/reader.c new/serd-0.22.0/src/reader.c --- old/serd-0.20.0/src/reader.c 2014-08-08 16:40:02.000000000 +0200 +++ new/serd-0.22.0/src/reader.c 2015-10-08 21:32:14.000000000 +0200 @@ -1,5 +1,5 @@ /* - Copyright 2011-2014 David Robillard <http://drobilla.net> + Copyright 2011-2015 David Robillard <http://drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -17,6 +17,7 @@ #include "serd_internal.h" #include <assert.h> +#include <ctype.h> #include <errno.h> #include <stdarg.h> #include <stdint.h> @@ -84,6 +85,7 @@ uint8_t read_byte; ///< 1-byte 'buffer' used when not paging bool from_file; ///< True iff reading from `fd` bool paging; ///< True iff reading a page at a time + bool strict; ///< True iff strict parsing bool eof; bool seen_genid; #ifdef SERD_STACK_CHECK @@ -633,7 +635,7 @@ if ((c & 0x80)) { // Multi-byte character return !read_utf8_character(reader, dest, eat_byte_safe(reader, c)); } - + if (is_alpha(c) || is_digit(c) || c == '_' || c == '-') { push_byte(reader, dest, eat_byte_safe(reader, c)); return true; @@ -654,7 +656,7 @@ } return false; } - + static SerdStatus read_PLX(SerdReader* reader, Ref dest) { @@ -802,7 +804,17 @@ break; default: if (c <= 0x20) { - return pop_node(reader, ref); + if (isprint(c)) { + r_err(reader, SERD_ERR_BAD_SYNTAX, + "invalid IRI character `%c' (escape %%%02X)\n", c, c); + } else { + r_err(reader, SERD_ERR_BAD_SYNTAX, + "invalid IRI character (escape %%%02X)\n", c, c); + } + if (reader->strict) { + return pop_node(reader, ref); + } + push_byte(reader, ref, eat_byte_safe(reader, c)); } else { push_byte(reader, ref, eat_byte_safe(reader, c)); } @@ -872,7 +884,7 @@ *ate_dot = true; // Force caller to deal with stupid grammar return true; // Next byte is not a number character, done } - + push_byte(reader, ref, '.'); read_0_9(reader, ref, false); } @@ -990,7 +1002,7 @@ } static Ref -read_BLANK_NODE_LABEL(SerdReader* reader) +read_BLANK_NODE_LABEL(SerdReader* reader, bool* ate_dot) { eat_byte_safe(reader, '_'); eat_byte_check(reader, ':'); @@ -1014,18 +1026,21 @@ } } - const SerdNode* n = deref(reader, ref); + SerdNode* n = deref(reader, ref); if (n->buf[n->n_bytes - 1] == '.' && !read_PN_CHARS(reader, ref)) { - r_err(reader, SERD_ERR_BAD_SYNTAX, "name ends with `.'\n"); - return pop_node(reader, ref); + // Ate trailing dot, pop it from stack/node and inform caller + --n->n_bytes; + serd_stack_pop(&reader->stack, 1); + *ate_dot = true; } if (reader->syntax == SERD_TURTLE) { - if (is_digit(n->buf[1])) { - if (n->buf[0] == 'b') { - ((char*)n->buf)[0] = 'B'; // Prevent clash + if (is_digit(n->buf[reader->bprefix_len + 1])) { + if ((n->buf[reader->bprefix_len]) == 'b') { + ((char*)n->buf)[reader->bprefix_len] = 'B'; // Prevent clash reader->seen_genid = true; - } else if (reader->seen_genid && n->buf[0] == 'B') { + } else if (reader->seen_genid && + n->buf[reader->bprefix_len] == 'B') { r_err(reader, SERD_ERR_ID_CLASH, "found both `b' and `B' blank IDs, prefix required\n"); return pop_node(reader, ref); @@ -1058,51 +1073,64 @@ return ref; } +static Ref +read_blankName(SerdReader* reader) +{ + eat_byte_safe(reader, '='); + if (eat_byte_check(reader, '=') != '=') { + return r_err(reader, SERD_ERR_BAD_SYNTAX, "expected `='\n"); + } + + Ref subject = 0; + bool ate_dot = false; + read_ws_star(reader); + read_iri(reader, &subject, &ate_dot); + return subject; +} + static bool -read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest) +read_anon(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest) { const SerdStatementFlags old_flags = *ctx.flags; bool empty; - switch (peek_byte(reader)) { - case '_': - return (*dest = read_BLANK_NODE_LABEL(reader)); - case '[': - eat_byte_safe(reader, '['); - if ((empty = peek_delim(reader, ']'))) { - *ctx.flags |= (subject) ? SERD_EMPTY_S : SERD_EMPTY_O; - } else { - *ctx.flags |= (subject) ? SERD_ANON_S_BEGIN : SERD_ANON_O_BEGIN; + eat_byte_safe(reader, '['); + if ((empty = peek_delim(reader, ']'))) { + *ctx.flags |= (subject) ? SERD_EMPTY_S : SERD_EMPTY_O; + } else { + *ctx.flags |= (subject) ? SERD_ANON_S_BEGIN : SERD_ANON_O_BEGIN; + if (peek_delim(reader, '=')) { + if (!(*dest = read_blankName(reader)) || + !eat_delim(reader, ';')) { + return false; + } } + } + if (!*dest) { *dest = blank_id(reader); - if (ctx.subject) { - TRY_RET(emit_statement(reader, ctx, *dest, 0, 0)); - } + } + if (ctx.subject) { + TRY_RET(emit_statement(reader, ctx, *dest, 0, 0)); + } - ctx.subject = *dest; - if (!empty) { - *ctx.flags &= ~(SERD_LIST_CONT); - if (!subject) { - *ctx.flags |= SERD_ANON_CONT; - } - bool ate_dot = false; - read_predicateObjectList(reader, ctx, &ate_dot); - if (ate_dot) { - return r_err(reader, SERD_ERR_BAD_SYNTAX, "`.' inside blank\n"); - } - read_ws_star(reader); - if (reader->end_sink) { - reader->end_sink(reader->handle, deref(reader, *dest)); - } - *ctx.flags = old_flags; + ctx.subject = *dest; + if (!empty) { + *ctx.flags &= ~(SERD_LIST_CONT); + if (!subject) { + *ctx.flags |= SERD_ANON_CONT; + } + bool ate_dot_in_list = false; + read_predicateObjectList(reader, ctx, &ate_dot_in_list); + if (ate_dot_in_list) { + return r_err(reader, SERD_ERR_BAD_SYNTAX, "`.' inside blank\n"); } - eat_byte_check(reader, ']'); - return true; - case '(': - return read_collection(reader, ctx, dest); - default: - return r_err(reader, SERD_ERR_BAD_SYNTAX, "invalid blank node\n"); + read_ws_star(reader); + if (reader->end_sink) { + reader->end_sink(reader->handle, deref(reader, *dest)); + } + *ctx.flags = old_flags; } + return (eat_byte_check(reader, ']') == ']'); } // Recurses, calling statement_sink for every statement encountered. @@ -1129,11 +1157,16 @@ case '\0': case ')': return false; - case '[': case '(': + case '[': emit = false; - // fall through + TRY_THROW(ret = read_anon(reader, ctx, false, &o)); + break; + case '(': + emit = false; + TRY_THROW(ret = read_collection(reader, ctx, &o)); + break; case '_': - TRY_THROW(ret = read_blank(reader, ctx, false, &o)); + TRY_THROW(ret = (o = read_BLANK_NODE_LABEL(reader, ate_dot))); break; case '<': case ':': TRY_THROW(ret = read_iri(reader, &o, ate_dot)); @@ -1298,11 +1331,17 @@ Ref subject = 0; bool ate_dot = false; switch (peek_byte(reader)) { - case '[': case '(': + case '[': + *nested = true; + read_anon(reader, ctx, true, &subject); + break; + case '(': *nested = true; - // nobreak + read_collection(reader, ctx, &subject); + break; case '_': - read_blank(reader, ctx, true, &subject); + *nested = false; + subject = read_BLANK_NODE_LABEL(reader, &ate_dot); break; default: read_iri(reader, &subject, &ate_dot); @@ -1320,10 +1359,10 @@ ctx.subject = subject; if (nested) { read_ws_star(reader); + ret = true; if (peek_byte(reader) != '.') { - read_predicateObjectList(reader, ctx, ate_dot); + ret = read_predicateObjectList(reader, ctx, ate_dot); } - ret = true; } else { TRY_RET(read_ws_plus(reader)); ret = read_predicateObjectList(reader, ctx, ate_dot); @@ -1411,14 +1450,15 @@ case '@': TRY_RET(read_directive(reader)); read_ws_star(reader); - return eat_byte_safe(reader, '.'); + return (eat_byte_check(reader, '.') == '.'); default: - TRY_RET(read_triples(reader, ctx, &ate_dot)); - if (ate_dot) { + if (!read_triples(reader, ctx, &ate_dot)) { + return false; + } else if (ate_dot) { return true; } else { read_ws_star(reader); - return eat_byte_check(reader, '.'); + return (eat_byte_check(reader, '.') == '.'); } break; } @@ -1466,6 +1506,7 @@ me->read_buf = 0; me->file_buf = 0; me->read_head = 0; + me->strict = false; me->eof = false; me->seen_genid = false; #ifdef SERD_STACK_CHECK @@ -1482,6 +1523,13 @@ SERD_API void +serd_reader_set_strict(SerdReader* reader, bool strict) +{ + reader->strict = strict; +} + +SERD_API +void serd_reader_set_error_sink(SerdReader* reader, SerdErrorSink error_sink, void* error_handle) @@ -1546,18 +1594,20 @@ serd_reader_read_file(SerdReader* reader, const uint8_t* uri) { - const uint8_t* path = serd_uri_to_path(uri); + uint8_t* const path = serd_file_uri_parse(uri, NULL); if (!path) { return SERD_ERR_BAD_ARG; } FILE* fd = serd_fopen((const char*)path, "r"); if (!fd) { + free(path); return SERD_ERR_UNKNOWN; } SerdStatus ret = serd_reader_read_file_handle(reader, fd, path); fclose(fd); + free(path); return ret; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/src/serd_internal.h new/serd-0.22.0/src/serd_internal.h --- old/serd-0.20.0/src/serd_internal.h 2014-08-08 16:40:02.000000000 +0200 +++ new/serd-0.22.0/src/serd_internal.h 2015-10-07 03:47:14.000000000 +0200 @@ -38,14 +38,6 @@ # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif -#ifndef HAVE_FMAX -static inline double -fmax(double a, double b) -{ - return (a < b) ? b : a; -} -#endif - /* File and Buffer Utilities */ static inline FILE* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/src/serdi.c new/serd-0.22.0/src/serdi.c --- old/serd-0.20.0/src/serdi.c 2014-08-08 07:14:04.000000000 +0200 +++ new/serd-0.22.0/src/serdi.c 2015-10-08 21:32:14.000000000 +0200 @@ -1,5 +1,5 @@ /* - Copyright 2011-2013 David Robillard <http://drobilla.net> + Copyright 2011-2015 David Robillard <http://drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -21,6 +21,9 @@ #include <stdlib.h> #include <string.h> +#define SERDI_ERROR(msg) fprintf(stderr, "serdi: " msg); +#define SERDI_ERRORF(fmt, ...) fprintf(stderr, "serdi: " fmt, __VA_ARGS__); + typedef struct { SerdEnv* env; SerdWriter* writer; @@ -41,6 +44,7 @@ print_usage(const char* name, bool error) { FILE* const os = error ? stderr : stdout; + fprintf(os, "%s", error ? "\n" : ""); fprintf(os, "Usage: %s [OPTION]... INPUT [BASE_URI]\n", name); fprintf(os, "Read and write RDF syntax.\n"); fprintf(os, "Use - for INPUT to read from standard input.\n\n"); @@ -50,6 +54,7 @@ fprintf(os, " -f Keep full URIs in input (don't qualify).\n"); fprintf(os, " -h Display this help and exit.\n"); fprintf(os, " -i SYNTAX Input syntax (`turtle' or `ntriples').\n"); + fprintf(os, " -l Lax (non-strict) parsing.\n"); fprintf(os, " -o SYNTAX Output syntax (`turtle' or `ntriples').\n"); fprintf(os, " -p PREFIX Add PREFIX to blank node IDs.\n"); fprintf(os, " -q Suppress all output except data.\n"); @@ -67,17 +72,17 @@ } else if (!strcmp(name, "ntriples")) { *syntax = SERD_NTRIPLES; } else { - fprintf(stderr, "Unknown input format `%s'\n", name); + SERDI_ERRORF("unknown syntax `%s'\n", name); return false; } return true; } static int -bad_arg(const char* name, char opt) +missing_arg(const char* name, char opt) { - fprintf(stderr, "%s: Bad or missing value for -%c\n", name, opt); - return 1; + SERDI_ERRORF("option requires an argument -- '%c'\n", opt); + return print_usage(name, true); } static SerdStatus @@ -100,6 +105,7 @@ bool bulk_read = true; bool bulk_write = false; bool full_uris = false; + bool lax = false; bool quiet = false; const uint8_t* in_name = NULL; const uint8_t* add_prefix = NULL; @@ -119,6 +125,8 @@ full_uris = true; } else if (argv[a][1] == 'h') { return print_usage(argv[0], false); + } else if (argv[a][1] == 'l') { + lax = true; } else if (argv[a][1] == 'q') { quiet = true; } else if (argv[a][1] == 'v') { @@ -129,36 +137,40 @@ ++a; break; } else if (argv[a][1] == 'i') { - if (++a == argc || !set_syntax(&input_syntax, argv[a])) { - return bad_arg(argv[0], 'i'); + if (++a == argc) { + return missing_arg(argv[0], 'i'); + } else if (!set_syntax(&input_syntax, argv[a])) { + return print_usage(argv[0], true); } } else if (argv[a][1] == 'o') { - if (++a == argc || !set_syntax(&output_syntax, argv[a])) { - return bad_arg(argv[0], 'o'); + if (++a == argc) { + return missing_arg(argv[0], 'o'); + } else if (!set_syntax(&output_syntax, argv[a])) { + return print_usage(argv[0], true); } } else if (argv[a][1] == 'p') { if (++a == argc) { - return bad_arg(argv[0], 'p'); + return missing_arg(argv[0], 'p'); } add_prefix = (const uint8_t*)argv[a]; } else if (argv[a][1] == 'c') { if (++a == argc) { - return bad_arg(argv[0], 'c'); + return missing_arg(argv[0], 'c'); } chop_prefix = (const uint8_t*)argv[a]; } else if (argv[a][1] == 'r') { if (++a == argc) { - return bad_arg(argv[0], 'r'); + return missing_arg(argv[0], 'r'); } root_uri = (const uint8_t*)argv[a]; } else { - fprintf(stderr, "%s: Unknown option `%s'\n", argv[0], argv[a]); + SERDI_ERRORF("invalid option -- '%s'\n", argv[a] + 1); return print_usage(argv[0], true); } } if (a == argc) { - fprintf(stderr, "%s: Missing input\n", argv[0]); + SERDI_ERROR("missing input\n"); return 1; } @@ -215,6 +227,7 @@ (SerdStatementSink)serd_writer_write_statement, (SerdEndSink)serd_writer_end_anon); + serd_reader_set_strict(reader, !lax); if (quiet) { serd_reader_set_error_sink(reader, quiet_error_sink, NULL); serd_writer_set_error_sink(writer, quiet_error_sink, NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/src/writer.c new/serd-0.22.0/src/writer.c --- old/serd-0.20.0/src/writer.c 2014-08-08 07:14:03.000000000 +0200 +++ new/serd-0.22.0/src/writer.c 2015-10-08 21:32:14.000000000 +0200 @@ -1,5 +1,5 @@ /* - Copyright 2011-2014 David Robillard <http://drobilla.net> + Copyright 2011-2015 David Robillard <http://drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -177,7 +177,7 @@ size_t i = 0; uint8_t in = utf8[i++]; - + #define READ_BYTE() \ in = utf8[i++] & 0x3F; \ c = (c << 6) | in; @@ -237,7 +237,7 @@ return !in_range(c, 0x20, 0x7E); } } - + static size_t write_uri(SerdWriter* writer, const uint8_t* utf8, size_t n_bytes) { @@ -435,6 +435,14 @@ } Field; static bool +is_inline_start(const SerdWriter* writer, Field field, SerdStatementFlags flags) +{ + return (writer->syntax != SERD_NTRIPLES && + ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN)) || + (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))); +} + +static bool write_node(SerdWriter* writer, const SerdNode* node, const SerdNode* datatype, @@ -443,13 +451,12 @@ SerdStatementFlags flags) { SerdChunk uri_prefix; - SerdChunk uri_suffix; + SerdNode prefix; + SerdChunk suffix; bool has_scheme; switch (node->type) { case SERD_BLANK: - if (writer->syntax != SERD_NTRIPLES - && ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN)) - || (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))) { + if (is_inline_start(writer, field, flags)) { ++writer->indent; write_sep(writer, SEP_ANON_BEGIN); } else if (writer->syntax != SERD_NTRIPLES @@ -484,18 +491,27 @@ case SERD_CURIE: switch (writer->syntax) { case SERD_NTRIPLES: - if (serd_env_expand(writer->env, node, &uri_prefix, &uri_suffix)) { + if (serd_env_expand(writer->env, node, &uri_prefix, &suffix)) { w_err(writer, SERD_ERR_BAD_CURIE, "undefined namespace prefix `%s'\n", node->buf); return false; } sink("<", 1, writer); write_uri(writer, uri_prefix.buf, uri_prefix.len); - write_uri(writer, uri_suffix.buf, uri_suffix.len); + write_uri(writer, suffix.buf, suffix.len); sink(">", 1, writer); break; case SERD_TURTLE: + if (is_inline_start(writer, field, flags)) { + ++writer->indent; + write_sep(writer, SEP_ANON_BEGIN); + sink("== ", 3, writer); + } write_lname(writer, node->buf, node->n_bytes); + if (is_inline_start(writer, field, flags)) { + sink(" ;", 2, writer); + write_newline(writer); + } } break; case SERD_LITERAL: @@ -536,6 +552,11 @@ } break; case SERD_URI: + if (is_inline_start(writer, field, flags)) { + ++writer->indent; + write_sep(writer, SEP_ANON_BEGIN); + sink("== ", 3, writer); + } has_scheme = serd_uri_string_has_scheme(node->buf); if (field == FIELD_PREDICATE && (writer->syntax == SERD_TURTLE) && !strcmp((const char*)node->buf, NS_RDF "type")) { @@ -545,15 +566,12 @@ && !strcmp((const char*)node->buf, NS_RDF "nil")) { sink("()", 2, writer); break; - } else if (has_scheme && (writer->style & SERD_STYLE_CURIED)) { - SerdNode prefix; - SerdChunk suffix; - if (serd_env_qualify(writer->env, node, &prefix, &suffix)) { - write_uri(writer, prefix.buf, prefix.n_bytes); - sink(":", 1, writer); - write_uri(writer, suffix.buf, suffix.len); - break; - } + } else if (has_scheme && (writer->style & SERD_STYLE_CURIED) && + serd_env_qualify(writer->env, node, &prefix, &suffix)) { + write_uri(writer, prefix.buf, prefix.n_bytes); + sink(":", 1, writer); + write_uri(writer, suffix.buf, suffix.len); + break; } sink("<", 1, writer); if (writer->style & SERD_STYLE_RESOLVED) { @@ -574,6 +592,10 @@ write_uri(writer, node->buf, node->n_bytes); } sink(">", 1, writer); + if (is_inline_start(writer, field, flags)) { + sink(" ;", 2, writer); + write_newline(writer); + } default: break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/bad/bad-ext-namedblank-op.ttl new/serd-0.22.0/tests/bad/bad-ext-namedblank-op.ttl --- old/serd-0.20.0/tests/bad/bad-ext-namedblank-op.ttl 1970-01-01 01:00:00.000000000 +0100 +++ new/serd-0.22.0/tests/bad/bad-ext-namedblank-op.ttl 2015-10-07 03:47:14.000000000 +0200 @@ -0,0 +1,3 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s eg:p [ =: _:o ; eg:name "o" ] . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/good/test-blankdot.nt new/serd-0.22.0/tests/good/test-blankdot.nt --- old/serd-0.20.0/tests/good/test-blankdot.nt 1970-01-01 01:00:00.000000000 +0100 +++ new/serd-0.22.0/tests/good/test-blankdot.nt 2015-10-07 03:47:14.000000000 +0200 @@ -0,0 +1 @@ +<http://example.org/subject> <http://example.org/predicate> _:c . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/good/test-blankdot.ttl new/serd-0.22.0/tests/good/test-blankdot.ttl --- old/serd-0.20.0/tests/good/test-blankdot.ttl 1970-01-01 01:00:00.000000000 +0100 +++ new/serd-0.22.0/tests/good/test-blankdot.ttl 2015-10-07 03:47:14.000000000 +0200 @@ -0,0 +1 @@ +<http://example.org/subject> <http://example.org/predicate> _:c. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/good/test-ext-namedblank-iri.nt new/serd-0.22.0/tests/good/test-ext-namedblank-iri.nt --- old/serd-0.20.0/tests/good/test-ext-namedblank-iri.nt 1970-01-01 01:00:00.000000000 +0100 +++ new/serd-0.22.0/tests/good/test-ext-namedblank-iri.nt 2015-10-07 03:47:14.000000000 +0200 @@ -0,0 +1,2 @@ +<http://example.org/eg#s> <http://example.org/eg#p> <http://example.org/object> . +<http://example.org/object> <http://example.org/eg#name> "o" . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/good/test-ext-namedblank-iri.ttl new/serd-0.22.0/tests/good/test-ext-namedblank-iri.ttl --- old/serd-0.20.0/tests/good/test-ext-namedblank-iri.ttl 1970-01-01 01:00:00.000000000 +0100 +++ new/serd-0.22.0/tests/good/test-ext-namedblank-iri.ttl 2015-10-07 03:47:14.000000000 +0200 @@ -0,0 +1,3 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s eg:p [ == <http://example.org/object> ; eg:name "o" ] . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/good/test-ext-namedblank-prefix.nt new/serd-0.22.0/tests/good/test-ext-namedblank-prefix.nt --- old/serd-0.20.0/tests/good/test-ext-namedblank-prefix.nt 1970-01-01 01:00:00.000000000 +0100 +++ new/serd-0.22.0/tests/good/test-ext-namedblank-prefix.nt 2015-10-07 03:47:14.000000000 +0200 @@ -0,0 +1,2 @@ +<http://example.org/eg#s> <http://example.org/eg#p> <http://example.org/eg#o> . +<http://example.org/eg#o> <http://example.org/eg#name> "o" . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/good/test-ext-namedblank-prefix.ttl new/serd-0.22.0/tests/good/test-ext-namedblank-prefix.ttl --- old/serd-0.20.0/tests/good/test-ext-namedblank-prefix.ttl 1970-01-01 01:00:00.000000000 +0100 +++ new/serd-0.22.0/tests/good/test-ext-namedblank-prefix.ttl 2015-10-07 03:47:14.000000000 +0200 @@ -0,0 +1,3 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s eg:p [ == eg:o ; eg:name "o" ] . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/tests/serd_test.c new/serd-0.22.0/tests/serd_test.c --- old/serd-0.20.0/tests/serd_test.c 2014-08-08 07:14:03.000000000 +0200 +++ new/serd-0.22.0/tests/serd_test.c 2015-10-07 03:47:14.000000000 +0200 @@ -25,9 +25,11 @@ #define USTR(s) ((const uint8_t*)(s)) -#ifdef _WIN32 +#ifndef INFINITY # define INFINITY (DBL_MAX + DBL_MAX) -# define NAN (INFINITY - INFINITY) +#endif +#ifndef NAN +# define NAN (INFINITY - INFINITY) #endif static int @@ -45,7 +47,7 @@ test_strtod(double dbl, double max_delta) { char buf[1024]; - snprintf(buf, sizeof(buf), "%lf", dbl); + snprintf(buf, sizeof(buf), "%f", dbl); char* endptr = NULL; const double out = serd_strtod(buf, &endptr); @@ -100,11 +102,11 @@ } const double expt_test_nums[] = { - 2.0E18, -5e19, +8e20, 2e+34, -5e-5, 8e0, 9e-0, 2e+0 + 2.0E18, -5e19, +8e20, 2e+24, -5e-5, 8e0, 9e-0, 2e+0 }; const char* expt_test_strs[] = { - "02e18", "-5e019", "+8e20", "2E+34", "-5E-5", "8E0", "9e-0", " 2e+0" + "02e18", "-5e019", "+8e20", "2E+24", "-5E-5", "8E0", "9e-0", " 2e+0" }; for (unsigned i = 0; i < sizeof(expt_test_nums) / sizeof(double); ++i) { @@ -399,6 +401,11 @@ // Test serd_node_new_uri_from_string + SerdNode nonsense = serd_node_new_uri_from_string(NULL, NULL, NULL); + if (nonsense.type != SERD_NOTHING) { + return failure("Successfully created NULL URI\n"); + } + SerdURI base_uri; SerdNode base = serd_node_new_uri_from_string(USTR("http://example.org/"), NULL, &base_uri); @@ -420,6 +427,10 @@ SerdEnv* env = serd_env_new(NULL); serd_env_set_prefix_from_strings(env, USTR("eg.2"), USTR("http://example.org/")); + if (!serd_env_set_base_uri(env, NULL)) { + return failure("Successfully set NULL base URI\n"); + } + if (!serd_env_set_base_uri(env, &node)) { return failure("Set base URI to %s\n", node.buf); } @@ -614,7 +625,10 @@ return failure("Apparently read an http URI\n"); } if (!serd_reader_read_file(reader, USTR("file:///better/not/exist"))) { - return failure("Apprently read a non-existent file\n"); + return failure("Apparently read a non-existent file\n"); + } + if (!serd_reader_read_file(reader, USTR("file://"))) { + return failure("Apparently read a file with no path\n"); } SerdStatus st = serd_reader_read_file(reader, USTR(path)); if (st) { Files old/serd-0.20.0/waf and new/serd-0.22.0/waf differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serd-0.20.0/wscript new/serd-0.22.0/wscript --- old/serd-0.20.0/wscript 2014-08-08 23:34:55.000000000 +0200 +++ new/serd-0.22.0/wscript 2015-10-08 21:34:01.000000000 +0200 @@ -11,7 +11,7 @@ # major increment <=> incompatible changes # minor increment <=> compatible changes (additions) # micro increment <=> no interface changes -SERD_VERSION = '0.20.0' +SERD_VERSION = '0.22.0' SERD_MAJOR_VERSION = '0' # Mandatory waf variables @@ -27,6 +27,8 @@ help='Do not build command line utilities') opt.add_option('--test', action='store_true', dest='build_tests', help='Build unit tests') + opt.add_option('--no-coverage', action='store_true', dest='no_coverage', + help='Do not use gcov for code coverage') opt.add_option('--stack-check', action='store_true', dest='stack_check', help='Include runtime stack sanity checks') opt.add_option('--static', action='store_true', dest='static', @@ -62,16 +64,8 @@ if Options.options.largefile: conf.env.append_unique('DEFINES', ['_FILE_OFFSET_BITS=64']) - if conf.env.BUILD_TESTS: - conf.check(lib = 'gcov', - define_name = 'HAVE_GCOV', - mandatory = False) - - conf.check(function_name = 'fmax', - header_name = 'math.h', - define_name = 'HAVE_FMAX', - lib = ['m'], - mandatory = False) + if conf.env.BUILD_TESTS and not Options.options.no_coverage: + conf.check_cc(lib='gcov', define_name='HAVE_GCOV', mandatory=False) if not Options.options.no_posix: conf.check(function_name = 'posix_memalign', @@ -96,8 +90,8 @@ autowaf.set_lib_env(conf, 'serd', SERD_VERSION) conf.write_config_header('serd_config.h', remove=False) - autowaf.display_msg(conf, 'Utilities', str(conf.env.BUILD_UTILS)) - autowaf.display_msg(conf, 'Unit tests', str(conf.env.BUILD_TESTS)) + autowaf.display_msg(conf, 'Utilities', bool(conf.env.BUILD_UTILS)) + autowaf.display_msg(conf, 'Unit tests', bool(conf.env.BUILD_TESTS)) print('') lib_source = [ @@ -431,7 +425,7 @@ autowaf.run_tests(ctx, APPNAME, ['serd_test'], dirs=['.']) autowaf.run_tests(ctx, APPNAME, [ - 'serdi_static -q -o turtle %s/tests/good/base.ttl "base.ttl" > tests/good/base.ttl.out' % srcdir], + 'serdi_static -q -o turtle "%s/tests/good/base.ttl" "base.ttl" > tests/good/base.ttl.out' % srcdir], 0, name='base') if not file_equals('%s/tests/good/base.ttl' % srcdir, 'tests/good/base.ttl.out'): @@ -439,7 +433,7 @@ nul = os.devnull autowaf.run_tests(ctx, APPNAME, [ - 'serdi_static file://%s/tests/good/manifest.ttl > %s' % (srcdir, nul), + 'serdi_static "file://%s/tests/good/manifest.ttl" > %s' % (srcdir, nul), # 'serdi_static %s/tests/good/UTF-8.ttl > %s' % (srcdir, nul), 'serdi_static -v > %s' % nul, 'serdi_static -h > %s' % nul, @@ -448,7 +442,7 @@ 0, name='serdi-cmd-good') autowaf.run_tests(ctx, APPNAME, [ - 'serdi_static -q file://%s/tests/bad-id-clash.ttl > %s' % (srcdir, nul), + 'serdi_static -q "file://%s/tests/bad-id-clash.ttl" > %s' % (srcdir, nul), 'serdi_static > %s' % nul, 'serdi_static ftp://example.org/unsupported.ttl > %s' % nul, 'serdi_static -i > %s' % nul, @@ -472,9 +466,10 @@ commands = [] for test in tests: - path = os.path.join('tests', tdir, test) - commands += [ 'serdi_static -f "%s" "%s" > %s.out' % ( - os.path.join(srcdir, path), test_base(test), path) ] + for lax in ['', '-l']: + path = os.path.join('tests', tdir, test) + commands += [ 'serdi_static %s -f "%s" "%s" > %s.out' % ( + lax, os.path.join(srcdir, path), test_base(test), path) ] autowaf.run_tests(ctx, APPNAME, commands, 0, name=tdir) @@ -493,8 +488,9 @@ # Bad tests commands = [] for test in bad_tests: - commands += [ 'serdi_static -q "%s" "%s" > %s.out' % ( - os.path.join(srcdir, test), test_base(test), test) ] + for lax in ['', '-l']: + commands += [ 'serdi_static %s -q "%s" "%s" > %s.out' % ( + lax, os.path.join(srcdir, test), test_base(test), test) ] autowaf.run_tests(ctx, APPNAME, commands, 1, name='bad')
