added qse_xli_definepair() and qse_xli_undefinepair().

renamed some xli functions.
updated cmd/httpd to utilize qse_xli_definepair()
This commit is contained in:
hyung-hwan 2013-07-12 15:37:29 +00:00
parent 67c47e906d
commit 2b58fc6fe3
8 changed files with 515 additions and 296 deletions

View File

@ -68,7 +68,6 @@ enum
XCFG_ROOT,
XCFG_REALM,
XCFG_AUTH,
XCFG_NOAUTH,
XCFG_DIRHEAD,
XCFG_DIRFOOT,
XCFG_ERRHEAD,
@ -846,8 +845,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_findpair (httpd_xtn->xli, list, loc_xcfg_items[i].x);
if (!pair) pair = qse_xli_findpair (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 +859,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_findpair (httpd_xtn->xli, list, QSE_T("index"));
if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.index"));
if (pair && pair->val->type == QSE_XLI_STR)
{
qse_char_t* duptmp;
@ -870,7 +869,7 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
duptmp = qse_xli_dupflatstr (httpd_xtn->xli, (qse_xli_str_t*)pair->val, &duplen, &count);
if (duptmp == QSE_NULL)
{
qse_printf (QSE_T("ERROR: in copying index\n"));
qse_printf (QSE_T("ERROR: memory failure in copying index\n"));
return -1;
}
@ -879,29 +878,26 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
if (cfg->index.files == QSE_NULL)
{
qse_printf (QSE_T("ERROR: in copying index\n"));
qse_printf (QSE_T("ERROR: memory failure in copying index\n"));
return -1;
}
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_findpair (httpd_xtn->xli, list, QSE_T("cgi"));
if (!pair) pair = qse_xli_findpair (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 */
qse_xli_list_t* cgilist = (qse_xli_list_t*)pair->val;
for (atom = cgilist->head; atom; atom = atom->next)
{
struct cgi_t* cgi;
int type;
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (pair->key && pair->alias &&
(pair->val->type == QSE_XLI_NIL || pair->val->type == QSE_XLI_STR))
{
struct cgi_t* cgi;
int type;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = CGI_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = CGI_SUFFIX;
@ -961,27 +957,25 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
cfg->cgi[type].tail = cgi;
}
}
}
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_findpair (httpd_xtn->xli, list, QSE_T("auth-rule"));
if (!pair) pair = qse_xli_findpair (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;
for (atom = auth_rule_list->head; atom; atom = atom->next)
{
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (pair->key && pair->val->type == QSE_XLI_STR)
{
struct auth_rule_t* auth_rule;
int type;
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;
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = AUTH_RULE_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = AUTH_RULE_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = AUTH_RULE_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0) type = AUTH_RULE_OTHER;
else continue;
auth_rule = qse_httpd_callocmem (httpd, QSE_SIZEOF(*auth_rule));
@ -1013,27 +1007,25 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
cfg->auth_rule[type].tail = auth_rule;
}
}
}
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_findpair (httpd_xtn->xli, list, QSE_T("mime"));
if (!pair) pair = qse_xli_findpair (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;
for (atom = mimelist->head; atom; atom = atom->next)
{
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (pair->key && pair->val->type == QSE_XLI_STR)
{
struct mime_t* mime;
int type;
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;
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = MIME_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = MIME_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = MIME_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0) type = MIME_OTHER;
else continue;
mime = qse_httpd_callocmem (httpd, QSE_SIZEOF(*mime));
@ -1068,31 +1060,29 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
cfg->mime[type].tail = mime;
}
}
}
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_findpair (httpd_xtn->xli, list, loc_acc_items[i].x);
if (!pair) pair = qse_xli_findpair (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;
for (atom = acclist->head; atom; atom = atom->next)
{
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (pair->key && pair->val->type == QSE_XLI_STR)
{
struct access_t* acc;
const qse_char_t* tmp;
qse_size_t len;
int type, value;
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;
if (atom->type != QSE_XLI_PAIR) continue;
pair = (qse_xli_pair_t*)atom;
if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = ACCESS_PREFIX;
else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = ACCESS_SUFFIX;
else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = ACCESS_NAME;
else if (qse_strcmp (pair->key, QSE_T("other")) == 0) type = ACCESS_OTHER;
else continue;
tmp = ((qse_xli_str_t*)pair->val)->ptr;
@ -1131,7 +1121,6 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg)
}
}
}
}
/* TODO: support multiple auth entries here and above */
@ -1208,8 +1197,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_findpair (httpd_xtn->xli, list, scfg_items[i].x);
if (!pair) pair = qse_xli_findpair (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 +1212,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_getnumpairs (httpd_xtn->xli, list, QSE_T("host"));
if (host_count <= 0) return 0; /* nothing to load */
QSE_ASSERT (server_xtn->cfgtab == QSE_NULL);
@ -1246,12 +1235,12 @@ 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_findpair (httpd_xtn->xli, list, buf);
if (!host) break;
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_getnumpairs (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->alias[0] == QSE_T('\0')? QSE_T("*"):host->alias))) == QSE_NULL)) goto oops;
@ -1263,7 +1252,7 @@ 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_findpair (httpd_xtn->xli, (qse_xli_list_t*)host->val, buf);
if (!loc) break;
if (loc->val->type == QSE_XLI_LIST && loc->alias)
@ -1335,7 +1324,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_findpair (httpd_xtn->xli, list, QSE_T("bind"));
if (pair == QSE_NULL || pair->val->type != QSE_XLI_STR)
{
/* TOOD: logging */
@ -1351,8 +1340,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_findpair (httpd_xtn->xli, list, QSE_T("ssl"));
if (!pair) pair = qse_xli_findpair (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;
@ -1389,7 +1378,94 @@ static int open_config_file (qse_httpd_t* httpd)
{
httpd_xtn_t* httpd_xtn;
qse_xli_iostd_t xli_in;
int trait;
int trait, i;
static struct
{
const qse_char_t* name;
qse_xli_scm_t scm;
} defs[] =
{
{ QSE_T("name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("max-nofile"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("max-nproc"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server-default.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server-default.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } },
{ QSE_T("server-default.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server-default.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server-default.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server-default.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server"), { QSE_XLI_SCM_VALLIST, 0, 0 } },
{ QSE_T("server.bind"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.ssl"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } },
{ QSE_T("server.host.location"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } },
{ QSE_T("server.host.location.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server.host.location.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server.host.location.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } },
{ QSE_T("server.host.location.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server.host.location.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server.host.location.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server.host.location.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }
};
httpd_xtn = (httpd_xtn_t*) qse_httpd_getxtnstd (httpd);
QSE_ASSERT (httpd_xtn->xli == QSE_NULL);
@ -1402,16 +1478,40 @@ static int open_config_file (qse_httpd_t* httpd)
}
qse_xli_getopt (httpd_xtn->xli, QSE_XLI_TRAIT, &trait);
trait |= QSE_XLI_KEYALIAS;
trait |= QSE_XLI_VALIDATE;
qse_xli_setopt (httpd_xtn->xli, QSE_XLI_TRAIT, &trait);
for (i = 0; i < QSE_COUNTOF(defs); i++)
{
if (qse_xli_definepair (httpd_xtn->xli, defs[i].name, &defs[i].scm) <= -1)
{
qse_fprintf (QSE_STDERR, QSE_T("Cannot define %s - %s\n"), defs[i].name, qse_xli_geterrmsg(httpd_xtn->xli));
qse_xli_close (httpd_xtn->xli);
httpd_xtn->xli = QSE_NULL;
return -1;
}
}
xli_in.type = QSE_XLI_IOSTD_FILE;
xli_in.u.file.path = httpd_xtn->cfgfile;
xli_in.u.file.cmgr = QSE_NULL;
if (qse_xli_readstd (httpd_xtn->xli, &xli_in) <= -1)
{
const qse_xli_loc_t* errloc;
errloc = qse_xli_geterrloc (httpd_xtn->xli);
if (errloc->line > 0 || errloc->colm > 0)
{
qse_fprintf (QSE_STDERR, QSE_T("Cannot load %s at line %lu column %lu - %s\n"),
xli_in.u.file.path, (unsigned long int)errloc->line, (unsigned long int)errloc->colm, qse_xli_geterrmsg(httpd_xtn->xli));
}
else
{
qse_fprintf (QSE_STDERR, QSE_T("Cannot load %s - %s\n"), xli_in.u.file.path, qse_xli_geterrmsg(httpd_xtn->xli));
}
qse_xli_close (httpd_xtn->xli);
httpd_xtn->xli = QSE_NULL;
return -1;
@ -1440,12 +1540,14 @@ 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);
if (pair && pair->val->type == QSE_XLI_STR)
pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, name);
if (pair)
{
#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
struct rlimit lim;
QSE_ASSERT (pair->val->type == QSE_XLI_STR);
if (getrlimit (what, &lim) == 0)
{
const qse_char_t* str;
@ -1479,10 +1581,12 @@ 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"));
if (pair && pair->val->type == QSE_XLI_STR)
pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("name"));
if (pair)
{
qse_mchar_t* tmp;
QSE_ASSERT (pair->val->type == QSE_XLI_STR);
tmp = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len);
if (tmp) qse_httpd_setname (httpd, tmp);
qse_httpd_freemem (httpd, tmp);
@ -1499,7 +1603,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_findpair (httpd_xtn->xli, QSE_NULL, buf);
if (pair == QSE_NULL) break;
if (pair->val->type != QSE_XLI_LIST)
@ -1529,7 +1633,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_findpair (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 +1667,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_findpair (httpd_xtn->xli, QSE_NULL, buf);
if (pair && pair->val->type == QSE_XLI_LIST)
{

View File

@ -37,6 +37,7 @@ server-default {
cgi {
#name "t3.nph" = "nph";
#prefix "t3." = "nph";
suffix ".cgi";
suffix ".nph" = "nph";
suffix ".awk" = "cgi", "/usr/bin/qseawk -f";

View File

@ -357,16 +357,104 @@ static int xli_main (int argc, qse_char_t* argv[])
qse_xli_setopt (xli, QSE_XLI_TRAIT, &g_trait);
}
#if 0
{
int i;
static struct
{
const qse_char_t* name;
qse_xli_scm_t scm;
} defs[] =
{
{ QSE_T("name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("max-nofile"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("max-nproc"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server-default.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server-default.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } },
{ QSE_T("server-default.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server-default.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server-default.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server-default.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server-default.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server-default.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server-default.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server"), { QSE_XLI_SCM_VALLIST, 0, 0 } },
{ QSE_T("server.bind"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.ssl"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } },
{ QSE_T("server.host.location"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } },
{ QSE_T("server.host.location.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server.host.location.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } },
{ QSE_T("server.host.location.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } },
{ QSE_T("server.host.location.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server.host.location.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server.host.location.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } },
{ QSE_T("server.host.location.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } },
{ QSE_T("server.host.location.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } },
{ QSE_T("server.host.location.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } },
{ QSE_T("server.host.location.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }
};
for (i = 0; i < QSE_COUNTOF(defs); i++) qse_xli_definepair (xli, defs[i].name, &defs[i].scm);
}
#endif
in.type = QSE_XLI_IOSTD_FILE;
in.u.file.path = g_input_file;
in.u.file.cmgr = g_infile_cmgr;
{
qse_xli_scm_t scm;
scm.flags = QSE_XLI_SCM_VAL_LIST | QSE_XLI_SCM_KEY_NODUP;
qse_xli_setschema (xli, QSE_T("a.b"), &scm);
}
if (qse_xli_readstd (xli, &in) <= -1)
{
const qse_xli_loc_t* errloc;
@ -399,7 +487,7 @@ qse_xli_setschema (xli, QSE_T("a.b"), &scm);
if (g_lookup_key)
{
qse_xli_pair_t* pair;
pair = qse_xli_findpairbyname (xli, QSE_NULL, g_lookup_key);
pair = qse_xli_findpair (xli, QSE_NULL, g_lookup_key);
if (pair == QSE_NULL)
{
qse_fprintf (QSE_STDERR,

View File

@ -57,18 +57,6 @@ enum qse_bool_t
};
typedef enum qse_bool_t qse_bool_t;
/**
* The qse_tri_t type defines a tri-state type that can represent #QSE_ALIVE,
* #QSE_ZOMBIE, and #QSE_DEAD.
*/
enum qse_tri_t
{
QSE_ALIVE = 1,
QSE_ZOMBIE = 0,
QSE_DEAD = -1
};
typedef enum qse_tri_t qse_tri_t;
/** @typedef qse_int_t
* The qse_int_t type defines a signed integer type as large as a pointer.
*/

View File

@ -50,8 +50,10 @@ enum qse_xli_errnum_t
QSE_XLI_ELXCHR, /**< invalid character '${0} */
QSE_XLI_EXKWNR, /**< @word '${0}' not recognized */
QSE_XLI_EXKWEM, /**< @ not followed by a valid word */
QSE_XLI_EILKEY, /**< illegal key '${0}' */
QSE_XLI_EUDKEY, /**< undefined key '${0}' */
QSE_XLI_ENOALI, /**< no alias for '${0}' */
QSE_XLI_EILVAL, /**< illegal value for '${0}' */
QSE_XLI_ENOVAL, /**< no value for '${0}' */
QSE_XLI_ESTRSEG /**< too many string segments for '${0}' */
};
typedef enum qse_xli_errnum_t qse_xli_errnum_t;
@ -295,12 +297,12 @@ typedef qse_ssize_t (*qse_xli_io_impl_t) (
enum qse_xli_scm_flag_t
{
QSE_XLI_SCM_REQUIRED = (1 << 0),
QSE_XLI_SCM_VAL_NIL = (1 << 1),
QSE_XLI_SCM_VAL_STR = (1 << 2),
QSE_XLI_SCM_VAL_LIST = (1 << 3),
QSE_XLI_SCM_KEY_NODUP = (1 << 4),
QSE_XLI_SCM_KEY_ALIAS = (1 << 5)
/*QSE_XLI_SCM_REQUIRED = (1 << 0), TODO: support this. */
QSE_XLI_SCM_VALNIL = (1 << 1),
QSE_XLI_SCM_VALSTR = (1 << 2),
QSE_XLI_SCM_VALLIST = (1 << 3),
QSE_XLI_SCM_KEYNODUP = (1 << 4),
QSE_XLI_SCM_KEYALIAS = (1 << 5)
};
struct qse_xli_scm_t
@ -542,13 +544,13 @@ QSE_EXPORT qse_xli_eof_t* qse_xli_inserteof (
qse_xli_atom_t* peer
);
QSE_EXPORT qse_xli_pair_t* qse_xli_findpairbyname (
QSE_EXPORT qse_xli_pair_t* qse_xli_findpair (
qse_xli_t* xli,
const qse_xli_list_t* list,
const qse_char_t* dotted_name
);
QSE_EXPORT qse_size_t qse_xli_getnumpairsbyname (
QSE_EXPORT qse_size_t qse_xli_getnumpairs (
qse_xli_t* xli,
const qse_xli_list_t* list,
const qse_char_t* dotted_name
@ -586,20 +588,26 @@ QSE_EXPORT void qse_xli_clearroot (
qse_xli_t* xli
);
QSE_EXPORT void qse_xli_clearschema (
qse_xli_t* xli
);
QSE_EXPORT void qse_xli_clear (
qse_xli_t* xli
);
QSE_EXPORT int qse_xli_setschema (
QSE_EXPORT int qse_xli_definepair (
qse_xli_t* xli,
const qse_char_t* dotted_name,
const qse_char_t* pair_name,
const qse_xli_scm_t* scm
);
QSE_EXPORT int qse_xli_undefinepair (
qse_xli_t* xli,
const qse_char_t* pair_name
);
QSE_EXPORT void qse_xli_undefinepairs (
qse_xli_t* xli
);
QSE_EXPORT int qse_xli_read (
qse_xli_t* xli,
qse_xli_io_impl_t io

View File

@ -49,8 +49,10 @@ const qse_char_t* qse_xli_dflerrstr (
QSE_T("invalid character '${0}'"),
QSE_T("'${0}' not recognized"),
QSE_T("@ not followed by a valid word"),
QSE_T("illegal key '${0}'"),
QSE_T("undefined key '${0}'"),
QSE_T("no alias for '${0}'"),
QSE_T("illegal value for '${0}'"),
QSE_T("no value for '${0}'"),
QSE_T("too many string segments for '${0}'")
};

View File

@ -600,7 +600,9 @@ 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_xli_scm_t* scm = QSE_NULL;
int key_nodup = 0, key_alias = 0;
key.ptr = QSE_NULL;
name = QSE_NULL;
@ -608,7 +610,44 @@ static int read_pair (qse_xli_t* xli)
parlist = xli->parlink->list;
if (xli->opt.trait & QSE_XLI_KEYNODUP)
if (xli->opt.trait & QSE_XLI_KEYNODUP) key_nodup = 1;
if (xli->opt.trait & QSE_XLI_KEYALIAS) key_alias = 1;
kloc = xli->tok.loc;
key.len = QSE_STR_LEN(xli->tok.name);
key.ptr = qse_strdup (QSE_STR_PTR(xli->tok.name), xli->mmgr);
if (key.ptr == QSE_NULL)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops;
}
dotted_curkey_len = QSE_STR_LEN (xli->dotted_curkey);
if ((dotted_curkey_len > 0 && qse_str_cat (xli->dotted_curkey, QSE_T(".")) == (qse_size_t)-1) ||
qse_str_cat (xli->dotted_curkey, key.ptr) == (qse_size_t)-1)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops;
}
if (xli->opt.trait & QSE_XLI_VALIDATE)
{
qse_rbt_pair_t* pair;
pair = qse_rbt_search (xli->schema, QSE_STR_PTR(xli->dotted_curkey), QSE_STR_LEN(xli->dotted_curkey));
if (pair == QSE_NULL)
{
qse_xli_seterror (xli, QSE_XLI_EUDKEY, (const qse_cstr_t*)&key, &kloc);
goto oops;
}
scm = (qse_xli_scm_t*)QSE_RBT_VPTR(pair);
if (scm->flags & QSE_XLI_SCM_KEYNODUP) key_nodup = 2;
if (scm->flags & QSE_XLI_SCM_KEYALIAS) key_alias = 2;
}
if (key_nodup)
{
qse_xli_atom_t* atom;
@ -628,47 +667,11 @@ static int read_pair (qse_xli_t* xli)
}
}
kloc = xli->tok.loc;
key.len = QSE_STR_LEN(xli->tok.name);
key.ptr = qse_strdup (QSE_STR_PTR(xli->tok.name), xli->mmgr);
if (key.ptr == QSE_NULL)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops;
}
dotted_curkey_len = QSE_STR_LEN (xli->dotted_curkey);
if ((dotted_curkey_len > 0 && qse_str_cat (xli->dotted_curkey, QSE_T(".")) == (qse_size_t)-1) ||
qse_str_cat (xli->dotted_curkey, key.ptr) == (qse_size_t)-1)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops;
}
if (xli->opt.trait & QSE_XLI_VALIDATE)
{
qse_rbt_pair_t* pair;
pair = qse_rbt_search (xli->schema, QSE_STR_PTR(xli->dotted_curkey), QSE_STR_LEN(xli->dotted_curkey));
if (pair == QSE_NULL)
{
qse_xli_seterror (xli, QSE_XLI_EILKEY, (const qse_cstr_t*)&key, &kloc);
goto oops;
}
scm = (qse_xli_scm_t*)QSE_RBT_VPTR(pair);
if (scm->flags & QSE_XLI_SCM_KEY_NODUP)
{
}
}
xli->tok_status |= TOK_STATUS_ENABLE_NSTR;
if (get_token (xli) <= -1) goto oops;
if (xli->opt.trait & QSE_XLI_KEYALIAS)
if (key_alias)
{
/* the name 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))
@ -698,6 +701,13 @@ static int read_pair (qse_xli_t* xli)
if (get_token (xli) <= -1) goto oops;
}
else if (key_alias == 2)
{
/* SCM_KEYALIAS is specified for this particular item. Let the alias be required.
* If KEYALIAS is globally specified with the specific one, it's optional. */
qse_xli_seterrnum (xli, QSE_XLI_ENOALI, &key);
goto oops;
}
}
if (MATCH (xli, TOK_EQ))
@ -709,7 +719,7 @@ static int read_pair (qse_xli_t* xli)
qse_xli_str_t* curstrseg;
qse_size_t segcount = 0;
if (scm && !(scm->flags & QSE_XLI_SCM_VAL_STR))
if (scm && !(scm->flags & QSE_XLI_SCM_VALSTR))
{
/* check the value type */
qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc);
@ -775,7 +785,7 @@ static int read_pair (qse_xli_t* xli)
}
else if (MATCH (xli, TOK_LBRACE))
{
if (scm && !(scm->flags & QSE_XLI_SCM_VAL_LIST))
if (scm && !(scm->flags & QSE_XLI_SCM_VALLIST))
{
/* check the value type */
qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc);
@ -809,10 +819,11 @@ static int read_pair (qse_xli_t* xli)
}
else if (MATCH (xli, TOK_SEMICOLON))
{
if (scm && !(scm->flags & QSE_XLI_SCM_VAL_NIL))
if (scm && !(scm->flags & QSE_XLI_SCM_VALNIL) &&
!((scm->flags & QSE_XLI_SCM_VALSTR) && scm->str_minseg <= 0))
{
/* check the value type */
qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc);
qse_xli_seterror (xli, QSE_XLI_ENOVAL, (const qse_cstr_t*)&key, &kloc);
goto oops;
}

View File

@ -64,6 +64,7 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr)
xli->schema = qse_rbt_open (mmgr, 0, QSE_SIZEOF(qse_char_t), 1);
if (xli->schema == QSE_NULL) goto oops;
qse_rbt_setstyle (xli->schema, qse_getrbtstyle(QSE_RBT_STYLE_INLINE_COPIERS));
xli->root.type = QSE_XLI_LIST;
xli->xnil.type = QSE_XLI_NIL;
@ -394,10 +395,6 @@ void qse_xli_clearroot (qse_xli_t* xli)
free_list (xli, &xli->root);
}
void qse_xli_clearschema (qse_xli_t* xli)
{
qse_rbt_clear (xli->schema);
}
/* ------------------------------------------------------ */
@ -481,7 +478,7 @@ static qse_xli_pair_t* find_pair_by_key_and_index (
return QSE_NULL;
}
qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* dotted_name)
qse_xli_pair_t* qse_xli_findpair (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* pair_name)
{
const qse_char_t* ptr;
const qse_xli_list_t* curlist;
@ -490,7 +487,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li
curlist = list? list: &xli->root;
ptr = dotted_name;
ptr = pair_name;
while (1)
{
seg.ptr = ptr;
@ -596,7 +593,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* dotted_name)
qse_size_t qse_xli_getnumpairs (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* pair_name)
{
const qse_char_t* ptr;
const qse_xli_list_t* curlist;
@ -605,7 +602,7 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list
curlist = list? list: &xli->root;
ptr = dotted_name;
ptr = pair_name;
while (1)
{
seg.ptr = ptr;
@ -768,20 +765,21 @@ qse_char_t* qse_xli_dupflatstr (qse_xli_t* xli, qse_xli_str_t* str, qse_size_t*
return tmp;
}
/* ------------------------------------------------------ */
int qse_xli_setschema (qse_xli_t* xli, const qse_char_t* dotted_name, const qse_xli_scm_t* scm)
int qse_xli_definepair (qse_xli_t* xli, const qse_char_t* pair_name, const qse_xli_scm_t* scm)
{
int tmp;
tmp = scm->flags & (QSE_XLI_SCM_VAL_LIST | QSE_XLI_SCM_VAL_STR | QSE_XLI_SCM_VAL_NIL);
if (tmp != QSE_XLI_SCM_VAL_LIST && tmp != QSE_XLI_SCM_VAL_STR && tmp != QSE_XLI_SCM_VAL_NIL)
tmp = scm->flags & (QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_VALNIL);
if (tmp != QSE_XLI_SCM_VALLIST && tmp != QSE_XLI_SCM_VALSTR && tmp != QSE_XLI_SCM_VALNIL)
{
/* VAL_LIST, VAL_STR, VAL_NIL can't co-exist */
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
return -1;
}
if (qse_rbt_upsert (xli->schema, dotted_name, qse_strlen(dotted_name), scm, QSE_SIZEOF(scm)) == QSE_NULL)
if (qse_rbt_upsert (xli->schema, pair_name, qse_strlen(pair_name), scm, QSE_SIZEOF(*scm)) == QSE_NULL)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
return -1;
@ -789,3 +787,22 @@ int qse_xli_setschema (qse_xli_t* xli, const qse_char_t* dotted_name, const qse_
return 0;
}
int qse_xli_undefinepair (qse_xli_t* xli, const qse_char_t* pair_name)
{
if (qse_rbt_delete (xli->schema, pair_name, qse_strlen(pair_name)) <= -1)
{
qse_cstr_t ea;
ea.ptr = pair_name;
ea.len = qse_strlen (ea.ptr);
qse_xli_seterrnum (xli, QSE_XLI_ENOENT, &ea);
return -1;
}
return 0;
}
void qse_xli_undefinepairs (qse_xli_t* xli)
{
qse_rbt_clear (xli->schema);
}