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_ROOT, | ||||||
| 	XCFG_REALM, | 	XCFG_REALM, | ||||||
| 	XCFG_AUTH, | 	XCFG_AUTH, | ||||||
| 	XCFG_NOAUTH, |  | ||||||
| 	XCFG_DIRHEAD, | 	XCFG_DIRHEAD, | ||||||
| 	XCFG_DIRFOOT, | 	XCFG_DIRFOOT, | ||||||
| 	XCFG_ERRHEAD, | 	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++) | 	for (i = 0; i < QSE_COUNTOF(loc_xcfg_items); i++) | ||||||
| 	{ | 	{ | ||||||
| 		pair = qse_xli_findpairbyname (httpd_xtn->xli, list, loc_xcfg_items[i].x); | 		pair = qse_xli_findpair (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); | 		if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, loc_xcfg_items[i].y); | ||||||
| 		if (pair && pair->val->type == QSE_XLI_STR) | 		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); | 			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")); | 	pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("index")); | ||||||
| 	if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.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) | 	if (pair && pair->val->type == QSE_XLI_STR) | ||||||
| 	{ | 	{ | ||||||
| 		qse_char_t* duptmp; | 		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); | 		duptmp = qse_xli_dupflatstr (httpd_xtn->xli, (qse_xli_str_t*)pair->val, &duplen, &count); | ||||||
| 		if (duptmp == QSE_NULL) | 		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; | 			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)  | 		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; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cfg->index.count = count; | 		cfg->index.count = count; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("cgi")); | 	pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("cgi")); | ||||||
| 	if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.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) | 	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; | 		qse_xli_list_t* cgilist = (qse_xli_list_t*)pair->val; | ||||||
| 		for (atom = cgilist->head; atom; atom = atom->next) | 		for (atom = cgilist->head; atom; atom = atom->next) | ||||||
| 		{ | 		{ | ||||||
|  | 			struct cgi_t* cgi; | ||||||
|  | 			int type; | ||||||
|  |  | ||||||
| 			if (atom->type != QSE_XLI_PAIR) continue; | 			if (atom->type != QSE_XLI_PAIR) continue; | ||||||
|  |  | ||||||
| 			pair = (qse_xli_pair_t*)atom; | 			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; | 			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; | 			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; | 			cfg->cgi[type].tail = cgi; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("auth-rule")); | 	pair = qse_xli_findpair (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")); | 	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) | 	if (pair && pair->val->type == QSE_XLI_LIST) | ||||||
| 	{ | 	{ | ||||||
| 		qse_xli_list_t* auth_rule_list = (qse_xli_list_t*)pair->val; | 		qse_xli_list_t* auth_rule_list = (qse_xli_list_t*)pair->val; | ||||||
| 		for (atom = auth_rule_list->head; atom; atom = atom->next) | 		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; | 			struct auth_rule_t* auth_rule; | ||||||
| 			int type; | 			int type; | ||||||
|  |  | ||||||
| 				if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = AUTH_RULE_PREFIX; | 			if (atom->type != QSE_XLI_PAIR) continue; | ||||||
| 				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; | 			pair = (qse_xli_pair_t*)atom; | ||||||
| 				else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = AUTH_RULE_OTHER; |  | ||||||
|  | 			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; | 			else continue; | ||||||
|  |  | ||||||
| 			auth_rule = qse_httpd_callocmem (httpd, QSE_SIZEOF(*auth_rule)); | 			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; | 			cfg->auth_rule[type].tail = auth_rule; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("mime")); | 	pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("mime")); | ||||||
| 	if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.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) | 	if (pair && pair->val->type == QSE_XLI_LIST) | ||||||
| 	{ | 	{ | ||||||
| 		qse_xli_list_t* mimelist = (qse_xli_list_t*)pair->val; | 		qse_xli_list_t* mimelist = (qse_xli_list_t*)pair->val; | ||||||
| 		for (atom = mimelist->head; atom; atom = atom->next) | 		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; | 			struct mime_t* mime; | ||||||
| 			int type; | 			int type; | ||||||
|  |  | ||||||
| 				if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = MIME_PREFIX; | 			if (atom->type != QSE_XLI_PAIR) continue; | ||||||
| 				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; | 			pair = (qse_xli_pair_t*)atom; | ||||||
| 				else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = MIME_OTHER; |  | ||||||
|  | 			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; | 			else continue; | ||||||
|  |  | ||||||
| 			mime = qse_httpd_callocmem (httpd, QSE_SIZEOF(*mime)); | 			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; | 			cfg->mime[type].tail = mime; | ||||||
| 		} | 		} | ||||||
| 	}	 | 	}	 | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for (i = 0; i < 2;  i++) | 	for (i = 0; i < 2;  i++) | ||||||
| 	{ | 	{ | ||||||
| 		pair = qse_xli_findpairbyname (httpd_xtn->xli, list, loc_acc_items[i].x); | 		pair = qse_xli_findpair (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); | 		if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, loc_acc_items[i].y); | ||||||
| 		if (pair && pair->val->type == QSE_XLI_LIST) | 		if (pair && pair->val->type == QSE_XLI_LIST) | ||||||
| 		{ | 		{ | ||||||
| 			qse_xli_list_t* acclist = (qse_xli_list_t*)pair->val; | 			qse_xli_list_t* acclist = (qse_xli_list_t*)pair->val; | ||||||
| 			for (atom = acclist->head; atom; atom = atom->next) | 			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; | 				struct access_t* acc; | ||||||
| 				const qse_char_t* tmp; | 				const qse_char_t* tmp; | ||||||
| 				qse_size_t len; | 				qse_size_t len; | ||||||
| 				int type, value; | 				int type, value; | ||||||
|  |  | ||||||
| 					if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = ACCESS_PREFIX; | 				if (atom->type != QSE_XLI_PAIR) continue; | ||||||
| 					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; | 				pair = (qse_xli_pair_t*)atom; | ||||||
| 					else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = ACCESS_OTHER; | 	 | ||||||
|  | 				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; | 				else continue; | ||||||
|  |  | ||||||
| 				tmp = ((qse_xli_str_t*)pair->val)->ptr; | 				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 */ | 	/* 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; | 		qse_xli_pair_t* pair; | ||||||
|  |  | ||||||
| 		pair = qse_xli_findpairbyname (httpd_xtn->xli, list, scfg_items[i].x); | 		pair = qse_xli_findpair (httpd_xtn->xli, list, scfg_items[i].x); | ||||||
| 		if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, scfg_items[i].y); | 		if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, scfg_items[i].y); | ||||||
| 		if (pair && pair->val->type == QSE_XLI_STR) | 		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); | 			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 */ | 	/* 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 */ | 	if (host_count <= 0) return 0; /* nothing to load */ | ||||||
|  |  | ||||||
| 	QSE_ASSERT (server_xtn->cfgtab == QSE_NULL); | 	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_char_t buf[32]; | ||||||
|  |  | ||||||
| 		qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("host[%d]"), i); | 		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) break; | ||||||
|  |  | ||||||
| 		if (host->val->type == QSE_XLI_LIST && host->alias)  | 		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) || | 			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; | 			    ((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--; | 				j--; | ||||||
|  |  | ||||||
| 				qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("location[%d]"), 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) break; | ||||||
|  |  | ||||||
| 				if (loc->val->type == QSE_XLI_LIST && loc->alias)  | 				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); | 	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) | 	if (pair == QSE_NULL || pair->val->type != QSE_XLI_STR) | ||||||
| 	{ | 	{ | ||||||
| 		/* TOOD: logging */ | 		/* 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; | 		return QSE_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("ssl")); | 	pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("ssl")); | ||||||
| 	if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.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 &&  | 	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;	 | 	    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; | 	httpd_xtn_t* httpd_xtn; | ||||||
| 	qse_xli_iostd_t xli_in; | 	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); | 	httpd_xtn = (httpd_xtn_t*) qse_httpd_getxtnstd (httpd); | ||||||
| 	QSE_ASSERT (httpd_xtn->xli == QSE_NULL); | 	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); | 	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); | 	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.type = QSE_XLI_IOSTD_FILE; | ||||||
| 	xli_in.u.file.path = httpd_xtn->cfgfile; | 	xli_in.u.file.path = httpd_xtn->cfgfile; | ||||||
| 	xli_in.u.file.cmgr = QSE_NULL; | 	xli_in.u.file.cmgr = QSE_NULL; | ||||||
| 	 | 	 | ||||||
| 	if (qse_xli_readstd (httpd_xtn->xli, &xli_in) <= -1) | 	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_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); | 		qse_xli_close (httpd_xtn->xli); | ||||||
| 		httpd_xtn->xli = QSE_NULL; | 		httpd_xtn->xli = QSE_NULL; | ||||||
| 		return -1; | 		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); | 	httpd_xtn = (httpd_xtn_t*)qse_httpd_getxtnstd (httpd); | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, name); | 	pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, name); | ||||||
| 	if (pair && pair->val->type == QSE_XLI_STR) | 	if (pair) | ||||||
| 	{ | 	{ | ||||||
| #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) | #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) | ||||||
| 		struct rlimit lim; | 		struct rlimit lim; | ||||||
|  |  | ||||||
|  | 		QSE_ASSERT (pair->val->type == QSE_XLI_STR); | ||||||
|  |  | ||||||
| 		if (getrlimit (what, &lim) == 0) | 		if (getrlimit (what, &lim) == 0) | ||||||
| 		{ | 		{ | ||||||
| 			const qse_char_t* str; | 			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; | 	if (open_config_file (httpd) <= -1) goto oops; | ||||||
|  |  | ||||||
| 	pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("name")); | 	pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("name")); | ||||||
| 	if (pair && pair->val->type == QSE_XLI_STR) | 	if (pair) | ||||||
| 	{ | 	{ | ||||||
| 		qse_mchar_t* tmp; | 		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); | 		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); | 		if (tmp) qse_httpd_setname (httpd, tmp); | ||||||
| 		qse_httpd_freemem (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_char_t buf[32]; | ||||||
| 		qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("server[%d]"), i); | 		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 == QSE_NULL) break; | ||||||
|  |  | ||||||
| 		if (pair->val->type != QSE_XLI_LIST) | 		if (pair->val->type != QSE_XLI_LIST) | ||||||
| @ -1529,7 +1633,7 @@ static int load_config (qse_httpd_t* httpd) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* load the global default */ | 	/* 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 (pair && pair->val->type == QSE_XLI_LIST) | ||||||
| 	{ | 	{ | ||||||
| 		if (load_loccfg (httpd, (qse_xli_list_t*)pair->val, &httpd_xtn->dflcfg) <=  -1) | 		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_char_t buf[32]; | ||||||
| 		qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("server[%d]"), server_xtn->num); | 		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)  | 		if (pair && pair->val->type == QSE_XLI_LIST)  | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
| @ -37,6 +37,7 @@ server-default { | |||||||
|  |  | ||||||
| 	cgi { | 	cgi { | ||||||
| 		#name "t3.nph" = "nph"; | 		#name "t3.nph" = "nph"; | ||||||
|  | 		#prefix "t3." = "nph"; | ||||||
| 		suffix ".cgi"; | 		suffix ".cgi"; | ||||||
| 		suffix ".nph" = "nph"; | 		suffix ".nph" = "nph"; | ||||||
| 		suffix ".awk" = "cgi", "/usr/bin/qseawk -f"; | 		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); | 		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.type = QSE_XLI_IOSTD_FILE; | ||||||
| 	in.u.file.path = g_input_file; | 	in.u.file.path = g_input_file; | ||||||
| 	in.u.file.cmgr = g_infile_cmgr; | 	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) | 	if (qse_xli_readstd (xli, &in) <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		const qse_xli_loc_t* errloc; | 		const qse_xli_loc_t* errloc; | ||||||
| @ -399,7 +487,7 @@ qse_xli_setschema (xli, QSE_T("a.b"), &scm); | |||||||
| 	if (g_lookup_key) | 	if (g_lookup_key) | ||||||
| 	{ | 	{ | ||||||
| 		qse_xli_pair_t* pair; | 		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) | 		if (pair == QSE_NULL) | ||||||
| 		{ | 		{ | ||||||
| 			qse_fprintf (QSE_STDERR,  | 			qse_fprintf (QSE_STDERR,  | ||||||
|  | |||||||
| @ -57,18 +57,6 @@ enum qse_bool_t | |||||||
| }; | }; | ||||||
| typedef enum qse_bool_t 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 | /** @typedef qse_int_t | ||||||
|  * The qse_int_t type defines a signed integer type as large as a pointer. |  * 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_ELXCHR,  /**< invalid character '${0} */ | ||||||
| 	QSE_XLI_EXKWNR,  /**< @word '${0}' not recognized */ | 	QSE_XLI_EXKWNR,  /**< @word '${0}' not recognized */ | ||||||
| 	QSE_XLI_EXKWEM,  /**< @ not followed by a valid word  */ | 	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_EILVAL,  /**< illegal value for '${0}' */ | ||||||
|  | 	QSE_XLI_ENOVAL,  /**< no value for '${0}' */ | ||||||
| 	QSE_XLI_ESTRSEG  /**< too many string segments for '${0}' */ | 	QSE_XLI_ESTRSEG  /**< too many string segments for '${0}' */ | ||||||
| }; | }; | ||||||
| typedef enum qse_xli_errnum_t qse_xli_errnum_t; | 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 | enum qse_xli_scm_flag_t | ||||||
| { | { | ||||||
| 	QSE_XLI_SCM_REQUIRED  = (1 << 0), | 	/*QSE_XLI_SCM_REQUIRED = (1 << 0), TODO: support this. */ | ||||||
| 	QSE_XLI_SCM_VAL_NIL   = (1 << 1), | 	QSE_XLI_SCM_VALNIL   = (1 << 1), | ||||||
| 	QSE_XLI_SCM_VAL_STR   = (1 << 2), | 	QSE_XLI_SCM_VALSTR   = (1 << 2), | ||||||
| 	QSE_XLI_SCM_VAL_LIST  = (1 << 3), | 	QSE_XLI_SCM_VALLIST  = (1 << 3), | ||||||
| 	QSE_XLI_SCM_KEY_NODUP = (1 << 4), | 	QSE_XLI_SCM_KEYNODUP = (1 << 4), | ||||||
| 	QSE_XLI_SCM_KEY_ALIAS = (1 << 5) | 	QSE_XLI_SCM_KEYALIAS = (1 << 5) | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct qse_xli_scm_t | struct qse_xli_scm_t | ||||||
| @ -542,13 +544,13 @@ QSE_EXPORT qse_xli_eof_t* qse_xli_inserteof ( | |||||||
| 	qse_xli_atom_t* peer | 	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, | 	qse_xli_t*            xli, | ||||||
| 	const qse_xli_list_t* list, | 	const qse_xli_list_t* list, | ||||||
| 	const qse_char_t*     dotted_name | 	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, | 	qse_xli_t*            xli, | ||||||
| 	const qse_xli_list_t* list, | 	const qse_xli_list_t* list, | ||||||
| 	const qse_char_t*     dotted_name  | 	const qse_char_t*     dotted_name  | ||||||
| @ -586,20 +588,26 @@ QSE_EXPORT void qse_xli_clearroot ( | |||||||
| 	qse_xli_t* xli | 	qse_xli_t* xli | ||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT void qse_xli_clearschema ( |  | ||||||
| 	qse_xli_t* xli |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| QSE_EXPORT void qse_xli_clear ( | QSE_EXPORT void qse_xli_clear ( | ||||||
| 	qse_xli_t* xli | 	qse_xli_t* xli | ||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_xli_setschema ( | QSE_EXPORT int qse_xli_definepair ( | ||||||
| 	qse_xli_t*           xli, | 	qse_xli_t*           xli, | ||||||
| 	const qse_char_t*    dotted_name, | 	const qse_char_t*    pair_name, | ||||||
| 	const qse_xli_scm_t* scm | 	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_EXPORT int qse_xli_read ( | ||||||
| 	qse_xli_t*        xli, | 	qse_xli_t*        xli, | ||||||
| 	qse_xli_io_impl_t io | 	qse_xli_io_impl_t io | ||||||
|  | |||||||
| @ -49,8 +49,10 @@ const qse_char_t* qse_xli_dflerrstr ( | |||||||
| 		QSE_T("invalid character '${0}'"), | 		QSE_T("invalid character '${0}'"), | ||||||
| 		QSE_T("'${0}' not recognized"), | 		QSE_T("'${0}' not recognized"), | ||||||
| 		QSE_T("@ not followed by a valid word"), | 		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("illegal value for '${0}'"), | ||||||
|  | 		QSE_T("no value for '${0}'"), | ||||||
| 		QSE_T("too many string segments 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_pair_t* pair; | ||||||
| 	qse_xli_list_t* parlist; | 	qse_xli_list_t* parlist; | ||||||
| 	qse_size_t dotted_curkey_len; | 	qse_size_t dotted_curkey_len; | ||||||
|  |  | ||||||
| 	qse_xli_scm_t* scm = QSE_NULL; | 	qse_xli_scm_t* scm = QSE_NULL; | ||||||
|  | 	int key_nodup = 0, key_alias = 0; | ||||||
|  |  | ||||||
| 	key.ptr = QSE_NULL; | 	key.ptr = QSE_NULL; | ||||||
| 	name = QSE_NULL; | 	name = QSE_NULL; | ||||||
| @ -608,7 +610,44 @@ static int read_pair (qse_xli_t* xli) | |||||||
|  |  | ||||||
| 	parlist = xli->parlink->list; | 	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; | 		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; | 	xli->tok_status |= TOK_STATUS_ENABLE_NSTR; | ||||||
|  |  | ||||||
| 	if (get_token (xli) <= -1) goto oops; | 	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) */ | 		/* 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)) | 		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; | 			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)) | 	if (MATCH (xli, TOK_EQ)) | ||||||
| @ -709,7 +719,7 @@ static int read_pair (qse_xli_t* xli) | |||||||
| 			qse_xli_str_t* curstrseg; | 			qse_xli_str_t* curstrseg; | ||||||
| 			qse_size_t segcount = 0; | 			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 */ | 				/* check the value type */ | ||||||
| 				qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc); | 				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)) | 	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 */ | 			/* check the value type */ | ||||||
| 			qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc); | 			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)) | 	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 */ | 			/* 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;	 | 			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); | 	xli->schema = qse_rbt_open (mmgr, 0, QSE_SIZEOF(qse_char_t), 1); | ||||||
| 	if (xli->schema == QSE_NULL) goto oops; | 	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->root.type = QSE_XLI_LIST; | ||||||
| 	xli->xnil.type = QSE_XLI_NIL; | 	xli->xnil.type = QSE_XLI_NIL; | ||||||
| @ -394,10 +395,6 @@ void qse_xli_clearroot (qse_xli_t* xli) | |||||||
| 	free_list (xli, &xli->root); | 	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; | 	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_char_t* ptr; | ||||||
| 	const qse_xli_list_t* curlist; | 	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; | 	curlist = list? list: &xli->root; | ||||||
|  |  | ||||||
| 	ptr = dotted_name; | 	ptr = pair_name; | ||||||
| 	while (1) | 	while (1) | ||||||
| 	{ | 	{ | ||||||
| 		seg.ptr = ptr; | 		seg.ptr = ptr; | ||||||
| @ -596,7 +593,7 @@ noent: | |||||||
| 	return QSE_NULL; | 	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_char_t* ptr; | ||||||
| 	const qse_xli_list_t* curlist; | 	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; | 	curlist = list? list: &xli->root; | ||||||
|  |  | ||||||
| 	ptr = dotted_name; | 	ptr = pair_name; | ||||||
| 	while (1) | 	while (1) | ||||||
| 	{ | 	{ | ||||||
| 		seg.ptr = ptr; | 		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; | 	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; | 	int tmp; | ||||||
|  |  | ||||||
| 	tmp = scm->flags & (QSE_XLI_SCM_VAL_LIST | QSE_XLI_SCM_VAL_STR | 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_VAL_LIST && tmp != QSE_XLI_SCM_VAL_STR && tmp != QSE_XLI_SCM_VAL_NIL) | 	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 */ | 		/* VAL_LIST, VAL_STR, VAL_NIL can't co-exist */ | ||||||
| 		qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); | 		qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); | ||||||
| 		return -1; | 		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); | 		qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); | ||||||
| 		return -1; | 		return -1; | ||||||
| @ -789,3 +787,22 @@ int qse_xli_setschema (qse_xli_t* xli, const qse_char_t* dotted_name, const qse_ | |||||||
|  |  | ||||||
| 	return 0; | 	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