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:
		| @ -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)  | ||||
| 		{ | ||||
|  | ||||
| @ -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"; | ||||
|  | ||||
| @ -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,  | ||||
|  | ||||
| @ -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. | ||||
|  */ | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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}'") | ||||
| 	}; | ||||
|  | ||||
|  | ||||
| @ -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;	 | ||||
| 		} | ||||
|  | ||||
|  | ||||
| @ -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); | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user