added QSE_XLI_KEYTAG

This commit is contained in:
2013-09-25 06:40:40 +00:00
parent abcf8988a5
commit ef25755996
6 changed files with 143 additions and 78 deletions

View File

@ -52,6 +52,7 @@ const qse_char_t* qse_xli_dflerrstr (
QSE_T("'${0}' not recognized"),
QSE_T("@ not followed by a valid word"),
QSE_T("invalid identifier '${0}'"),
QSE_T("missing key after key tag"),
QSE_T("undefined key '${0}'"),
QSE_T("no alias for '${0}'"),
QSE_T("illegal value for '${0}'"),

View File

@ -60,7 +60,7 @@ enum tok_t
TOK_NSTR,
TOK_IDENT,
TOK_TEXT,
TOK_STRTAG,
TOK_TAG,
__TOKEN_COUNT__
};
@ -569,14 +569,14 @@ retry:
}
}
}
else if ((xli->opt.trait & QSE_XLI_STRTAG) && c == QSE_T('['))
else if ((xli->opt.trait & (QSE_XLI_KEYTAG | QSE_XLI_STRTAG)) && c == QSE_T('['))
{
/* a string tag is a bracketed word placed in front of a string value.
* A = [tg] "abc";
* "tg" is stored into the tag field of qse_xli_str_t.
*/
SET_TOKEN_TYPE (xli, tok, TOK_STRTAG);
SET_TOKEN_TYPE (xli, tok, TOK_TAG);
while (1)
{
@ -596,7 +596,7 @@ retry:
break;
}
if (!QSE_ISALNUM(c))
if (!QSE_ISALNUM(c) && c != QSE_T('-') && c != QSE_T('_'))
{
qse_char_t cc = (qse_char_t)c;
qse_cstr_t ea;
@ -658,7 +658,7 @@ static int get_token (qse_xli_t* xli)
return get_token_into (xli, &xli->tok);
}
static int read_pair (qse_xli_t* xli)
static int read_pair (qse_xli_t* xli, const qse_char_t* keytag)
{
qse_xstr_t key;
qse_xli_loc_t kloc;
@ -666,14 +666,14 @@ static int read_pair (qse_xli_t* xli)
qse_xli_pair_t* pair;
qse_xli_list_t* parlist;
qse_size_t dotted_curkey_len;
qse_char_t* tag;
qse_char_t* strtag;
qse_xli_scm_t* scm = QSE_NULL;
int key_nodup = 0, key_alias = 0;
key.ptr = QSE_NULL;
name = QSE_NULL;
tag = QSE_NULL;
strtag = QSE_NULL;
dotted_curkey_len = (qse_size_t)-1;
parlist = xli->parlink->list;
@ -742,7 +742,7 @@ static int read_pair (qse_xli_t* xli)
if (key_alias)
{
/* the name 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))
{
qse_xli_atom_t* atom;
@ -783,10 +783,10 @@ static int read_pair (qse_xli_t* xli)
{
if (get_token (xli) <= -1) goto oops;
if (MATCH (xli, TOK_STRTAG))
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, TOK_TAG))
{
tag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
if (tag == QSE_NULL)
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
if (strtag == QSE_NULL)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops;
@ -808,7 +808,7 @@ static int read_pair (qse_xli_t* xli)
}
/* add a new pair with the initial string segment */
pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key.ptr, name, tag, QSE_STR_CSTR(xli->tok.name));
pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key.ptr, name, keytag, QSE_STR_CSTR(xli->tok.name), strtag);
if (pair == QSE_NULL) goto oops;
segcount++;
@ -822,16 +822,16 @@ static int read_pair (qse_xli_t* xli)
{
if (get_token (xli) <= -1) goto oops; /* skip the comma */
if (tag)
if (strtag)
{
QSE_MMGR_FREE (xli->mmgr, tag);
tag = QSE_NULL;
QSE_MMGR_FREE (xli->mmgr, strtag);
strtag = QSE_NULL;
}
if (MATCH (xli, TOK_STRTAG))
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, TOK_TAG))
{
tag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
if (tag == QSE_NULL)
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
if (strtag == QSE_NULL)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops;
@ -847,7 +847,7 @@ static int read_pair (qse_xli_t* xli)
}
/* add an additional segment to the string */
curstrseg = qse_xli_addsegtostr (xli, curstrseg, tag, QSE_STR_CSTR(xli->tok.name));
curstrseg = qse_xli_addsegtostr (xli, curstrseg, strtag, QSE_STR_CSTR(xli->tok.name));
if (curstrseg == QSE_NULL) goto oops;
segcount++;
@ -896,7 +896,7 @@ static int read_pair (qse_xli_t* xli)
xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR;
/* insert a pair with an empty list */
pair = qse_xli_insertpairwithemptylist (xli, parlist, QSE_NULL, key.ptr, name);
pair = qse_xli_insertpairwithemptylist (xli, parlist, QSE_NULL, key.ptr, name, keytag);
if (pair == QSE_NULL) goto oops;
if (read_list (xli, (qse_xli_list_t*)pair->val) <= -1) goto oops;
@ -937,7 +937,7 @@ static int read_pair (qse_xli_t* xli)
xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR;
/* no value has been specified for the pair */
pair = qse_xli_insertpair (xli, parlist, QSE_NULL, key.ptr, name, (qse_xli_val_t*)&xli->root->xnil);
pair = qse_xli_insertpair (xli, parlist, QSE_NULL, key.ptr, name, keytag, (qse_xli_val_t*)&xli->root->xnil);
if (pair == QSE_NULL) goto oops;
/* skip the semicolon */
@ -951,7 +951,7 @@ static int read_pair (qse_xli_t* xli)
goto oops;
}
if (tag) QSE_MMGR_FREE (xli->mmgr, tag);
if (strtag) QSE_MMGR_FREE (xli->mmgr, strtag);
QSE_MMGR_FREE (xli->mmgr, name);
QSE_MMGR_FREE (xli->mmgr, key.ptr);
qse_str_setlen (xli->dotted_curkey, dotted_curkey_len);
@ -959,7 +959,7 @@ static int read_pair (qse_xli_t* xli)
oops:
xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR;
if (tag) QSE_MMGR_FREE (xli->mmgr, tag);
if (strtag) QSE_MMGR_FREE (xli->mmgr, strtag);
if (name) QSE_MMGR_FREE (xli->mmgr, name);
if (key.ptr) QSE_MMGR_FREE (xli->mmgr, key.ptr);
if (dotted_curkey_len != (qse_size_t)-1)
@ -1003,9 +1003,38 @@ static int __read_list (qse_xli_t* xli)
if (begin_include (xli) <= -1) return -1;
}
else if ((xli->opt.trait & QSE_XLI_KEYTAG) && MATCH (xli, TOK_TAG))
{
qse_char_t* keytag;
int x;
keytag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
if (keytag == QSE_NULL)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
return -1;
}
if (get_token(xli) <= -1)
{
QSE_MMGR_FREE (xli->mmgr, keytag);
return -1;
}
if (!MATCH(xli,TOK_IDENT))
{
QSE_MMGR_FREE (xli->mmgr, keytag);
qse_xli_seterror (xli, QSE_XLI_ENOKEY, QSE_NULL, &xli->tok.loc);
return -1;
}
x = read_pair (xli, keytag);
QSE_MMGR_FREE (xli->mmgr, keytag);
if (x <= -1) return -1;
}
else if (MATCH (xli, TOK_IDENT))
{
if (read_pair (xli) <= -1) return -1;
if (read_pair (xli, QSE_NULL) <= -1) return -1;
}
else if (MATCH (xli, TOK_TEXT))
{

View File

@ -194,8 +194,16 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
{
qse_xli_pair_t* pair = (qse_xli_pair_t*)curatom;
if (write_indentation (xli, depth) <= -1 ||
write_to_current_stream (xli, pair->key, qse_strlen(pair->key), 0) <= -1) return -1;
if (write_indentation (xli, depth) <= -1) return -1;
if (pair->tag)
{
if (write_to_current_stream (xli, QSE_T("["), 1, 0) <= -1 ||
write_to_current_stream (xli, pair->tag, qse_strlen(pair->tag), 0) <= -1 ||
write_to_current_stream (xli, QSE_T("]"), 1, 0) <= -1) return -1;
}
if (write_to_current_stream (xli, pair->key, qse_strlen(pair->key), 0) <= -1) return -1;
if (pair->alias)
{

View File

@ -225,18 +225,20 @@ static void insert_atom (
static qse_xli_pair_t* insert_pair (
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
const qse_cstr_t* key, const qse_cstr_t* alias, qse_xli_val_t* value)
const qse_cstr_t* key, const qse_cstr_t* alias, const qse_cstr_t* keytag, qse_xli_val_t* value)
{
qse_xli_pair_t* pair;
qse_size_t alen;
qse_size_t alen, tlen;
qse_char_t* kptr, * nptr;
alen = alias? alias->len: 0;
tlen = keytag? keytag->len: 0;
pair = qse_xli_callocmem (xli,
QSE_SIZEOF(*pair) + xli->opt.pair_xtnsize +
((key->len + 1) * QSE_SIZEOF(*key->ptr)) +
((alen + 1) * QSE_SIZEOF(*alias->ptr)));
((alen + 1) * QSE_SIZEOF(*alias->ptr)) +
((tlen + 1) * QSE_SIZEOF(*keytag->ptr)));
if (pair == QSE_NULL) return QSE_NULL;
kptr = (qse_char_t*)((qse_uint8_t*)(pair + 1) + xli->opt.pair_xtnsize);
@ -250,6 +252,12 @@ static qse_xli_pair_t* insert_pair (
qse_strcpy (nptr, alias->ptr);
pair->alias = nptr;
}
if (keytag)
{
nptr = kptr + key->len + 1 + alen + 1;
qse_strcpy (nptr, keytag->ptr);
pair->tag = nptr;
}
pair->val = value; /* take note of no duplication here */
insert_atom (xli, parent, peer, (qse_xli_atom_t*)pair);
@ -259,31 +267,35 @@ static qse_xli_pair_t* insert_pair (
qse_xli_pair_t* qse_xli_insertpair (
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
const qse_char_t* key, const qse_char_t* alias, qse_xli_val_t* value)
const qse_char_t* key, const qse_char_t* alias,
const qse_char_t* keytag, qse_xli_val_t* value)
{
qse_cstr_t k;
qse_cstr_t a, * ap = QSE_NULL;
qse_cstr_t t, * tp = QSE_NULL;
k.ptr = key;
k.len = qse_strlen (key);
if (alias)
{
qse_cstr_t a;
a.ptr = alias;
a.len = qse_strlen (alias);
return insert_pair (xli, parent, peer, &k, &a, value);
ap = &a;
}
else
if (keytag)
{
return insert_pair (xli, parent, peer, &k, QSE_NULL, value);
t.ptr = keytag;
t.len = qse_strlen (keytag);
tp = &t;
}
return insert_pair (xli, parent, peer, &k, ap, tp, value);
}
qse_xli_pair_t* qse_xli_insertpairwithemptylist (
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
const qse_char_t* key, const qse_char_t* alias)
const qse_char_t* key, const qse_char_t* alias, const qse_char_t* keytag)
{
qse_xli_list_t* val;
qse_xli_pair_t* tmp;
@ -292,22 +304,22 @@ qse_xli_pair_t* qse_xli_insertpairwithemptylist (
if (val == QSE_NULL) return QSE_NULL;
val->type = QSE_XLI_LIST;
tmp = qse_xli_insertpair (xli, parent, peer, key, alias, (qse_xli_val_t*)val);
tmp = qse_xli_insertpair (xli, parent, peer, key, alias, keytag, (qse_xli_val_t*)val);
if (tmp == QSE_NULL) qse_xli_freemem (xli, val);
return tmp;
}
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* alias,
const qse_char_t* tag, const qse_cstr_t* value)
const qse_char_t* key, const qse_char_t* alias, const qse_char_t* keytag,
const qse_cstr_t* value, const qse_char_t* strtag)
{
qse_xli_str_t* val;
qse_xli_pair_t* tmp;
qse_size_t reqlen;
reqlen = QSE_SIZEOF(*val) + ((value->len + 1) * QSE_SIZEOF(*value->ptr));
if (tag) reqlen += (qse_strlen (tag) + 1) * QSE_SIZEOF(*tag);
if (strtag) reqlen += (qse_strlen (strtag) + 1) * QSE_SIZEOF(*strtag);
val = qse_xli_callocmem (xli, reqlen);
if (val == QSE_NULL) return QSE_NULL;
@ -318,20 +330,20 @@ qse_xli_pair_t* qse_xli_insertpairwithstr (
val->ptr = (const qse_char_t*)(val + 1);
val->len = value->len;
if (tag)
if (strtag)
{
val->tag = val->ptr + val->len + 1;
qse_strcpy ((qse_char_t*)val->tag, tag);
qse_strcpy ((qse_char_t*)val->tag, strtag);
}
tmp = qse_xli_insertpair (xli, parent, peer, key, alias, (qse_xli_val_t*)val);
tmp = qse_xli_insertpair (xli, parent, peer, key, alias, keytag, (qse_xli_val_t*)val);
if (tmp == QSE_NULL) qse_xli_freemem (xli, val);
return tmp;
}
qse_xli_pair_t* qse_xli_insertpairwithstrs (
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
const qse_char_t* key, const qse_char_t* alias,
const qse_char_t* key, const qse_char_t* alias, const qse_char_t* keytag,
const qse_cstr_t value[], qse_size_t count)
{
qse_xli_pair_t* tmp;
@ -344,7 +356,7 @@ qse_xli_pair_t* qse_xli_insertpairwithstrs (
return QSE_NULL;
}
tmp = qse_xli_insertpairwithstr (xli, parent, peer, key, alias, QSE_NULL, &value[0]);
tmp = qse_xli_insertpairwithstr (xli, parent, peer, key, alias, keytag, &value[0], QSE_NULL);
if (tmp == QSE_NULL) return QSE_NULL;
str = (qse_xli_str_t*)tmp->val;