added code to accept a number as a xli value.

renamed pair->name to pair->alias and related functions.
enhanced xli reader to support string escaping
This commit is contained in:
hyung-hwan 2013-07-01 15:16:19 +00:00
parent 3e21bc4f98
commit d2505bdbcd
7 changed files with 186 additions and 139 deletions

View File

@ -846,8 +846,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
for (i = 0; i < QSE_COUNTOF(loc_xcfg_items); i++)
{
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, loc_xcfg_items[i].x);
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, loc_xcfg_items[i].y);
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, loc_xcfg_items[i].x);
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, loc_xcfg_items[i].y);
if (pair && pair->val->type == QSE_XLI_STR)
{
cfg->xcfg[i] = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len);
@ -860,8 +860,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
}
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("index"));
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.index"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, QSE_T("index"));
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.index"));
if (pair && pair->val->type == QSE_XLI_STR)
{
qse_char_t* duptmp;
@ -886,8 +886,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
cfg->index.count = count;
}
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("cgi"));
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.cgi"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, QSE_T("cgi"));
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.cgi"));
if (pair && pair->val->type == QSE_XLI_LIST)
{
/* TODO: more sanity check... this can be done with xli schema... if supported */
@ -897,7 +897,7 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (pair->key && pair->name &&
if (pair->key && pair->alias &&
(pair->val->type == QSE_XLI_NIL || pair->val->type == QSE_XLI_STR))
{
struct cgi_t* cgi;
@ -916,7 +916,7 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
cgi->type = type;
cgi->spec = qse_httpd_strtombsdup (httpd, pair->name);
cgi->spec = qse_httpd_strtombsdup (httpd, pair->alias);
if (!cgi->spec)
{
qse_httpd_freemem (httpd, cgi);
@ -963,8 +963,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
}
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("auth-rule"));
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.auth-rule"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, QSE_T("auth-rule"));
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.auth-rule"));
if (pair && pair->val->type == QSE_XLI_LIST)
{
qse_xli_list_t* auth_rule_list = (qse_xli_list_t*)pair->val;
@ -978,10 +978,10 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
struct auth_rule_t* auth_rule;
int type;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->name) type = AUTH_RULE_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->name) type = AUTH_RULE_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->name) type = AUTH_RULE_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->name) type = AUTH_RULE_OTHER;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = AUTH_RULE_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->alias) type = AUTH_RULE_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->alias) type = AUTH_RULE_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = AUTH_RULE_OTHER;
else continue;
auth_rule = qse_httpd_callocmem (httpd, QSE_SIZEOF(*auth_rule));
@ -992,9 +992,9 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
auth_rule->type = type;
if (pair->name)
if (pair->alias)
{
auth_rule->spec = qse_httpd_strtombsdup (httpd, pair->name);
auth_rule->spec = qse_httpd_strtombsdup (httpd, pair->alias);
if (!auth_rule->spec)
{
qse_httpd_freemem (httpd, auth_rule);
@ -1015,8 +1015,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
}
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("mime"));
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.mime"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, QSE_T("mime"));
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.mime"));
if (pair && pair->val->type == QSE_XLI_LIST)
{
qse_xli_list_t* mimelist = (qse_xli_list_t*)pair->val;
@ -1030,10 +1030,10 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
struct mime_t* mime;
int type;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->name) type = MIME_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->name) type = MIME_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->name) type = MIME_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->name) type = MIME_OTHER;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = MIME_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->alias) type = MIME_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->alias) type = MIME_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = MIME_OTHER;
else continue;
mime = qse_httpd_callocmem (httpd, QSE_SIZEOF(*mime));
@ -1044,7 +1044,7 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
mime->type = type;
mime->spec = qse_httpd_strtombsdup (httpd, pair->name);
mime->spec = qse_httpd_strtombsdup (httpd, pair->alias);
if (!mime->spec)
{
qse_httpd_freemem (httpd, mime);
@ -1072,8 +1072,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
for (i = 0; i < 2; i++)
{
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, loc_acc_items[i].x);
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, loc_acc_items[i].y);
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, loc_acc_items[i].x);
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, loc_acc_items[i].y);
if (pair && pair->val->type == QSE_XLI_LIST)
{
qse_xli_list_t* acclist = (qse_xli_list_t*)pair->val;
@ -1089,10 +1089,10 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
qse_size_t len;
int type, value;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->name) type = ACCESS_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->name) type = ACCESS_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->name) type = ACCESS_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->name) type = ACCESS_OTHER;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = ACCESS_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->alias) type = ACCESS_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->alias) type = ACCESS_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = ACCESS_OTHER;
else continue;
tmp = ((qse_xli_str_t*)pair->val)->ptr;
@ -1111,9 +1111,9 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
acc->type = type;
if (pair->name)
if (pair->alias)
{
acc->spec = qse_httpd_strtombsdup (httpd, pair->name);
acc->spec = qse_httpd_strtombsdup (httpd, pair->alias);
if (!acc->spec)
{
qse_httpd_freemem (httpd, acc);
@ -1208,8 +1208,8 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q
{
qse_xli_pair_t* pair;
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, scfg_items[i].x);
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, scfg_items[i].y);
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, scfg_items[i].x);
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, scfg_items[i].y);
if (pair && pair->val->type == QSE_XLI_STR)
{
server_xtn->scfg[i] = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len);
@ -1223,7 +1223,7 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q
}
/* load host/location specific configuration */
host_count = qse_xli_getnumpairsbyname (httpd_xtn->xli, list, QSE_T("host"));
host_count = qse_xli_getnumpairsbyalias (httpd_xtn->xli, list, QSE_T("host"));
if (host_count <= 0) return 0; /* nothing to load */
QSE_ASSERT (server_xtn->cfgtab == QSE_NULL);
@ -1246,15 +1246,15 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q
qse_char_t buf[32];
qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("host[%d]"), i);
host = qse_xli_findpairbyname (httpd_xtn->xli, list, buf);
host = qse_xli_findpairbyalias (httpd_xtn->xli, list, buf);
if (!host) break;
if (host->val->type == QSE_XLI_LIST && host->name)
if (host->val->type == QSE_XLI_LIST && host->alias)
{
loc_count = qse_xli_getnumpairsbyname (httpd_xtn->xli, (qse_xli_list_t*)host->val, QSE_T("location"));
loc_count = qse_xli_getnumpairsbyalias (httpd_xtn->xli, (qse_xli_list_t*)host->val, QSE_T("location"));
if (((hostcfg = qse_httpd_callocmem (httpd, QSE_SIZEOF(*hostcfg))) == QSE_NULL) ||
((hostcfg->hostname = qse_httpd_strtombsdup (httpd, (host->name[0] == QSE_T('\0')? QSE_T("*"):host->name))) == QSE_NULL)) goto oops;
((hostcfg->hostname = qse_httpd_strtombsdup (httpd, (host->alias[0] == QSE_T('\0')? QSE_T("*"):host->alias))) == QSE_NULL)) goto oops;
for (j = loc_count; j > 0; )
{
@ -1263,10 +1263,10 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q
j--;
qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("location[%d]"), j);
loc = qse_xli_findpairbyname (httpd_xtn->xli, (qse_xli_list_t*)host->val, buf);
loc = qse_xli_findpairbyalias (httpd_xtn->xli, (qse_xli_list_t*)host->val, buf);
if (!loc) break;
if (loc->val->type == QSE_XLI_LIST && loc->name)
if (loc->val->type == QSE_XLI_LIST && loc->alias)
{
loccfg = qse_httpd_callocmem (httpd, QSE_SIZEOF(*loccfg));
if (loccfg == QSE_NULL) goto oops;
@ -1280,7 +1280,7 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q
/* clone the location name */
loccfg->locname.ptr = qse_httpd_strtombsdup (httpd,
(loc->name[0] == QSE_T('\0')? QSE_T("/"): loc->name));
(loc->alias[0] == QSE_T('\0')? QSE_T("/"): loc->alias));
if (loccfg->locname.ptr == QSE_NULL) goto oops;
loccfg->locname.len = qse_mbslen (loccfg->locname.ptr);
@ -1335,7 +1335,7 @@ static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, int num, qse_xli_l
httpd_xtn = qse_httpd_getxtnstd (httpd);
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("bind"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, QSE_T("bind"));
if (pair == QSE_NULL || pair->val->type != QSE_XLI_STR)
{
/* TOOD: logging */
@ -1351,8 +1351,8 @@ static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, int num, qse_xli_l
return QSE_NULL;
}
pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("ssl"));
if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.ssl"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, list, QSE_T("ssl"));
if (!pair) pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.ssl"));
if (pair && pair->val->type == QSE_XLI_STR &&
qse_strxcmp (((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len, QSE_T("yes")) == 0) dope.flags |= QSE_HTTPD_SERVER_SECURE;
@ -1402,7 +1402,7 @@ static int open_config_file (qse_httpd_t* httpd)
}
qse_xli_getopt (httpd_xtn->xli, QSE_XLI_TRAIT, &trait);
trait |= QSE_XLI_KEYNAME;
trait |= QSE_XLI_KEYALIAS;
qse_xli_setopt (httpd_xtn->xli, QSE_XLI_TRAIT, &trait);
xli_in.type = QSE_XLI_IOSTD_FILE;
@ -1440,7 +1440,7 @@ static void set_limit (qse_httpd_t* httpd, const qse_char_t* name, int what)
httpd_xtn = (httpd_xtn_t*)qse_httpd_getxtnstd (httpd);
pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, name);
pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, name);
if (pair && pair->val->type == QSE_XLI_STR)
{
#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
@ -1479,7 +1479,7 @@ static int load_config (qse_httpd_t* httpd)
if (open_config_file (httpd) <= -1) goto oops;
pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("name"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, QSE_T("name"));
if (pair && pair->val->type == QSE_XLI_STR)
{
qse_mchar_t* tmp;
@ -1499,7 +1499,7 @@ static int load_config (qse_httpd_t* httpd)
{
qse_char_t buf[32];
qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("server[%d]"), i);
pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, buf);
pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, buf);
if (pair == QSE_NULL) break;
if (pair->val->type != QSE_XLI_LIST)
@ -1529,7 +1529,7 @@ static int load_config (qse_httpd_t* httpd)
}
/* load the global default */
pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default"));
pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, QSE_T("server-default"));
if (pair && pair->val->type == QSE_XLI_LIST)
{
if (load_loccfg (httpd, (qse_xli_list_t*)pair->val, &httpd_xtn->dflcfg) <= -1)
@ -1563,7 +1563,7 @@ static void reconf_server (qse_httpd_t* httpd, qse_httpd_server_t* server)
{
qse_char_t buf[32];
qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("server[%d]"), server_xtn->num);
pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, buf);
pair = qse_xli_findpairbyalias (httpd_xtn->xli, QSE_NULL, buf);
if (pair && pair->val->type == QSE_XLI_LIST)
{

View File

@ -130,7 +130,7 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[])
qse_fprintf (out, QSE_T(" --version show version\n"));
qse_fprintf (out, QSE_T(" -i file specify an input file\n"));
qse_fprintf (out, QSE_T(" -o file specify an output file\n"));
qse_fprintf (out, QSE_T(" -n allow a key name\n"));
qse_fprintf (out, QSE_T(" -a allow a key alias\n"));
qse_fprintf (out, QSE_T(" -f keep file inclusion info\n"));
qse_fprintf (out, QSE_T(" -t keep comment text\n"));
qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n"));
@ -159,9 +159,9 @@ static int handle_args (int argc, qse_char_t* argv[])
static qse_opt_t opt =
{
#if defined(QSE_BUILD_DEBUG)
QSE_T("hi:o:nftm:X:"),
QSE_T("hi:o:aftm:X:"),
#else
QSE_T("hi:o:nftm:"),
QSE_T("hi:o:aftm:"),
#endif
lng
};
@ -203,8 +203,8 @@ static int handle_args (int argc, qse_char_t* argv[])
g_output_file = opt.arg;
break;
case QSE_T('n'):
g_trait |= QSE_XLI_KEYNAME;
case QSE_T('a'):
g_trait |= QSE_XLI_KEYALIAS;
break;
case QSE_T('f'):
@ -384,7 +384,7 @@ static int xli_main (int argc, qse_char_t* argv[])
if (g_lookup_key)
{
qse_xli_pair_t* pair;
pair = qse_xli_findpairbyname (xli, QSE_NULL, g_lookup_key);
pair = qse_xli_findpairbyalias (xli, QSE_NULL, g_lookup_key);
if (pair == QSE_NULL)
{
qse_fprintf (QSE_STDERR,

View File

@ -74,7 +74,7 @@ typedef enum qse_xli_opt_t qse_xli_opt_t;
enum qse_xli_trait_t
{
QSE_XLI_KEYNODUP = (1 << 1),
QSE_XLI_KEYNAME = (1 << 2),
QSE_XLI_KEYALIAS = (1 << 2),
QSE_XLI_KEEPTEXT = (1 << 3), /**< keep comment text */
QSE_XLI_KEEPFILE = (1 << 4), /**< keep inclusion file info */
@ -152,7 +152,7 @@ struct qse_xli_pair_t
{
QSE_XLI_ATOM_HDR;
const qse_char_t* key;
const qse_char_t* name;
const qse_char_t* alias;
qse_xli_val_t* val;
};
@ -477,7 +477,7 @@ QSE_EXPORT qse_xli_pair_t* qse_xli_insertpair (
qse_xli_list_t* list,
qse_xli_atom_t* peer,
const qse_char_t* key,
const qse_char_t* name,
const qse_char_t* alias,
qse_xli_val_t* val
);
@ -486,7 +486,7 @@ QSE_EXPORT qse_xli_pair_t* qse_xli_insertpairwithemptylist (
qse_xli_list_t* list,
qse_xli_atom_t* peer,
const qse_char_t* key,
const qse_char_t* name
const qse_char_t* alias
);
QSE_EXPORT qse_xli_pair_t* qse_xli_insertpairwithstr (
@ -494,7 +494,7 @@ QSE_EXPORT qse_xli_pair_t* qse_xli_insertpairwithstr (
qse_xli_list_t* list,
qse_xli_atom_t* peer,
const qse_char_t* key,
const qse_char_t* name,
const qse_char_t* alias,
const qse_cstr_t* value
);
@ -522,18 +522,23 @@ QSE_EXPORT qse_xli_list_t* qse_xli_getroot (
qse_xli_t* xli
);
QSE_EXPORT qse_xli_pair_t* qse_xli_findpairbyname (
QSE_EXPORT qse_xli_pair_t* qse_xli_findpairbyalias (
qse_xli_t* xli,
const qse_xli_list_t* list,
const qse_char_t* name
const qse_char_t* alias
);
QSE_EXPORT qse_size_t qse_xli_getnumpairsbyname (
QSE_EXPORT qse_size_t qse_xli_getnumpairsbyalias (
qse_xli_t* xli,
const qse_xli_list_t* list,
const qse_char_t* name
const qse_char_t* alias
);
/**
* The qse_xli_addsegtostr() function creates a new string segment made of
* the character string pointed to by \a value and chains it to the XLI string
* pointed to by \a str.
*/
QSE_EXPORT qse_xli_str_t* qse_xli_addsegtostr (
qse_xli_t* xli,
qse_xli_str_t* str,

View File

@ -25,6 +25,12 @@ static int get_char (qse_xli_t* xli);
static int get_token (qse_xli_t* xli);
static int read_list (qse_xli_t* xli, qse_xli_list_t* list);
enum
{
TOK_STATUS_ENABLE_NSTR = (1 << 0)
};
static int close_current_stream (qse_xli_t* xli)
{
qse_ssize_t n;
@ -51,6 +57,7 @@ enum tok_t
TOK_COMMA,
TOK_DQSTR,
TOK_SQSTR,
TOK_NSTR,
TOK_IDENT,
TOK_TEXT,
@ -458,12 +465,10 @@ retry:
type = classify_ident (xli, QSE_STR_CSTR(tok->name));
SET_TOKEN_TYPE (xli, tok, type);
}
else if (c == QSE_T('\'') || c == QSE_T('\"'))
else if (c == QSE_T('\''))
{
/* single-quoted string - no escaping */
qse_cint_t cc = c;
SET_TOKEN_TYPE (xli, tok, ((cc == QSE_T('\''))? TOK_SQSTR: TOK_DQSTR));
SET_TOKEN_TYPE (xli, tok, TOK_SQSTR);
while (1)
{
@ -476,7 +481,7 @@ retry:
return -1;
}
if (c == cc)
if (c == QSE_T('\''))
{
/* terminating quote */
GET_CHAR (xli);
@ -486,6 +491,58 @@ retry:
ADD_TOKEN_CHAR (xli, tok, c);
}
}
else if (c == QSE_T('\"'))
{
/* double-quoted string - support escaping */
int escaped = 0;
SET_TOKEN_TYPE (xli, tok, TOK_DQSTR);
while (1)
{
GET_CHAR_TO (xli, c);
if (c == QSE_CHAR_EOF)
{
/* the string is not closed */
qse_xli_seterror (xli, QSE_XLI_ESTRNC, QSE_NULL, &xli->tok.loc);
return -1;
}
if (!escaped)
{
if (c == QSE_T('\\'))
{
escaped = 1;
continue;
}
if (c == QSE_T('\"'))
{
/* terminating quote */
GET_CHAR (xli);
break;
}
ADD_TOKEN_CHAR (xli, tok, c);
}
else
{
ADD_TOKEN_CHAR (xli, tok, c);
escaped = 0;
}
}
}
else if ((xli->tok_status & TOK_STATUS_ENABLE_NSTR) && QSE_ISDIGIT(c))
{
SET_TOKEN_TYPE (xli, tok, TOK_NSTR);
do
{
ADD_TOKEN_CHAR (xli, tok, c);
GET_CHAR_TO (xli, c);
}
while (QSE_ISDIGIT(c));
}
else
{
n = get_symbols (xli, c, tok);
@ -570,12 +627,14 @@ static int read_pair (qse_xli_t* xli)
goto oops;
}
xli->tok_status |= TOK_STATUS_ENABLE_NSTR;
if (get_token (xli) <= -1) goto oops;
if (xli->opt.trait & QSE_XLI_KEYNAME)
if (xli->opt.trait & QSE_XLI_KEYALIAS)
{
/* the name part must be unique for the same key(s) */
if (MATCH (xli, TOK_IDENT) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_SQSTR))
if (MATCH (xli, TOK_IDENT) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_SQSTR) || MATCH(xli, TOK_NSTR))
{
qse_xli_atom_t* atom;
@ -583,9 +642,9 @@ static int read_pair (qse_xli_t* xli)
while (atom)
{
if (atom->type == QSE_XLI_PAIR &&
((qse_xli_pair_t*)atom)->name &&
((qse_xli_pair_t*)atom)->alias &&
qse_strcmp (((qse_xli_pair_t*)atom)->key, key) == 0 &&
qse_strcmp (((qse_xli_pair_t*)atom)->name, QSE_STR_PTR(xli->tok.name)) == 0)
qse_strcmp (((qse_xli_pair_t*)atom)->alias, QSE_STR_PTR(xli->tok.name)) == 0)
{
qse_xli_seterror (xli, QSE_XLI_EEXIST, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc);
goto oops;
@ -608,7 +667,7 @@ static int read_pair (qse_xli_t* xli)
{
if (get_token (xli) <= -1) goto oops;
if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_IDENT))
if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH(xli, TOK_NSTR) || MATCH (xli, TOK_IDENT))
{
qse_xli_str_t* curstrseg;
@ -626,7 +685,7 @@ static int read_pair (qse_xli_t* xli)
{
if (get_token (xli) <= -1) goto oops; /* skip the comma */
if (!MATCH (xli, TOK_SQSTR) && !MATCH (xli, TOK_DQSTR) && !MATCH (xli, TOK_IDENT))
if (!MATCH (xli, TOK_SQSTR) && !MATCH (xli, TOK_DQSTR) && !MATCH (xli, TOK_NSTR) && !MATCH (xli, TOK_IDENT))
{
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);
goto oops;
@ -656,9 +715,12 @@ static int read_pair (qse_xli_t* xli)
qse_xli_seterror (xli, QSE_XLI_EPAVAL, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc);
goto oops;
}
}
else if (MATCH (xli, TOK_LBRACE))
{
xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR;
if (get_token (xli) <= -1) goto oops;
/* insert a pair with an empty list */
@ -684,8 +746,10 @@ static int read_pair (qse_xli_t* xli)
}
else if (MATCH (xli, TOK_SEMICOLON))
{
xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR;
/* no value has been specified for the pair */
pair = qse_xli_insertpair (xli, parlist, QSE_NULL, key, name, &xli->xnil);
pair = qse_xli_insertpair (xli, parlist, QSE_NULL, key, name, (qse_xli_val_t*)&xli->xnil);
if (pair == QSE_NULL) goto oops;
/* skip the semicolon */
@ -702,6 +766,7 @@ static int read_pair (qse_xli_t* xli)
return 0;
oops:
xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR;
if (name) QSE_MMGR_FREE (xli->mmgr, name);
if (key) QSE_MMGR_FREE (xli->mmgr, key);
return -1;

View File

@ -145,13 +145,12 @@ static int write_to_current_stream (qse_xli_t* xli, const qse_char_t* ptr, qse_s
{
if (arg->b.len + 2 > QSE_COUNTOF(arg->b.buf) && flush (xli, arg) <= -1) return -1;
arg->b.buf[arg->b.len++] = QSE_T('\\');
arg->b.buf[arg->b.len++] = ptr[i];
}
else
{
if (arg->b.len + 1 > QSE_COUNTOF(arg->b.buf) && flush (xli, arg) <= -1) return -1;
arg->b.buf[arg->b.len++] = ptr[i];
}
arg->b.buf[arg->b.len++] = ptr[i];
}
return 0;
@ -177,10 +176,10 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
if (write_to_current_stream (xli, pair->key, qse_strlen(pair->key), 0) <= -1) return -1;
if (pair->name)
if (pair->alias)
{
if (write_to_current_stream (xli, QSE_T(" \""), 2, 0) <= -1 ||
write_to_current_stream (xli, pair->name, qse_strlen(pair->name), 1) <= -1 ||
write_to_current_stream (xli, pair->alias, qse_strlen(pair->alias), 1) <= -1 ||
write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1) return -1;
}

View File

@ -52,18 +52,10 @@ 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;
@ -74,26 +66,14 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr)
oops:
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
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_str_close (xli->tok.name);
for (i = QSE_COUNTOF(xli->tmp); i > 0; )
{
if (xli->tmp[--i]) qse_str_close (xli->tmp[i]);
}
qse_xli_clearrionames (xli);
qse_xli_clearwionames (xli);
}
@ -181,7 +161,6 @@ qse_xli_list_t* qse_xli_getroot (qse_xli_t* xli)
return &xli->root;
}
/* ------------------------------------------------------ */
static void insert_atom (
@ -218,19 +197,19 @@ static void insert_atom (
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* name, qse_xli_val_t* value)
const qse_char_t* key, const qse_char_t* alias, qse_xli_val_t* value)
{
qse_xli_pair_t* pair;
qse_size_t klen, nlen;
qse_char_t* kptr, * nptr;
klen = qse_strlen (key);
nlen = name? qse_strlen (name): 0;
nlen = alias? qse_strlen (alias): 0;
pair = qse_xli_callocmem (xli,
QSE_SIZEOF(*pair) +
((klen + 1) * QSE_SIZEOF(*key)) +
((nlen + 1) * QSE_SIZEOF(*name)));
((nlen + 1) * QSE_SIZEOF(*alias)));
if (pair == QSE_NULL) return QSE_NULL;
kptr = (qse_char_t*)(pair + 1);
@ -238,11 +217,11 @@ qse_xli_pair_t* qse_xli_insertpair (
pair->type = QSE_XLI_PAIR;
pair->key = kptr;
if (name)
if (alias)
{
nptr = kptr + klen + 1;
qse_strcpy (nptr, name);
pair->name = nptr;
qse_strcpy (nptr, alias);
pair->alias = nptr;
}
pair->val = value; /* this assumes it points to a dynamically allocated atom */
@ -252,7 +231,7 @@ qse_xli_pair_t* qse_xli_insertpair (
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* name)
const qse_char_t* key, const qse_char_t* alias)
{
qse_xli_list_t* val;
qse_xli_pair_t* tmp;
@ -261,14 +240,14 @@ 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, name, (qse_xli_val_t*)val);
tmp = qse_xli_insertpair (xli, parent, peer, key, alias, (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* name, const qse_cstr_t* value)
const qse_char_t* key, const qse_char_t* alias, const qse_cstr_t* value)
{
qse_xli_str_t* val;
qse_xli_pair_t* tmp;
@ -282,7 +261,7 @@ qse_xli_pair_t* qse_xli_insertpairwithstr (
val->ptr = (const qse_char_t*)(val + 1);
val->len = value->len;
tmp = qse_xli_insertpair (xli, parent, peer, key, name, (qse_xli_val_t*)val);
tmp = qse_xli_insertpair (xli, parent, peer, key, alias, (qse_xli_val_t*)val);
if (tmp == QSE_NULL) qse_xli_freemem (xli, val);
return tmp;
}
@ -398,9 +377,9 @@ void qse_xli_clear (qse_xli_t* xli)
free_list (xli, &xli->root);
}
static qse_size_t count_pair_byname (
static qse_size_t count_pair_byalias (
qse_xli_t* xli, const qse_xli_list_t* list,
const qse_cstr_t* key, const qse_cstr_t* name)
const qse_cstr_t* key, const qse_cstr_t* alias)
{
qse_xli_atom_t* p;
qse_size_t count = 0;
@ -414,8 +393,8 @@ static qse_size_t count_pair_byname (
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) count++;
if (alias == QSE_NULL ||
qse_strxcmp (alias->ptr, alias->len, pair->alias) == 0) count++;
}
}
@ -425,9 +404,9 @@ static qse_size_t count_pair_byname (
return count;
}
static qse_xli_pair_t* find_pair_byname (
static qse_xli_pair_t* find_pair_byalias (
qse_xli_t* xli, const qse_xli_list_t* list,
const qse_cstr_t* key, const qse_cstr_t* name)
const qse_cstr_t* key, const qse_cstr_t* alias)
{
qse_xli_atom_t* p;
@ -440,8 +419,8 @@ static qse_xli_pair_t* find_pair_byname (
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;
if (alias == QSE_NULL ||
qse_strxcmp (alias->ptr, alias->len, pair->alias) == 0) return pair;
}
}
@ -478,7 +457,7 @@ static qse_xli_pair_t* find_pair_byindex (
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)
qse_xli_pair_t* qse_xli_findpairbyalias (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* alias)
{
const qse_char_t* ptr;
const qse_xli_list_t* curlist;
@ -487,7 +466,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li
curlist = list? list: &xli->root;
ptr = name;
ptr = alias;
while (1)
{
seg.ptr = ptr;
@ -500,7 +479,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li
/* 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. */
* to provide the segment alias easily. */
goto noent;
}
@ -540,7 +519,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li
if (*ptr != QSE_T(']')) goto inval;
pair = find_pair_byname (xli, curlist, &seg, &idx);
pair = find_pair_byalias (xli, curlist, &seg, &idx);
if (pair == QSE_NULL)
{
seg.len += idx.len + 2; /* adjustment for error message */
@ -559,7 +538,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li
if (*ptr != cc) goto inval;
if (*++ptr != QSE_T(']')) goto inval;
pair = find_pair_byname (xli, curlist, &seg, &idx);
pair = find_pair_byalias (xli, curlist, &seg, &idx);
if (pair == QSE_NULL)
{
seg.len += idx.len + 4; /* adjustment for error message */
@ -575,7 +554,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li
}
else
{
pair = find_pair_byname (xli, curlist, &seg, QSE_NULL);
pair = find_pair_byalias (xli, curlist, &seg, QSE_NULL);
if (pair == QSE_NULL) goto noent;
if (*ptr == QSE_T('\0')) break; /* no more segments */
@ -587,7 +566,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li
/* 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 */
* just after having gotten the next segment alias */
curlist = (qse_xli_list_t*)pair->val;
}
@ -602,7 +581,7 @@ noent:
return QSE_NULL;
}
qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* name)
qse_size_t qse_xli_getnumpairsbyalias (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* alias)
{
const qse_char_t* ptr;
const qse_xli_list_t* curlist;
@ -611,7 +590,7 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list
curlist = list? list: &xli->root;
ptr = name;
ptr = alias;
while (1)
{
seg.ptr = ptr;
@ -624,7 +603,7 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* 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. */
* to provide the segment alias easily. */
goto noent;
}
@ -664,7 +643,7 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list
if (*ptr != QSE_T(']')) goto inval;
pair = find_pair_byname (xli, curlist, &seg, &idx);
pair = find_pair_byalias (xli, curlist, &seg, &idx);
if (pair == QSE_NULL)
{
seg.len += idx.len + 2; /* adjustment for error message */
@ -683,7 +662,7 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list
if (*ptr != cc) goto inval;
if (*++ptr != QSE_T(']')) goto inval;
pair = find_pair_byname (xli, curlist, &seg, &idx);
pair = find_pair_byalias (xli, curlist, &seg, &idx);
if (pair == QSE_NULL)
{
seg.len += idx.len + 4; /* adjustment for error message */
@ -703,16 +682,16 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list
}
else
{
pair = find_pair_byname (xli, curlist, &seg, QSE_NULL);
pair = find_pair_byalias (xli, curlist, &seg, QSE_NULL);
if (pair == QSE_NULL) goto noent;
if (*ptr == QSE_T('\0'))
{
return count_pair_byname (xli, curlist, &seg, QSE_NULL);
return count_pair_byalias (xli, curlist, &seg, QSE_NULL);
}
else
{
pair = find_pair_byname (xli, curlist, &seg, QSE_NULL);
pair = find_pair_byalias (xli, curlist, &seg, QSE_NULL);
if (pair == QSE_NULL) goto noent;
}
}
@ -723,7 +702,7 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list
/* 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 */
* just after having gotten the next segment alias */
curlist = (qse_xli_list_t*)pair->val;
}
@ -776,7 +755,6 @@ qse_char_t* qse_xli_dupflatstr (qse_xli_t* xli, qse_xli_str_t* str, qse_size_t*
}
tmp[x] = QSE_T('\0');
if (len) *len = x;
if (nsegs) *nsegs = y;

View File

@ -62,8 +62,8 @@ struct qse_xli_t
qse_xli_list_t root;
qse_xli_list_link_t* parlink;
qse_str_t* tmp[1];
qse_xli_tok_t tok;
int tok_status;
struct
{
qse_xli_io_impl_t impl; /* input handler */