added QSE_XLI_STRTAG and changed related functions and defintions
This commit is contained in:
		| @ -138,6 +138,7 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[]) | |||||||
| 	qse_fprintf (out, QSE_T(" -d                        allow a leading digit in identifiers\n")); | 	qse_fprintf (out, QSE_T(" -d                        allow a leading digit in identifiers\n")); | ||||||
| 	qse_fprintf (out, QSE_T(" -n                        disallow nil\n")); | 	qse_fprintf (out, QSE_T(" -n                        disallow nil\n")); | ||||||
| 	qse_fprintf (out, QSE_T(" -l                        disallow lists\n")); | 	qse_fprintf (out, QSE_T(" -l                        disallow lists\n")); | ||||||
|  | 	qse_fprintf (out, QSE_T(" -T                        allow string tags\n")); | ||||||
| 	qse_fprintf (out, QSE_T(" -v                        perform validation\n")); | 	qse_fprintf (out, QSE_T(" -v                        perform validation\n")); | ||||||
| 	qse_fprintf (out, QSE_T(" -m                 number specify the maximum amount of memory to use in bytes\n")); | 	qse_fprintf (out, QSE_T(" -m                 number specify the maximum amount of memory to use in bytes\n")); | ||||||
| #if defined(QSE_BUILD_DEBUG) | #if defined(QSE_BUILD_DEBUG) | ||||||
| @ -165,9 +166,9 @@ static int handle_args (int argc, qse_char_t* argv[]) | |||||||
| 	static qse_opt_t opt =  | 	static qse_opt_t opt =  | ||||||
| 	{ | 	{ | ||||||
| #if defined(QSE_BUILD_DEBUG) | #if defined(QSE_BUILD_DEBUG) | ||||||
| 		QSE_T("hi:o:uaftsdnlvm:X:"), | 		QSE_T("hi:o:uaftsdnlTvm:X:"), | ||||||
| #else | #else | ||||||
| 		QSE_T("hi:o:uaftsdnlvm:"), | 		QSE_T("hi:o:uaftsdnlTvm:"), | ||||||
| #endif | #endif | ||||||
| 		lng | 		lng | ||||||
| 	}; | 	}; | ||||||
| @ -241,6 +242,10 @@ static int handle_args (int argc, qse_char_t* argv[]) | |||||||
| 				g_trait |= QSE_XLI_NOLIST; | 				g_trait |= QSE_XLI_NOLIST; | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
|  | 			case QSE_T('T'): | ||||||
|  | 				g_trait |= QSE_XLI_STRTAG; | ||||||
|  | 				break; | ||||||
|  |  | ||||||
| 			case QSE_T('v'): | 			case QSE_T('v'): | ||||||
| 				g_trait |= QSE_XLI_VALIDATE; | 				g_trait |= QSE_XLI_VALIDATE; | ||||||
| 				break; | 				break; | ||||||
|  | |||||||
| @ -46,8 +46,10 @@ enum qse_xli_errnum_t | |||||||
| 	QSE_XLI_ERBRCE,  /**< } expected in place of '${0}' */ | 	QSE_XLI_ERBRCE,  /**< } expected in place of '${0}' */ | ||||||
| 	QSE_XLI_EPAVAL,  /**< pair value expected in place of '${0}' */ | 	QSE_XLI_EPAVAL,  /**< pair value expected in place of '${0}' */ | ||||||
| 	QSE_XLI_ESTRNC,  /**< string not closed */ | 	QSE_XLI_ESTRNC,  /**< string not closed */ | ||||||
|  | 	QSE_XLI_ETAGNC,  /**< string tag not closed */ | ||||||
| 	QSE_XLI_EINCLSTR,/**< '@include' not followed by a string */ | 	QSE_XLI_EINCLSTR,/**< '@include' not followed by a string */ | ||||||
| 	QSE_XLI_ELXCHR,  /**< invalid character '${0} */ | 	QSE_XLI_ELXCHR,  /**< invalid character '${0} */ | ||||||
|  | 	QSE_XLI_ETAGCHR, /**< invalid tag 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_EIDENT,  /**< invalid identifier '${0}' */ | 	QSE_XLI_EIDENT,  /**< invalid identifier '${0}' */ | ||||||
| @ -100,7 +102,14 @@ enum qse_xli_trait_t | |||||||
| 	QSE_XLI_NONIL     = (1 << 7),  | 	QSE_XLI_NONIL     = (1 << 7),  | ||||||
| 	QSE_XLI_NOLIST    = (1 << 8), | 	QSE_XLI_NOLIST    = (1 << 8), | ||||||
|  |  | ||||||
| 	QSE_XLI_VALIDATE  = (1 << 9) | 	/** enable a string tag. a string tag is a bracketed word  | ||||||
|  | 	 *  placed in front of a string value. for example,  | ||||||
|  | 	 *    A = [tg] "abc";  | ||||||
|  | 	 *  "tg" is stored into the tag field of qse_xli_str_t.  | ||||||
|  | 	 */ | ||||||
|  | 	QSE_XLI_STRTAG    = (1 << 9),  | ||||||
|  |  | ||||||
|  | 	QSE_XLI_VALIDATE  = (1 << 10) | ||||||
| }; | }; | ||||||
| typedef enum qse_xli_trait_t qse_xli_trait_t; | typedef enum qse_xli_trait_t qse_xli_trait_t; | ||||||
|  |  | ||||||
| @ -155,6 +164,7 @@ struct qse_xli_list_t | |||||||
| struct qse_xli_str_t | struct qse_xli_str_t | ||||||
| { | { | ||||||
| 	QSE_XLI_VAL_HDR; | 	QSE_XLI_VAL_HDR; | ||||||
|  | 	const qse_char_t*  tag; | ||||||
| 	const qse_char_t*  ptr; | 	const qse_char_t*  ptr; | ||||||
| 	qse_size_t         len;  | 	qse_size_t         len;  | ||||||
| 	qse_xli_str_t*     next; | 	qse_xli_str_t*     next; | ||||||
| @ -539,6 +549,7 @@ QSE_EXPORT qse_xli_pair_t* qse_xli_insertpairwithstr ( | |||||||
| 	qse_xli_atom_t*   peer, | 	qse_xli_atom_t*   peer, | ||||||
| 	const qse_char_t* key, | 	const qse_char_t* key, | ||||||
| 	const qse_char_t* alias, | 	const qse_char_t* alias, | ||||||
|  | 	const qse_char_t* tag, | ||||||
| 	const qse_cstr_t* value | 	const qse_cstr_t* value | ||||||
| ); | ); | ||||||
|  |  | ||||||
| @ -592,6 +603,7 @@ QSE_EXPORT qse_size_t qse_xli_countpairs ( | |||||||
| QSE_EXPORT qse_xli_str_t* qse_xli_addsegtostr ( | QSE_EXPORT qse_xli_str_t* qse_xli_addsegtostr ( | ||||||
| 	qse_xli_t*        xli,  | 	qse_xli_t*        xli,  | ||||||
| 	qse_xli_str_t*    str, | 	qse_xli_str_t*    str, | ||||||
|  | 	const qse_char_t* tag, | ||||||
| 	const qse_cstr_t* value | 	const qse_cstr_t* value | ||||||
| ); | ); | ||||||
|  |  | ||||||
| @ -599,7 +611,7 @@ QSE_EXPORT qse_xli_str_t* qse_xli_addsegtostr ( | |||||||
|  * The qse_xli_dupflatstr() function duplicates the character strings |  * The qse_xli_dupflatstr() function duplicates the character strings | ||||||
|  * found in the string list led by \a str and flattens them into a single |  * found in the string list led by \a str and flattens them into a single | ||||||
|  * character string each of whose segment is delimited by '\0' and the last |  * character string each of whose segment is delimited by '\0' and the last | ||||||
|  * segment is delimited by double '\0's. |  * segment is delimited by double '\0's. The string tags are not included. | ||||||
|  */ |  */ | ||||||
| qse_char_t* qse_xli_dupflatstr ( | qse_char_t* qse_xli_dupflatstr ( | ||||||
| 	qse_xli_t*     xli, | 	qse_xli_t*     xli, | ||||||
|  | |||||||
| @ -45,8 +45,10 @@ const qse_char_t* qse_xli_dflerrstr ( | |||||||
| 		QSE_T("right-brace expected in place of '${0}'"), | 		QSE_T("right-brace expected in place of '${0}'"), | ||||||
| 		QSE_T("pair value expected in place of '${0}'"), | 		QSE_T("pair value expected in place of '${0}'"), | ||||||
| 		QSE_T("string not closed"), | 		QSE_T("string not closed"), | ||||||
|  | 		QSE_T("string tag not closed"), | ||||||
| 		QSE_T("'@include' not followed by a string"), | 		QSE_T("'@include' not followed by a string"), | ||||||
| 		QSE_T("invalid character '${0}'"), | 		QSE_T("invalid character '${0}'"), | ||||||
|  | 		QSE_T("invalid tag 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("invalid identifier '${0}'"), | 		QSE_T("invalid identifier '${0}'"), | ||||||
|  | |||||||
| @ -60,6 +60,7 @@ enum tok_t | |||||||
| 	TOK_NSTR, | 	TOK_NSTR, | ||||||
| 	TOK_IDENT, | 	TOK_IDENT, | ||||||
| 	TOK_TEXT, | 	TOK_TEXT, | ||||||
|  | 	TOK_STRTAG, | ||||||
|  |  | ||||||
| 	__TOKEN_COUNT__ | 	__TOKEN_COUNT__ | ||||||
| }; | }; | ||||||
| @ -431,7 +432,7 @@ retry: | |||||||
| 		if (!QSE_ISALPHA (c)) | 		if (!QSE_ISALPHA (c)) | ||||||
| 		{ | 		{ | ||||||
| 			/* this directive is empty, not followed by a valid word */ | 			/* this directive is empty, not followed by a valid word */ | ||||||
| 			qse_xli_seterror (xli, QSE_XLI_EXKWEM, QSE_NULL, &xli->tok.loc); | 			qse_xli_seterror (xli, QSE_XLI_EXKWEM, QSE_NULL, &tok->loc); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -448,7 +449,7 @@ retry: | |||||||
| 		if (type == TOK_IDENT) | 		if (type == TOK_IDENT) | ||||||
| 		{ | 		{ | ||||||
| 			/* this keyword/directive is not recognized */ | 			/* this keyword/directive is not recognized */ | ||||||
| 			qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc); | 			qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_CSTR(tok->name), &tok->loc); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
| 		SET_TOKEN_TYPE (xli, tok, type); | 		SET_TOKEN_TYPE (xli, tok, type); | ||||||
| @ -484,7 +485,7 @@ retry: | |||||||
| 		if (lead_digit && all_digits) | 		if (lead_digit && all_digits) | ||||||
| 		{ | 		{ | ||||||
| 			/* if an identifier begins with a digit, it must contain a non-digits character */ | 			/* if an identifier begins with a digit, it must contain a non-digits character */ | ||||||
| 			qse_xli_seterror (xli, QSE_XLI_EIDENT, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc); | 			qse_xli_seterror (xli, QSE_XLI_EIDENT, QSE_STR_CSTR(tok->name), &tok->loc); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -512,7 +513,7 @@ retry: | |||||||
| 			if (c == QSE_CHAR_EOF) | 			if (c == QSE_CHAR_EOF) | ||||||
| 			{ | 			{ | ||||||
| 				/* the string is not closed */ | 				/* the string is not closed */ | ||||||
| 				qse_xli_seterror (xli, QSE_XLI_ESTRNC, QSE_NULL, &xli->tok.loc); | 				qse_xli_seterror (xli, QSE_XLI_ESTRNC, QSE_NULL, &tok->loc); | ||||||
| 				return -1; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -540,7 +541,7 @@ retry: | |||||||
| 			if (c == QSE_CHAR_EOF) | 			if (c == QSE_CHAR_EOF) | ||||||
| 			{ | 			{ | ||||||
| 				/* the string is not closed */ | 				/* the string is not closed */ | ||||||
| 				qse_xli_seterror (xli, QSE_XLI_ESTRNC, QSE_NULL, &xli->tok.loc); | 				qse_xli_seterror (xli, QSE_XLI_ESTRNC, QSE_NULL, &tok->loc); | ||||||
| 				return -1; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -568,6 +569,46 @@ retry: | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	else if ((xli->opt.trait & QSE_XLI_STRTAG) && c == QSE_T('[')) | ||||||
|  | 	{ | ||||||
|  | 		/* a string tag is a bracketed word placed in front of a string value. | ||||||
|  | 		 *   A = [tg] "abc";  | ||||||
|  | 		 * "tg" is stored into the tag field of qse_xli_str_t.  | ||||||
|  | 		 */ | ||||||
|  |  | ||||||
|  | 		SET_TOKEN_TYPE (xli, tok, TOK_STRTAG); | ||||||
|  | 		 | ||||||
|  | 		while (1) | ||||||
|  | 		{ | ||||||
|  | 			GET_CHAR_TO (xli, c); | ||||||
|  |  | ||||||
|  | 			if (c == QSE_CHAR_EOF) | ||||||
|  | 			{ | ||||||
|  | 				/* the string tag is not closed */ | ||||||
|  | 				qse_xli_seterror (xli, QSE_XLI_ETAGNC, QSE_NULL, &xli->tok.loc); | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (c == QSE_T(']')) | ||||||
|  | 			{ | ||||||
|  | 				/* terminating quote */ | ||||||
|  | 				GET_CHAR (xli); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (!QSE_ISALNUM(c)) | ||||||
|  | 			{ | ||||||
|  | 				qse_char_t cc = (qse_char_t)c; | ||||||
|  | 				qse_cstr_t ea; | ||||||
|  | 				ea.ptr = &cc; | ||||||
|  | 				ea.len = 1; | ||||||
|  | 				qse_xli_seterror (xli, QSE_XLI_ETAGCHR, &ea, &tok->loc); | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			ADD_TOKEN_CHAR (xli, tok, c); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		n = get_symbols (xli, c, tok); | 		n = get_symbols (xli, c, tok); | ||||||
| @ -625,12 +666,14 @@ 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_char_t* tag; | ||||||
|  |  | ||||||
| 	qse_xli_scm_t* scm = QSE_NULL; | 	qse_xli_scm_t* scm = QSE_NULL; | ||||||
| 	int key_nodup = 0, key_alias = 0; | 	int key_nodup = 0, key_alias = 0; | ||||||
|  |  | ||||||
| 	key.ptr = QSE_NULL; | 	key.ptr = QSE_NULL; | ||||||
| 	name = QSE_NULL; | 	name = QSE_NULL; | ||||||
|  | 	tag = QSE_NULL; | ||||||
| 	dotted_curkey_len = (qse_size_t)-1; | 	dotted_curkey_len = (qse_size_t)-1; | ||||||
|  |  | ||||||
| 	parlist = xli->parlink->list; | 	parlist = xli->parlink->list; | ||||||
| @ -740,6 +783,18 @@ static int read_pair (qse_xli_t* xli) | |||||||
| 	{ | 	{ | ||||||
| 		if (get_token (xli) <= -1) goto oops; | 		if (get_token (xli) <= -1) goto oops; | ||||||
|  |  | ||||||
|  | 		if (MATCH (xli, TOK_STRTAG)) | ||||||
|  | 		{ | ||||||
|  | 			tag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr); | ||||||
|  | 			if (tag == QSE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);  | ||||||
|  | 				goto oops; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (get_token (xli) <= -1) goto oops; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH(xli, TOK_NSTR) || MATCH (xli, TOK_IDENT)) | 		if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH(xli, TOK_NSTR) || MATCH (xli, TOK_IDENT)) | ||||||
| 		{ | 		{ | ||||||
| 			qse_xli_str_t* curstrseg; | 			qse_xli_str_t* curstrseg; | ||||||
| @ -753,7 +808,7 @@ static int read_pair (qse_xli_t* xli) | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			/* add a new pair with the initial string segment */ | 			/* add a new pair with the initial string segment */ | ||||||
| 			pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key.ptr, name, QSE_STR_CSTR(xli->tok.name)); | 			pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key.ptr, name, tag, QSE_STR_CSTR(xli->tok.name)); | ||||||
| 			if (pair == QSE_NULL) goto oops; | 			if (pair == QSE_NULL) goto oops; | ||||||
|  |  | ||||||
| 			segcount++; | 			segcount++; | ||||||
| @ -767,6 +822,24 @@ static int read_pair (qse_xli_t* xli) | |||||||
| 				{ | 				{ | ||||||
| 					if (get_token (xli) <= -1) goto oops; /* skip the comma */ | 					if (get_token (xli) <= -1) goto oops; /* skip the comma */ | ||||||
|  |  | ||||||
|  | 					if (tag)  | ||||||
|  | 					{ | ||||||
|  | 						QSE_MMGR_FREE (xli->mmgr, tag); | ||||||
|  | 						tag = QSE_NULL; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					if (MATCH (xli, TOK_STRTAG)) | ||||||
|  | 					{ | ||||||
|  | 						tag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr); | ||||||
|  | 						if (tag == QSE_NULL) | ||||||
|  | 						{ | ||||||
|  | 							qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);  | ||||||
|  | 							goto oops; | ||||||
|  | 						} | ||||||
|  | 						 | ||||||
|  | 						if (get_token (xli) <= -1) goto oops;  | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 					if (!MATCH (xli, TOK_SQSTR) && !MATCH (xli, TOK_DQSTR) && !MATCH (xli, TOK_NSTR) && !MATCH (xli, TOK_IDENT)) | 					if (!MATCH (xli, TOK_SQSTR) && !MATCH (xli, TOK_DQSTR) && !MATCH (xli, TOK_NSTR) && !MATCH (xli, TOK_IDENT)) | ||||||
| 					{ | 					{ | ||||||
| 						qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc); | 						qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc); | ||||||
| @ -774,7 +847,7 @@ static int read_pair (qse_xli_t* xli) | |||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					/* add an additional segment to the string */ | 					/* add an additional segment to the string */ | ||||||
| 					curstrseg = qse_xli_addsegtostr (xli, curstrseg, QSE_STR_CSTR(xli->tok.name)); | 					curstrseg = qse_xli_addsegtostr (xli, curstrseg, tag, QSE_STR_CSTR(xli->tok.name)); | ||||||
| 					if (curstrseg == QSE_NULL) goto oops; | 					if (curstrseg == QSE_NULL) goto oops; | ||||||
|  |  | ||||||
| 					segcount++; | 					segcount++; | ||||||
| @ -878,6 +951,7 @@ static int read_pair (qse_xli_t* xli) | |||||||
| 		goto oops;	 | 		goto oops;	 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (tag) QSE_MMGR_FREE (xli->mmgr, tag); | ||||||
| 	QSE_MMGR_FREE (xli->mmgr, name); | 	QSE_MMGR_FREE (xli->mmgr, name); | ||||||
| 	QSE_MMGR_FREE (xli->mmgr, key.ptr); | 	QSE_MMGR_FREE (xli->mmgr, key.ptr); | ||||||
| 	qse_str_setlen (xli->dotted_curkey, dotted_curkey_len); | 	qse_str_setlen (xli->dotted_curkey, dotted_curkey_len); | ||||||
| @ -885,6 +959,7 @@ static int read_pair (qse_xli_t* xli) | |||||||
| 	 | 	 | ||||||
| oops: | oops: | ||||||
| 	xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR; | 	xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR; | ||||||
|  | 	if (tag) QSE_MMGR_FREE (xli->mmgr, tag); | ||||||
| 	if (name) QSE_MMGR_FREE (xli->mmgr, name); | 	if (name) QSE_MMGR_FREE (xli->mmgr, name); | ||||||
| 	if (key.ptr) QSE_MMGR_FREE (xli->mmgr, key.ptr); | 	if (key.ptr) QSE_MMGR_FREE (xli->mmgr, key.ptr); | ||||||
| 	if (dotted_curkey_len != (qse_size_t)-1) | 	if (dotted_curkey_len != (qse_size_t)-1) | ||||||
|  | |||||||
| @ -217,6 +217,13 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | |||||||
| 						if (write_to_current_stream (xli, QSE_T(" = "), 3, 0) <= -1) return -1; | 						if (write_to_current_stream (xli, QSE_T(" = "), 3, 0) <= -1) return -1; | ||||||
| 						while (1) | 						while (1) | ||||||
| 						{ | 						{ | ||||||
|  | 							if (str->tag) | ||||||
|  | 							{ | ||||||
|  | 								if (write_to_current_stream (xli, QSE_T("["), 1, 0) <= -1 || | ||||||
|  | 								    write_to_current_stream (xli, str->tag, qse_strlen(str->tag), 0) <= -1 ||  | ||||||
|  | 								    write_to_current_stream (xli, QSE_T("]"), 1, 0) <= -1) return -1; | ||||||
|  | 							} | ||||||
|  | 						 | ||||||
| 							if (write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1 || | 							if (write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1 || | ||||||
| 							    write_to_current_stream (xli, str->ptr, str->len, 1) <= -1 || | 							    write_to_current_stream (xli, str->ptr, str->len, 1) <= -1 || | ||||||
| 							    write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1) return -1; | 							    write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1) return -1; | ||||||
|  | |||||||
| @ -299,12 +299,17 @@ qse_xli_pair_t* qse_xli_insertpairwithemptylist ( | |||||||
|  |  | ||||||
| qse_xli_pair_t* qse_xli_insertpairwithstr ( | qse_xli_pair_t* qse_xli_insertpairwithstr ( | ||||||
| 	qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, | 	qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, | ||||||
| 	const qse_char_t* key, const qse_char_t* alias, const qse_cstr_t* value) | 	const qse_char_t* key, const qse_char_t* alias,  | ||||||
|  | 	const qse_char_t* tag, const qse_cstr_t* value) | ||||||
| { | { | ||||||
| 	qse_xli_str_t* val; | 	qse_xli_str_t* val; | ||||||
| 	qse_xli_pair_t* tmp; | 	qse_xli_pair_t* tmp; | ||||||
|  | 	qse_size_t reqlen; | ||||||
|  |  | ||||||
| 	val = qse_xli_callocmem (xli, QSE_SIZEOF(*val) + ((value->len  + 1) * QSE_SIZEOF(*value->ptr))); | 	reqlen = QSE_SIZEOF(*val) + ((value->len + 1) * QSE_SIZEOF(*value->ptr)); | ||||||
|  | 	if (tag) reqlen += (qse_strlen (tag) + 1) * QSE_SIZEOF(*tag); | ||||||
|  |  | ||||||
|  | 	val = qse_xli_callocmem (xli, reqlen); | ||||||
| 	if (val == QSE_NULL) return QSE_NULL; | 	if (val == QSE_NULL) return QSE_NULL; | ||||||
|  |  | ||||||
| 	val->type = QSE_XLI_STR; | 	val->type = QSE_XLI_STR; | ||||||
| @ -313,6 +318,12 @@ qse_xli_pair_t* qse_xli_insertpairwithstr ( | |||||||
| 	val->ptr = (const qse_char_t*)(val + 1); | 	val->ptr = (const qse_char_t*)(val + 1); | ||||||
| 	val->len = value->len; | 	val->len = value->len; | ||||||
|  |  | ||||||
|  | 	if (tag) | ||||||
|  | 	{ | ||||||
|  | 		val->tag = val->ptr + val->len + 1; | ||||||
|  | 		qse_strcpy ((qse_char_t*)val->tag, tag); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
| 	tmp = qse_xli_insertpair (xli, parent, peer, key, alias, (qse_xli_val_t*)val);	 | 	tmp = qse_xli_insertpair (xli, parent, peer, key, alias, (qse_xli_val_t*)val);	 | ||||||
| 	if (tmp == QSE_NULL) qse_xli_freemem (xli, val); | 	if (tmp == QSE_NULL) qse_xli_freemem (xli, val); | ||||||
| 	return tmp; | 	return tmp; | ||||||
| @ -333,13 +344,13 @@ qse_xli_pair_t* qse_xli_insertpairwithstrs ( | |||||||
| 		return QSE_NULL; | 		return QSE_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tmp = qse_xli_insertpairwithstr (xli, parent, peer, key, alias, &value[0]); | 	tmp = qse_xli_insertpairwithstr (xli, parent, peer, key, alias, QSE_NULL, &value[0]); | ||||||
| 	if (tmp == QSE_NULL) return QSE_NULL; | 	if (tmp == QSE_NULL) return QSE_NULL; | ||||||
|  |  | ||||||
| 	str = (qse_xli_str_t*)tmp->val; | 	str = (qse_xli_str_t*)tmp->val; | ||||||
| 	for (i = 1; i < count; i++) | 	for (i = 1; i < count; i++) | ||||||
| 	{ | 	{ | ||||||
| 		str = qse_xli_addsegtostr (xli, str, &value[i]);			 | 		str = qse_xli_addsegtostr (xli, str, QSE_NULL, &value[i]);			 | ||||||
| 		if (str == QSE_NULL) | 		if (str == QSE_NULL) | ||||||
| 		{ | 		{ | ||||||
| 			free_atom (xli->root, (qse_xli_atom_t*)tmp); | 			free_atom (xli->root, (qse_xli_atom_t*)tmp); | ||||||
| @ -811,13 +822,16 @@ noent: | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| qse_xli_str_t* qse_xli_addsegtostr ( | qse_xli_str_t* qse_xli_addsegtostr ( | ||||||
| 	qse_xli_t* xli, qse_xli_str_t* str, const qse_cstr_t* value) | 	qse_xli_t* xli, qse_xli_str_t* str, const qse_char_t* tag, const qse_cstr_t* value) | ||||||
| { | { | ||||||
| 	qse_xli_str_t* val; | 	qse_xli_str_t* val; | ||||||
|  | 	qse_size_t reqlen; | ||||||
|  |  | ||||||
| 	val = qse_xli_callocmem (xli, QSE_SIZEOF(*val) + ((value->len  + 1) * QSE_SIZEOF(*value->ptr))); | 	reqlen = QSE_SIZEOF(*val) + ((value->len + 1) * QSE_SIZEOF(*value->ptr)); | ||||||
|  | 	if (tag) reqlen += (qse_strlen (tag) + 1) * QSE_SIZEOF(*tag); | ||||||
|  |  | ||||||
|  | 	val = qse_xli_callocmem (xli, reqlen); | ||||||
| 	if (val == QSE_NULL) return QSE_NULL; | 	if (val == QSE_NULL) return QSE_NULL; | ||||||
|  |  | ||||||
| 	val->type = QSE_XLI_STR; | 	val->type = QSE_XLI_STR; | ||||||
| @ -825,6 +839,12 @@ qse_xli_str_t* qse_xli_addsegtostr ( | |||||||
| 	val->ptr = (const qse_char_t*)(val + 1); | 	val->ptr = (const qse_char_t*)(val + 1); | ||||||
| 	val->len = value->len; | 	val->len = value->len; | ||||||
|  |  | ||||||
|  | 	if (tag) | ||||||
|  | 	{ | ||||||
|  | 		val->tag = val->ptr + val->len + 1; | ||||||
|  | 		qse_strcpy ((qse_char_t*)val->tag, tag); | ||||||
|  | 	} | ||||||
|  | 		 | ||||||
| 	val->next = str->next; | 	val->next = str->next; | ||||||
| 	str->next = val; | 	str->next = val; | ||||||
| 	return str->next; | 	return str->next; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user