Browse Source

Adapt code to ISO C11. Buggy.

scossu 1 day ago
parent
commit
828c297075

+ 1 - 1
Makefile

@@ -36,7 +36,7 @@ MASSIF_DUMP := $(TMPDIR)/volksdata_massif.out
 
 
 INCLUDE_BASE := . -Iinclude -Iext/hashmap -Iext/log/src
 INCLUDE_BASE := . -Iinclude -Iext/hashmap -Iext/log/src
 INCLUDE := -I$(INCLUDE_BASE)
 INCLUDE := -I$(INCLUDE_BASE)
-_CFLAGS = -std=gnu11 -Wall -Wextra -fPIC $(INCLUDE)
+_CFLAGS = -std=c11 -Wall -Wextra -fPIC $(INCLUDE)
 CFLAGS = $(if $(DEBUG),\
 CFLAGS = $(if $(DEBUG),\
 		 $(_CFLAGS) -Itest -O0 -ggdb -DDEBUG,\
 		 $(_CFLAGS) -Itest -O0 -ggdb -DDEBUG,\
 		 $(_CFLAGS) -O3 -g0)
 		 $(_CFLAGS) -O3 -g0)

+ 17 - 20
README.md

@@ -37,10 +37,6 @@ Test coverage is not sufficient. Documentation is fairly extensive but needs
 reformatting. This code is being integrated in higher-level projects and is
 reformatting. This code is being integrated in higher-level projects and is
 being improved as issues arise.
 being improved as issues arise.
 
 
-Portability is still under assessment. The goal is to make this code POSIX
-compatible. ANSI C compatibility is out of reach because of the LMDB
-dependency.
-
 This is my first stab at writing a C library (coming from Python) and an
 This is my first stab at writing a C library (coming from Python) and an
 unpaid fun project, so don't be surprised if you find some gross stuff.
 unpaid fun project, so don't be surprised if you find some gross stuff.
 
 
@@ -88,51 +84,52 @@ workable set of features as a standalone library:
 
 
 ## Building
 ## Building
 
 
-### Requirements
+### Required dependencies
 
 
-- It is recommended to build and run Volksdata on a Linux system. No other
-  OS has been tested so far.
-- A C compiler. This has been only tested with `gcc` so far.
+- A C compiler and standard library. This has been only tested with GCC and
+  GNU libc so far. Testing with musl libc is planned.
 - [LMDB](https://symas.com/lmdb/) libraries and headers.
 - [LMDB](https://symas.com/lmdb/) libraries and headers.
 - [XXHash](https://github.com/Cyan4973/xxHash) >=0.8 libraries and headers.
 - [XXHash](https://github.com/Cyan4973/xxHash) >=0.8 libraries and headers.
 
 
 ### Optional dependencies
 ### Optional dependencies
 - [re2c](https://re2c.org/) to build the RDF language lexers. Only required if
 - [re2c](https://re2c.org/) to build the RDF language lexers. Only required if
-  the codecs are changed. Otherwise, compiled lexers are included in this git
+  the lexers are changed. Otherwise, compiled lexers are included in this git
   repo.
   repo.
 - [cinclude2dot](https://www.flourish.org/cinclude2dot) and
 - [cinclude2dot](https://www.flourish.org/cinclude2dot) and
   [Graphviz](https://graphviz.org/) for generating visual dependency graph.
   [Graphviz](https://graphviz.org/) for generating visual dependency graph.
 
 
+### Conformance
+
+Volksdata is written in ISO C11. Note that LMDB uses by default POSIX-1.2011
+extensions, and may have to be compiled separately in non-POSIX systems.
 
 
 ### `make` commands
 ### `make` commands
 
 
 The default `make` command (`make lib`) compiles the library. Enter `make help`
 The default `make` command (`make lib`) compiles the library. Enter `make help`
 to get an overview of the other available commands.
 to get an overview of the other available commands.
 
 
-`make install` and installs libraries and headers in the
-directories set by the environment variable `$PREFIX`. If this is unset, the
-default `/usr/local` prefix is used.
+`make install` installs libraries and headers in the directories set by the
+environment variable `$PREFIX`. If this is unset, the default `/usr/local`
+prefix is used.
 
 
-If `LOCAL` is set to anything else than `0`, the library will be installed in
-`$LOCAL_PREFIX` instead (by default,`$HOME/.local`.
+If `LOCAL` is set to `1`, the library will be installed in `$LOCAL_PREFIX`
+instead (by default,`$HOME/.local`).
 
 
-If `DEBUG` is set to anything else than `0`, the library will be compiled with
-debug symbols.
+If `DEBUG` is set to `1`, the library will be compiled with debug symbols.
 
 
 E.g.
 E.g.
 
 
 ```
 ```
+make DEBUG=1
 make install DEBUG=1 LOCAL=1
 make install DEBUG=1 LOCAL=1
 ```
 ```
 
 
-Installs the library with debug symbols in `~/.local`.
+Builds and installs the library with debug symbols in `~/.local`.
 
 
+`make test` and similar always force `DEBUG=1`.
 
 
 ### Compile-Time defines (`-D[...]`)
 ### Compile-Time defines (`-D[...]`)
 
 
-`DEBUG`: Set debug mode: memory map is at reduced size, logging is forced to
-TRACE level, etc.
-
 `VOLK_RDF_STREAM_CHUNK_SIZE`: Size of RDF decoding buffer, i.e., maximum size
 `VOLK_RDF_STREAM_CHUNK_SIZE`: Size of RDF decoding buffer, i.e., maximum size
 of a chunk of RDF data fed to the parser when decoding a RDF file into a graph.
 of a chunk of RDF data fed to the parser when decoding a RDF file into a graph.
 This should be larger than the maximum expected size of a single term in your
 This should be larger than the maximum expected size of a single term in your

+ 1 - 1
include/volksdata/codec.h

@@ -257,7 +257,7 @@ typedef VOLK_rc (*term_decode_fn_t)(const char *rep, VOLK_Term **term);
  *  on parsing error.
  *  on parsing error.
  */
  */
 typedef VOLK_rc (*gr_decode_fn_t)(
 typedef VOLK_rc (*gr_decode_fn_t)(
-        FILE *rep, VOLK_Graph **gr, size_t *ct, char **err);
+        FILE *fh, const char *sh, VOLK_Graph **gr, size_t *ct, char **err);
 
 
 
 
 /** @brief Codec structure.
 /** @brief Codec structure.

+ 2 - 1
include/volksdata/codec/parser_nt.h

@@ -33,6 +33,7 @@ VOLK_nt_parse_term (const char *rep, VOLK_Term **term);
  *  encountered. On error, `err` will contain the error message.
  *  encountered. On error, `err` will contain the error message.
  */
  */
 VOLK_rc
 VOLK_rc
-VOLK_nt_parse_doc (FILE *stream, VOLK_Graph **gr, size_t *ct, char **err);
+VOLK_nt_parse_doc (
+        FILE *fh, const char *sh, VOLK_Graph **gr, size_t *ct, char **err);
 
 
 #endif
 #endif

+ 2 - 1
include/volksdata/codec/parser_ttl.h

@@ -20,6 +20,7 @@
  *  encountered. On error, `err` will contain the error message.
  *  encountered. On error, `err` will contain the error message.
  */
  */
 VOLK_rc
 VOLK_rc
-VOLK_ttl_parse_doc (FILE *stream, VOLK_Graph **gr, size_t *ct, char **err);
+VOLK_ttl_parse_doc (
+        FILE *fh, const char *sh, VOLK_Graph **gr, size_t *ct, char **err);
 
 
 #endif
 #endif

+ 21 - 0
include/volksdata/core.h

@@ -382,6 +382,27 @@ VOLK_strerror (VOLK_rc rc);
 */
 */
 
 
 
 
+/** @brief Replacement for GNU strndup.
+ *
+ * param[in] src String to duplicate.
+ * param[in] max Max number of characters to duplicate. The length is capped
+ *  to the smaller value between this and the source string length (characters
+ *  up to the trailing `\0`).
+ *
+ * return Duplicated string. The caller is in charge of freeing it after use.
+ */
+char *strndup (const char *src, size_t max);
+
+
+/** @brief Replacement for GNU strdup.
+ *
+ * param[in] str String to duplicate.
+ *
+ * return Duplicated string. The caller is in charge of freeing it after use.
+ */
+char *strdup (const char *src);
+
+
 /** @brief Make recursive directories.
 /** @brief Make recursive directories.
  *
  *
  * Modified from
  * Modified from

+ 17 - 20
src/codec/Makefile

@@ -10,30 +10,27 @@ BUILDDIR = $(BASEDIR)/build
 
 
 CODEC_SRC = $(wildcard codec_*.c)
 CODEC_SRC = $(wildcard codec_*.c)
 PARSER_SRC = $(CODEC_SRC:codec_%=parser_%)
 PARSER_SRC = $(CODEC_SRC:codec_%=parser_%)
-ifneq ($(DEBUG),)
-CODEC_OBJ := $(CODEC_SRC:%.c=$(BUILDDIR)/%_dbg.o)
-else
-CODEC_OBJ := $(CODEC_SRC:%.c=$(BUILDDIR)/%.o)
-endif
-PARSER_OBJ := $(subst codec,parser,$(CODEC_OBJ))
-GRAMMAR_OBJ := $(subst codec,grammar,$(CODEC_OBJ))
+CODEC_OBJ = $(if $(DEBUG),\
+		$(CODEC_SRC:%.c=$(BUILDDIR)/%_dbg.o),\
+		$(CODEC_SRC:%.c=$(BUILDDIR)/%.o))
+
+PARSER_OBJ = $(subst codec,parser,$(CODEC_OBJ))
+GRAMMAR_OBJ = $(subst codec,grammar,$(CODEC_OBJ))
 OBJ = $(GRAMMAR_OBJ) $(PARSER_OBJ) $(CODEC_OBJ)
 OBJ = $(GRAMMAR_OBJ) $(PARSER_OBJ) $(CODEC_OBJ)
 
 
 INCLUDE := -I$(INCLUDE_DIR) -I$(BASEDIR)/ext/tpl/src -I$(BASEDIR)/ext/hashmap \
 INCLUDE := -I$(INCLUDE_DIR) -I$(BASEDIR)/ext/tpl/src -I$(BASEDIR)/ext/hashmap \
 	-I$(BASEDIR)/ext/log/src
 	-I$(BASEDIR)/ext/log/src
-_CFLAGS := -std=gnu11 -Wall -fPIC $(INCLUDE)
-
-ifneq ($(DEBUG),)
-CFLAGS = $(_CFLAGS) -I$(BASEDIR)/test -O0 -g3 -DDEBUG
-else
-CFLAGS = $(_CFLAGS) -O3 -g0
-endif
-
-$(info CODEC_OBJ: $(CODEC_OBJ))
-$(info GRAMMAR_OBJ: $(GRAMMAR_OBJ))
-$(info PARSER_OBJ: $(PARSER_OBJ))
-$(info OBJ: $(OBJ))
-$(info CFLAGS: $(CFLAGS))
+_CFLAGS := -std=c11 -Wall -fPIC $(INCLUDE)
+
+CFLAGS = $(if $(DEBUG),\
+		$(_CFLAGS) -I$(BASEDIR)/test -O0 -g3 -DDEBUG,\
+		$(_CFLAGS) -O3 -g0 -DNDEBUG)
+
+#$(info CODEC_OBJ: $(CODEC_OBJ))
+#$(info GRAMMAR_OBJ: $(GRAMMAR_OBJ))
+#$(info PARSER_OBJ: $(PARSER_OBJ))
+#$(info OBJ: $(OBJ))
+#$(info CFLAGS: $(CFLAGS))
 
 
 .DEFAULT_GOAL := codec
 .DEFAULT_GOAL := codec
 
 

+ 36 - 23
src/codec/lexer_nt.re

@@ -10,19 +10,20 @@
 
 
 
 
 typedef struct {
 typedef struct {
-    FILE *          fh;                 // Input file handle.
-    YYCTYPE         buf[CHUNK_SIZE],    // Start of buffer.
-            *       lim,                // Position after the last available
-                                        //   input character (YYLIMIT).
-            *       cur,                // Next input character to be read
-                                        //   (YYCURSOR)
-            *       mar,                // Most recent match (YYMARKER)
-            *       tok,                // Start of current token.
-            *       bol;                // Address of the beginning of the
-                                        //   current line (for debugging).
-    unsigned        line;               // Current line no. (for debugging).
-    unsigned        ct;                 // Number of parsed triples.
-    bool            eof;                // if we have reached EOF.
+    FILE           *fh;                 ///< Input file handle.
+    const char     *sh;                 ///< Input string. Exclusive with fh.
+    YYCTYPE         buf[CHUNK_SIZE],    ///< Start of buffer.
+                   *lim,                ///< Position after the last available
+                                        ///<   input character (YYLIMIT).
+                   *cur,                ///< Next input character to be read
+                                        ///<   (YYCURSOR)
+                   *mar,                ///< Most recent match (YYMARKER)
+                   *tok,                ///< Start of current token.
+                   *bol;                ///< Address of the beginning of the
+                                        ///<   current line (for debugging).
+    unsigned        line;               ///< Current line no. (for debugging).
+    unsigned        ct;                 ///< Number of parsed triples.
+    bool            eof;                ///< if we have reached EOF.
     /*!stags:re2c format = "YYCTYPE *@@;"; */
     /*!stags:re2c format = "YYCTYPE *@@;"; */
 } ParseIterator;
 } ParseIterator;
 
 
@@ -37,12 +38,14 @@ static int fill(ParseIterator *it)
         return 2;
         return 2;
     }
     }
     LOG_DEBUG("Shifting bytes: %lu", shift);
     LOG_DEBUG("Shifting bytes: %lu", shift);
-    memmove(it->buf, it->tok, it->lim - it->tok);
+    memmove (it->buf, it->tok, it->lim - it->tok);
     it->lim -= shift;
     it->lim -= shift;
     it->cur -= shift;
     it->cur -= shift;
     it->mar -= shift;
     it->mar -= shift;
     it->tok -= shift;
     it->tok -= shift;
-    it->lim += fread(it->lim, 1, shift, it->fh);
+    if (it->fh) it->lim += fread (it->lim, 1, shift, it->fh);
+    // With a string handle, assume the whole input fits in CHUNK_SIZE.
+    else it->lim = memcpy (it->lim, it->sh, sizeof(it->buf));
     /*!stags:re2c format = "if (it->@@) it->@@ -= shift; "; */
     /*!stags:re2c format = "if (it->@@) it->@@ -= shift; "; */
     it->lim[0] = 0;
     it->lim[0] = 0;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
@@ -50,9 +53,19 @@ static int fill(ParseIterator *it)
 }
 }
 
 
 
 
-static void parse_init(ParseIterator *it, FILE *fh)
+/** @brief Initialize parser.
+ *
+ * @param[in] it iterator handle to be initialized.
+ *
+ * @param[in] fh Open file handle to read from. This is exclusive with sh. If
+ *  both fh and sh are provided, fh has precedence.
+ *
+ * @param[in] sh String to read from. This is exclusive with fh.
+ */
+static void parse_init(ParseIterator *it, FILE *fh, const char *sh)
 {
 {
     it->fh = fh;
     it->fh = fh;
+    it->sh = sh;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->line = 1;
     it->line = 1;
     it->bol = it->buf;
     it->bol = it->buf;
@@ -76,6 +89,9 @@ void NTParseTrace();
 static int lex (ParseIterator *it, VOLK_Term **term)
 static int lex (ParseIterator *it, VOLK_Term **term)
 {
 {
     const YYCTYPE *lit_data_e, *dtype_s, *lang_s;
     const YYCTYPE *lit_data_e, *dtype_s, *lang_s;
+    //(void) lit_data_e;
+    //(void) dtype_s;
+    //(void) lang_s;
 
 
 loop:
 loop:
 
 
@@ -230,15 +246,11 @@ loop:
 VOLK_rc
 VOLK_rc
 VOLK_nt_parse_term (const char *rep, VOLK_Term **term)
 VOLK_nt_parse_term (const char *rep, VOLK_Term **term)
 {
 {
-    FILE *fh = fmemopen ((void *)rep, strlen (rep), "r");
-
     ParseIterator it;
     ParseIterator it;
-    parse_init (&it, fh);
+    parse_init (&it, NULL, rep);
 
 
     int ttype = lex (&it, term);
     int ttype = lex (&it, term);
 
 
-    fclose (fh);
-
     switch (ttype) {
     switch (ttype) {
         case T_IRIREF:
         case T_IRIREF:
         case T_LITERAL:
         case T_LITERAL:
@@ -250,13 +262,14 @@ VOLK_nt_parse_term (const char *rep, VOLK_Term **term)
 }
 }
 
 
 VOLK_rc
 VOLK_rc
-VOLK_nt_parse_doc (FILE *fh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
+VOLK_nt_parse_doc (
+        FILE *fh, const char *sh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
 {
 {
     *err_p = NULL;
     *err_p = NULL;
     *gr_p = NULL;
     *gr_p = NULL;
 
 
     ParseIterator parse_it;
     ParseIterator parse_it;
-    parse_init (&parse_it, fh);
+    parse_init (&parse_it, fh, sh);
 
 
 #ifdef DEBUG
 #ifdef DEBUG
     NTParseTrace (stdout, "NT Parser > ");
     NTParseTrace (stdout, "NT Parser > ");

+ 22 - 17
src/codec/lexer_ttl.re

@@ -17,19 +17,20 @@
 
 
 
 
 typedef struct {
 typedef struct {
-    FILE *          fh;                 // Input file handle.
-    YYCTYPE         buf[CHUNK_SIZE],    // Start of buffer.
-            *       lim,                // Position after the last available
-                                        //   input character (YYLIMIT).
-            *       cur,                // Next input character to be read
-                                        //   (YYCURSOR)
-            *       mar,                // Most recent match (YYMARKER)
-            *       tok,                // Start of current token.
-            *       bol;                // Address of the beginning of the
-                                        //   current line (for debugging).
-    unsigned        line;               // Current line no. (for debugging).
-    unsigned        stmt;               // Current statement.
-    bool            eof;                // if we have reached EOF.
+    FILE          * fh;                 ///< Input file handle.
+    const char    * sh;                 ///< Input string. Exclusive with fh.
+    YYCTYPE         buf[CHUNK_SIZE],    ///< Start of buffer.
+                  * lim,                ///< Position after the last available
+                                        ///<   input character (YYLIMIT).
+                  * cur,                ///< Next input character to be read
+                                        ///<   (YYCURSOR)
+                  * mar,                ///< Most recent match (YYMARKER)
+                  * tok,                ///< Start of current token.
+                  * bol;                ///< Address of the beginning of the
+                                        ///<   current line (for debugging).
+    unsigned        line;               ///< Current line no. (for debugging).
+    unsigned        stmt;               ///< Current statement.
+    bool            eof;                ///< if we have reached EOF.
     /*!stags:re2c format = "YYCTYPE *@@;"; */
     /*!stags:re2c format = "YYCTYPE *@@;"; */
 } ParseIterator;
 } ParseIterator;
 
 
@@ -54,7 +55,9 @@ static int fill (ParseIterator *it)
     it->cur -= shift;
     it->cur -= shift;
     it->mar -= shift;
     it->mar -= shift;
     it->tok -= shift;
     it->tok -= shift;
-    it->lim += fread(it->lim, 1, shift, it->fh);
+    if (it->fh) it->lim += fread (it->lim, 1, shift, it->fh);
+    // With a string handle, assume the whole input fits in CHUNK_SIZE.
+    else it->lim = memcpy (it->lim, it->sh, sizeof(it->buf));
     /*!stags:re2c format = "if (it->@@) it->@@ -= shift; "; */
     /*!stags:re2c format = "if (it->@@) it->@@ -= shift; "; */
     it->lim[0] = 0;
     it->lim[0] = 0;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
@@ -62,9 +65,10 @@ static int fill (ParseIterator *it)
 }
 }
 
 
 
 
-static void parse_init (ParseIterator *it, FILE *fh)
+static void parse_init (ParseIterator *it, FILE *fh, const char *sh)
 {
 {
     it->fh = fh;
     it->fh = fh;
+    it->sh = sh;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->line = 1;
     it->line = 1;
     it->stmt = 1;
     it->stmt = 1;
@@ -359,7 +363,8 @@ lchar:
 
 
 
 
 VOLK_rc
 VOLK_rc
-VOLK_ttl_parse_doc (FILE *fh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
+VOLK_ttl_parse_doc (
+        FILE *fh, const char *sh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
 {
 {
     *err_p = NULL;
     *err_p = NULL;
     *gr_p = NULL;
     *gr_p = NULL;
@@ -373,7 +378,7 @@ VOLK_ttl_parse_doc (FILE *fh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
     state->rc = VOLK_NORESULT;
     state->rc = VOLK_NORESULT;
 
 
     ParseIterator parse_it;
     ParseIterator parse_it;
-    parse_init (&parse_it, fh);
+    parse_init (&parse_it, fh, sh);
 
 
     void *parser = TTLParseAlloc (malloc);
     void *parser = TTLParseAlloc (malloc);
 
 

+ 63 - 50
src/codec/parser_nt.c

@@ -1,4 +1,4 @@
-/* Generated by re2c 4.1 on Sun Aug 17 18:56:10 2025 */
+/* Generated by re2c 4.1 on Wed Aug 20 17:28:48 2025 */
 #line 1 "lexer_nt.re"
 #line 1 "lexer_nt.re"
 #include "volksdata/codec/parser_nt.h"
 #include "volksdata/codec/parser_nt.h"
 #include "volksdata/codec/tokens_nt.h"
 #include "volksdata/codec/tokens_nt.h"
@@ -12,23 +12,24 @@
 
 
 
 
 typedef struct {
 typedef struct {
-    FILE *          fh;                 // Input file handle.
-    YYCTYPE         buf[CHUNK_SIZE],    // Start of buffer.
-            *       lim,                // Position after the last available
-                                        //   input character (YYLIMIT).
-            *       cur,                // Next input character to be read
-                                        //   (YYCURSOR)
-            *       mar,                // Most recent match (YYMARKER)
-            *       tok,                // Start of current token.
-            *       bol;                // Address of the beginning of the
-                                        //   current line (for debugging).
-    unsigned        line;               // Current line no. (for debugging).
-    unsigned        ct;                 // Number of parsed triples.
-    bool            eof;                // if we have reached EOF.
+    FILE           *fh;                 ///< Input file handle.
+    const char     *sh;                 ///< Input string. Exclusive with fh.
+    YYCTYPE         buf[CHUNK_SIZE],    ///< Start of buffer.
+                   *lim,                ///< Position after the last available
+                                        ///<   input character (YYLIMIT).
+                   *cur,                ///< Next input character to be read
+                                        ///<   (YYCURSOR)
+                   *mar,                ///< Most recent match (YYMARKER)
+                   *tok,                ///< Start of current token.
+                   *bol;                ///< Address of the beginning of the
+                                        ///<   current line (for debugging).
+    unsigned        line;               ///< Current line no. (for debugging).
+    unsigned        ct;                 ///< Number of parsed triples.
+    bool            eof;                ///< if we have reached EOF.
     
     
-#line 30 "parser_nt.c"
+#line 31 "parser_nt.c"
 YYCTYPE *yyt1;YYCTYPE *yyt2;YYCTYPE *yyt3;
 YYCTYPE *yyt1;YYCTYPE *yyt2;YYCTYPE *yyt3;
-#line 26 "lexer_nt.re"
+#line 27 "lexer_nt.re"
 
 
 } ParseIterator;
 } ParseIterator;
 
 
@@ -43,16 +44,18 @@ static int fill(ParseIterator *it)
         return 2;
         return 2;
     }
     }
     LOG_DEBUG("Shifting bytes: %lu", shift);
     LOG_DEBUG("Shifting bytes: %lu", shift);
-    memmove(it->buf, it->tok, it->lim - it->tok);
+    memmove (it->buf, it->tok, it->lim - it->tok);
     it->lim -= shift;
     it->lim -= shift;
     it->cur -= shift;
     it->cur -= shift;
     it->mar -= shift;
     it->mar -= shift;
     it->tok -= shift;
     it->tok -= shift;
-    it->lim += fread(it->lim, 1, shift, it->fh);
+    if (it->fh) it->lim += fread (it->lim, 1, shift, it->fh);
+    // With a string handle, assume the whole input fits in CHUNK_SIZE.
+    else it->lim = memcpy (it->lim, it->sh, sizeof(it->buf));
     
     
-#line 54 "parser_nt.c"
+#line 57 "parser_nt.c"
 if (it->yyt1) it->yyt1 -= shift; if (it->yyt2) it->yyt2 -= shift; if (it->yyt3) it->yyt3 -= shift; 
 if (it->yyt1) it->yyt1 -= shift; if (it->yyt2) it->yyt2 -= shift; if (it->yyt3) it->yyt3 -= shift; 
-#line 46 "lexer_nt.re"
+#line 49 "lexer_nt.re"
 
 
     it->lim[0] = 0;
     it->lim[0] = 0;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
@@ -60,18 +63,28 @@ if (it->yyt1) it->yyt1 -= shift; if (it->yyt2) it->yyt2 -= shift; if (it->yyt3)
 }
 }
 
 
 
 
-static void parse_init(ParseIterator *it, FILE *fh)
+/** @brief Initialize parser.
+ *
+ * @param[in] it iterator handle to be initialized.
+ *
+ * @param[in] fh Open file handle to read from. This is exclusive with sh. If
+ *  both fh and sh are provided, fh has precedence.
+ *
+ * @param[in] sh String to read from. This is exclusive with fh.
+ */
+static void parse_init(ParseIterator *it, FILE *fh, const char *sh)
 {
 {
     it->fh = fh;
     it->fh = fh;
+    it->sh = sh;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->line = 1;
     it->line = 1;
     it->bol = it->buf;
     it->bol = it->buf;
     it->ct = 0;
     it->ct = 0;
     it->eof = 0;
     it->eof = 0;
     
     
-#line 73 "parser_nt.c"
+#line 86 "parser_nt.c"
 it->yyt1 = NULL; it->yyt2 = NULL; it->yyt3 = NULL; 
 it->yyt1 = NULL; it->yyt2 = NULL; it->yyt3 = NULL; 
-#line 61 "lexer_nt.re"
+#line 74 "lexer_nt.re"
 
 
     fill (it);
     fill (it);
 }
 }
@@ -90,6 +103,9 @@ void NTParseTrace();
 static int lex (ParseIterator *it, VOLK_Term **term)
 static int lex (ParseIterator *it, VOLK_Term **term)
 {
 {
     const YYCTYPE *lit_data_e, *dtype_s, *lang_s;
     const YYCTYPE *lit_data_e, *dtype_s, *lang_s;
+    //(void) lit_data_e;
+    //(void) dtype_s;
+    //(void) lang_s;
 
 
 loop:
 loop:
 
 
@@ -98,7 +114,7 @@ loop:
     *term = NULL;
     *term = NULL;
 
 
     
     
-#line 102 "parser_nt.c"
+#line 118 "parser_nt.c"
 {
 {
 	YYCTYPE yych;
 	YYCTYPE yych;
 	unsigned int yyaccept = 0;
 	unsigned int yyaccept = 0;
@@ -124,7 +140,7 @@ yyFillLabel0:
 yy1:
 yy1:
 	++YYCURSOR;
 	++YYCURSOR;
 yy2:
 yy2:
-#line 218 "lexer_nt.re"
+#line 234 "lexer_nt.re"
 	{
 	{
         LOG_DEBUG(
         LOG_DEBUG(
             "Invalid token @ %lu: %s (\\x%x)",
             "Invalid token @ %lu: %s (\\x%x)",
@@ -132,7 +148,7 @@ yy2:
 
 
         return -1;
         return -1;
     }
     }
-#line 136 "parser_nt.c"
+#line 152 "parser_nt.c"
 yy3:
 yy3:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel1:
 yyFillLabel1:
@@ -147,13 +163,13 @@ yyFillLabel1:
 			goto yy4;
 			goto yy4;
 	}
 	}
 yy4:
 yy4:
-#line 201 "lexer_nt.re"
+#line 217 "lexer_nt.re"
 	{
 	{
         LOG_DEBUG("Separator.");
         LOG_DEBUG("Separator.");
 
 
         return T_WS;
         return T_WS;
     }
     }
-#line 157 "parser_nt.c"
+#line 173 "parser_nt.c"
 yy5:
 yy5:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel2:
 yyFillLabel2:
@@ -169,14 +185,14 @@ yyFillLabel2:
 			goto yy6;
 			goto yy6;
 	}
 	}
 yy6:
 yy6:
-#line 117 "lexer_nt.re"
+#line 133 "lexer_nt.re"
 	{
 	{
         it->line ++;
         it->line ++;
         it->bol = YYCURSOR;
         it->bol = YYCURSOR;
         LOG_DEBUG("New line: #%u.", it->line);
         LOG_DEBUG("New line: #%u.", it->line);
         return T_EOL;
         return T_EOL;
     }
     }
-#line 180 "parser_nt.c"
+#line 196 "parser_nt.c"
 yy7:
 yy7:
 	yyaccept = 0;
 	yyaccept = 0;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -218,7 +234,7 @@ yyFillLabel4:
 		default: goto yy9;
 		default: goto yy9;
 	}
 	}
 yy9:
 yy9:
-#line 207 "lexer_nt.re"
+#line 223 "lexer_nt.re"
 	{
 	{
         size_t size = YYCURSOR - it->tok + 1;
         size_t size = YYCURSOR - it->tok + 1;
         YYCTYPE *data = malloc (size);
         YYCTYPE *data = malloc (size);
@@ -229,17 +245,17 @@ yy9:
 
 
         goto loop;
         goto loop;
     }
     }
-#line 233 "parser_nt.c"
+#line 249 "parser_nt.c"
 yy10:
 yy10:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 194 "lexer_nt.re"
+#line 210 "lexer_nt.re"
 	{
 	{
         LOG_DEBUG("End of triple.");
         LOG_DEBUG("End of triple.");
         it->ct ++;
         it->ct ++;
 
 
         return T_DOT;
         return T_DOT;
     }
     }
-#line 243 "parser_nt.c"
+#line 259 "parser_nt.c"
 yy11:
 yy11:
 	yyaccept = 0;
 	yyaccept = 0;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -348,7 +364,7 @@ yy17:
 	lit_data_e = it->yyt1;
 	lit_data_e = it->yyt1;
 	dtype_s = it->yyt2;
 	dtype_s = it->yyt2;
 	lang_s = it->yyt3;
 	lang_s = it->yyt3;
-#line 141 "lexer_nt.re"
+#line 157 "lexer_nt.re"
 	{
 	{
         // Only unescape Unicode from data.
         // Only unescape Unicode from data.
         size_t size = lit_data_e - it->tok - 2;
         size_t size = lit_data_e - it->tok - 2;
@@ -389,7 +405,7 @@ yy17:
         if (!UNLIKELY (term)) return -1;
         if (!UNLIKELY (term)) return -1;
         return T_LITERAL;
         return T_LITERAL;
     }
     }
-#line 393 "parser_nt.c"
+#line 409 "parser_nt.c"
 yy18:
 yy18:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel9:
 yyFillLabel9:
@@ -585,7 +601,7 @@ yy32:
 	}
 	}
 yy33:
 yy33:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 129 "lexer_nt.re"
+#line 145 "lexer_nt.re"
 	{
 	{
         YYCTYPE *data = unescape_unicode (it->tok + 1, YYCURSOR - it->tok - 2);
         YYCTYPE *data = unescape_unicode (it->tok + 1, YYCURSOR - it->tok - 2);
 
 
@@ -597,7 +613,7 @@ yy33:
         if (!UNLIKELY (term)) return -1;
         if (!UNLIKELY (term)) return -1;
         return T_IRIREF;
         return T_IRIREF;
     }
     }
-#line 601 "parser_nt.c"
+#line 617 "parser_nt.c"
 yy34:
 yy34:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel23:
 yyFillLabel23:
@@ -840,7 +856,7 @@ yy50:
 			goto yy51;
 			goto yy51;
 	}
 	}
 yy51:
 yy51:
-#line 182 "lexer_nt.re"
+#line 198 "lexer_nt.re"
 	{
 	{
         YYCTYPE *data = unescape_unicode (it->tok + 2, YYCURSOR - it->tok - 2);
         YYCTYPE *data = unescape_unicode (it->tok + 2, YYCURSOR - it->tok - 2);
 
 
@@ -852,7 +868,7 @@ yy51:
         if (!UNLIKELY (term)) return -1;
         if (!UNLIKELY (term)) return -1;
         return T_BNODE;
         return T_BNODE;
     }
     }
-#line 856 "parser_nt.c"
+#line 872 "parser_nt.c"
 yy52:
 yy52:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel39:
 yyFillLabel39:
@@ -1654,14 +1670,14 @@ yyFillLabel95:
 			goto yy15;
 			goto yy15;
 	}
 	}
 yy110:
 yy110:
-#line 124 "lexer_nt.re"
+#line 140 "lexer_nt.re"
 	{
 	{
         LOG_DEBUG("End of buffer.");
         LOG_DEBUG("End of buffer.");
         return T_EOF;
         return T_EOF;
     }
     }
-#line 1663 "parser_nt.c"
+#line 1679 "parser_nt.c"
 }
 }
-#line 226 "lexer_nt.re"
+#line 242 "lexer_nt.re"
 
 
 }
 }
 
 
@@ -1669,15 +1685,11 @@ yy110:
 VOLK_rc
 VOLK_rc
 VOLK_nt_parse_term (const char *rep, VOLK_Term **term)
 VOLK_nt_parse_term (const char *rep, VOLK_Term **term)
 {
 {
-    FILE *fh = fmemopen ((void *)rep, strlen (rep), "r");
-
     ParseIterator it;
     ParseIterator it;
-    parse_init (&it, fh);
+    parse_init (&it, NULL, rep);
 
 
     int ttype = lex (&it, term);
     int ttype = lex (&it, term);
 
 
-    fclose (fh);
-
     switch (ttype) {
     switch (ttype) {
         case T_IRIREF:
         case T_IRIREF:
         case T_LITERAL:
         case T_LITERAL:
@@ -1689,13 +1701,14 @@ VOLK_nt_parse_term (const char *rep, VOLK_Term **term)
 }
 }
 
 
 VOLK_rc
 VOLK_rc
-VOLK_nt_parse_doc (FILE *fh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
+VOLK_nt_parse_doc (
+        FILE *fh, const char *sh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
 {
 {
     *err_p = NULL;
     *err_p = NULL;
     *gr_p = NULL;
     *gr_p = NULL;
 
 
     ParseIterator parse_it;
     ParseIterator parse_it;
-    parse_init (&parse_it, fh);
+    parse_init (&parse_it, fh, sh);
 
 
 #ifdef DEBUG
 #ifdef DEBUG
     NTParseTrace (stdout, "NT Parser > ");
     NTParseTrace (stdout, "NT Parser > ");

+ 104 - 99
src/codec/parser_ttl.c

@@ -1,4 +1,4 @@
-/* Generated by re2c 4.1 on Sun Aug 17 18:56:10 2025 */
+/* Generated by re2c 4.1 on Wed Aug 20 17:28:48 2025 */
 #line 1 "lexer_ttl.re"
 #line 1 "lexer_ttl.re"
 #include "volksdata/codec/parser_ttl.h"
 #include "volksdata/codec/parser_ttl.h"
 #include "volksdata/codec/tokens_ttl.h"
 #include "volksdata/codec/tokens_ttl.h"
@@ -19,23 +19,24 @@
 
 
 
 
 typedef struct {
 typedef struct {
-    FILE *          fh;                 // Input file handle.
-    YYCTYPE         buf[CHUNK_SIZE],    // Start of buffer.
-            *       lim,                // Position after the last available
-                                        //   input character (YYLIMIT).
-            *       cur,                // Next input character to be read
-                                        //   (YYCURSOR)
-            *       mar,                // Most recent match (YYMARKER)
-            *       tok,                // Start of current token.
-            *       bol;                // Address of the beginning of the
-                                        //   current line (for debugging).
-    unsigned        line;               // Current line no. (for debugging).
-    unsigned        stmt;               // Current statement.
-    bool            eof;                // if we have reached EOF.
+    FILE          * fh;                 ///< Input file handle.
+    const char    * sh;                 ///< Input string. Exclusive with fh.
+    YYCTYPE         buf[CHUNK_SIZE],    ///< Start of buffer.
+                  * lim,                ///< Position after the last available
+                                        ///<   input character (YYLIMIT).
+                  * cur,                ///< Next input character to be read
+                                        ///<   (YYCURSOR)
+                  * mar,                ///< Most recent match (YYMARKER)
+                  * tok,                ///< Start of current token.
+                  * bol;                ///< Address of the beginning of the
+                                        ///<   current line (for debugging).
+    unsigned        line;               ///< Current line no. (for debugging).
+    unsigned        stmt;               ///< Current statement.
+    bool            eof;                ///< if we have reached EOF.
     
     
-#line 37 "parser_ttl.c"
+#line 38 "parser_ttl.c"
 YYCTYPE *yyt1;
 YYCTYPE *yyt1;
-#line 33 "lexer_ttl.re"
+#line 34 "lexer_ttl.re"
 
 
 } ParseIterator;
 } ParseIterator;
 
 
@@ -60,11 +61,13 @@ static int fill (ParseIterator *it)
     it->cur -= shift;
     it->cur -= shift;
     it->mar -= shift;
     it->mar -= shift;
     it->tok -= shift;
     it->tok -= shift;
-    it->lim += fread(it->lim, 1, shift, it->fh);
+    if (it->fh) it->lim += fread (it->lim, 1, shift, it->fh);
+    // With a string handle, assume the whole input fits in CHUNK_SIZE.
+    else it->lim = memcpy (it->lim, it->sh, sizeof(it->buf));
     
     
-#line 66 "parser_ttl.c"
+#line 69 "parser_ttl.c"
 if (it->yyt1) it->yyt1 -= shift; 
 if (it->yyt1) it->yyt1 -= shift; 
-#line 58 "lexer_ttl.re"
+#line 61 "lexer_ttl.re"
 
 
     it->lim[0] = 0;
     it->lim[0] = 0;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
     it->eof |= it->lim < it->buf + CHUNK_SIZE - 1;
@@ -72,18 +75,19 @@ if (it->yyt1) it->yyt1 -= shift;
 }
 }
 
 
 
 
-static void parse_init (ParseIterator *it, FILE *fh)
+static void parse_init (ParseIterator *it, FILE *fh, const char *sh)
 {
 {
     it->fh = fh;
     it->fh = fh;
+    it->sh = sh;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
     it->line = 1;
     it->line = 1;
     it->stmt = 1;
     it->stmt = 1;
     it->bol = it->buf;
     it->bol = it->buf;
     it->eof = 0;
     it->eof = 0;
     
     
-#line 85 "parser_ttl.c"
+#line 89 "parser_ttl.c"
 it->yyt1 = NULL; 
 it->yyt1 = NULL; 
-#line 73 "lexer_ttl.re"
+#line 77 "lexer_ttl.re"
 
 
     fill (it);
     fill (it);
 }
 }
@@ -110,7 +114,7 @@ static int lex (ParseIterator *it, YYCTYPE **token_p)
 {
 {
     const YYCTYPE *pfx;
     const YYCTYPE *pfx;
 
 
-    #line 138 "lexer_ttl.re"
+    #line 142 "lexer_ttl.re"
 
 
 
 
 loop: // Start new token.
 loop: // Start new token.
@@ -119,7 +123,7 @@ loop: // Start new token.
     *token_p = NULL;
     *token_p = NULL;
 
 
     
     
-#line 123 "parser_ttl.c"
+#line 127 "parser_ttl.c"
 {
 {
 	YYCTYPE yych;
 	YYCTYPE yych;
 	unsigned int yyaccept = 0;
 	unsigned int yyaccept = 0;
@@ -178,7 +182,7 @@ yyFillLabel0:
 yy1:
 yy1:
 	++YYCURSOR;
 	++YYCURSOR;
 yy2:
 yy2:
-#line 147 "lexer_ttl.re"
+#line 151 "lexer_ttl.re"
 	{
 	{
         log_warn (
         log_warn (
             "Invalid token @ %lu: %s (\\x%x)",
             "Invalid token @ %lu: %s (\\x%x)",
@@ -186,7 +190,7 @@ yy2:
 
 
         return -1;
         return -1;
     }
     }
-#line 190 "parser_ttl.c"
+#line 194 "parser_ttl.c"
 yy3:
 yy3:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel1:
 yyFillLabel1:
@@ -208,7 +212,7 @@ yyFillLabel1:
 			goto yy4;
 			goto yy4;
 	}
 	}
 yy4:
 yy4:
-#line 215 "lexer_ttl.re"
+#line 219 "lexer_ttl.re"
 	{
 	{
         uint8_t *ws = uint8_ndup (it->tok, YYCURSOR - it->tok);
         uint8_t *ws = uint8_ndup (it->tok, YYCURSOR - it->tok);
         LOG_TRACE("Whitespace: '%s'", ws);
         LOG_TRACE("Whitespace: '%s'", ws);
@@ -221,7 +225,7 @@ yy4:
 
 
         return T_WS;
         return T_WS;
     }
     }
-#line 225 "parser_ttl.c"
+#line 229 "parser_ttl.c"
 yy5:
 yy5:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel2:
 yyFillLabel2:
@@ -243,12 +247,12 @@ yyFillLabel2:
 			goto yy6;
 			goto yy6;
 	}
 	}
 yy6:
 yy6:
-#line 160 "lexer_ttl.re"
+#line 164 "lexer_ttl.re"
 	{
 	{
         newline (it);
         newline (it);
         goto loop;
         goto loop;
     }
     }
-#line 252 "parser_ttl.c"
+#line 256 "parser_ttl.c"
 yy7:
 yy7:
 	yyaccept = 0;
 	yyaccept = 0;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -263,9 +267,9 @@ yyFillLabel3:
 			goto yy8;
 			goto yy8;
 	}
 	}
 yy8:
 yy8:
-#line 167 "lexer_ttl.re"
+#line 171 "lexer_ttl.re"
 	{ goto schar; }
 	{ goto schar; }
-#line 269 "parser_ttl.c"
+#line 273 "parser_ttl.c"
 yy9:
 yy9:
 	yyaccept = 1;
 	yyaccept = 1;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -292,12 +296,12 @@ yyFillLabel4:
 		default: goto yy10;
 		default: goto yy10;
 	}
 	}
 yy10:
 yy10:
-#line 210 "lexer_ttl.re"
+#line 214 "lexer_ttl.re"
 	{
 	{
         LOG_TRACE("Comment: `%s`", it->tok);
         LOG_TRACE("Comment: `%s`", it->tok);
         goto loop;
         goto loop;
     }
     }
-#line 301 "parser_ttl.c"
+#line 305 "parser_ttl.c"
 yy11:
 yy11:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel5:
 yyFillLabel5:
@@ -314,14 +318,14 @@ yyFillLabel5:
 			goto yy12;
 			goto yy12;
 	}
 	}
 yy12:
 yy12:
-#line 270 "lexer_ttl.re"
+#line 274 "lexer_ttl.re"
 	{ return T_LPAREN; }
 	{ return T_LPAREN; }
-#line 320 "parser_ttl.c"
+#line 324 "parser_ttl.c"
 yy13:
 yy13:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 272 "lexer_ttl.re"
+#line 276 "lexer_ttl.re"
 	{ return T_RPAREN; }
 	{ return T_RPAREN; }
-#line 325 "parser_ttl.c"
+#line 329 "parser_ttl.c"
 yy14:
 yy14:
 	yyaccept = 2;
 	yyaccept = 2;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -352,9 +356,9 @@ yyFillLabel7:
 			goto yy16;
 			goto yy16;
 	}
 	}
 yy16:
 yy16:
-#line 286 "lexer_ttl.re"
+#line 290 "lexer_ttl.re"
 	{ return T_COMMA; }
 	{ return T_COMMA; }
-#line 358 "parser_ttl.c"
+#line 362 "parser_ttl.c"
 yy17:
 yy17:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel8:
 yyFillLabel8:
@@ -368,13 +372,13 @@ yyFillLabel8:
 			goto yy18;
 			goto yy18;
 	}
 	}
 yy18:
 yy18:
-#line 288 "lexer_ttl.re"
+#line 292 "lexer_ttl.re"
 	{
 	{
         LOG_TRACE("End of statement #%u.", it->stmt);
         LOG_TRACE("End of statement #%u.", it->stmt);
         it->stmt++;
         it->stmt++;
         return T_PERIOD;
         return T_PERIOD;
     }
     }
-#line 378 "parser_ttl.c"
+#line 382 "parser_ttl.c"
 yy19:
 yy19:
 	yyaccept = 3;
 	yyaccept = 3;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -392,7 +396,7 @@ yyFillLabel9:
 			goto yy20;
 			goto yy20;
 	}
 	}
 yy20:
 yy20:
-#line 235 "lexer_ttl.re"
+#line 239 "lexer_ttl.re"
 	{
 	{
         // Normalize sign.
         // Normalize sign.
         size_t offset = *it->tok == '+' ? 1 : 0;
         size_t offset = *it->tok == '+' ? 1 : 0;
@@ -402,7 +406,7 @@ yy20:
 
 
         return T_INTEGER;
         return T_INTEGER;
     }
     }
-#line 406 "parser_ttl.c"
+#line 410 "parser_ttl.c"
 yy21:
 yy21:
 	yyaccept = 4;
 	yyaccept = 4;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -423,14 +427,14 @@ yyFillLabel10:
 		default: goto yy66;
 		default: goto yy66;
 	}
 	}
 yy22:
 yy22:
-#line 196 "lexer_ttl.re"
+#line 200 "lexer_ttl.re"
 	{
 	{
         *token_p = uint8_ndup (it->tok, YYCURSOR - it->tok);
         *token_p = uint8_ndup (it->tok, YYCURSOR - it->tok);
         LOG_TRACE("ID name: %s", *token_p);
         LOG_TRACE("ID name: %s", *token_p);
 
 
         return T_QNAME;
         return T_QNAME;
     }
     }
-#line 434 "parser_ttl.c"
+#line 438 "parser_ttl.c"
 yy23:
 yy23:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel11:
 yyFillLabel11:
@@ -447,13 +451,13 @@ yyFillLabel11:
 			goto yy24;
 			goto yy24;
 	}
 	}
 yy24:
 yy24:
-#line 280 "lexer_ttl.re"
+#line 284 "lexer_ttl.re"
 	{
 	{
         LOG_TRACE("End of object list.");
         LOG_TRACE("End of object list.");
 
 
         return T_SEMICOLON;
         return T_SEMICOLON;
     }
     }
-#line 457 "parser_ttl.c"
+#line 461 "parser_ttl.c"
 yy25:
 yy25:
 	yyaccept = 2;
 	yyaccept = 2;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -522,14 +526,14 @@ yyFillLabel15:
 			goto yy29;
 			goto yy29;
 	}
 	}
 yy29:
 yy29:
-#line 274 "lexer_ttl.re"
+#line 278 "lexer_ttl.re"
 	{ return T_LBRACKET; }
 	{ return T_LBRACKET; }
-#line 528 "parser_ttl.c"
+#line 532 "parser_ttl.c"
 yy30:
 yy30:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 276 "lexer_ttl.re"
+#line 280 "lexer_ttl.re"
 	{ return T_RBRACKET; }
 	{ return T_RBRACKET; }
-#line 533 "parser_ttl.c"
+#line 537 "parser_ttl.c"
 yy31:
 yy31:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel16:
 yyFillLabel16:
@@ -575,12 +579,12 @@ yyFillLabel18:
 			goto yy34;
 			goto yy34;
 	}
 	}
 yy34:
 yy34:
-#line 296 "lexer_ttl.re"
+#line 300 "lexer_ttl.re"
 	{
 	{
         LOG_TRACE("RDF type shorthand 'a'.");
         LOG_TRACE("RDF type shorthand 'a'.");
         return T_RDF_TYPE;
         return T_RDF_TYPE;
     }
     }
-#line 584 "parser_ttl.c"
+#line 588 "parser_ttl.c"
 yy35:
 yy35:
 	yyaccept = 2;
 	yyaccept = 2;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -1002,7 +1006,7 @@ yyFillLabel44:
 			goto yy63;
 			goto yy63;
 	}
 	}
 yy63:
 yy63:
-#line 255 "lexer_ttl.re"
+#line 259 "lexer_ttl.re"
 	{
 	{
         // Normalize sign.
         // Normalize sign.
         YYCTYPE offset = *it->tok == '+' ? 1 : 0;
         YYCTYPE offset = *it->tok == '+' ? 1 : 0;
@@ -1017,7 +1021,7 @@ yy63:
 
 
         return T_DECIMAL;
         return T_DECIMAL;
     }
     }
-#line 1021 "parser_ttl.c"
+#line 1025 "parser_ttl.c"
 yy64:
 yy64:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel45:
 yyFillLabel45:
@@ -1272,14 +1276,14 @@ yy81:
 yy82:
 yy82:
 	++YYCURSOR;
 	++YYCURSOR;
 yy83:
 yy83:
-#line 176 "lexer_ttl.re"
+#line 180 "lexer_ttl.re"
 	{
 	{
         *token_p = uint8_ndup (it->tok + 1, YYCURSOR - it->tok - 2);
         *token_p = uint8_ndup (it->tok + 1, YYCURSOR - it->tok - 2);
         LOG_TRACE("URI data: %s", *token_p);
         LOG_TRACE("URI data: %s", *token_p);
 
 
         return T_IRIREF;
         return T_IRIREF;
     }
     }
-#line 1283 "parser_ttl.c"
+#line 1287 "parser_ttl.c"
 yy84:
 yy84:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel61:
 yyFillLabel61:
@@ -1416,14 +1420,14 @@ yy94:
 			goto yy95;
 			goto yy95;
 	}
 	}
 yy95:
 yy95:
-#line 228 "lexer_ttl.re"
+#line 232 "lexer_ttl.re"
 	{
 	{
         *token_p = uint8_ndup (it->tok + 1, YYCURSOR - it->tok - 1);
         *token_p = uint8_ndup (it->tok + 1, YYCURSOR - it->tok - 1);
         LOG_TRACE("Lang tag: '%s'", *token_p);
         LOG_TRACE("Lang tag: '%s'", *token_p);
 
 
         return T_LANGTAG;
         return T_LANGTAG;
     }
     }
-#line 1427 "parser_ttl.c"
+#line 1431 "parser_ttl.c"
 yy96:
 yy96:
 	yyaccept = 11;
 	yyaccept = 11;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -1682,9 +1686,9 @@ yyFillLabel87:
 	}
 	}
 yy114:
 yy114:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 294 "lexer_ttl.re"
+#line 298 "lexer_ttl.re"
 	{ return T_DTYPE_MARKER; }
 	{ return T_DTYPE_MARKER; }
-#line 1688 "parser_ttl.c"
+#line 1692 "parser_ttl.c"
 yy115:
 yy115:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel88:
 yyFillLabel88:
@@ -1890,9 +1894,9 @@ yyFillLabel103:
 	}
 	}
 yy131:
 yy131:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 165 "lexer_ttl.re"
+#line 169 "lexer_ttl.re"
 	{ goto lchar; }
 	{ goto lchar; }
-#line 1896 "parser_ttl.c"
+#line 1900 "parser_ttl.c"
 yy132:
 yy132:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel104:
 yyFillLabel104:
@@ -2062,7 +2066,7 @@ yyFillLabel117:
 			goto yy146;
 			goto yy146;
 	}
 	}
 yy146:
 yy146:
-#line 245 "lexer_ttl.re"
+#line 249 "lexer_ttl.re"
 	{
 	{
         // Normalize sign.
         // Normalize sign.
         size_t offset = *it->tok == '+' ? 1 : 0;
         size_t offset = *it->tok == '+' ? 1 : 0;
@@ -2072,7 +2076,7 @@ yy146:
 
 
         return T_DOUBLE;
         return T_DOUBLE;
     }
     }
-#line 2076 "parser_ttl.c"
+#line 2080 "parser_ttl.c"
 yy147:
 yy147:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel118:
 yyFillLabel118:
@@ -2497,14 +2501,14 @@ yy178:
 			goto yy179;
 			goto yy179;
 	}
 	}
 yy179:
 yy179:
-#line 203 "lexer_ttl.re"
+#line 207 "lexer_ttl.re"
 	{
 	{
         *token_p = uint8_ndup (it->tok + 2, YYCURSOR - it->tok - 2);
         *token_p = uint8_ndup (it->tok + 2, YYCURSOR - it->tok - 2);
         LOG_TRACE("BNode name: %s", *token_p);
         LOG_TRACE("BNode name: %s", *token_p);
 
 
         return T_BNODE_ID;
         return T_BNODE_ID;
     }
     }
-#line 2508 "parser_ttl.c"
+#line 2512 "parser_ttl.c"
 yy180:
 yy180:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel149:
 yyFillLabel149:
@@ -2932,24 +2936,24 @@ yyFillLabel180:
 			goto yy212;
 			goto yy212;
 	}
 	}
 yy212:
 yy212:
-#line 169 "lexer_ttl.re"
+#line 173 "lexer_ttl.re"
 	{
 	{
         *token_p = uint8_ndup (it->tok, YYCURSOR - it->tok);
         *token_p = uint8_ndup (it->tok, YYCURSOR - it->tok);
         LOG_TRACE("Boolean: %s", *token_p);
         LOG_TRACE("Boolean: %s", *token_p);
 
 
         return T_BOOLEAN;
         return T_BOOLEAN;
     }
     }
-#line 2943 "parser_ttl.c"
+#line 2947 "parser_ttl.c"
 yy213:
 yy213:
 	++YYCURSOR;
 	++YYCURSOR;
 yy214:
 yy214:
-#line 190 "lexer_ttl.re"
+#line 194 "lexer_ttl.re"
 	{
 	{
         LOG_TRACE("'@base' keyword.");
         LOG_TRACE("'@base' keyword.");
 
 
         return T_BASE;
         return T_BASE;
     }
     }
-#line 2953 "parser_ttl.c"
+#line 2957 "parser_ttl.c"
 yy215:
 yy215:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel181:
 yyFillLabel181:
@@ -3170,14 +3174,14 @@ yy226:
 	++YYCURSOR;
 	++YYCURSOR;
 yy227:
 yy227:
 	pfx = it->yyt1;
 	pfx = it->yyt1;
-#line 183 "lexer_ttl.re"
+#line 187 "lexer_ttl.re"
 	{
 	{
         *token_p = uint8_ndup (pfx, YYCURSOR - pfx - 1);
         *token_p = uint8_ndup (pfx, YYCURSOR - pfx - 1);
         LOG_TRACE("Prefix declaration: '%s'", *token_p);
         LOG_TRACE("Prefix declaration: '%s'", *token_p);
 
 
         return T_PREFIX;
         return T_PREFIX;
     }
     }
-#line 3181 "parser_ttl.c"
+#line 3185 "parser_ttl.c"
 yy228:
 yy228:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel192:
 yyFillLabel192:
@@ -3621,19 +3625,19 @@ yyFillLabel223:
 			goto yy52;
 			goto yy52;
 	}
 	}
 yy260:
 yy260:
-#line 155 "lexer_ttl.re"
+#line 159 "lexer_ttl.re"
 	{
 	{
         LOG_TRACE("End of document.");
         LOG_TRACE("End of document.");
         return T_EOF;
         return T_EOF;
     }
     }
-#line 3630 "parser_ttl.c"
+#line 3634 "parser_ttl.c"
 }
 }
-#line 301 "lexer_ttl.re"
+#line 305 "lexer_ttl.re"
 
 
 
 
 schar:
 schar:
     
     
-#line 3637 "parser_ttl.c"
+#line 3641 "parser_ttl.c"
 {
 {
 	YYCTYPE yych;
 	YYCTYPE yych;
 	unsigned int yyaccept = 0;
 	unsigned int yyaccept = 0;
@@ -3661,7 +3665,7 @@ yyFillLabel224:
 yy262:
 yy262:
 	++YYCURSOR;
 	++YYCURSOR;
 yy263:
 yy263:
-#line 306 "lexer_ttl.re"
+#line 310 "lexer_ttl.re"
 	{
 	{
         log_warn (
         log_warn (
             "Invalid token in string @ %lu: %s (\\x%x)",
             "Invalid token in string @ %lu: %s (\\x%x)",
@@ -3669,23 +3673,23 @@ yy263:
 
 
         return -1;
         return -1;
     }
     }
-#line 3673 "parser_ttl.c"
+#line 3677 "parser_ttl.c"
 yy264:
 yy264:
 	++YYCURSOR;
 	++YYCURSOR;
 yy265:
 yy265:
-#line 320 "lexer_ttl.re"
+#line 324 "lexer_ttl.re"
 	{ goto schar; }
 	{ goto schar; }
-#line 3679 "parser_ttl.c"
+#line 3683 "parser_ttl.c"
 yy266:
 yy266:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 322 "lexer_ttl.re"
+#line 326 "lexer_ttl.re"
 	{
 	{
         *token_p = unescape_unicode (it->tok + 1, YYCURSOR - it->tok - 2);
         *token_p = unescape_unicode (it->tok + 1, YYCURSOR - it->tok - 2);
         LOG_TRACE("String: %s", *token_p);
         LOG_TRACE("String: %s", *token_p);
 
 
         return T_STRING;
         return T_STRING;
     }
     }
-#line 3689 "parser_ttl.c"
+#line 3693 "parser_ttl.c"
 yy267:
 yy267:
 	yyaccept = 0;
 	yyaccept = 0;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -3911,20 +3915,20 @@ yyFillLabel241:
 			goto yy275;
 			goto yy275;
 	}
 	}
 yy285:
 yy285:
-#line 314 "lexer_ttl.re"
+#line 318 "lexer_ttl.re"
 	{
 	{
         log_warn ("Unterminated string!");
         log_warn ("Unterminated string!");
 
 
         return -1;
         return -1;
     }
     }
-#line 3921 "parser_ttl.c"
+#line 3925 "parser_ttl.c"
 }
 }
-#line 329 "lexer_ttl.re"
+#line 333 "lexer_ttl.re"
 
 
 
 
 lchar:
 lchar:
     
     
-#line 3928 "parser_ttl.c"
+#line 3932 "parser_ttl.c"
 {
 {
 	YYCTYPE yych;
 	YYCTYPE yych;
 	unsigned int yyaccept = 0;
 	unsigned int yyaccept = 0;
@@ -3954,7 +3958,7 @@ yyFillLabel242:
 yy287:
 yy287:
 	++YYCURSOR;
 	++YYCURSOR;
 yy288:
 yy288:
-#line 349 "lexer_ttl.re"
+#line 353 "lexer_ttl.re"
 	{
 	{
         log_warn (
         log_warn (
             "Invalid token in long string @ %lu: %s (\\x%x)",
             "Invalid token in long string @ %lu: %s (\\x%x)",
@@ -3962,13 +3966,13 @@ yy288:
 
 
         return -1;
         return -1;
     }
     }
-#line 3966 "parser_ttl.c"
+#line 3970 "parser_ttl.c"
 yy289:
 yy289:
 	++YYCURSOR;
 	++YYCURSOR;
 yy290:
 yy290:
-#line 340 "lexer_ttl.re"
+#line 344 "lexer_ttl.re"
 	{ goto lchar; }
 	{ goto lchar; }
-#line 3972 "parser_ttl.c"
+#line 3976 "parser_ttl.c"
 yy291:
 yy291:
 	yyaccept = 0;
 	yyaccept = 0;
 	YYMARKER = ++YYCURSOR;
 	YYMARKER = ++YYCURSOR;
@@ -4145,14 +4149,14 @@ yyFillLabel255:
 	}
 	}
 yy305:
 yy305:
 	++YYCURSOR;
 	++YYCURSOR;
-#line 342 "lexer_ttl.re"
+#line 346 "lexer_ttl.re"
 	{
 	{
         *token_p = unescape_unicode (it->tok + 3, YYCURSOR - it->tok - 6);
         *token_p = unescape_unicode (it->tok + 3, YYCURSOR - it->tok - 6);
         LOG_TRACE("Long string: %s", it->tok);
         LOG_TRACE("Long string: %s", it->tok);
 
 
         return T_STRING;
         return T_STRING;
     }
     }
-#line 4156 "parser_ttl.c"
+#line 4160 "parser_ttl.c"
 yy306:
 yy306:
 	++YYCURSOR;
 	++YYCURSOR;
 yyFillLabel256:
 yyFillLabel256:
@@ -4232,21 +4236,22 @@ yyFillLabel261:
 			goto yy300;
 			goto yy300;
 	}
 	}
 yy312:
 yy312:
-#line 334 "lexer_ttl.re"
+#line 338 "lexer_ttl.re"
 	{
 	{
         log_warn ("Unterminated long string!");
         log_warn ("Unterminated long string!");
 
 
         return -1;
         return -1;
     }
     }
-#line 4242 "parser_ttl.c"
+#line 4246 "parser_ttl.c"
 }
 }
-#line 357 "lexer_ttl.re"
+#line 361 "lexer_ttl.re"
 
 
 }
 }
 
 
 
 
 VOLK_rc
 VOLK_rc
-VOLK_ttl_parse_doc (FILE *fh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
+VOLK_ttl_parse_doc (
+        FILE *fh, const char *sh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
 {
 {
     *err_p = NULL;
     *err_p = NULL;
     *gr_p = NULL;
     *gr_p = NULL;
@@ -4260,7 +4265,7 @@ VOLK_ttl_parse_doc (FILE *fh, VOLK_Graph **gr_p, size_t *ct, char **err_p)
     state->rc = VOLK_NORESULT;
     state->rc = VOLK_NORESULT;
 
 
     ParseIterator parse_it;
     ParseIterator parse_it;
-    parse_init (&parse_it, fh);
+    parse_init (&parse_it, fh, sh);
 
 
     void *parser = TTLParseAlloc (malloc);
     void *parser = TTLParseAlloc (malloc);
 
 

+ 94 - 16
src/core.c

@@ -1,6 +1,7 @@
-#define _XOPEN_SOURCE 500
 #include <errno.h>
 #include <errno.h>
-#include <ftw.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include <string.h>
 #include <string.h>
 
 
 #include "lmdb.h"
 #include "lmdb.h"
@@ -87,26 +88,103 @@ finally:
 }
 }
 
 
 
 
-int
-unlink_cb(
-        const char *fpath, const struct stat *sb, int typeflag,
-        struct FTW *ftwbuf)
+char *strndup (const char *src, size_t max)
 {
 {
-    (void) sb;
-    (void) typeflag;
-    (void) ftwbuf;
+    size_t len = strlen (src);
+    if (len > max) len = max;
 
 
-    LOG_DEBUG("Removing %s", fpath);
-    int rv = remove(fpath);
+    char *res = (char*)malloc (len + 1);
+    if (res) {
+        memcpy (res, src, len);
+        res[len] = '\0';
+    }
+
+    return res;
+}
 
 
-    if (rv)
-        perror(fpath);
 
 
-    return rv;
+char *strdup (const char *src)
+{
+   char *res = (char*)malloc (strlen (src) + 1);
+   if (res) strcpy(res, src);
+
+   return res;
 }
 }
 
 
-int rm_r(const char *path)
-{ return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); }
+
+/** @brief Remove a directory recursively (POSIX compatible).
+ *
+ * Adapted from
+ * https://stackoverflow.com/questions/5467725/how-to-delete-a-directory-and-its-contents-in-posix-c/42596507#42596507
+ */
+VOLK_rc rm_r (const char *path)
+{
+    size_t path_len;
+    char *full_path;
+    DIR *dir;
+    struct stat stat_path, stat_entry;
+    struct dirent *entry;
+
+    // stat for the path
+    stat(path, &stat_path);
+
+    // if path does not exists or is not dir - exit with status -1
+    if (S_ISDIR(stat_path.st_mode) == 0) {
+        log_error ("%s: %s\n", "Is not directory", path);
+        return VOLK_IO_ERR;
+    }
+
+    // if not possible to read the directory for this user
+    if ((dir = opendir(path)) == NULL) {
+        log_error ("%s: %s\n", "Can`t open directory", path);
+        return VOLK_IO_ERR;
+    }
+
+    // the length of the path
+    path_len = strlen(path);
+
+    // iteration through entries in the directory
+    while ((entry = readdir(dir)) != NULL) {
+
+        // skip entries "." and ".."
+        if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
+            continue;
+
+        // determine a full path of an entry
+        full_path = calloc(
+                path_len + 1 + strlen(entry->d_name) + 1, sizeof(char));
+        strcpy(full_path, path);
+        strcat(full_path, "/");
+        strcat(full_path, entry->d_name);
+
+        // stat for the entry
+        stat(full_path, &stat_entry);
+
+        // recursively remove a nested directory
+        if (S_ISDIR(stat_entry.st_mode) != 0) {
+            rm_r (full_path);
+            free (full_path);
+            continue;
+        }
+
+        // remove a file object
+        if (unlink(full_path) == 0)
+            LOG_DEBUG ("Removed a file:\t%s\n", full_path);
+        else
+            log_error ("Can't remove a file:\t%s\n", full_path);
+        free(full_path);
+    }
+
+    // remove the devastated directory and close the object of it
+    if (rmdir(path) == 0)
+        LOG_DEBUG ("Removed a directory:\t%s\n", path);
+    else
+        log_error ("Can't remove a directory:\t%s\n", path);
+
+    closedir(dir);
+
+    return VOLK_OK;
+}
 
 
 
 
 const char *
 const char *

+ 0 - 2
test.c

@@ -13,9 +13,7 @@
 int main() {
 int main() {
 
 
     // Set env variable to test path.
     // Set env variable to test path.
-    putenv ("VOLK_MDB_STORE_PATH=" TEST_STORE_PATH);
     // Clear out database from previous test.
     // Clear out database from previous test.
-    rm_r (TEST_STORE_PATH);
 
 
     clock_t start, end;
     clock_t start, end;
     double wallclock;
     double wallclock;

+ 2 - 7
test/test_codec_nt.c

@@ -210,14 +210,11 @@ test_decode_nt_term()
 int
 int
 test_decode_nt_graph()
 test_decode_nt_graph()
 {
 {
-    FILE *input = fmemopen ((void *)start_nt_doc, strlen (start_nt_doc), "r");
 
 
     VOLK_Graph *gr;
     VOLK_Graph *gr;
     size_t ct;
     size_t ct;
     char *err;
     char *err;
-    EXPECT_PASS (codec.decode_graph (input, &gr, &ct, &err));
-
-    fclose (input);
+    EXPECT_PASS (codec.decode_graph (NULL, start_nt_doc, &gr, &ct, &err));
 
 
     ASSERT (err == NULL, "Error string is not NULL!");
     ASSERT (err == NULL, "Error string is not NULL!");
 
 
@@ -254,12 +251,11 @@ int
 test_decode_nt_bad_graph()
 test_decode_nt_bad_graph()
 {
 {
     log_info ("testing illegal NT document.");
     log_info ("testing illegal NT document.");
-    FILE *input = fmemopen ((void *)bad_nt_doc, strlen (bad_nt_doc), "r");
 
 
     VOLK_Graph *gr;
     VOLK_Graph *gr;
     size_t ct;
     size_t ct;
     char *err;
     char *err;
-    VOLK_rc rc = codec.decode_graph (input, &gr, &ct, &err);
+    VOLK_rc rc = codec.decode_graph (NULL, bad_nt_doc, &gr, &ct, &err);
     EXPECT_INT_EQ (rc, VOLK_PARSE_ERR);
     EXPECT_INT_EQ (rc, VOLK_PARSE_ERR);
 
 
     log_info ("Error: %s", err);
     log_info ("Error: %s", err);
@@ -268,7 +264,6 @@ test_decode_nt_bad_graph()
     ASSERT (strstr (err, "character 16") != NULL, "Wrong error char report!");
     ASSERT (strstr (err, "character 16") != NULL, "Wrong error char report!");
 
 
     free (err);
     free (err);
-    fclose (input);
     VOLK_graph_free (gr);
     VOLK_graph_free (gr);
 
 
     return 0;
     return 0;

+ 2 - 2
test/test_codec_ttl.c

@@ -77,7 +77,7 @@ test_w3c_pos()
             if (ch == '\n') nt_ct++;
             if (ch == '\n') nt_ct++;
         }
         }
 
 
-        EXPECT_PASS (codec.decode_graph (test_stream, &gr, &ct, &err));
+        EXPECT_PASS (codec.decode_graph (test_stream, NULL, &gr, &ct, &err));
         EXPECT_INT_EQ (VOLK_graph_size (gr), nt_ct); // Just count NT lines.
         EXPECT_INT_EQ (VOLK_graph_size (gr), nt_ct); // Just count NT lines.
         VOLK_graph_free (gr);
         VOLK_graph_free (gr);
         fclose (test_stream);
         fclose (test_stream);
@@ -103,7 +103,7 @@ test_w3c_neg()
         FILE *test_stream = fopen (test_fname, "r");
         FILE *test_stream = fopen (test_fname, "r");
         log_info ("Testing %s", test_fname);
         log_info ("Testing %s", test_fname);
 
 
-        VOLK_rc rc = codec.decode_graph (test_stream, &gr, &ct, &err);
+        VOLK_rc rc = codec.decode_graph (test_stream, NULL, &gr, &ct, &err);
         log_info ("rc: %d", rc);
         log_info ("rc: %d", rc);
         ASSERT (rc == VOLK_PARSE_ERR, "Bad test did not raise a parse error!");
         ASSERT (rc == VOLK_PARSE_ERR, "Bad test did not raise a parse error!");
         fclose (test_stream);
         fclose (test_stream);

+ 1 - 1
test/test_store_mdb.c

@@ -18,7 +18,7 @@ static int test_ctx_switch()
 
 
     // Create enough triples to test a multi-page copy of triple data.
     // Create enough triples to test a multi-page copy of triple data.
     // Add small buffer (4) to create a 3rd page.
     // Add small buffer (4) to create a 3rd page.
-    size_t num_trp = (getpagesize() * 2 / TRP_KLEN) + 4;
+    size_t num_trp = (sysconf(_SC_PAGESIZE) * 2 / TRP_KLEN) + 4;
     VOLK_BufferTriple **tdata = malloc (num_trp * sizeof (*tdata));
     VOLK_BufferTriple **tdata = malloc (num_trp * sizeof (*tdata));
     VOLK_Triple *trp = VOLK_triple_new (
     VOLK_Triple *trp = VOLK_triple_new (
         VOLK_iriref_new ("urn:s:1"),
         VOLK_iriref_new ("urn:s:1"),