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_char_t buf[1024];
|
||||||
qse_size_t pos;
|
qse_size_t pos;
|
||||||
qse_size_t len;
|
qse_size_t len;
|
||||||
|
int state;
|
||||||
} b;
|
} b;
|
||||||
|
|
||||||
qse_size_t line;
|
qse_size_t line;
|
||||||
|
@ -35,15 +35,20 @@
|
|||||||
* key1 = value1
|
* key1 = value1
|
||||||
* --------------------------------
|
* --------------------------------
|
||||||
*
|
*
|
||||||
* SECTION1 = {
|
* SECTION1 {
|
||||||
* key1 = value1;
|
* key1 = value1;
|
||||||
* key2 = value2;
|
* key2 = value2;
|
||||||
* }
|
* }
|
||||||
* SECTION2 = {
|
* SECTION2 {
|
||||||
* key1 = value1;
|
* key1 = value1;
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TOK_STATUS_UPTO_EOL = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
#define GET_CHAR(xli) \
|
#define GET_CHAR(xli) \
|
||||||
do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0)
|
do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0)
|
||||||
|
|
||||||
@ -71,6 +76,10 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} 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)
|
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;
|
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 */
|
GET_CHAR (xli); /* eat the new line letter */
|
||||||
return 1; /* comment by # */
|
return 1; /* comment by ; */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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 (c == QSE_CHAR_EOF)
|
||||||
{
|
{
|
||||||
#if 0
|
ADD_TOKEN_STR (xli, tok, QSE_T("<EOF>"), 5);
|
||||||
n = end_include (xli, 0);
|
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_EOF);
|
||||||
if (n <= -1) return -1;
|
}
|
||||||
if (n >= 1)
|
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;*/
|
GET_CHAR_TO (xli, c);
|
||||||
/* mark that i'm retrying after end of an included file */
|
if (c == QSE_CHAR_EOF || c == QSE_T(';')) break;
|
||||||
skip_semicolon_after_include = 1;
|
|
||||||
goto retry;
|
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);
|
/* trim away trailing spaces */
|
||||||
SET_TOKEN_TYPE (xli, tok, TOK_EOF);
|
qse_str_setlen (tok->name, xlen);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
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)
|
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.top.colm = 1;
|
||||||
xli->rio.inp = &xli->rio.top;
|
xli->rio.inp = &xli->rio.top;
|
||||||
|
|
||||||
|
xli->tok_status = 0;
|
||||||
|
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL);
|
||||||
qse_xli_clearrionames (xli);
|
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);
|
QSE_ASSERT (xli->parlink == QSE_NULL);
|
||||||
|
|
||||||
/*
|
if (!MATCH (xli, QSE_XLI_TOK_EOF))
|
||||||
if (!MATCH (xli, TOK_EOF))
|
|
||||||
{
|
{
|
||||||
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
QSE_ASSERT (xli->rio.inp == &xli->rio.top);
|
QSE_ASSERT (xli->rio.inp == &xli->rio.top);
|
||||||
qse_xli_closecurrentstream (xli);
|
qse_xli_closecurrentstream (xli);
|
||||||
|
@ -67,24 +67,7 @@ int qse_xli_closecurrentstream (qse_xli_t* xli)
|
|||||||
return 0;
|
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) \
|
#define GET_CHAR(xli) \
|
||||||
do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0)
|
do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0)
|
||||||
@ -130,12 +113,24 @@ struct kwent_t
|
|||||||
static kwent_t kwtab[] =
|
static kwent_t kwtab[] =
|
||||||
{
|
{
|
||||||
/* keep it sorted by the first field for binary search */
|
/* 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)
|
int qse_xli_getchar (qse_xli_t* xli)
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
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)
|
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)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
|
return_eof:
|
||||||
xli->rio.inp->last.c = QSE_CHAR_EOF;
|
xli->rio.inp->last.c = QSE_CHAR_EOF;
|
||||||
xli->rio.inp->last.line = xli->rio.inp->line;
|
xli->rio.inp->last.line = xli->rio.inp->line;
|
||||||
xli->rio.inp->last.colm = xli->rio.inp->colm;
|
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.
|
* increment the line counter and reset column to 1.
|
||||||
* incrementing it line number here instead of
|
* incrementing it line number here instead of
|
||||||
* updating inp->last causes the line number for
|
* 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->line++;
|
||||||
xli->rio.inp->colm = 1;
|
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.line = xli->rio.inp->line;
|
||||||
xli->rio.inp->last.colm = xli->rio.inp->colm++;
|
xli->rio.inp->last.colm = xli->rio.inp->colm++;
|
||||||
xli->rio.inp->last.file = xli->rio.inp->name;
|
xli->rio.inp->last.file = xli->rio.inp->name;
|
||||||
xli->rio.last = xli->rio.inp->last;
|
xli->rio.last = xli->rio.inp->last;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +285,7 @@ static int classify_ident (qse_xli_t* xli, const qse_cstr_t* name)
|
|||||||
else return kwp->type;
|
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)
|
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[] =
|
static struct ops_t ops[] =
|
||||||
{
|
{
|
||||||
{ QSE_T("="), 1, TOK_EQ },
|
{ QSE_T("="), 1, QSE_XLI_TOK_EQ },
|
||||||
{ QSE_T(","), 1, TOK_COMMA },
|
{ QSE_T(","), 1, QSE_XLI_TOK_COMMA },
|
||||||
{ QSE_T(";"), 1, TOK_SEMICOLON },
|
{ QSE_T(";"), 1, QSE_XLI_TOK_SEMICOLON },
|
||||||
{ QSE_T("{"), 1, TOK_LBRACE },
|
{ QSE_T("{"), 1, QSE_XLI_TOK_LBRACE },
|
||||||
{ QSE_T("}"), 1, TOK_RBRACE },
|
{ QSE_T("}"), 1, QSE_XLI_TOK_RBRACE },
|
||||||
{ QSE_NULL, 0, 0, }
|
{ QSE_NULL, 0, 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -434,7 +471,7 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ADD_TOKEN_STR (xli, tok, QSE_T("<EOF>"), 5);
|
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('@'))
|
else if (c == QSE_T('@'))
|
||||||
{
|
{
|
||||||
@ -462,7 +499,7 @@ retry:
|
|||||||
while (QSE_ISALPHA (c));
|
while (QSE_ISALPHA (c));
|
||||||
|
|
||||||
type = classify_ident (xli, QSE_STR_XSTR(tok->name));
|
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 */
|
/* this keyword/directive is not recognized */
|
||||||
qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_XSTR(tok->name), &tok->loc);
|
qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_XSTR(tok->name), &tok->loc);
|
||||||
@ -505,11 +542,11 @@ retry:
|
|||||||
return -1;
|
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))
|
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
|
do
|
||||||
{
|
{
|
||||||
ADD_TOKEN_CHAR (xli, tok, c);
|
ADD_TOKEN_CHAR (xli, tok, c);
|
||||||
@ -520,7 +557,7 @@ retry:
|
|||||||
else if (c == QSE_T('\''))
|
else if (c == QSE_T('\''))
|
||||||
{
|
{
|
||||||
/* single-quoted string - no escaping */
|
/* single-quoted string - no escaping */
|
||||||
SET_TOKEN_TYPE (xli, tok, TOK_SQSTR);
|
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_SQSTR);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -548,7 +585,7 @@ retry:
|
|||||||
/* double-quoted string - support escaping */
|
/* double-quoted string - support escaping */
|
||||||
int escaped = 0;
|
int escaped = 0;
|
||||||
|
|
||||||
SET_TOKEN_TYPE (xli, tok, TOK_DQSTR);
|
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_DQSTR);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -592,7 +629,7 @@ retry:
|
|||||||
* "tg" is stored into the tag field of qse_xli_str_t.
|
* "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)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -630,7 +667,7 @@ retry:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
n = get_symbols (xli, c, tok);
|
n = get_symbols (xli, c, tok);
|
||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1; // hard failure
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* not handled yet */
|
/* not handled yet */
|
||||||
@ -652,7 +689,7 @@ retry:
|
|||||||
return -1;
|
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
|
/* this handles the optional semicolon after the
|
||||||
* included file named as in @include "file-name"; */
|
* 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)
|
if (key_alias)
|
||||||
{
|
{
|
||||||
/* the alias part must be unique for the same key(s) */
|
/* 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;
|
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 (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);
|
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
||||||
if (strtag == QSE_NULL)
|
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 (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_xli_str_t* curstrseg;
|
||||||
qse_size_t segcount = 0;
|
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;
|
curstrseg = (qse_xli_str_t*)pair->val;
|
||||||
|
|
||||||
if (get_token (xli) <= -1) goto oops;
|
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 */
|
/* multi-segmented string */
|
||||||
do
|
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;
|
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);
|
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
||||||
if (strtag == QSE_NULL)
|
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 (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);
|
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||||
goto oops;
|
goto oops;
|
||||||
@ -876,11 +913,11 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
segcount++;
|
segcount++;
|
||||||
if (get_token (xli) <= -1) goto oops; /* skip the value */
|
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 */
|
/* 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);
|
qse_xli_seterror (xli, QSE_XLI_ESCOLON, QSE_STR_XSTR(xli->tok.name), &xli->tok.loc);
|
||||||
goto oops;
|
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 */
|
/* 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))
|
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. */
|
* take effect. */
|
||||||
if (read_list (xli, (qse_xli_list_t*)pair->val, (val_iffy? &scm_val_iffy: QSE_NULL)) <= -1) goto oops;
|
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);
|
qse_xli_seterror (xli, QSE_XLI_ERBRCE, QSE_STR_XSTR(xli->tok.name), &xli->tok.loc);
|
||||||
goto oops;
|
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;
|
if (get_token (xli) <= -1) goto oops;
|
||||||
|
|
||||||
/* semicolon is optional for a list */
|
/* semicolon is optional for a list */
|
||||||
if (MATCH (xli, TOK_SEMICOLON))
|
if (MATCH (xli, QSE_XLI_TOK_SEMICOLON))
|
||||||
{
|
{
|
||||||
/* skip the semicolon */
|
/* skip the semicolon */
|
||||||
if (get_token (xli) <= -1) goto oops;
|
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 */
|
/* 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)
|
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)
|
while (1)
|
||||||
{
|
{
|
||||||
if (MATCH (xli, TOK_XINCLUDE))
|
if (MATCH (xli, QSE_XLI_TOK_XINCLUDE))
|
||||||
{
|
{
|
||||||
if (get_token(xli) <= -1) return -1;
|
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);
|
qse_xli_seterror (xli, QSE_XLI_EINCLSTR, QSE_NULL, &xli->tok.loc);
|
||||||
return -1;
|
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;
|
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;
|
qse_char_t* keytag;
|
||||||
int x;
|
int x;
|
||||||
@ -1048,7 +1085,7 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MATCH(xli,TOK_IDENT))
|
if (!MATCH(xli,QSE_XLI_TOK_IDENT))
|
||||||
{
|
{
|
||||||
QSE_MMGR_FREE (xli->mmgr, keytag);
|
QSE_MMGR_FREE (xli->mmgr, keytag);
|
||||||
qse_xli_seterror (xli, QSE_XLI_ENOKEY, QSE_NULL, &xli->tok.loc);
|
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);
|
QSE_MMGR_FREE (xli->mmgr, keytag);
|
||||||
if (x <= -1) return -1;
|
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;
|
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;
|
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.top.colm = 1;
|
||||||
xli->rio.inp = &xli->rio.top;
|
xli->rio.inp = &xli->rio.top;
|
||||||
|
|
||||||
|
xli->tok_status = 0;
|
||||||
|
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL);
|
||||||
qse_xli_clearrionames (xli);
|
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);
|
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);
|
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||||
goto oops;
|
goto oops;
|
||||||
|
@ -32,13 +32,32 @@
|
|||||||
#include <qse/cmn/rbt.h>
|
#include <qse/cmn/rbt.h>
|
||||||
#include "../cmn/mem.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;
|
typedef struct qse_xli_tok_t qse_xli_tok_t;
|
||||||
|
|
||||||
struct qse_xli_tok_t
|
struct qse_xli_tok_t
|
||||||
{
|
{
|
||||||
int type;
|
qse_xli_tok_type_t type;
|
||||||
qse_str_t* name;
|
qse_str_t* name;
|
||||||
qse_xli_loc_t loc;
|
qse_xli_loc_t loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct qse_xli_list_link_t qse_xli_list_link_t;
|
typedef struct qse_xli_list_link_t qse_xli_list_link_t;
|
||||||
@ -88,7 +107,7 @@ struct qse_xli_t
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_xli_io_impl_t impl; /* input handler */
|
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 top; /* for top level */
|
||||||
qse_xli_io_arg_t* inp; /* current */
|
qse_xli_io_arg_t* inp; /* current */
|
||||||
} rio;
|
} rio;
|
||||||
|
Loading…
Reference in New Issue
Block a user