changed the structure of qse_xli_str_t. this breaks cmd/httpd/httpd.c
finished the xli output functions mostly
This commit is contained in:
		| @ -29,7 +29,7 @@ static int close_current_stream (qse_xli_t* xli) | ||||
| { | ||||
| 	qse_ssize_t n; | ||||
|  | ||||
| 	n = xli->sio.impl (xli, QSE_XLI_IO_CLOSE, xli->sio.inp, QSE_NULL, 0); | ||||
| 	n = xli->rio.impl (xli, QSE_XLI_IO_CLOSE, xli->rio.inp, QSE_NULL, 0); | ||||
| 	if (n <= -1) | ||||
| 	{ | ||||
| 		if (xli->errnum == QSE_XLI_ENOERR)  | ||||
| @ -63,7 +63,7 @@ enum tok_t | ||||
| #define GET_CHAR_TO(xli,c) \ | ||||
| 	do { \ | ||||
| 		if (get_char(xli) <= -1) return -1; \ | ||||
| 		c = (xli)->sio.last.c; \ | ||||
| 		c = (xli)->rio.last.c; \ | ||||
| 	} while(0) | ||||
|  | ||||
| #define ADD_TOKEN_CHAR(xli,tok,c) \ | ||||
| @ -107,11 +107,11 @@ static int get_char (qse_xli_t* xli) | ||||
| { | ||||
| 	qse_ssize_t n; | ||||
|  | ||||
| 	if (xli->sio.inp->b.pos >= xli->sio.inp->b.len) | ||||
| 	if (xli->rio.inp->b.pos >= xli->rio.inp->b.len) | ||||
| 	{ | ||||
| 		n = xli->sio.impl ( | ||||
| 			xli, QSE_XLI_IO_READ, xli->sio.inp, | ||||
| 			xli->sio.inp->b.buf, QSE_COUNTOF(xli->sio.inp->b.buf) | ||||
| 		n = xli->rio.impl ( | ||||
| 			xli, QSE_XLI_IO_READ, xli->rio.inp, | ||||
| 			xli->rio.inp->b.buf, QSE_COUNTOF(xli->rio.inp->b.buf) | ||||
| 		); | ||||
| 		if (n <= -1) | ||||
| 		{ | ||||
| @ -122,47 +122,47 @@ static int get_char (qse_xli_t* xli) | ||||
|  | ||||
| 		if (n == 0) | ||||
| 		{ | ||||
| 			xli->sio.inp->last.c = QSE_CHAR_EOF; | ||||
| 			xli->sio.inp->last.line = xli->sio.inp->line; | ||||
| 			xli->sio.inp->last.colm = xli->sio.inp->colm; | ||||
| 			xli->sio.inp->last.file = xli->sio.inp->name; | ||||
| 			xli->sio.last = xli->sio.inp->last; | ||||
| 			xli->rio.inp->last.c = QSE_CHAR_EOF; | ||||
| 			xli->rio.inp->last.line = xli->rio.inp->line; | ||||
| 			xli->rio.inp->last.colm = xli->rio.inp->colm; | ||||
| 			xli->rio.inp->last.file = xli->rio.inp->name; | ||||
| 			xli->rio.last = xli->rio.inp->last; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		xli->sio.inp->b.pos = 0; | ||||
| 		xli->sio.inp->b.len = n;	 | ||||
| 		xli->rio.inp->b.pos = 0; | ||||
| 		xli->rio.inp->b.len = n;	 | ||||
| 	} | ||||
|  | ||||
| 	if (xli->sio.inp->last.c == QSE_T('\n')) | ||||
| 	if (xli->rio.inp->last.c == QSE_T('\n')) | ||||
| 	{ | ||||
| 		/* if the previous charater was a newline, | ||||
| 		 * increment the line counter and reset column to 1. | ||||
| 		 * incrementing it line number here instead of | ||||
| 		 * updating inp->last causes the line number for | ||||
| 		 * TOK_EOF to be the same line as the last newline. */ | ||||
| 		xli->sio.inp->line++; | ||||
| 		xli->sio.inp->colm = 1; | ||||
| 		xli->rio.inp->line++; | ||||
| 		xli->rio.inp->colm = 1; | ||||
| 	} | ||||
| 	 | ||||
| 	xli->sio.inp->last.c = xli->sio.inp->b.buf[xli->sio.inp->b.pos++]; | ||||
| 	xli->sio.inp->last.line = xli->sio.inp->line; | ||||
| 	xli->sio.inp->last.colm = xli->sio.inp->colm++; | ||||
| 	xli->sio.inp->last.file = xli->sio.inp->name; | ||||
| 	xli->sio.last = xli->sio.inp->last; | ||||
| 	xli->rio.inp->last.c = xli->rio.inp->b.buf[xli->rio.inp->b.pos++]; | ||||
| 	xli->rio.inp->last.line = xli->rio.inp->line; | ||||
| 	xli->rio.inp->last.colm = xli->rio.inp->colm++; | ||||
| 	xli->rio.inp->last.file = xli->rio.inp->name; | ||||
| 	xli->rio.last = xli->rio.inp->last; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int skip_spaces (qse_xli_t* xli) | ||||
| { | ||||
| 	qse_cint_t c = xli->sio.last.c; | ||||
| 	qse_cint_t c = xli->rio.last.c; | ||||
| 	while (QSE_ISSPACE(c)) GET_CHAR_TO (xli, c); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int skip_comment (qse_xli_t* xli, qse_xli_tok_t* tok) | ||||
| { | ||||
| 	qse_cint_t c = xli->sio.last.c; | ||||
| 	qse_cint_t c = xli->rio.last.c; | ||||
|  | ||||
| 	if (c == QSE_T('#')) | ||||
| 	{ | ||||
| @ -274,24 +274,24 @@ static int end_include (qse_xli_t* xli, int noeof) | ||||
| 	int x; | ||||
| 	qse_xli_io_arg_t* cur; | ||||
|  | ||||
| 	if (xli->sio.inp == &xli->sio.arg) return 0; /* no include */ | ||||
| 	if (xli->rio.inp == &xli->rio.top) return 0; /* no include */ | ||||
|  | ||||
|  | ||||
| 	/* if it is an included file, close it and | ||||
| 	 * retry to read a character from an outer file */ | ||||
|  | ||||
| 	x = xli->sio.impl ( | ||||
| 	x = xli->rio.impl ( | ||||
| 		xli, QSE_XLI_IO_CLOSE,  | ||||
| 		xli->sio.inp, QSE_NULL, 0); | ||||
| 		xli->rio.inp, QSE_NULL, 0); | ||||
|  | ||||
| 	/* if closing has failed, still destroy the | ||||
| 	 * sio structure first as normal and return | ||||
| 	 * the failure below. this way, the caller  | ||||
| 	 * does not call QSE_XLI_SIO_CLOSE on  | ||||
| 	 * xli->sio.inp again. */ | ||||
| 	 * xli->rio.inp again. */ | ||||
|  | ||||
| 	cur = xli->sio.inp; | ||||
| 	xli->sio.inp = xli->sio.inp->prev; | ||||
| 	cur = xli->rio.inp; | ||||
| 	xli->rio.inp = xli->rio.inp->prev; | ||||
|  | ||||
| 	QSE_ASSERT (cur->name != QSE_NULL); | ||||
| 	QSE_MMGR_FREE (xli->mmgr, cur); | ||||
| @ -308,7 +308,7 @@ static int end_include (qse_xli_t* xli, int noeof) | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	xli->sio.last = xli->sio.inp->last; | ||||
| 	xli->rio.last = xli->rio.inp->last; | ||||
| 	return 1; /* ended the included file successfully */ | ||||
| } | ||||
|  | ||||
| @ -322,8 +322,8 @@ static int begin_include (qse_xli_t* xli) | ||||
| 	if (link == QSE_NULL) goto oops; | ||||
|  | ||||
| 	qse_strncpy ((qse_char_t*)(link + 1), QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name)); | ||||
| 	link->link = xli->sio_names; | ||||
| 	xli->sio_names = link; | ||||
| 	link->link = xli->rio_names; | ||||
| 	xli->rio_names = link; | ||||
|  | ||||
| 	arg = (qse_xli_io_arg_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*arg)); | ||||
| 	if (arg == QSE_NULL) goto oops; | ||||
| @ -333,9 +333,9 @@ static int begin_include (qse_xli_t* xli) | ||||
| 	arg->colm = 1; | ||||
|  | ||||
| 	/* let the argument's prev point field to the current */ | ||||
| 	arg->prev = xli->sio.inp;  | ||||
| 	arg->prev = xli->rio.inp;  | ||||
|  | ||||
| 	if (xli->sio.impl (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1) | ||||
| 	if (xli->rio.impl (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1) | ||||
| 	{ | ||||
| 		if (xli->errnum == QSE_XLI_ENOERR) | ||||
| 			qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL);  | ||||
| @ -343,7 +343,7 @@ static int begin_include (qse_xli_t* xli) | ||||
| 	} | ||||
|  | ||||
| 	/* i update the current pointer after opening is successful */ | ||||
| 	xli->sio.inp = arg; | ||||
| 	xli->rio.inp = arg; | ||||
| 	/* xli->parse.depth.incl++; */ | ||||
|  | ||||
| 	/* read in the first character in the included file.  | ||||
| @ -353,7 +353,7 @@ static int begin_include (qse_xli_t* xli) | ||||
| 	{ | ||||
| 		end_include (xli, 1);  | ||||
| 		/* i don't jump to oops since i've called  | ||||
| 		 * end_include() where xli->sio.inp/arg is freed. */ | ||||
| 		 * end_include() where xli->rio.inp/arg is freed. */ | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @ -368,7 +368,7 @@ static int begin_include (qse_xli_t* xli) | ||||
|  | ||||
| oops: | ||||
| 	/* i don't need to free 'link' since it's linked to | ||||
| 	 * xli->sio_names that's freed at the beginning of qse_xli_read() | ||||
| 	 * xli->rio_names that's freed at the beginning of qse_xli_read() | ||||
| 	 * or by qse_xli_fini() */ | ||||
| 	if (arg) QSE_MMGR_FREE (xli->mmgr, arg); | ||||
| 	return -1; | ||||
| @ -390,11 +390,11 @@ retry: | ||||
| 	while (n >= 1); | ||||
|  | ||||
| 	qse_str_clear (tok->name); | ||||
| 	tok->loc.file = xli->sio.last.file; | ||||
| 	tok->loc.line = xli->sio.last.line; | ||||
| 	tok->loc.colm = xli->sio.last.colm; | ||||
| 	tok->loc.file = xli->rio.last.file; | ||||
| 	tok->loc.line = xli->rio.last.line; | ||||
| 	tok->loc.colm = xli->rio.last.colm; | ||||
|  | ||||
| 	c = xli->sio.last.c; | ||||
| 	c = xli->rio.last.c; | ||||
|  | ||||
| 	if (c == QSE_CHAR_EOF)  | ||||
| 	{ | ||||
| @ -402,7 +402,7 @@ retry: | ||||
| 		if (n <= -1) return -1; | ||||
| 		if (n >= 1)  | ||||
| 		{ | ||||
| 			/*xli->sio.last = xli->sio.inp->last;*/ | ||||
| 			/*xli->rio.last = xli->rio.inp->last;*/ | ||||
| 			/* mark that i'm retrying after end of an included file */ | ||||
| 			skip_semicolon_after_include = 1;  | ||||
| 			goto retry; | ||||
| @ -610,11 +610,21 @@ static int read_pair (qse_xli_t* xli) | ||||
|  | ||||
| 		if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_IDENT)) | ||||
| 		{ | ||||
| 			qse_xli_str_t* curstrseg; | ||||
|  | ||||
| pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key, name, QSE_STR_CSTR(xli->tok.name)); | ||||
| if (pair == QSE_NULL) goto oops; | ||||
|  | ||||
|  | ||||
| 			curstrseg = (qse_xli_str_t*)pair->val; | ||||
|  | ||||
| #if 0 | ||||
| 			if (qse_str_ncpy (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1) | ||||
| 			{ | ||||
| 				qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); | ||||
| 				goto oops; | ||||
| 			} | ||||
| #endif | ||||
|  | ||||
| 			if (get_token (xli) <= -1) goto oops; | ||||
| 			if (MATCH(xli, TOK_COMMA)) | ||||
| @ -630,20 +640,28 @@ static int read_pair (qse_xli_t* xli) | ||||
| 						goto oops; | ||||
| 					} | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| 					if (qse_str_ncat (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1) | ||||
| 					{ | ||||
| 						qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); | ||||
| 						goto oops; | ||||
| 					} | ||||
| #endif | ||||
|  | ||||
| curstrseg = qse_xli_addnextsegtostr (xli, curstrseg, QSE_STR_CSTR(xli->tok.name)); | ||||
| if (curstrseg == QSE_NULL) goto oops; | ||||
|  | ||||
| 					if (get_token (xli) <= -1) goto oops; /* skip the value */ | ||||
| 				} | ||||
| 				while (MATCH (xli, TOK_COMMA)); | ||||
| 			} | ||||
| 			 | ||||
| #if 0 | ||||
| 			pair = qse_xli_insertpairwithstr ( | ||||
| 				xli, parlist, QSE_NULL, key, name, QSE_STR_CSTR(xli->tmp[0])); | ||||
| 			if (pair == QSE_NULL) goto oops; | ||||
| #endif | ||||
|  | ||||
| 			/* semicolon is mandatory for a string */ | ||||
| 			if (!MATCH (xli, TOK_SEMICOLON)) | ||||
| @ -710,22 +728,33 @@ oops: | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist) | ||||
| static qse_xli_list_link_t* make_list_link (qse_xli_t* xli, qse_xli_list_t* parlist) | ||||
| { | ||||
| 	qse_xli_list_link_t* link = QSE_NULL; | ||||
| 	qse_xli_list_link_t* link; | ||||
|  | ||||
| 	link = (qse_xli_list_link_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*link)); | ||||
| 	if (link == QSE_NULL) goto oops; | ||||
| 	if (link == QSE_NULL) return QSE_NULL; | ||||
|  | ||||
| 	link->list = parlist; | ||||
| 	link->next = xli->parlink; | ||||
| 	xli->parlink = link; | ||||
|  | ||||
| 	return link;	 | ||||
| } | ||||
|  | ||||
| static void free_list_link (qse_xli_t* xli, qse_xli_list_link_t* link) | ||||
| { | ||||
| 	xli->parlink = link->next; | ||||
| 	qse_xli_freemem (xli, link); | ||||
| } | ||||
|  | ||||
| static int __read_list (qse_xli_t* xli) | ||||
| { | ||||
| 	while (1) | ||||
| 	{ | ||||
| 		if (MATCH (xli, TOK_XINCLUDE)) | ||||
| 		{ | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 			if (get_token(xli) <= -1) return -1; | ||||
|  | ||||
| 			if (!MATCH(xli,TOK_SQSTR) && !MATCH(xli,TOK_DQSTR)) | ||||
| 			{ | ||||
| @ -733,15 +762,15 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist) | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			if (begin_include (xli) <= -1) goto oops; | ||||
| 			if (begin_include (xli) <= -1) return -1; | ||||
| 		} | ||||
| 		else if (MATCH (xli, TOK_IDENT)) | ||||
| 		{ | ||||
| 			if (read_pair (xli) <= -1) goto oops; | ||||
| 			if (read_pair (xli) <= -1) return -1; | ||||
| 		} | ||||
| 		else if (MATCH (xli, TOK_TEXT)) | ||||
| 		{ | ||||
| 			if (get_token(xli) <= -1) goto oops; | ||||
| 			if (get_token(xli) <= -1) return -1; | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| @ -749,29 +778,54 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	QSE_ASSERT (link == xli->parlink); | ||||
| 	xli->parlink = link->next; | ||||
| 	qse_xli_freemem (xli, link); | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| oops: | ||||
| 	if (link) | ||||
| 	{ | ||||
| 		QSE_ASSERT (link == xli->parlink); | ||||
| 		xli->parlink = link->next; | ||||
| 		qse_xli_freemem (xli, link); | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| void qse_xli_clearsionames (qse_xli_t* xli) | ||||
| static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist) | ||||
| { | ||||
| 	qse_xli_list_link_t* link; | ||||
|  | ||||
| 	link = make_list_link (xli, parlist); | ||||
| 	if (link == QSE_NULL) return -1; | ||||
|  | ||||
| 	if (__read_list (xli) <= -1)  | ||||
| 	{ | ||||
| 		free_list_link (xli, link); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	QSE_ASSERT (link == xli->parlink); | ||||
| 	free_list_link (xli, link); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int read_root_list (qse_xli_t* xli) | ||||
| { | ||||
| 	qse_xli_list_link_t* link; | ||||
|  | ||||
| 	link = make_list_link (xli, &xli->root); | ||||
| 	if (link == QSE_NULL) return -1; | ||||
|  | ||||
| 	if (get_char (xli) <= -1 || get_token (xli) <= -1 || __read_list (xli) <= -1) | ||||
| 	{ | ||||
| 		free_list_link (xli, link); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	QSE_ASSERT (link == xli->parlink); | ||||
| 	free_list_link (xli, link); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void qse_xli_clearrionames (qse_xli_t* xli) | ||||
| { | ||||
| 	qse_link_t* cur; | ||||
| 	while (xli->sio_names) | ||||
| 	while (xli->rio_names) | ||||
| 	{ | ||||
| 		cur = xli->sio_names; | ||||
| 		xli->sio_names = cur->link; | ||||
| 		cur = xli->rio_names; | ||||
| 		xli->rio_names = cur->link; | ||||
| 		QSE_MMGR_FREE (xli->mmgr, cur); | ||||
| 	} | ||||
| } | ||||
| @ -786,14 +840,14 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	QSE_MEMSET (&xli->sio, 0, QSE_SIZEOF(xli->sio)); | ||||
| 	xli->sio.impl = io; | ||||
| 	xli->sio.arg.line = 1; | ||||
| 	xli->sio.arg.colm = 1; | ||||
| 	xli->sio.inp = &xli->sio.arg; | ||||
| 	qse_xli_clearsionames (xli); | ||||
| 	QSE_MEMSET (&xli->rio, 0, QSE_SIZEOF(xli->rio)); | ||||
| 	xli->rio.impl = io; | ||||
| 	xli->rio.top.line = 1; | ||||
| 	xli->rio.top.colm = 1; | ||||
| 	xli->rio.inp = &xli->rio.top; | ||||
| 	qse_xli_clearrionames (xli); | ||||
|  | ||||
| 	n = xli->sio.impl (xli, QSE_XLI_IO_OPEN, xli->sio.inp, QSE_NULL, 0); | ||||
| 	n = xli->rio.impl (xli, QSE_XLI_IO_OPEN, xli->rio.inp, QSE_NULL, 0); | ||||
| 	if (n <= -1) | ||||
| 	{ | ||||
| 		if (xli->errnum == QSE_XLI_ENOERR) | ||||
| @ -802,8 +856,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) | ||||
| 	} | ||||
| 	/* the input stream is open now */ | ||||
|  | ||||
| 	if (get_char (xli) <= -1 || get_token (xli) <= -1) goto oops; | ||||
| 	if (read_list (xli, &xli->root) <= -1) goto oops; | ||||
| 	if (read_root_list (xli) <= -1) goto oops; | ||||
|  | ||||
| 	QSE_ASSERT (xli->parlink == QSE_NULL); | ||||
|  | ||||
| @ -813,7 +866,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) | ||||
| 		goto oops; | ||||
| 	} | ||||
|  | ||||
| 	QSE_ASSERT (xli->sio.inp == &xli->sio.arg); | ||||
| 	QSE_ASSERT (xli->rio.inp == &xli->rio.top); | ||||
| 	close_current_stream (xli); | ||||
| 	return 0; | ||||
|  | ||||
| @ -821,17 +874,17 @@ oops: | ||||
| 	/* an error occurred and control has reached here | ||||
| 	 * probably, some included files might not have been  | ||||
| 	 * closed. close them */ | ||||
| 	while (xli->sio.inp != &xli->sio.arg) | ||||
| 	while (xli->rio.inp != &xli->rio.top) | ||||
| 	{ | ||||
| 		qse_xli_io_arg_t* prev; | ||||
|  | ||||
| 		/* nothing much to do about a close error */ | ||||
| 		close_current_stream (xli); | ||||
|  | ||||
| 		prev = xli->sio.inp->prev; | ||||
| 		QSE_ASSERT (xli->sio.inp->name != QSE_NULL); | ||||
| 		QSE_MMGR_FREE (xli->mmgr, xli->sio.inp); | ||||
| 		xli->sio.inp = prev; | ||||
| 		prev = xli->rio.inp->prev; | ||||
| 		QSE_ASSERT (xli->rio.inp->name != QSE_NULL); | ||||
| 		QSE_MMGR_FREE (xli->mmgr, xli->rio.inp); | ||||
| 		xli->rio.inp = prev; | ||||
| 	} | ||||
| 	 | ||||
| 	close_current_stream (xli); | ||||
|  | ||||
| @ -143,7 +143,7 @@ static qse_ssize_t sf_in_open (qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn | ||||
| 	{ | ||||
| 		qse_xli_iostd_t* psin = xtn->s.in.x; | ||||
| 	 | ||||
| 		QSE_ASSERT (arg == &xli->sio.arg); | ||||
| 		QSE_ASSERT (arg == &xli->rio.top); | ||||
|  | ||||
| 		switch (psin->type) | ||||
| 		{ | ||||
| @ -360,6 +360,7 @@ static qse_ssize_t sf_in ( | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| static qse_ssize_t sf_out ( | ||||
| 	qse_xli_t* xli, qse_xli_io_cmd_t cmd,  | ||||
| 	qse_xli_io_arg_t* arg, qse_char_t* data, qse_size_t size) | ||||
| @ -475,6 +476,243 @@ static qse_ssize_t sf_out ( | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| static qse_ssize_t sf_out_open (qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn) | ||||
| { | ||||
| 	if (arg->prev == QSE_NULL) | ||||
| 	{ | ||||
| 		qse_xli_iostd_t* psout = xtn->s.out.x; | ||||
| 	 | ||||
| 		QSE_ASSERT (arg == &xli->wio.top); | ||||
|  | ||||
| 		switch (psout->type) | ||||
| 		{ | ||||
| 			/* normal source files */ | ||||
| 			case QSE_XLI_IOSTD_FILE: | ||||
| 				if (psout->u.file.path == QSE_NULL || | ||||
| 				    (psout->u.file.path[0] == QSE_T('-') && | ||||
| 				     psout->u.file.path[1] == QSE_T('\0'))) | ||||
| 				{ | ||||
| 					/* no path name or - -> stdout */ | ||||
| 					arg->handle = open_sio_std (xli, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					arg->handle = open_sio (xli, psout->u.file.path, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH); | ||||
| 				} | ||||
| 				if (arg->handle == QSE_NULL) return -1; | ||||
| 				if (psout->u.file.cmgr) qse_sio_setcmgr (arg->handle, psout->u.file.cmgr); | ||||
|  | ||||
| 				/* update the object name to something more specific */ | ||||
| 				arg->name = psout->u.file.path; | ||||
| 				if (arg->name == QSE_NULL) arg->name = sio_std_names[QSE_SIO_STDOUT].ptr; | ||||
|  | ||||
| 				return 0; | ||||
| 	 | ||||
| 			case QSE_XLI_IOSTD_STR: | ||||
| 				xtn->s.out.u.str.buf = qse_str_open (xli->mmgr, 0, 512); | ||||
| 				if (xtn->s.out.u.str.buf == QSE_NULL) | ||||
| 				{ | ||||
| 					qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); | ||||
| 					return -1; | ||||
| 				} | ||||
|  | ||||
| 				return 0; | ||||
| 			default: | ||||
| 				qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL); | ||||
| 				return -1; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* handle the included file - @include */ | ||||
| 		const qse_char_t* path; | ||||
| 		qse_char_t fbuf[64]; | ||||
| 		qse_char_t* dbuf = QSE_NULL; | ||||
| 	 | ||||
| 		QSE_ASSERT (arg->name != QSE_NULL); | ||||
|  | ||||
| 		path = arg->name; | ||||
| 		if (arg->prev->handle) | ||||
| 		{ | ||||
| 			const qse_char_t* outer; | ||||
|  | ||||
| 			outer = qse_sio_getpath (arg->prev->handle); | ||||
|  | ||||
| 			if (outer) | ||||
| 			{ | ||||
| 				const qse_char_t* base; | ||||
| 	 | ||||
| 				/* i'm being included from another file */ | ||||
| 				base = qse_basename (outer); | ||||
| 				if (base != outer && arg->name[0] != QSE_T('/')) | ||||
| 				{ | ||||
| 					qse_size_t tmplen, totlen, dirlen; | ||||
| 	 | ||||
| 					dirlen = base - outer;	 | ||||
| 					 | ||||
| 					totlen = qse_strlen(arg->name) + dirlen; | ||||
| 					if (totlen >= QSE_COUNTOF(fbuf)) | ||||
| 					{ | ||||
| 						dbuf = qse_xli_allocmem ( | ||||
| 							xli, QSE_SIZEOF(qse_char_t) * (totlen + 1) | ||||
| 						); | ||||
| 						if (dbuf == QSE_NULL) return -1; | ||||
| 		 | ||||
| 						path = dbuf; | ||||
| 					} | ||||
| 					else path = fbuf; | ||||
| 		 | ||||
| 					tmplen = qse_strncpy ((qse_char_t*)path, outer, dirlen); | ||||
| 					qse_strcpy ((qse_char_t*)path + tmplen, arg->name); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		arg->handle = qse_sio_open ( | ||||
| 			xli->mmgr, 0, path, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH | ||||
| 		); | ||||
|  | ||||
| 		if (dbuf) QSE_MMGR_FREE (xli->mmgr, dbuf); | ||||
| 		if (arg->handle == QSE_NULL) | ||||
| 		{ | ||||
| 			qse_cstr_t ea; | ||||
| 			ea.ptr = arg->name; | ||||
| 			ea.len = qse_strlen(ea.ptr); | ||||
| 			qse_xli_seterrnum (xli, QSE_XLI_EIOFIL, &ea); | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| static qse_ssize_t sf_out_close ( | ||||
| 	qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn) | ||||
| { | ||||
| 	if (arg->prev == QSE_NULL) | ||||
| 	{ | ||||
| 		switch (xtn->s.out.x->type) | ||||
| 		{ | ||||
| 			case QSE_XLI_IOSTD_FILE: | ||||
| 				QSE_ASSERT (arg->handle != QSE_NULL); | ||||
| 				qse_sio_close (arg->handle); | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_XLI_IOSTD_STR: | ||||
| 				/* nothing to close */ | ||||
| 				break; | ||||
|  | ||||
| 			default: | ||||
| 				/* nothing to close */ | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* handle the included source file - @include */ | ||||
| 		QSE_ASSERT (arg->handle != QSE_NULL); | ||||
| 		qse_sio_close (arg->handle); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static qse_ssize_t sf_out_write ( | ||||
| 	qse_xli_t* xli, qse_xli_io_arg_t* arg, | ||||
| 	qse_char_t* data, qse_size_t size, xtn_t* xtn) | ||||
| { | ||||
| 	if (arg->prev == QSE_NULL) | ||||
| 	{ | ||||
| 		qse_ssize_t n; | ||||
|  | ||||
| 		switch (xtn->s.out.x->type) | ||||
| 		{ | ||||
| 			case QSE_XLI_IOSTD_FILE: | ||||
| 				QSE_ASSERT (arg->handle != QSE_NULL); | ||||
| 				n = qse_sio_putstrn (arg->handle, data, size); | ||||
| 				if (n <= -1) | ||||
| 				{ | ||||
| 					qse_cstr_t ea; | ||||
| 					ea.ptr = xtn->s.out.x->u.file.path; | ||||
| 					if (ea.ptr == QSE_NULL) ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr; | ||||
| 					ea.len = qse_strlen(ea.ptr); | ||||
| 					qse_xli_seterrnum (xli, QSE_XLI_EIOFIL, &ea); | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 			case QSE_XLI_IOSTD_STR: | ||||
| 				if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t); | ||||
| 				if (qse_str_ncat (xtn->s.out.u.str.buf, data, size) == (qse_size_t)-1) | ||||
| 				{ | ||||
| 					qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); | ||||
| 					return -1; | ||||
| 				} | ||||
| 				n = size; | ||||
| 				break; | ||||
|  | ||||
| 			default: | ||||
| 				/* this should never happen */ | ||||
| 				qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL); | ||||
| 				n = -1; | ||||
| 				break; | ||||
| 		} | ||||
|  | ||||
| 		return n; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* handle the included source file - @include */ | ||||
| 		qse_ssize_t n; | ||||
|  | ||||
| 		QSE_ASSERT (arg->name != QSE_NULL); | ||||
| 		QSE_ASSERT (arg->handle != QSE_NULL); | ||||
|  | ||||
| 		n = qse_sio_putstrn (arg->handle, data, size); | ||||
| 		if (n <= -1) | ||||
| 		{ | ||||
| 			qse_cstr_t ea; | ||||
| 			ea.ptr = arg->name; | ||||
| 			ea.len = qse_strlen(ea.ptr); | ||||
| 			qse_xli_seterrnum (xli, QSE_XLI_EIOFIL, &ea); | ||||
| 		} | ||||
| 		return n; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static qse_ssize_t sf_out ( | ||||
| 	qse_xli_t* xli, qse_xli_io_cmd_t cmd,  | ||||
| 	qse_xli_io_arg_t* arg, qse_char_t* data, qse_size_t size) | ||||
| { | ||||
| 	xtn_t* xtn = QSE_XTN (xli); | ||||
|  | ||||
| 	QSE_ASSERT (arg != QSE_NULL); | ||||
|  | ||||
| 	switch (cmd) | ||||
| 	{ | ||||
| 		case QSE_XLI_IO_OPEN: | ||||
| 			return sf_out_open (xli, arg, xtn); | ||||
|  | ||||
| 		case QSE_XLI_IO_CLOSE: | ||||
| 			return sf_out_close (xli, arg, xtn); | ||||
|  | ||||
| 		case QSE_XLI_IO_WRITE: | ||||
| 			return sf_out_write (xli, arg, data, size, xtn); | ||||
|  | ||||
| 		default: | ||||
| 			qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL); | ||||
| 			return -1; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int qse_xli_readstd (qse_xli_t* xli, qse_xli_iostd_t* in) | ||||
| { | ||||
| 	xtn_t* xtn = (xtn_t*) QSE_XTN (xli); | ||||
|  | ||||
| @ -108,12 +108,16 @@ static int close_current_stream (qse_xli_t* xli, int* org_depth) | ||||
| 	} | ||||
|  | ||||
| 	xli->wio.inp = arg->prev; | ||||
| 	if (org_depth) | ||||
| 	if (arg == &xli->wio.top) | ||||
| 	{ | ||||
| 		*org_depth = (arg == &xli->wio.top)? 0: (((arg_data_t*)(arg + 1))->org_depth); | ||||
| 		if (org_depth) *org_depth = 0;			 | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if (org_depth) *org_depth = ((arg_data_t*)(arg + 1))->org_depth; | ||||
| 		qse_xli_freemem (xli, arg); | ||||
| 	} | ||||
|  | ||||
| 	qse_xli_freemem (xli, arg); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -180,7 +184,7 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | ||||
| 						qse_xli_str_t* str = (qse_xli_str_t*)pair->val; | ||||
| 						if (write_to_current_stream (xli, QSE_T(" = \""), 4, 0) <= -1 || | ||||
| 						    write_to_current_stream (xli, str->ptr, str->len, 1) <= -1 || | ||||
| 						    write_to_current_stream (xli, QSE_T("\";"), 2, 0) <= -1) return -1; | ||||
| 						    write_to_current_stream (xli, QSE_T("\";\n"), 3, 0) <= -1) return -1; | ||||
| 						break;	 | ||||
| 					} | ||||
|  | ||||
| @ -197,7 +201,14 @@ 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; | ||||
| @ -206,11 +217,17 @@ 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_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("\""), 1, 0) <= -1) return -1; | ||||
| 				    write_to_current_stream (xli, QSE_T("\";\n"), 3, 0) <= -1) return -1; | ||||
| 				 | ||||
| 				if (open_new_stream (xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1; | ||||
| 				depth = 0; | ||||
| @ -230,13 +247,11 @@ int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io) | ||||
| { | ||||
| 	int n; | ||||
|  | ||||
| #if 0 | ||||
| 	if (io == QSE_NULL) | ||||
| 	{ | ||||
| 		qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); | ||||
| 		return -1; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	QSE_MEMSET (&xli->wio, 0, QSE_SIZEOF(xli->wio)); | ||||
| 	xli->wio.impl = io; | ||||
|  | ||||
| @ -94,7 +94,7 @@ void qse_xli_fini (qse_xli_t* xli) | ||||
| 		if (xli->tmp[--i]) qse_str_close (xli->tmp[i]); | ||||
| 	} | ||||
|  | ||||
| 	qse_xli_clearsionames (xli); | ||||
| 	qse_xli_clearrionames (xli); | ||||
| } | ||||
|  | ||||
| qse_mmgr_t* qse_xli_getmmgr (qse_xli_t* xli) | ||||
| @ -286,6 +286,23 @@ qse_xli_pair_t* qse_xli_insertpairwithstr ( | ||||
| 	return tmp; | ||||
| } | ||||
|  | ||||
| qse_xli_str_t* qse_xli_addnextsegtostr ( | ||||
| 	qse_xli_t* xli, qse_xli_str_t* str, const qse_cstr_t* value) | ||||
| { | ||||
| 	qse_xli_str_t* val; | ||||
|  | ||||
| 	val = qse_xli_callocmem (xli, QSE_SIZEOF(*val) + ((value->len  + 1) * QSE_SIZEOF(*value->ptr))); | ||||
| 	if (val == QSE_NULL) return QSE_NULL; | ||||
|  | ||||
| 	val->type = QSE_XLI_STR; | ||||
| 	qse_strncpy ((qse_char_t*)(val + 1), value->ptr, value->len); | ||||
| 	val->ptr = (const qse_char_t*)(val + 1); | ||||
| 	val->len = value->len; | ||||
| 		 | ||||
| 	str->next = val; | ||||
| 	return str->next; | ||||
| } | ||||
|  | ||||
| qse_xli_text_t* qse_xli_inserttext ( | ||||
| 	qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, const qse_char_t* str) | ||||
| { | ||||
|  | ||||
| @ -68,10 +68,10 @@ struct qse_xli_t | ||||
| 	{ | ||||
| 		qse_xli_io_impl_t impl; /* input handler */ | ||||
| 		qse_xli_io_lxc_t  last;	 | ||||
| 		qse_xli_io_arg_t  arg; /* for top level */ | ||||
| 		qse_xli_io_arg_t  top; /* for top level */ | ||||
| 		qse_xli_io_arg_t* inp; /* current */ | ||||
| 	} sio; | ||||
| 	qse_link_t* sio_names; | ||||
| 	} rio; | ||||
| 	qse_link_t* rio_names; | ||||
|  | ||||
| 	struct  | ||||
| 	{ | ||||
| @ -93,7 +93,7 @@ void qse_xli_fini (qse_xli_t* xli); | ||||
| const qse_char_t* qse_xli_dflerrstr ( | ||||
|      const qse_xli_t* xli, qse_xli_errnum_t errnum); | ||||
|  | ||||
| void qse_xli_clearsionames (qse_xli_t* xli); | ||||
| void qse_xli_clearrionames (qse_xli_t* xli); | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user