revising httpd
This commit is contained in:
@ -39,10 +39,16 @@ const qse_char_t* qse_xli_dflerrstr (
|
||||
QSE_T("I/O error with file '${0}'"),
|
||||
QSE_T("error returned by user I/O handler"),
|
||||
|
||||
QSE_T("syntax error"),
|
||||
QSE_T("semicolon expected in place of '${0}'"),
|
||||
QSE_T("left-brace or equal-sign expected in place of '${0}'"),
|
||||
QSE_T("right-brace expected in place of '${0}'"),
|
||||
QSE_T("pair value expected in place of '${0}'")
|
||||
QSE_T("pair value expected in place of '${0}'"),
|
||||
QSE_T("string not closed"),
|
||||
QSE_T("'@include' not followed by a string"),
|
||||
QSE_T("invalid character '${0}'"),
|
||||
QSE_T("'${0}' not recognized"),
|
||||
QSE_T("@ not followed by a valid word")
|
||||
};
|
||||
|
||||
return (errnum >= 0 && errnum < QSE_COUNTOF(errstr))?
|
||||
|
@ -48,6 +48,7 @@ enum tok_t
|
||||
TOK_LBRACE,
|
||||
TOK_RBRACE,
|
||||
TOK_EQ,
|
||||
TOK_COMMA,
|
||||
TOK_DQSTR,
|
||||
TOK_SQSTR,
|
||||
TOK_IDENT,
|
||||
@ -221,6 +222,7 @@ 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 },
|
||||
@ -310,9 +312,7 @@ static int begin_include (qse_xli_t* xli)
|
||||
);
|
||||
if (pair == QSE_NULL)
|
||||
{
|
||||
#if 0
|
||||
SETERR_LOC (xli, QSE_XLI_ENOMEM, &xli->ptok.loc);
|
||||
#endif
|
||||
qse_xli_seterror (xli, QSE_XLI_ENOMEM, QSE_NULL, &xli->tok.loc);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
@ -320,13 +320,7 @@ static int begin_include (qse_xli_t* xli)
|
||||
QSE_HTB_VLEN(pair) = QSE_HTB_KLEN(pair);*/
|
||||
|
||||
arg = (qse_xli_io_arg_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*arg));
|
||||
if (arg == QSE_NULL)
|
||||
{
|
||||
#if 0
|
||||
ADJERR_LOC (xli, &xli->ptok.loc);
|
||||
#endif
|
||||
goto oops;
|
||||
}
|
||||
if (arg == QSE_NULL) goto oops;
|
||||
|
||||
arg->flags = QSE_XLI_IO_INCLUDED;
|
||||
arg->name = QSE_HTB_KPTR(pair);
|
||||
@ -411,9 +405,7 @@ retry:
|
||||
{
|
||||
/* this directive is empty,
|
||||
* not followed by a valid word */
|
||||
#if 0
|
||||
SETERR_LOC (xli, QSE_XLI_EXKWEM, &(xli)->tok.loc);
|
||||
#endif
|
||||
qse_xli_seterror (xli, QSE_XLI_EXKWEM, QSE_NULL, &xli->tok.loc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -429,9 +421,7 @@ retry:
|
||||
if (type == TOK_IDENT)
|
||||
{
|
||||
/* this directive is not recognized */
|
||||
#if 0
|
||||
SETERR_TOK (xli, QSE_XLI_EXKWNR);
|
||||
#endif
|
||||
qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc);
|
||||
return -1;
|
||||
}
|
||||
SET_TOKEN_TYPE (xli, tok, type);
|
||||
@ -465,9 +455,7 @@ retry:
|
||||
if (c == QSE_CHAR_EOF)
|
||||
{
|
||||
/* the string is not closed */
|
||||
#if 0
|
||||
SETERR_TOK (xli, QSE_XLI_ESTRNC);
|
||||
#endif
|
||||
qse_xli_seterror (xli, QSE_XLI_ESTRNC, QSE_NULL, &xli->tok.loc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -490,18 +478,18 @@ retry:
|
||||
/* not handled yet */
|
||||
if (c == QSE_T('\0'))
|
||||
{
|
||||
#if 0
|
||||
SETERR_ARG_LOC (
|
||||
xli, QSE_XLI_ELXCHR,
|
||||
QSE_T("<NUL>"), 5, &tok->loc);
|
||||
#endif
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = QSE_T("<NUL>");
|
||||
ea.len = 5;
|
||||
qse_xli_seterror (xli, QSE_XLI_ELXCHR, &ea, &tok->loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
qse_char_t cc = (qse_char_t)c;
|
||||
SETERR_ARG_LOC (xli, QSE_XLI_ELXCHR, &cc, 1, &tok->loc);
|
||||
#endif
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = &cc;
|
||||
ea.len = 1;
|
||||
qse_xli_seterror (xli, QSE_XLI_ELXCHR, &ea, &tok->loc);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -518,9 +506,7 @@ retry:
|
||||
if (skip_semicolon_after_include)
|
||||
{
|
||||
/* semiclon has not been skipped yet */
|
||||
#if 0
|
||||
qse_xli_seterror (xli, QSE_XLI_ESCOLON, QSE_STR_CSTR(tok->name), &tok->loc);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -538,7 +524,7 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
qse_char_t* name = QSE_NULL;
|
||||
qse_xli_pair_t* pair;
|
||||
|
||||
if (xli->opt.trait & QSE_XLI_NODUPKEY)
|
||||
if (xli->opt.trait & QSE_XLI_KEYNODUP)
|
||||
{
|
||||
qse_xli_atom_t* atom;
|
||||
|
||||
@ -566,10 +552,10 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
|
||||
if (xli->opt.trait & QSE_XLI_NAMEDKEY)
|
||||
if (xli->opt.trait & QSE_XLI_KEYNAME)
|
||||
{
|
||||
/* the name part must be unique for the same key(s) */
|
||||
if (MATCH (xli, TOK_SQSTR) || MATCH(xli, TOK_DQSTR))
|
||||
if (MATCH (xli, TOK_IDENT) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_SQSTR))
|
||||
{
|
||||
qse_xli_atom_t* atom;
|
||||
|
||||
@ -602,14 +588,42 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
{
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
|
||||
if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR))
|
||||
if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_IDENT))
|
||||
{
|
||||
pair = qse_xli_insertpairwithstr (
|
||||
xli, list, QSE_NULL, key, name,
|
||||
QSE_STR_PTR(xli->tok.name), MATCH (xli, TOK_SQSTR));
|
||||
if (pair == QSE_NULL) goto oops;
|
||||
if (qse_str_ncpy (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1)
|
||||
{
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
if (MATCH(xli, TOK_COMMA))
|
||||
{
|
||||
/* multi-segmented string */
|
||||
do
|
||||
{
|
||||
if (get_token (xli) <= -1) goto oops; /* skip the comma */
|
||||
|
||||
if (!MATCH (xli, TOK_SQSTR) && !MATCH (xli, TOK_DQSTR) && !MATCH (xli, TOK_IDENT))
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (qse_str_ncat (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1)
|
||||
{
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (get_token (xli) <= -1) goto oops; /* skip the value */
|
||||
}
|
||||
while (MATCH (xli, TOK_COMMA));
|
||||
}
|
||||
|
||||
pair = qse_xli_insertpairwithstr (
|
||||
xli, list, QSE_NULL, key, name, QSE_STR_CSTR(xli->tmp[0]));
|
||||
if (pair == QSE_NULL) goto oops;
|
||||
|
||||
/* semicolon is mandatory for a string */
|
||||
if (!MATCH (xli, TOK_SEMICOLON))
|
||||
@ -651,6 +665,15 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
}
|
||||
}
|
||||
else if (MATCH (xli, TOK_SEMICOLON))
|
||||
{
|
||||
/* no value has been specified for the pair */
|
||||
pair = qse_xli_insertpair (xli, list, QSE_NULL, key, name, &xli->xnil);
|
||||
if (pair == QSE_NULL) goto oops;
|
||||
|
||||
/* skip the semicolon */
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_xli_seterror (xli, QSE_XLI_ELBREQ, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc);
|
||||
@ -677,9 +700,7 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
|
||||
if (!MATCH(xli,TOK_SQSTR) && !MATCH(xli,TOK_DQSTR))
|
||||
{
|
||||
#if 0
|
||||
SETERR_LOC (xli, QSE_XLI_EINCLSTR, &xli->ptok.loc);
|
||||
#endif
|
||||
qse_xli_seterror (xli, QSE_XLI_EINCLSTR, QSE_NULL, &xli->tok.loc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -693,7 +714,10 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
{
|
||||
if (get_token(xli) <= -1) goto oops;
|
||||
}
|
||||
else break;
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -733,8 +757,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
|
||||
if (!MATCH (xli, TOK_EOF))
|
||||
{
|
||||
/* TODO: set erro code */
|
||||
qse_printf (QSE_T("NOT ENDING WITH EOF... %s\n"), QSE_STR_PTR(xli->tok.name));
|
||||
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
|
@ -24,12 +24,12 @@ int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
{
|
||||
if (io == QSE_NULL)
|
||||
{
|
||||
xli->errnum = QSE_XLI_EINVAL;
|
||||
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: write data to io stream */
|
||||
xli->errnum = QSE_XLI_ENOIMPL;
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOIMPL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "xli.h"
|
||||
#include <qse/cmn/chr.h>
|
||||
|
||||
qse_xli_t* qse_xli_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
||||
{
|
||||
@ -51,10 +52,18 @@ void qse_xli_close (qse_xli_t* xli)
|
||||
|
||||
int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr)
|
||||
{
|
||||
qse_size_t i;
|
||||
|
||||
QSE_MEMSET (xli, 0, QSE_SIZEOF(*xli));
|
||||
xli->mmgr = mmgr;
|
||||
xli->errstr = qse_xli_dflerrstr;
|
||||
|
||||
for (i = 0; i < QSE_COUNTOF(xli->tmp); i++)
|
||||
{
|
||||
xli->tmp[i] = qse_str_open (mmgr, 0, 128);
|
||||
if (xli->tmp[i] == QSE_NULL) goto oops;
|
||||
}
|
||||
|
||||
xli->tok.name = qse_str_open (mmgr, 0, 128);
|
||||
if (xli->tok.name == QSE_NULL) goto oops;
|
||||
|
||||
@ -67,20 +76,34 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr)
|
||||
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
|
||||
);
|
||||
|
||||
xli->root.type = QSE_XLI_LIST;
|
||||
xli->xnil.type = QSE_XLI_NIL;
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
||||
if (xli->sio_names) qse_htb_close (xli->sio_names);
|
||||
if (xli->tok.name) qse_str_close (xli->tok.name);
|
||||
|
||||
for (i = QSE_COUNTOF(xli->tmp); i > 0; )
|
||||
{
|
||||
if (xli->tmp[--i]) qse_str_close (xli->tmp[i]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void qse_xli_fini (qse_xli_t* xli)
|
||||
{
|
||||
qse_size_t i;
|
||||
|
||||
qse_xli_clear (xli);
|
||||
qse_htb_close (xli->sio_names);
|
||||
qse_str_close (xli->tok.name);
|
||||
|
||||
for (i = QSE_COUNTOF(xli->tmp); i > 0; )
|
||||
{
|
||||
if (xli->tmp[--i]) qse_str_close (xli->tmp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
qse_mmgr_t* qse_xli_getmmgr (qse_xli_t* xli)
|
||||
@ -243,20 +266,20 @@ qse_xli_pair_t* qse_xli_insertpairwithemptylist (
|
||||
|
||||
qse_xli_pair_t* qse_xli_insertpairwithstr (
|
||||
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
|
||||
const qse_char_t* key, const qse_char_t* name, const qse_char_t* value, int verbatim)
|
||||
const qse_char_t* key, const qse_char_t* name, const qse_cstr_t* value)
|
||||
{
|
||||
qse_xli_str_t* val;
|
||||
qse_xli_pair_t* tmp;
|
||||
qse_size_t vlen;
|
||||
|
||||
vlen = qse_strlen (value);
|
||||
val = qse_xli_callocmem (xli, QSE_SIZEOF(*val) + ((vlen + 1) * QSE_SIZEOF(*value)));
|
||||
val = qse_xli_callocmem (xli, QSE_SIZEOF(*val) + ((value->len + 1) * QSE_SIZEOF(*value->ptr)));
|
||||
if (val == QSE_NULL) return QSE_NULL;
|
||||
|
||||
val->type = QSE_XLI_STR;
|
||||
|
||||
qse_strncpy ((qse_char_t*)(val + 1), value->ptr, value->len);
|
||||
val->ptr = (const qse_char_t*)(val + 1);
|
||||
val->len = vlen;
|
||||
val->verbatim = verbatim;
|
||||
val->len = value->len;
|
||||
|
||||
tmp = qse_xli_insertpair (xli, parent, peer, key, name, (qse_xli_val_t*)val);
|
||||
if (tmp == QSE_NULL) qse_xli_freemem (xli, val);
|
||||
return tmp;
|
||||
@ -275,7 +298,6 @@ qse_xli_text_t* qse_xli_inserttext (
|
||||
|
||||
text->type = QSE_XLI_TEXT;
|
||||
text->ptr = (const qse_char_t*)(text + 1);
|
||||
text->len = slen;
|
||||
|
||||
insert_atom (xli, parent, peer, (qse_xli_atom_t*)text);
|
||||
|
||||
@ -292,10 +314,13 @@ static void free_atom (qse_xli_t* xli, qse_xli_atom_t* atom)
|
||||
{
|
||||
qse_xli_pair_t* pair = (qse_xli_pair_t*)atom;
|
||||
|
||||
if (pair->val->type == QSE_XLI_LIST)
|
||||
free_list (xli, (qse_xli_list_t*)pair->val);
|
||||
if (pair->val != &xli->xnil)
|
||||
{
|
||||
if (pair->val->type == QSE_XLI_LIST)
|
||||
free_list (xli, (qse_xli_list_t*)pair->val);
|
||||
|
||||
QSE_MMGR_FREE (xli->mmgr, pair->val);
|
||||
QSE_MMGR_FREE (xli->mmgr, pair->val);
|
||||
}
|
||||
}
|
||||
|
||||
QSE_MMGR_FREE (xli->mmgr, atom);
|
||||
@ -319,6 +344,186 @@ static void free_list (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
|
||||
void qse_xli_clear (qse_xli_t* xli)
|
||||
{
|
||||
/* TODO: free data under xli->root */
|
||||
free_list (xli, &xli->root);
|
||||
}
|
||||
|
||||
static qse_xli_pair_t* find_pair_byname (
|
||||
qse_xli_t* xli, const qse_xli_list_t* list,
|
||||
const qse_cstr_t* key, const qse_cstr_t* name)
|
||||
{
|
||||
qse_xli_atom_t* p;
|
||||
|
||||
/* TODO: speed up. no linear search */
|
||||
p = list->head;
|
||||
while (p)
|
||||
{
|
||||
if (p->type == QSE_XLI_PAIR)
|
||||
{
|
||||
qse_xli_pair_t* pair = (qse_xli_pair_t*)p;
|
||||
if (qse_strxcmp (key->ptr, key->len, pair->key) == 0)
|
||||
{
|
||||
if (name == QSE_NULL ||
|
||||
qse_strxcmp (name->ptr, name->len, pair->name) == 0) return pair;
|
||||
}
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
static qse_xli_pair_t* find_pair_byindex (
|
||||
qse_xli_t* xli, const qse_xli_list_t* list,
|
||||
const qse_cstr_t* key, qse_size_t index)
|
||||
{
|
||||
qse_xli_atom_t* p;
|
||||
qse_size_t count = 0;
|
||||
|
||||
/* TODO: speed up. no linear search */
|
||||
p = list->head;
|
||||
while (p)
|
||||
{
|
||||
if (p->type == QSE_XLI_PAIR)
|
||||
{
|
||||
qse_xli_pair_t* pair = (qse_xli_pair_t*)p;
|
||||
if (qse_strxcmp (key->ptr, key->len, pair->key) == 0)
|
||||
{
|
||||
if (index == count) return pair;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
qse_xli_pair_t* qse_xli_findpairbyname (
|
||||
qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* name)
|
||||
{
|
||||
const qse_char_t* ptr;
|
||||
qse_cstr_t seg;
|
||||
qse_xli_list_t* curlist;
|
||||
qse_xli_pair_t* pair;
|
||||
|
||||
curlist = list? list: &xli->root;
|
||||
|
||||
ptr = name;
|
||||
while (1)
|
||||
{
|
||||
seg.ptr = ptr;
|
||||
while (*ptr != QSE_T('\0') &&
|
||||
*ptr != QSE_T('.') &&
|
||||
*ptr != QSE_T('[')) ptr++;
|
||||
if (ptr == seg.ptr) goto inval;
|
||||
seg.len = ptr - seg.ptr;
|
||||
|
||||
if (curlist->type != QSE_XLI_LIST)
|
||||
{
|
||||
/* check the type of curlist. this check is needed
|
||||
* because of the unconditional switching at the bottom of the
|
||||
* this loop. this implementation strategy has been chosen
|
||||
* to provide the segment name easily. */
|
||||
goto noent;
|
||||
}
|
||||
|
||||
if (*ptr == QSE_T('['))
|
||||
{
|
||||
/* index is specified */
|
||||
ptr++;
|
||||
|
||||
if (QSE_ISDIGIT(*ptr))
|
||||
{
|
||||
/* numeric index */
|
||||
qse_size_t index = 0, count = 0;
|
||||
do
|
||||
{
|
||||
index = index * 10 + (*ptr++ - QSE_T('0'));
|
||||
count++;
|
||||
}
|
||||
while (QSE_ISDIGIT(*ptr));
|
||||
|
||||
if (*ptr != QSE_T(']')) goto inval;
|
||||
|
||||
pair = find_pair_byindex (xli, curlist, &seg, index);
|
||||
if (pair == QSE_NULL)
|
||||
{
|
||||
seg.len += count + 2; /* adjustment for error message */
|
||||
goto noent;
|
||||
}
|
||||
}
|
||||
else if (QSE_ISALPHA(*ptr))
|
||||
{
|
||||
/* word index */
|
||||
qse_cstr_t idx;
|
||||
|
||||
idx.ptr = ptr;
|
||||
do ptr++; while (QSE_ISALNUM(*ptr) || *ptr == QSE_T('_') || *ptr == QSE_T('-'));
|
||||
idx.len = ptr - idx.ptr;
|
||||
|
||||
if (*ptr != QSE_T(']')) goto inval;
|
||||
|
||||
pair = find_pair_byname (xli, curlist, &seg, &idx);
|
||||
if (pair == QSE_NULL)
|
||||
{
|
||||
seg.len += idx.len + 2; /* adjustment for error message */
|
||||
goto noent;
|
||||
}
|
||||
}
|
||||
else if (*ptr == QSE_T('\'') || *ptr == QSE_T('\"'))
|
||||
{
|
||||
qse_cstr_t idx;
|
||||
qse_char_t cc = *ptr++;
|
||||
|
||||
idx.ptr = ptr;
|
||||
do ptr++; while (*ptr != cc && *ptr != QSE_T('\0'));
|
||||
idx.len = ptr - idx.ptr;
|
||||
|
||||
if (*ptr != cc) goto inval;
|
||||
if (*++ptr != QSE_T(']')) goto inval;
|
||||
|
||||
pair = find_pair_byname (xli, curlist, &seg, &idx);
|
||||
if (pair == QSE_NULL)
|
||||
{
|
||||
seg.len += idx.len + 4; /* adjustment for error message */
|
||||
goto noent;
|
||||
}
|
||||
}
|
||||
else goto inval;
|
||||
|
||||
ptr++; /* skip ] */
|
||||
|
||||
if (*ptr == QSE_T('\0')) break; /* no more segments */
|
||||
else if (*ptr != QSE_T('.')) goto inval;
|
||||
}
|
||||
else
|
||||
{
|
||||
pair = find_pair_byname (xli, curlist, &seg, QSE_NULL);
|
||||
if (pair == QSE_NULL) goto noent;
|
||||
|
||||
if (*ptr == QSE_T('\0')) break; /* no more segments */
|
||||
}
|
||||
|
||||
/* more segments to handle */
|
||||
QSE_ASSERT (*ptr == QSE_T('.'));
|
||||
ptr++;
|
||||
|
||||
/* switch to the value regardless of its type.
|
||||
* check if it is a list in the beginning of the loop
|
||||
* just after having gotten the next segment name */
|
||||
curlist = (qse_xli_list_t*)pair->val;
|
||||
}
|
||||
|
||||
return pair;
|
||||
|
||||
inval:
|
||||
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
|
||||
return QSE_NULL;
|
||||
|
||||
noent:
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOENT, &seg);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
|
@ -52,12 +52,14 @@ struct qse_xli_t
|
||||
qse_xli_ecb_t* ecb;
|
||||
|
||||
qse_xli_list_t root;
|
||||
qse_xli_nil_t xnil;
|
||||
|
||||
qse_str_t* tmp[1];
|
||||
qse_xli_tok_t tok;
|
||||
struct
|
||||
{
|
||||
qse_xli_io_impl_t inf; /* input handler */
|
||||
qse_xli_io_lxc_t last;
|
||||
qse_xli_io_lxc_t last;
|
||||
qse_xli_io_arg_t arg; /* for top level */
|
||||
qse_xli_io_arg_t* inp; /* current */
|
||||
} sio;
|
||||
|
Reference in New Issue
Block a user