diff --git a/qse/include/qse/xli/xli.h b/qse/include/qse/xli/xli.h index 7b8b36f7..9901364e 100644 --- a/qse/include/qse/xli/xli.h +++ b/qse/include/qse/xli/xli.h @@ -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; diff --git a/qse/lib/xli/read-ini.c b/qse/lib/xli/read-ini.c index f29da070..3941141b 100644 --- a/qse/lib/xli/read-ini.c +++ b/qse/lib/xli/read-ini.c @@ -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(""), 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(""), 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(""); + 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); diff --git a/qse/lib/xli/read.c b/qse/lib/xli/read.c index e8b36af5..3c15dce9 100644 --- a/qse/lib/xli/read.c +++ b/qse/lib/xli/read.c @@ -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(""), 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; diff --git a/qse/lib/xli/xli.h b/qse/lib/xli/xli.h index 1cd03983..1f9a7ad3 100644 --- a/qse/lib/xli/xli.h +++ b/qse/lib/xli/xli.h @@ -32,13 +32,32 @@ #include #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;