added a working json format writer
This commit is contained in:
		| @ -28,16 +28,27 @@ | ||||
| #include <qse/cmn/chr.h> | ||||
|  | ||||
| /* | ||||
| 	"key1" { | ||||
| { | ||||
| 	"key1": { | ||||
| 		# comment | ||||
| 		[keytag]key11 "alias" = [strtag]"test machine; | ||||
| 		key1122 { | ||||
| 			key112233 = "hello"; | ||||
| 		} | ||||
| 	  } | ||||
| 		"key11": = "test machine, | ||||
| 		"key1122": [ | ||||
| 			1, | ||||
|  			2, | ||||
|  			{  | ||||
| 				"a": 10, | ||||
|  				"b": 20, | ||||
|  			} | ||||
| 		] | ||||
| 	} | ||||
| } | ||||
| */ | ||||
|  | ||||
| enum | ||||
| { | ||||
| 	TOK_STATUS_DEINDENT_TEXT = (1 << 0) | ||||
| }; | ||||
|  | ||||
| static int get_token (qse_xli_t* xli); | ||||
| static int read_list (qse_xli_t* xli, qse_xli_list_t* lv); | ||||
| static int read_array (qse_xli_t* xli, qse_xli_list_t* lv); | ||||
| @ -123,8 +134,14 @@ static int skip_comment (qse_xli_t* xli, qse_xli_tok_t* tok) | ||||
| 		} | ||||
| 		while (1); | ||||
|  | ||||
| 		if ((xli->opt.trait & QSE_XLI_KEEPTEXT) &&  | ||||
| 		    qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(tok->name)) == QSE_NULL) return -1; | ||||
| 		if (xli->opt.trait & QSE_XLI_KEEPTEXT) | ||||
| 		{ | ||||
| 			qse_xli_text_t* ta; | ||||
| 			ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(tok->name)); | ||||
| 			if (!ta) return -1; | ||||
|  | ||||
| 			if (xli->tok_status & TOK_STATUS_DEINDENT_TEXT) ta->flags |= QSE_XLI_TEXT_DEINDENT; | ||||
| 		} | ||||
|  | ||||
| 		GET_CHAR (xli); /* eat the new line letter */ | ||||
| 		return 1; /* comment by # */ | ||||
| @ -803,11 +820,12 @@ static int read_root_list (qse_xli_t* xli) | ||||
| 	link = qse_xli_makelistlink (xli, &xli->root->list); | ||||
| 	if (!link) goto oops; | ||||
|  | ||||
| 	xli->tok_status |= TOK_STATUS_DEINDENT_TEXT; | ||||
| 	if (qse_xli_getchar(xli) <= -1 || get_token(xli) <= -1) goto oops; | ||||
|  | ||||
| 	while (1) | ||||
| 	{ | ||||
| 		if (MATCH(xli, QSE_XLI_TOK_XINCLUDE)) | ||||
| 		/*if (MATCH(xli, QSE_XLI_TOK_XINCLUDE)) | ||||
| 		{ | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
|  | ||||
| @ -823,14 +841,24 @@ static int read_root_list (qse_xli_t* xli) | ||||
| 		{ | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 		} | ||||
| 		else if (MATCH(xli, QSE_XLI_TOK_LBRACK)) | ||||
| 		else*/if (MATCH(xli, QSE_XLI_TOK_LBRACK)) | ||||
| 		{ | ||||
| 			qse_xli_text_t* ta; | ||||
| 			xli->root->list.flags |= QSE_XLI_LIST_ARRAYED;  | ||||
| 			ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); | ||||
| 			if (!ta) goto oops; | ||||
| 			ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; | ||||
| 			xli->tok_status &= ~TOK_STATUS_DEINDENT_TEXT; | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 			break; | ||||
| 		} | ||||
| 		else if (MATCH(xli, QSE_XLI_TOK_LBRACE)) | ||||
| 		{ | ||||
| 			qse_xli_text_t* ta; | ||||
| 			ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); | ||||
| 			if (!ta) goto oops; | ||||
| 			ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; | ||||
| 			xli->tok_status &= ~TOK_STATUS_DEINDENT_TEXT; | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 			break; | ||||
| 		} | ||||
| @ -845,7 +873,7 @@ static int read_root_list (qse_xli_t* xli) | ||||
|  | ||||
| 	while (1) | ||||
| 	{ | ||||
| 		if (MATCH(xli, QSE_XLI_TOK_XINCLUDE)) | ||||
| 		/*if (MATCH(xli, QSE_XLI_TOK_XINCLUDE)) | ||||
| 		{ | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
|  | ||||
| @ -861,15 +889,25 @@ static int read_root_list (qse_xli_t* xli) | ||||
| 		{ | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 		} | ||||
| 		else if (MATCH(xli, QSE_XLI_TOK_RBRACK)) | ||||
| 		else*/if (MATCH(xli, QSE_XLI_TOK_RBRACK)) | ||||
| 		{ | ||||
| 			qse_xli_text_t* ta; | ||||
| 			if (!(xli->root->list.flags & QSE_XLI_LIST_ARRAYED)) goto oops_rbrac; | ||||
| 			ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); | ||||
| 			if (!ta) goto oops; | ||||
| 			ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; | ||||
| 			xli->tok_status |= TOK_STATUS_DEINDENT_TEXT; | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 			break; | ||||
| 		} | ||||
| 		else if (MATCH(xli, QSE_XLI_TOK_RBRACE)) | ||||
| 		{ | ||||
| 			qse_xli_text_t* ta; | ||||
| 			if (xli->root->list.flags & QSE_XLI_LIST_ARRAYED) goto oops_rbrac; | ||||
| 			ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); | ||||
| 			if (!ta) goto oops; | ||||
| 			ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; | ||||
| 			xli->tok_status |= TOK_STATUS_DEINDENT_TEXT; | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 			break; | ||||
| 		} | ||||
| @ -884,7 +922,6 @@ static int read_root_list (qse_xli_t* xli) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	QSE_ASSERT (link == xli->parlink); | ||||
| 	qse_xli_freelistlink (xli, link); | ||||
|  | ||||
|  | ||||
| @ -146,19 +146,13 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | ||||
| 			{ | ||||
| 				const qse_char_t* str = ((qse_xli_text_t*)curatom)->ptr; | ||||
|  | ||||
| 				/* don't honor VERBATIM and DEINDENT flags */ | ||||
| 				if (write_to_current_stream(xli, QSE_T(";"), 1) <= -1 || | ||||
| 				    write_to_current_stream(xli, str, qse_strlen(str)) <= -1 || | ||||
| 				    write_to_current_stream(xli, QSE_T("\n"), 1) <= -1) return -1; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case QSE_XLI_VTEXT: | ||||
| 			{ | ||||
| 				/* no vtext element can be included in the ini format */ | ||||
| 				/* do nothing */ | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case QSE_XLI_FILE: | ||||
| 				/* no file inclusion is supported by the ini-format. ignore it */ | ||||
| 				break; | ||||
|  | ||||
| @ -33,8 +33,6 @@ struct arg_data_t | ||||
| 	int org_depth; | ||||
| }; | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| static int write_to_current_stream(qse_xli_t* xli, const qse_char_t* ptr, qse_size_t len, int escape) | ||||
| { | ||||
| 	qse_xli_io_arg_t* arg; | ||||
| @ -85,111 +83,20 @@ static int write_indentation (qse_xli_t* xli, int depth) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int key_needs_quoting (qse_xli_t* xli, const qse_char_t* str, int nstr) | ||||
| static int need_comma (qse_xli_atom_t* start) | ||||
| { | ||||
| 	/* this determines if a key or an alias requires quoting for output. | ||||
| 	 * NSTR is not taken into account because it's only allowed as a value */ | ||||
|  | ||||
| 	/* refer to the tokenization rule in get_token_into() in read.c */ | ||||
| 	qse_char_t c; | ||||
|  | ||||
| 	c = *str++; | ||||
| 	if (c == QSE_T('\0')) return 1; /* an empty string requires a quoting */ | ||||
|  | ||||
| 	if (c == QSE_T('_') || QSE_ISALPHA(c) || (!nstr && (xli->opt.trait & QSE_XLI_LEADDIGIT) && QSE_ISDIGIT(c))) | ||||
| 	qse_xli_atom_t* cur; | ||||
| 	for (cur = start; cur; cur = cur->next) | ||||
| 	{ | ||||
| 		int lead_digit = QSE_ISDIGIT(c); | ||||
| 		int all_digits = 1; | ||||
|  | ||||
| 		/* a normal identifier can be composed of wider varieties of  | ||||
| 		 * characters than a keyword/directive */ | ||||
| 		while (1) | ||||
| 		{ | ||||
| 			c = *str++; | ||||
| 			if (c == QSE_T('\0')) break; | ||||
|  | ||||
| 			if (c == QSE_T('_') || c == QSE_T('-') ||  | ||||
| 			    (!(xli->opt.trait & QSE_XLI_JSON) && c == QSE_T(':')) || | ||||
| 			    c == QSE_T('*') || c == QSE_T('/') || QSE_ISALPHA(c))  | ||||
| 			{ | ||||
| 				all_digits = 0; | ||||
| 			} | ||||
| 			else if (QSE_ISDIGIT(c))  | ||||
| 			{ | ||||
| 				/* nothing to do */ | ||||
| 			} | ||||
| 			else  | ||||
| 			{ | ||||
| 				/* a disallowed character for an identifier */ | ||||
| 				return 1; /* quote it */ | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (lead_digit && all_digits) | ||||
| 		{ | ||||
| 			/* if an identifier begins with a digit, it must contain a non-digit character */ | ||||
| 			/* in fact, it is not a valid identifer. so quote it */ | ||||
| 			return 1; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* this must be a normal identifer */ | ||||
| 			return 0; /* no quoting needed */ | ||||
| 		} | ||||
| 		if (cur->type == QSE_XLI_PAIR) return 1; | ||||
| 		if (cur->type == QSE_XLI_EOF) return 0; /* if EOF encountered in the included file, i don't want a comma at the end of the file */ | ||||
| 	} | ||||
| 	else if (nstr && QSE_ISDIGIT(c)) | ||||
| 	{ | ||||
| 		do  | ||||
| 		{ | ||||
| 			c = *str++; | ||||
| 			if (c == QSE_T('\0')) return 0; /* it's a numeric string */ | ||||
| 		} | ||||
| 		while (QSE_ISDIGIT(c)); | ||||
| 	} | ||||
|  | ||||
| 	/* quote all the rest */ | ||||
| 	return 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | ||||
| { | ||||
| 	static struct | ||||
| 	{ | ||||
| 		qse_char_t* qptr; | ||||
| 		qse_size_t  qlen; | ||||
| 	} quotes[] = | ||||
| 	{ | ||||
| 		{ QSE_T(""),   0 }, | ||||
| 		{ QSE_T("\'"), 1 }, | ||||
| 		{ QSE_T("\""), 1 } | ||||
| 	}; | ||||
|  | ||||
| 	static qse_char_t tag_opener[] = { QSE_T('['), QSE_T('(') }; | ||||
| 	static qse_char_t tag_closer[] = { QSE_T(']'), QSE_T(')') }; | ||||
|  | ||||
| 	static struct | ||||
| 	{ | ||||
| 		qse_char_t* ptr; | ||||
| 		qse_size_t  len; | ||||
| 	} assign_symbol[] = | ||||
| 	{ | ||||
| 		{ QSE_T(" = "), 3 }, | ||||
| 		{ QSE_T(": "),  2 } | ||||
| 	}; | ||||
|  | ||||
| 	static struct | ||||
| 	{ | ||||
| 		qse_char_t* ptr; | ||||
| 		qse_size_t  len; | ||||
| 	} list_assign_symbol[] = | ||||
| 	{ | ||||
| 		{ QSE_T(" "), 1 }, | ||||
| 		{ QSE_T(": "),  2 } | ||||
| 	}; | ||||
|  | ||||
| 	qse_xli_atom_t* curatom; | ||||
| 	int tag_mode = (xli->opt.trait & QSE_XLI_JSON)? 1: 0; | ||||
|  | ||||
| 	for (curatom = list->head; curatom; curatom = curatom->next) | ||||
| 	{ | ||||
| @ -197,104 +104,98 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | ||||
| 		{ | ||||
| 			case QSE_XLI_PAIR: | ||||
| 			{ | ||||
| 				int qtype; | ||||
| 				qse_xli_pair_t* pair = (qse_xli_pair_t*)curatom; | ||||
|  | ||||
| 				if (write_indentation(xli, depth) <= -1) return -1; | ||||
|  | ||||
| 				if (pair->tag) | ||||
| 				if (!(list->flags & QSE_XLI_LIST_ARRAYED)) | ||||
| 				{ | ||||
| 					if (write_to_current_stream(xli, &tag_opener[tag_mode], 1, 0) <= -1 || | ||||
| 					    write_to_current_stream(xli, pair->tag, qse_strlen(pair->tag), 0) <= -1 ||  | ||||
| 					    write_to_current_stream(xli, &tag_closer[tag_mode], 1, 0) <= -1) return -1; | ||||
| 				} | ||||
| 					if (pair->tag) | ||||
| 					{ | ||||
| 						/* ignore tag in the json format */ | ||||
| 					} | ||||
|  | ||||
| 				QSE_ASSERT(pair->_key_quoted >= 0 && pair->_key_quoted < QSE_COUNTOF(quotes)); | ||||
| 				qtype = pair->_key_quoted; | ||||
| 				if (qtype <= 0 && key_needs_quoting(xli, pair->key, 0)) qtype = 2; /* force double quoting */ | ||||
| 					if (write_to_current_stream(xli, QSE_T("\""), 1, 0) <= -1 || | ||||
| 					    write_to_current_stream(xli, pair->key, qse_strlen(pair->key), 1) <= -1 || | ||||
| 					    write_to_current_stream(xli, QSE_T("\""), 1, 0) <= -1) return -1; | ||||
|  | ||||
| 				if (write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1 || | ||||
| 				    write_to_current_stream(xli, pair->key, qse_strlen(pair->key), (qtype >= 2)) <= -1 || | ||||
| 				    write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1) return -1; | ||||
| 					if (pair->alias)  | ||||
| 					{ | ||||
| 						/* ignore alias in the json format */ | ||||
| 					} | ||||
|  | ||||
| 				if (pair->alias)  | ||||
| 				{ | ||||
| 					QSE_ASSERT(pair->_alias_quoted >= 0 && pair->_alias_quoted < QSE_COUNTOF(quotes)); | ||||
| 					qtype = pair->_alias_quoted; | ||||
| 					if (qtype <= 0 && key_needs_quoting(xli, pair->alias, 1)) qtype = 2; | ||||
|  | ||||
| 					if (write_to_current_stream(xli, QSE_T(" "), 1, 0) <= -1 || | ||||
| 					    write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1 || | ||||
| 					    write_to_current_stream(xli, pair->alias, qse_strlen(pair->alias), (qtype >= 2)) <= -1 || | ||||
| 					    write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1) return -1; | ||||
| 					if (write_to_current_stream(xli, QSE_T(": "), 2, 0) <= -1) return -1; | ||||
| 				} | ||||
|  | ||||
| 				switch (pair->val->type) | ||||
| 				{ | ||||
| 					case QSE_XLI_NIL: | ||||
| 						if (write_to_current_stream(xli, QSE_T("nil;\n"), 5, 0) <= -1) return -1; | ||||
| 						if (write_to_current_stream(xli, QSE_T("nil"), 5, 0) <= -1) return -1; | ||||
| 						break; | ||||
|  | ||||
| 					case QSE_XLI_TRUE: | ||||
| 						if (write_to_current_stream(xli, QSE_T("true;\n"), 6, 0) <= -1) return -1; | ||||
| 						if (write_to_current_stream(xli, QSE_T("true"), 6, 0) <= -1) return -1; | ||||
| 						break; | ||||
|  | ||||
| 					case QSE_XLI_FALSE: | ||||
| 						if (write_to_current_stream(xli, QSE_T("false;\n"), 7, 0) <= -1) return -1; | ||||
| 						if (write_to_current_stream(xli, QSE_T("false"), 7, 0) <= -1) return -1; | ||||
| 						break; | ||||
|  | ||||
| 					case QSE_XLI_STR: | ||||
| 					{ | ||||
| 						qse_xli_str_t* str = (qse_xli_str_t*)pair->val; | ||||
|  | ||||
| 						if (write_to_current_stream(xli, assign_symbol[tag_mode].ptr, assign_symbol[tag_mode].len, 0) <= -1) return -1; | ||||
|  | ||||
| 						/* ignore the string tag(str->tag) in the json format. | ||||
| 						 * concatenate multi-segmented string into 1 */ | ||||
| 						if (write_to_current_stream(xli, QSE_T("\""), 1, 0) <= -1) return -1; | ||||
| 						while (1) | ||||
| 						{ | ||||
| 							if (str->tag) | ||||
| 							{ | ||||
| 								if (write_to_current_stream(xli, &tag_opener[tag_mode], 1, 0) <= -1 || | ||||
| 								    write_to_current_stream(xli, str->tag, qse_strlen(str->tag), 0) <= -1 ||  | ||||
| 								    write_to_current_stream(xli, &tag_closer[tag_mode], 1, 0) <= -1) return -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, QSE_T("\""), 1, 0) <= -1) return -1; | ||||
| 							if (write_to_current_stream(xli, str->ptr, str->len, 1) <= -1) return -1; | ||||
| 							if (!str->next) break; | ||||
|  | ||||
| 							if (write_to_current_stream(xli, QSE_T(", "), 2, 0) <= -1) return -1; | ||||
| 							str = str->next; | ||||
| 						} | ||||
| 						if (write_to_current_stream(xli, QSE_T(";\n"), 2, 0) <= -1) return -1; | ||||
|  | ||||
| 						if (write_to_current_stream(xli, QSE_T("\""), 1, 0) <= -1) return -1; | ||||
| 						break; | ||||
| 					} | ||||
|  | ||||
| 					case QSE_XLI_LIST: | ||||
| 					{ | ||||
| 						if (write_to_current_stream(xli, list_assign_symbol[tag_mode].ptr, list_assign_symbol[tag_mode].len, 0) <= -1) return -1; | ||||
|  | ||||
| 						if (write_to_current_stream(xli, QSE_T("{\n"), 2, 0) <= -1 || | ||||
| 						static qse_char_t* obrac[] = | ||||
| 						{ | ||||
| 							QSE_T("{\n"), | ||||
| 							QSE_T("[\n") | ||||
| 						}; | ||||
| 						static qse_char_t* cbrac[] = | ||||
| 						{ | ||||
| 							QSE_T("}"), | ||||
| 							QSE_T("]") | ||||
| 						}; | ||||
| 						qse_xli_list_t* lv = (qse_xli_list_t*)pair->val; | ||||
| 						if (write_to_current_stream(xli, obrac[lv->flags & QSE_XLI_LIST_ARRAYED], 2, 0) <= -1 || | ||||
| 						    write_list (xli, (qse_xli_list_t*)pair->val, depth + 1) <= -1 || | ||||
| 						    write_indentation (xli, depth) <= -1 || | ||||
| 						    write_to_current_stream(xli, QSE_T("}\n"), 2, 0) <= -1) return -1; | ||||
| 						    write_to_current_stream(xli, cbrac[lv->flags & QSE_XLI_LIST_ARRAYED], 1, 0) <= -1) return -1; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				if (need_comma(curatom->next) && write_to_current_stream(xli, QSE_T(","), 1, 0) <= -1) return -1; | ||||
| 				if (write_to_current_stream(xli, QSE_T("\n"), 1, 0) <= -1) return -1; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case QSE_XLI_TEXT: | ||||
| 			{ | ||||
| 				int i; | ||||
| 				const qse_char_t* str = ((qse_xli_text_t*)curatom)->ptr; | ||||
| 				qse_xli_text_t* ta; | ||||
| 				const qse_char_t* str; | ||||
|  | ||||
| 				for (i = 0; i < depth; i++)  | ||||
| 				{ | ||||
| 					if (write_to_current_stream(xli, QSE_T("\t"), 1, 0) <= -1) return -1; | ||||
| 				} | ||||
| 				ta = (qse_xli_text_t*)curatom; | ||||
| 				str = ta->ptr; | ||||
|  | ||||
| 				if (write_to_current_stream(xli, QSE_T("#"), 1, 0) <= -1 || | ||||
| 				if (write_indentation(xli, depth - !!(ta->flags & QSE_XLI_TEXT_DEINDENT)) <= -1) return -1; | ||||
|  | ||||
| 				if ((!(ta->flags & QSE_XLI_TEXT_VERBATIM) && write_to_current_stream(xli, QSE_T("#"), 1, 0) <= -1) || | ||||
| 				    write_to_current_stream(xli, str, qse_strlen(str), 0) <= -1 || | ||||
| 				    write_to_current_stream(xli, QSE_T("\n"), 1, 0) <= -1) return -1; | ||||
| 				break; | ||||
| @ -302,39 +203,35 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | ||||
|  | ||||
| 			case QSE_XLI_FILE: | ||||
| 			{ | ||||
| 				int i; | ||||
| 				const qse_char_t* path = ((qse_xli_file_t*)curatom)->path; | ||||
|  | ||||
| 				for (i = 0; i < depth; i++)  | ||||
| 				{ | ||||
| 					if (write_to_current_stream(xli, QSE_T("\t"), 1, 0) <= -1) return -1; | ||||
| 				} | ||||
| 				if (write_indentation(xli, depth) <= -1) return -1; | ||||
|  | ||||
| 				if (write_to_current_stream(xli, QSE_T("@include \""), 10, 0) <= -1 || | ||||
| 				    write_to_current_stream(xli, path, qse_strlen(path), 1) <= -1 || | ||||
| 				    write_to_current_stream(xli, QSE_T("\";\n"), 3, 0) <= -1) return -1; | ||||
| 				 | ||||
| 				    write_to_current_stream(xli, QSE_T("\""), 1, 0) <= -1) return -1; | ||||
|  | ||||
| 				if (qse_xli_openwstream (xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1; | ||||
| 				depth = 0; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case QSE_XLI_EOF: | ||||
| 				if (qse_xli_closeactivewstream (xli, &depth) <= -1) return -1; | ||||
| 				if (qse_xli_closeactivewstream(xli, &depth) <= -1) return -1; | ||||
|  | ||||
| 				if (need_comma(curatom->next) && write_to_current_stream(xli, QSE_T(","), 1, 0) <= -1) return -1; | ||||
| 				if (write_to_current_stream(xli, QSE_T("\n"), 1, 0) <= -1) return -1; | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| int qse_xli_writejson (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_io_impl_t io) | ||||
| { | ||||
| 	int n; | ||||
|  | ||||
| #if 0 | ||||
| 	if (io == QSE_NULL) | ||||
| 	{ | ||||
| 		qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); | ||||
| @ -352,12 +249,11 @@ int qse_xli_writejson (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_io_imp | ||||
| 	if (qse_xli_openwstream (xli, QSE_NULL, 0) <= -1) return -1; | ||||
|  | ||||
| 	/* begin writing the root list */ | ||||
| 	n = write_list (xli, (root_list? root_list: &xli->root->list), 0); | ||||
| 	 | ||||
| 	n = write_list (xli, (root_list? root_list: &xli->root->list), 1); | ||||
|  | ||||
| 	/* close all open streams. there should be only the | ||||
| 	 * top-level stream here if there occurred no errors */ | ||||
| 	while (xli->wio.inp) qse_xli_closeactivewstream (xli, QSE_NULL); | ||||
| #endif | ||||
|  | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| @ -346,40 +346,24 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | ||||
|  | ||||
| 			case QSE_XLI_TEXT: | ||||
| 			{ | ||||
| 				int i; | ||||
| 				const qse_char_t* str = ((qse_xli_text_t*)curatom)->ptr; | ||||
|  | ||||
| 				for (i = 0; i < depth; i++)  | ||||
| 				{ | ||||
| 					if (write_to_current_stream (xli, QSE_T("\t"), 1, 0) <= -1) return -1; | ||||
| 				} | ||||
|  | ||||
| 				if (write_to_current_stream (xli, QSE_T("#"), 1, 0) <= -1 || | ||||
| 				    write_to_current_stream (xli, str, qse_strlen(str), 0) <= -1 || | ||||
| 				    write_to_current_stream (xli, QSE_T("\n"), 1, 0) <= -1) return -1; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case QSE_XLI_VTEXT: | ||||
| 			{ | ||||
| 				/* no vtext element can be included in the xli format */ | ||||
| 				/* do nothing */ | ||||
| 				/* don't honor VERBATIM and DEINDENT flags */ | ||||
| 				if (write_indentation(xli, depth) <= -1 || | ||||
| 				    write_to_current_stream(xli, QSE_T("#"), 1, 0) <= -1 || | ||||
| 				    write_to_current_stream(xli, str, qse_strlen(str), 0) <= -1 || | ||||
| 				    write_to_current_stream(xli, QSE_T("\n"), 1, 0) <= -1) return -1; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case QSE_XLI_FILE: | ||||
| 			{ | ||||
| 				int i; | ||||
| 				const qse_char_t* path = ((qse_xli_file_t*)curatom)->path; | ||||
|  | ||||
| 				for (i = 0; i < depth; i++)  | ||||
| 				{ | ||||
| 					if (write_to_current_stream (xli, QSE_T("\t"), 1, 0) <= -1) return -1; | ||||
| 				} | ||||
|  | ||||
| 				if (write_to_current_stream (xli, QSE_T("@include \""), 10, 0) <= -1 || | ||||
| 				    write_to_current_stream (xli, path, qse_strlen(path), 1) <= -1 || | ||||
| 				    write_to_current_stream (xli, QSE_T("\";\n"), 3, 0) <= -1) return -1; | ||||
| 				if (write_indentation(xli, depth) <= -1 || | ||||
| 				    write_to_current_stream(xli, QSE_T("@include \""), 10, 0) <= -1 || | ||||
| 				    write_to_current_stream(xli, path, qse_strlen(path), 1) <= -1 || | ||||
| 				    write_to_current_stream(xli, QSE_T("\";\n"), 3, 0) <= -1) return -1; | ||||
|  | ||||
| 				if (qse_xli_openwstream(xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1; | ||||
| 				depth = 0; | ||||
|  | ||||
| @ -542,20 +542,6 @@ qse_xli_text_t* qse_xli_inserttext ( | ||||
| 	return text; | ||||
| } | ||||
|  | ||||
| qse_xli_vtext_t* qse_xli_insertvtext ( | ||||
| 	qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, const qse_char_t* str) | ||||
| { | ||||
| 	qse_xli_text_t* text; | ||||
|  | ||||
| 	QSE_ASSERT (QSE_SIZEOF(qse_xli_text_t) == QSE_SIZEOF(qse_xli_vtext_t)); | ||||
|  | ||||
| 	text = qse_xli_inserttext (xli, parent, peer, str); | ||||
| 	if (!text) return QSE_NULL; | ||||
|  | ||||
| 	((qse_xli_vtext_t*)text)->type = QSE_XLI_VTEXT; | ||||
| 	return (qse_xli_vtext_t*)text; | ||||
| } | ||||
|  | ||||
| qse_xli_file_t* qse_xli_insertfile ( | ||||
| 	qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, const qse_char_t* path) | ||||
| { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user