enhanced the xli reader to recognize some other line termination conventions than a single LF.
added more code to the upcoming ini-style format reader
This commit is contained in:
parent
e8fb5c1948
commit
63ecef90a0
@ -334,6 +334,7 @@ struct qse_xli_io_arg_t
|
||||
qse_char_t buf[1024];
|
||||
qse_size_t pos;
|
||||
qse_size_t len;
|
||||
int state;
|
||||
} b;
|
||||
|
||||
qse_size_t line;
|
||||
|
@ -35,15 +35,20 @@
|
||||
* key1 = value1
|
||||
* --------------------------------
|
||||
*
|
||||
* SECTION1 = {
|
||||
* SECTION1 {
|
||||
* key1 = value1;
|
||||
* key2 = value2;
|
||||
* }
|
||||
* SECTION2 = {
|
||||
* SECTION2 {
|
||||
* key1 = value1;
|
||||
* }
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
TOK_STATUS_UPTO_EOL = (1 << 0)
|
||||
};
|
||||
|
||||
#define GET_CHAR(xli) \
|
||||
do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0)
|
||||
|
||||
@ -71,6 +76,10 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SET_TOKEN_TYPE(xli,tok,code) \
|
||||
do { (tok)->type = (code); } while (0)
|
||||
|
||||
#define MATCH(xli,tok_type) ((xli)->tok.type == (tok_type))
|
||||
|
||||
static int skip_spaces (qse_xli_t* xli)
|
||||
{
|
||||
@ -102,7 +111,7 @@ static int skip_comment (qse_xli_t* xli, qse_xli_tok_t* tok)
|
||||
qse_xli_inserttext (xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(tok->name)) == QSE_NULL) return -1;
|
||||
|
||||
GET_CHAR (xli); /* eat the new line letter */
|
||||
return 1; /* comment by # */
|
||||
return 1; /* comment by ; */
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -130,21 +139,132 @@ static int get_token_into (qse_xli_t* xli, qse_xli_tok_t* tok)
|
||||
|
||||
if (c == QSE_CHAR_EOF)
|
||||
{
|
||||
#if 0
|
||||
n = end_include (xli, 0);
|
||||
if (n <= -1) return -1;
|
||||
if (n >= 1)
|
||||
ADD_TOKEN_STR (xli, tok, QSE_T("<EOF>"), 5);
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_EOF);
|
||||
}
|
||||
else if (xli->tok_status & TOK_STATUS_UPTO_EOL)
|
||||
{
|
||||
qse_size_t xlen = 0;
|
||||
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_SQSTR);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/*xli->rio.last = xli->rio.inp->last;*/
|
||||
/* mark that i'm retrying after end of an included file */
|
||||
skip_semicolon_after_include = 1;
|
||||
goto retry;
|
||||
GET_CHAR_TO (xli, c);
|
||||
if (c == QSE_CHAR_EOF || c == QSE_T(';')) break;
|
||||
|
||||
ADD_TOKEN_CHAR (xli, tok, c);
|
||||
if (!QSE_ISSPACE(c)) xlen = QSE_STR_LEN(tok->name);
|
||||
}
|
||||
|
||||
ADD_TOKEN_STR (xli, tok, QSE_T("<EOF>"), 5);
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_EOF);
|
||||
#endif
|
||||
/* trim away trailing spaces */
|
||||
qse_str_setlen (tok->name, xlen);
|
||||
}
|
||||
else if (c == QSE_T('['))
|
||||
{
|
||||
/* in the ini-styled format, a tag is used as a section name.
|
||||
* but the kinds of allowed charaters are more limited than
|
||||
* a normal tag in the xli format. */
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_TAG);
|
||||
|
||||
while (1)
|
||||
{
|
||||
GET_CHAR_TO (xli, c);
|
||||
|
||||
if (c == QSE_CHAR_EOF)
|
||||
{
|
||||
/* the string tag is not closed */
|
||||
qse_xli_seterror (xli, QSE_XLI_ETAGNC, QSE_NULL, &xli->tok.loc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c == QSE_T(']'))
|
||||
{
|
||||
/* terminating quote */
|
||||
GET_CHAR (xli);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!QSE_ISALNUM(c) && c != QSE_T('-') && c != QSE_T('_') && c != QSE_T(':'))
|
||||
{
|
||||
qse_char_t cc = (qse_char_t)c;
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = &cc;
|
||||
ea.len = 1;
|
||||
qse_xli_seterror (xli, QSE_XLI_ETAGCHR, &ea, &tok->loc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ADD_TOKEN_CHAR (xli, tok, c);
|
||||
}
|
||||
}
|
||||
else if (c == QSE_T('_') || QSE_ISALPHA (c) ||
|
||||
((xli->opt.trait & QSE_XLI_LEADDIGIT) && QSE_ISDIGIT(c)))
|
||||
{
|
||||
int lead_digit = QSE_ISDIGIT(c);
|
||||
int all_digits = 1;
|
||||
|
||||
/* a normal identifier can be composed of wider varieties of
|
||||
* characters than a keyword/directive */
|
||||
while (1)
|
||||
{
|
||||
ADD_TOKEN_CHAR (xli, tok, c);
|
||||
GET_CHAR_TO (xli, c);
|
||||
|
||||
if (c == QSE_T('_') || c == QSE_T('-') ||
|
||||
c == QSE_T(':') || c == QSE_T('*') ||
|
||||
c == QSE_T('/') || QSE_ISALPHA (c))
|
||||
{
|
||||
all_digits = 0;
|
||||
}
|
||||
else if (QSE_ISDIGIT(c))
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if (lead_digit && all_digits)
|
||||
{
|
||||
/* if an identifier begins with a digit, it must contain a non-digits character */
|
||||
qse_xli_seterror (xli, QSE_XLI_EIDENT, QSE_STR_XSTR(tok->name), &tok->loc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_IDENT);
|
||||
}
|
||||
else if (c == QSE_T('='))
|
||||
{
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_EQ);
|
||||
ADD_TOKEN_CHAR (xli, tok, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not handled yet */
|
||||
if (c == QSE_T('\0'))
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = QSE_T("<NUL>");
|
||||
ea.len = 5;
|
||||
qse_xli_seterror (xli, QSE_XLI_ELXCHR, &ea, &tok->loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_char_t cc = (qse_char_t)c;
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = &cc;
|
||||
ea.len = 1;
|
||||
qse_xli_seterror (xli, QSE_XLI_ELXCHR, &ea, &tok->loc);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_token (qse_xli_t* xli)
|
||||
{
|
||||
return get_token_into (xli, &xli->tok);
|
||||
}
|
||||
|
||||
static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
||||
@ -185,6 +305,8 @@ int qse_xli_readini (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
xli->rio.top.colm = 1;
|
||||
xli->rio.inp = &xli->rio.top;
|
||||
|
||||
xli->tok_status = 0;
|
||||
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL);
|
||||
qse_xli_clearrionames (xli);
|
||||
|
||||
@ -197,13 +319,11 @@ int qse_xli_readini (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
|
||||
QSE_ASSERT (xli->parlink == QSE_NULL);
|
||||
|
||||
/*
|
||||
if (!MATCH (xli, TOK_EOF))
|
||||
if (!MATCH (xli, QSE_XLI_TOK_EOF))
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||
goto oops;
|
||||
}
|
||||
*/
|
||||
|
||||
QSE_ASSERT (xli->rio.inp == &xli->rio.top);
|
||||
qse_xli_closecurrentstream (xli);
|
||||
|
@ -67,24 +67,7 @@ int qse_xli_closecurrentstream (qse_xli_t* xli)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum tok_t
|
||||
{
|
||||
TOK_EOF,
|
||||
TOK_XINCLUDE,
|
||||
TOK_SEMICOLON,
|
||||
TOK_LBRACE,
|
||||
TOK_RBRACE,
|
||||
TOK_EQ,
|
||||
TOK_COMMA,
|
||||
TOK_DQSTR,
|
||||
TOK_SQSTR,
|
||||
TOK_NSTR,
|
||||
TOK_IDENT,
|
||||
TOK_TEXT,
|
||||
TOK_TAG,
|
||||
|
||||
__TOKEN_COUNT__
|
||||
};
|
||||
|
||||
#define GET_CHAR(xli) \
|
||||
do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0)
|
||||
@ -130,12 +113,24 @@ struct kwent_t
|
||||
static kwent_t kwtab[] =
|
||||
{
|
||||
/* keep it sorted by the first field for binary search */
|
||||
{ { QSE_T("@include"), 8 }, TOK_XINCLUDE }
|
||||
{ { QSE_T("@include"), 8 }, QSE_XLI_TOK_XINCLUDE }
|
||||
};
|
||||
|
||||
int qse_xli_getchar (qse_xli_t* xli)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
qse_char_t lc, ec;
|
||||
|
||||
if (xli->rio.inp->b.state == -1)
|
||||
{
|
||||
xli->rio.inp->b.state = 0;
|
||||
return -1;
|
||||
}
|
||||
else if (xli->rio.inp->b.state == 1)
|
||||
{
|
||||
xli->rio.inp->b.state = 0;
|
||||
goto return_eof;
|
||||
}
|
||||
|
||||
if (xli->rio.inp->b.pos >= xli->rio.inp->b.len)
|
||||
{
|
||||
@ -152,6 +147,7 @@ int qse_xli_getchar (qse_xli_t* xli)
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
return_eof:
|
||||
xli->rio.inp->last.c = QSE_CHAR_EOF;
|
||||
xli->rio.inp->last.line = xli->rio.inp->line;
|
||||
xli->rio.inp->last.colm = xli->rio.inp->colm;
|
||||
@ -170,16 +166,57 @@ int qse_xli_getchar (qse_xli_t* xli)
|
||||
* increment the line counter and reset column to 1.
|
||||
* incrementing it line number here instead of
|
||||
* updating inp->last causes the line number for
|
||||
* TOK_EOF to be the same line as the last newline. */
|
||||
* QSE_XLI_TOK_EOF to be the same line as the last newline. */
|
||||
xli->rio.inp->line++;
|
||||
xli->rio.inp->colm = 1;
|
||||
}
|
||||
|
||||
xli->rio.inp->last.c = xli->rio.inp->b.buf[xli->rio.inp->b.pos++];
|
||||
|
||||
lc = xli->rio.inp->b.buf[xli->rio.inp->b.pos++];
|
||||
if (lc == QSE_T('\n') || lc == QSE_T('\r'))
|
||||
{
|
||||
/* handle common newline conventions.
|
||||
* LF+CR
|
||||
* CR+LF
|
||||
* LF
|
||||
* CR
|
||||
* convert all above to a single LF.
|
||||
*/
|
||||
if (xli->rio.inp->b.pos >= xli->rio.inp->b.len)
|
||||
{
|
||||
n = xli->rio.impl (
|
||||
xli, QSE_XLI_IO_READ, xli->rio.inp,
|
||||
xli->rio.inp->b.buf, QSE_COUNTOF(xli->rio.inp->b.buf)
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
xli->rio.inp->b.state = -1;
|
||||
goto done;
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
xli->rio.inp->b.state = 1;
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
xli->rio.inp->b.pos = 0;
|
||||
xli->rio.inp->b.len = n;
|
||||
}
|
||||
}
|
||||
|
||||
ec = (lc == '\n')? '\r': '\n';
|
||||
if (xli->rio.inp->b.buf[xli->rio.inp->b.pos] == ec) xli->rio.inp->b.pos++;
|
||||
|
||||
done:
|
||||
lc = QSE_T('\n');
|
||||
}
|
||||
|
||||
xli->rio.inp->last.c = lc;
|
||||
xli->rio.inp->last.line = xli->rio.inp->line;
|
||||
xli->rio.inp->last.colm = xli->rio.inp->colm++;
|
||||
xli->rio.inp->last.file = xli->rio.inp->name;
|
||||
xli->rio.last = xli->rio.inp->last;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -248,7 +285,7 @@ static int classify_ident (qse_xli_t* xli, const qse_cstr_t* name)
|
||||
else return kwp->type;
|
||||
}
|
||||
|
||||
return TOK_IDENT;
|
||||
return QSE_XLI_TOK_IDENT;
|
||||
}
|
||||
|
||||
static int get_symbols (qse_xli_t* xli, qse_cint_t c, qse_xli_tok_t* tok)
|
||||
@ -262,11 +299,11 @@ static int get_symbols (qse_xli_t* xli, qse_cint_t c, qse_xli_tok_t* tok)
|
||||
|
||||
static struct ops_t ops[] =
|
||||
{
|
||||
{ QSE_T("="), 1, TOK_EQ },
|
||||
{ QSE_T(","), 1, TOK_COMMA },
|
||||
{ QSE_T(";"), 1, TOK_SEMICOLON },
|
||||
{ QSE_T("{"), 1, TOK_LBRACE },
|
||||
{ QSE_T("}"), 1, TOK_RBRACE },
|
||||
{ QSE_T("="), 1, QSE_XLI_TOK_EQ },
|
||||
{ QSE_T(","), 1, QSE_XLI_TOK_COMMA },
|
||||
{ QSE_T(";"), 1, QSE_XLI_TOK_SEMICOLON },
|
||||
{ QSE_T("{"), 1, QSE_XLI_TOK_LBRACE },
|
||||
{ QSE_T("}"), 1, QSE_XLI_TOK_RBRACE },
|
||||
{ QSE_NULL, 0, 0, }
|
||||
};
|
||||
|
||||
@ -434,7 +471,7 @@ retry:
|
||||
}
|
||||
|
||||
ADD_TOKEN_STR (xli, tok, QSE_T("<EOF>"), 5);
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_EOF);
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_EOF);
|
||||
}
|
||||
else if (c == QSE_T('@'))
|
||||
{
|
||||
@ -462,7 +499,7 @@ retry:
|
||||
while (QSE_ISALPHA (c));
|
||||
|
||||
type = classify_ident (xli, QSE_STR_XSTR(tok->name));
|
||||
if (type == TOK_IDENT)
|
||||
if (type == QSE_XLI_TOK_IDENT)
|
||||
{
|
||||
/* this keyword/directive is not recognized */
|
||||
qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_XSTR(tok->name), &tok->loc);
|
||||
@ -505,11 +542,11 @@ retry:
|
||||
return -1;
|
||||
}
|
||||
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_IDENT);
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_IDENT);
|
||||
}
|
||||
else if ((xli->tok_status & TOK_STATUS_ENABLE_NSTR) && QSE_ISDIGIT(c))
|
||||
{
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_NSTR);
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_NSTR);
|
||||
do
|
||||
{
|
||||
ADD_TOKEN_CHAR (xli, tok, c);
|
||||
@ -520,7 +557,7 @@ retry:
|
||||
else if (c == QSE_T('\''))
|
||||
{
|
||||
/* single-quoted string - no escaping */
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_SQSTR);
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_SQSTR);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -548,7 +585,7 @@ retry:
|
||||
/* double-quoted string - support escaping */
|
||||
int escaped = 0;
|
||||
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_DQSTR);
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_DQSTR);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -592,7 +629,7 @@ retry:
|
||||
* "tg" is stored into the tag field of qse_xli_str_t.
|
||||
*/
|
||||
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_TAG);
|
||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_TAG);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -630,7 +667,7 @@ retry:
|
||||
else
|
||||
{
|
||||
n = get_symbols (xli, c, tok);
|
||||
if (n <= -1) return -1;
|
||||
if (n <= -1) return -1; // hard failure
|
||||
if (n == 0)
|
||||
{
|
||||
/* not handled yet */
|
||||
@ -652,7 +689,7 @@ retry:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (skip_semicolon_after_include && tok->type == TOK_SEMICOLON)
|
||||
if (skip_semicolon_after_include && tok->type == QSE_XLI_TOK_SEMICOLON)
|
||||
{
|
||||
/* this handles the optional semicolon after the
|
||||
* included file named as in @include "file-name"; */
|
||||
@ -766,7 +803,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
if (key_alias)
|
||||
{
|
||||
/* the alias part must be unique for the same key(s) */
|
||||
if (MATCH (xli, TOK_IDENT) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_SQSTR) || MATCH(xli, TOK_NSTR))
|
||||
if (MATCH (xli, QSE_XLI_TOK_IDENT) || MATCH (xli, QSE_XLI_TOK_DQSTR) || MATCH (xli, QSE_XLI_TOK_SQSTR) || MATCH(xli, QSE_XLI_TOK_NSTR))
|
||||
{
|
||||
qse_xli_atom_t* atom;
|
||||
|
||||
@ -802,11 +839,11 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
}
|
||||
}
|
||||
|
||||
if (MATCH (xli, TOK_EQ))
|
||||
if (MATCH (xli, QSE_XLI_TOK_EQ))
|
||||
{
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
|
||||
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, TOK_TAG))
|
||||
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, QSE_XLI_TOK_TAG))
|
||||
{
|
||||
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
||||
if (strtag == QSE_NULL)
|
||||
@ -818,7 +855,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
}
|
||||
|
||||
if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH(xli, TOK_NSTR) || MATCH (xli, TOK_IDENT))
|
||||
if (MATCH (xli, QSE_XLI_TOK_SQSTR) || MATCH (xli, QSE_XLI_TOK_DQSTR) || MATCH(xli, QSE_XLI_TOK_NSTR) || MATCH (xli, QSE_XLI_TOK_IDENT))
|
||||
{
|
||||
qse_xli_str_t* curstrseg;
|
||||
qse_size_t segcount = 0;
|
||||
@ -838,7 +875,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
curstrseg = (qse_xli_str_t*)pair->val;
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
if ((xli->opt.trait & QSE_XLI_MULSEGSTR) && MATCH(xli, TOK_COMMA))
|
||||
if ((xli->opt.trait & QSE_XLI_MULSEGSTR) && MATCH(xli, QSE_XLI_TOK_COMMA))
|
||||
{
|
||||
/* multi-segmented string */
|
||||
do
|
||||
@ -851,7 +888,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
strtag = QSE_NULL;
|
||||
}
|
||||
|
||||
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, TOK_TAG))
|
||||
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, QSE_XLI_TOK_TAG))
|
||||
{
|
||||
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
||||
if (strtag == QSE_NULL)
|
||||
@ -863,7 +900,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
}
|
||||
|
||||
if (!MATCH (xli, TOK_SQSTR) && !MATCH (xli, TOK_DQSTR) && !MATCH (xli, TOK_NSTR) && !MATCH (xli, TOK_IDENT))
|
||||
if (!MATCH (xli, QSE_XLI_TOK_SQSTR) && !MATCH (xli, QSE_XLI_TOK_DQSTR) && !MATCH (xli, QSE_XLI_TOK_NSTR) && !MATCH (xli, QSE_XLI_TOK_IDENT))
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||
goto oops;
|
||||
@ -876,11 +913,11 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
segcount++;
|
||||
if (get_token (xli) <= -1) goto oops; /* skip the value */
|
||||
}
|
||||
while (MATCH (xli, TOK_COMMA));
|
||||
while (MATCH (xli, QSE_XLI_TOK_COMMA));
|
||||
}
|
||||
|
||||
/* semicolon is mandatory for a string */
|
||||
if (!MATCH (xli, TOK_SEMICOLON))
|
||||
if (!MATCH (xli, QSE_XLI_TOK_SEMICOLON))
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_ESCOLON, QSE_STR_XSTR(xli->tok.name), &xli->tok.loc);
|
||||
goto oops;
|
||||
@ -907,7 +944,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
/* TODO: check against schema */
|
||||
|
||||
}
|
||||
else if (!(xli->opt.trait & QSE_XLI_NOLIST) && MATCH (xli, TOK_LBRACE))
|
||||
else if (!(xli->opt.trait & QSE_XLI_NOLIST) && MATCH (xli, QSE_XLI_TOK_LBRACE))
|
||||
{
|
||||
if (scm && !(scm->flags & QSE_XLI_SCM_VALLIST))
|
||||
{
|
||||
@ -928,7 +965,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
* take effect. */
|
||||
if (read_list (xli, (qse_xli_list_t*)pair->val, (val_iffy? &scm_val_iffy: QSE_NULL)) <= -1) goto oops;
|
||||
|
||||
if (!MATCH (xli, TOK_RBRACE))
|
||||
if (!MATCH (xli, QSE_XLI_TOK_RBRACE))
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_ERBRCE, QSE_STR_XSTR(xli->tok.name), &xli->tok.loc);
|
||||
goto oops;
|
||||
@ -937,7 +974,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
|
||||
/* semicolon is optional for a list */
|
||||
if (MATCH (xli, TOK_SEMICOLON))
|
||||
if (MATCH (xli, QSE_XLI_TOK_SEMICOLON))
|
||||
{
|
||||
/* skip the semicolon */
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
@ -945,7 +982,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
||||
|
||||
/* TODO: check against schema */
|
||||
}
|
||||
else if (MATCH (xli, TOK_SEMICOLON))
|
||||
else if (MATCH (xli, QSE_XLI_TOK_SEMICOLON))
|
||||
{
|
||||
if (xli->opt.trait & QSE_XLI_NONIL)
|
||||
{
|
||||
@ -1018,11 +1055,11 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (MATCH (xli, TOK_XINCLUDE))
|
||||
if (MATCH (xli, QSE_XLI_TOK_XINCLUDE))
|
||||
{
|
||||
if (get_token(xli) <= -1) return -1;
|
||||
|
||||
if (!MATCH(xli,TOK_SQSTR) && !MATCH(xli,TOK_DQSTR))
|
||||
if (!MATCH(xli,QSE_XLI_TOK_SQSTR) && !MATCH(xli,QSE_XLI_TOK_DQSTR))
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_EINCLSTR, QSE_NULL, &xli->tok.loc);
|
||||
return -1;
|
||||
@ -1030,7 +1067,7 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
||||
|
||||
if (begin_include (xli) <= -1) return -1;
|
||||
}
|
||||
else if ((xli->opt.trait & QSE_XLI_KEYTAG) && MATCH (xli, TOK_TAG))
|
||||
else if ((xli->opt.trait & QSE_XLI_KEYTAG) && MATCH (xli, QSE_XLI_TOK_TAG))
|
||||
{
|
||||
qse_char_t* keytag;
|
||||
int x;
|
||||
@ -1048,7 +1085,7 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!MATCH(xli,TOK_IDENT))
|
||||
if (!MATCH(xli,QSE_XLI_TOK_IDENT))
|
||||
{
|
||||
QSE_MMGR_FREE (xli->mmgr, keytag);
|
||||
qse_xli_seterror (xli, QSE_XLI_ENOKEY, QSE_NULL, &xli->tok.loc);
|
||||
@ -1059,11 +1096,11 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
||||
QSE_MMGR_FREE (xli->mmgr, keytag);
|
||||
if (x <= -1) return -1;
|
||||
}
|
||||
else if (MATCH (xli, TOK_IDENT))
|
||||
else if (MATCH (xli, QSE_XLI_TOK_IDENT))
|
||||
{
|
||||
if (read_pair (xli, QSE_NULL, override) <= -1) return -1;
|
||||
}
|
||||
else if (MATCH (xli, TOK_TEXT))
|
||||
else if (MATCH (xli, QSE_XLI_TOK_TEXT))
|
||||
{
|
||||
if (get_token(xli) <= -1) return -1;
|
||||
}
|
||||
@ -1142,6 +1179,8 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
xli->rio.top.colm = 1;
|
||||
xli->rio.inp = &xli->rio.top;
|
||||
|
||||
xli->tok_status = 0;
|
||||
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL);
|
||||
qse_xli_clearrionames (xli);
|
||||
|
||||
@ -1154,7 +1193,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
|
||||
QSE_ASSERT (xli->parlink == QSE_NULL);
|
||||
|
||||
if (!MATCH (xli, TOK_EOF))
|
||||
if (!MATCH (xli, QSE_XLI_TOK_EOF))
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||
goto oops;
|
||||
|
@ -32,13 +32,32 @@
|
||||
#include <qse/cmn/rbt.h>
|
||||
#include "../cmn/mem.h"
|
||||
|
||||
enum qse_xli_tok_type_t
|
||||
{
|
||||
QSE_XLI_TOK_EOF,
|
||||
QSE_XLI_TOK_XINCLUDE,
|
||||
QSE_XLI_TOK_SEMICOLON,
|
||||
QSE_XLI_TOK_LBRACE,
|
||||
QSE_XLI_TOK_RBRACE,
|
||||
QSE_XLI_TOK_EQ,
|
||||
QSE_XLI_TOK_COMMA,
|
||||
QSE_XLI_TOK_DQSTR,
|
||||
QSE_XLI_TOK_SQSTR,
|
||||
QSE_XLI_TOK_NSTR,
|
||||
QSE_XLI_TOK_IDENT,
|
||||
QSE_XLI_TOK_TEXT,
|
||||
QSE_XLI_TOK_TAG
|
||||
};
|
||||
|
||||
typedef enum qse_xli_tok_type_t qse_xli_tok_type_t;
|
||||
|
||||
typedef struct qse_xli_tok_t qse_xli_tok_t;
|
||||
|
||||
struct qse_xli_tok_t
|
||||
{
|
||||
int type;
|
||||
qse_str_t* name;
|
||||
qse_xli_loc_t loc;
|
||||
qse_xli_tok_type_t type;
|
||||
qse_str_t* name;
|
||||
qse_xli_loc_t loc;
|
||||
};
|
||||
|
||||
typedef struct qse_xli_list_link_t qse_xli_list_link_t;
|
||||
@ -88,7 +107,7 @@ struct qse_xli_t
|
||||
struct
|
||||
{
|
||||
qse_xli_io_impl_t impl; /* input handler */
|
||||
qse_xli_io_lxc_t last;
|
||||
qse_xli_io_lxc_t last;
|
||||
qse_xli_io_arg_t top; /* for top level */
|
||||
qse_xli_io_arg_t* inp; /* current */
|
||||
} rio;
|
||||
|
Loading…
Reference in New Issue
Block a user