|
@@ -10,15 +10,16 @@
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
- FILE * fh; ///< Input file handle.
|
|
|
+ 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
|
|
|
+ *lim, ///< Position after the last available
|
|
|
///< input character (YYLIMIT).
|
|
|
- * cur, ///< Next input character to be read
|
|
|
+ *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
|
|
|
+ *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.
|
|
@@ -37,12 +38,14 @@ static int fill(ParseIterator *it)
|
|
|
return 2;
|
|
|
}
|
|
|
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->cur -= shift;
|
|
|
it->mar -= 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; "; */
|
|
|
it->lim[0] = 0;
|
|
|
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->sh = sh;
|
|
|
it->cur = it->mar = it->tok = it->lim = it->buf + CHUNK_SIZE - 1;
|
|
|
it->line = 1;
|
|
|
it->bol = it->buf;
|
|
@@ -64,9 +77,9 @@ static void parse_init(ParseIterator *it, FILE *fh)
|
|
|
|
|
|
|
|
|
// Parser interface. Required here to silence linters.
|
|
|
-//void *NTParseAlloc(void *);
|
|
|
-//void NTParse(void *);
|
|
|
-//void NTParseFree(void *);
|
|
|
+void *NTParseAlloc();
|
|
|
+void NTParse();
|
|
|
+void NTParseFree();
|
|
|
#ifdef DEBUG
|
|
|
void NTParseTrace();
|
|
|
#endif
|
|
@@ -234,15 +247,11 @@ loop:
|
|
|
LSUP_rc
|
|
|
LSUP_nt_parse_term (const char *rep, const LSUP_NSMap *map, LSUP_Term **term)
|
|
|
{
|
|
|
- FILE *fh = fmemopen ((void *)rep, strlen (rep), "r");
|
|
|
-
|
|
|
ParseIterator it;
|
|
|
- parse_init (&it, fh);
|
|
|
+ parse_init (&it, NULL, rep);
|
|
|
|
|
|
int ttype = lex (&it, term);
|
|
|
|
|
|
- fclose (fh);
|
|
|
-
|
|
|
switch (ttype) {
|
|
|
case T_IRIREF:
|
|
|
case T_LITERAL:
|
|
@@ -260,7 +269,7 @@ LSUP_nt_parse_doc (FILE *fh, LSUP_Graph **gr_p, size_t *ct, char **err_p)
|
|
|
*gr_p = NULL;
|
|
|
|
|
|
ParseIterator parse_it;
|
|
|
- parse_init (&parse_it, fh);
|
|
|
+ parse_init (&parse_it, fh, NULL);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
NTParseTrace (stdout, "NT Parser > ");
|
|
@@ -285,7 +294,7 @@ LSUP_nt_parse_doc (FILE *fh, LSUP_Graph **gr_p, size_t *ct, char **err_p)
|
|
|
int ttype = lex (&parse_it, &term);
|
|
|
|
|
|
if (ttype == -1) {
|
|
|
- char token[16] = {};
|
|
|
+ char token[16] = {'\0'};
|
|
|
strncpy (token, (const char *)parse_it.tok, 15);
|
|
|
|
|
|
char *err_start = "Parse error near token `";
|