added qse_xli_getroot() and started implementing qse_xli_write()
This commit is contained in:
		| @ -402,6 +402,10 @@ static int xli_main (int argc, qse_char_t* argv[]) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* TODO: qse_xli_writestd??? */ | ||||||
|  | qse_xli_write (xli, QSE_NULL); | ||||||
|  |  | ||||||
| 	ret = 0; | 	ret = 0; | ||||||
|  |  | ||||||
| oops: | oops: | ||||||
|  | |||||||
| @ -487,6 +487,9 @@ QSE_EXPORT qse_xli_pair_t* qse_xli_insertpairwithstr ( | |||||||
| 	const qse_cstr_t* value | 	const qse_cstr_t* value | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_xli_list_t* qse_xli_getroot ( | ||||||
|  | 	qse_xli_t* xli | ||||||
|  | ); | ||||||
|  |  | ||||||
| QSE_EXPORT qse_xli_pair_t* qse_xli_findpairbyname ( | QSE_EXPORT qse_xli_pair_t* qse_xli_findpairbyname ( | ||||||
| 	qse_xli_t*            xli, | 	qse_xli_t*            xli, | ||||||
|  | |||||||
| @ -25,11 +25,11 @@ static int get_char (qse_xli_t* xli); | |||||||
| static int get_token (qse_xli_t* xli); | static int get_token (qse_xli_t* xli); | ||||||
| static int read_list (qse_xli_t* xli, qse_xli_list_t* list); | static int read_list (qse_xli_t* xli, qse_xli_list_t* list); | ||||||
|  |  | ||||||
| static int close_stream (qse_xli_t* xli) | static int close_current_stream (qse_xli_t* xli) | ||||||
| { | { | ||||||
| 	qse_ssize_t n; | 	qse_ssize_t n; | ||||||
|  |  | ||||||
| 	n = xli->sio.inf (xli, QSE_XLI_IO_CLOSE, xli->sio.inp, QSE_NULL, 0); | 	n = xli->sio.impl (xli, QSE_XLI_IO_CLOSE, xli->sio.inp, QSE_NULL, 0); | ||||||
| 	if (n <= -1) | 	if (n <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		if (xli->errnum == QSE_XLI_ENOERR)  | 		if (xli->errnum == QSE_XLI_ENOERR)  | ||||||
| @ -109,7 +109,7 @@ static int get_char (qse_xli_t* xli) | |||||||
|  |  | ||||||
| 	if (xli->sio.inp->b.pos >= xli->sio.inp->b.len) | 	if (xli->sio.inp->b.pos >= xli->sio.inp->b.len) | ||||||
| 	{ | 	{ | ||||||
| 		n = xli->sio.inf ( | 		n = xli->sio.impl ( | ||||||
| 			xli, QSE_XLI_IO_READ, xli->sio.inp, | 			xli, QSE_XLI_IO_READ, xli->sio.inp, | ||||||
| 			xli->sio.inp->b.buf, QSE_COUNTOF(xli->sio.inp->b.buf) | 			xli->sio.inp->b.buf, QSE_COUNTOF(xli->sio.inp->b.buf) | ||||||
| 		); | 		); | ||||||
| @ -160,17 +160,30 @@ static int skip_spaces (qse_xli_t* xli) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int skip_comment (qse_xli_t* xli) | 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->sio.last.c; | ||||||
|  |  | ||||||
| 	if (c == QSE_T('#')) | 	if (c == QSE_T('#')) | ||||||
| 	{ | 	{ | ||||||
| 		 |  | ||||||
| 		/* skip up to \n */ | 		/* skip up to \n */ | ||||||
| 		/* TODO: support a different line terminator */ | 		/* TODO: support a different line terminator */ | ||||||
| 		do { GET_CHAR_TO (xli, c); } | 		qse_str_clear (tok->name); | ||||||
| 		while (c != QSE_T('\n') && c != QSE_CHAR_EOF); |  | ||||||
|  | 		do | ||||||
|  | 		{  | ||||||
|  | 			GET_CHAR_TO (xli, c);  | ||||||
|  | 			if (c == QSE_T('\n') || c == QSE_CHAR_EOF) break; | ||||||
|  | #if 0 | ||||||
|  | 			ADD_TOKEN_CHAR (xli, tok, c); | ||||||
|  | #endif | ||||||
|  | 		} | ||||||
|  | 		while (1); | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  | 		if (qse_xli_inserttext (xli, list, QSE_NULL, QSE_STR_PTR(tok->name)) <= -1) return -1; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 		GET_CHAR (xli); /* eat the new line letter */ | 		GET_CHAR (xli); /* eat the new line letter */ | ||||||
| 		return 1; /* comment by # */ | 		return 1; /* comment by # */ | ||||||
| 	} | 	} | ||||||
| @ -268,7 +281,7 @@ static int end_include (qse_xli_t* xli) | |||||||
| 	/* if it is an included file, close it and | 	/* if it is an included file, close it and | ||||||
| 	 * retry to read a character from an outer file */ | 	 * retry to read a character from an outer file */ | ||||||
|  |  | ||||||
| 	x = xli->sio.inf ( | 	x = xli->sio.impl ( | ||||||
| 		xli, QSE_XLI_IO_CLOSE,  | 		xli, QSE_XLI_IO_CLOSE,  | ||||||
| 		xli->sio.inp, QSE_NULL, 0); | 		xli->sio.inp, QSE_NULL, 0); | ||||||
|  |  | ||||||
| @ -302,7 +315,7 @@ static int begin_include (qse_xli_t* xli) | |||||||
| 	qse_link_t* link; | 	qse_link_t* link; | ||||||
| 	qse_xli_io_arg_t* arg = QSE_NULL; | 	qse_xli_io_arg_t* arg = QSE_NULL; | ||||||
|  |  | ||||||
| 	link = (qse_xli_io_arg_t*) qse_xli_callocmem (xli,  | 	link = (qse_link_t*) qse_xli_callocmem (xli,  | ||||||
| 		QSE_SIZEOF(*link) + QSE_SIZEOF(qse_char_t) * (QSE_STR_LEN(xli->tok.name) + 1)); | 		QSE_SIZEOF(*link) + QSE_SIZEOF(qse_char_t) * (QSE_STR_LEN(xli->tok.name) + 1)); | ||||||
| 	if (link == QSE_NULL) goto oops; | 	if (link == QSE_NULL) goto oops; | ||||||
|  |  | ||||||
| @ -320,7 +333,7 @@ static int begin_include (qse_xli_t* xli) | |||||||
| 	/* let the argument's prev point field to the current */ | 	/* let the argument's prev point field to the current */ | ||||||
| 	arg->prev = xli->sio.inp;  | 	arg->prev = xli->sio.inp;  | ||||||
|  |  | ||||||
| 	if (xli->sio.inf (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1) | 	if (xli->sio.impl (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		if (xli->errnum == QSE_XLI_ENOERR) | 		if (xli->errnum == QSE_XLI_ENOERR) | ||||||
| 			qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL);  | 			qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL);  | ||||||
| @ -362,8 +375,8 @@ static int get_token_into (qse_xli_t* xli, qse_xli_tok_t* tok) | |||||||
| retry: | retry: | ||||||
| 	do  | 	do  | ||||||
| 	{ | 	{ | ||||||
| 		if (skip_spaces(xli) <= -1) return -1; | 		if (skip_spaces (xli) <= -1) return -1; | ||||||
| 		if ((n = skip_comment(xli)) <= -1) return -1;  | 		if ((n = skip_comment (xli, tok)) <= -1) return -1;  | ||||||
| 	}  | 	}  | ||||||
| 	while (n >= 1); | 	while (n >= 1); | ||||||
|  |  | ||||||
| @ -743,13 +756,13 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	QSE_MEMSET (&xli->sio, 0, QSE_SIZEOF(xli->sio)); | 	QSE_MEMSET (&xli->sio, 0, QSE_SIZEOF(xli->sio)); | ||||||
| 	xli->sio.inf = io; | 	xli->sio.impl = io; | ||||||
| 	xli->sio.arg.line = 1; | 	xli->sio.arg.line = 1; | ||||||
| 	xli->sio.arg.colm = 1; | 	xli->sio.arg.colm = 1; | ||||||
| 	xli->sio.inp = &xli->sio.arg; | 	xli->sio.inp = &xli->sio.arg; | ||||||
| 	qse_xli_clearsionames (xli); | 	qse_xli_clearsionames (xli); | ||||||
|  |  | ||||||
| 	n = xli->sio.inf (xli, QSE_XLI_IO_OPEN, xli->sio.inp, QSE_NULL, 0); | 	n = xli->sio.impl (xli, QSE_XLI_IO_OPEN, xli->sio.inp, QSE_NULL, 0); | ||||||
| 	if (n <= -1) | 	if (n <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		if (xli->errnum == QSE_XLI_ENOERR) | 		if (xli->errnum == QSE_XLI_ENOERR) | ||||||
| @ -768,7 +781,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	QSE_ASSERT (xli->sio.inp == &xli->sio.arg); | 	QSE_ASSERT (xli->sio.inp == &xli->sio.arg); | ||||||
| 	close_stream (xli); | 	close_current_stream (xli); | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| oops: | oops: | ||||||
| @ -780,7 +793,7 @@ oops: | |||||||
| 		qse_xli_io_arg_t* prev; | 		qse_xli_io_arg_t* prev; | ||||||
|  |  | ||||||
| 		/* nothing much to do about a close error */ | 		/* nothing much to do about a close error */ | ||||||
| 		close_stream (xli); | 		close_current_stream (xli); | ||||||
|  |  | ||||||
| 		prev = xli->sio.inp->prev; | 		prev = xli->sio.inp->prev; | ||||||
| 		QSE_ASSERT (xli->sio.inp->name != QSE_NULL); | 		QSE_ASSERT (xli->sio.inp->name != QSE_NULL); | ||||||
| @ -788,6 +801,6 @@ oops: | |||||||
| 		xli->sio.inp = prev; | 		xli->sio.inp = prev; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	close_stream (xli); | 	close_current_stream (xli); | ||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,16 +20,117 @@ | |||||||
|  |  | ||||||
| #include "xli.h" | #include "xli.h" | ||||||
|  |  | ||||||
|  | static int close_current_stream (qse_xli_t* xli) | ||||||
|  | { | ||||||
|  | 	qse_ssize_t n; | ||||||
|  |  | ||||||
|  | 	n = xli->wio.impl (xli, QSE_XLI_IO_CLOSE, xli->wio.inp, QSE_NULL, 0); | ||||||
|  | 	if (n <= -1) | ||||||
|  | 	{ | ||||||
|  | 		if (xli->errnum == QSE_XLI_ENOERR)  | ||||||
|  | 			qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) | ||||||
|  | { | ||||||
|  | 	qse_xli_atom_t* curatom; | ||||||
|  |  | ||||||
|  | 	for (curatom = list->head; curatom; curatom = curatom->next) | ||||||
|  | 	{ | ||||||
|  | 		switch (curatom->type) | ||||||
|  | 		{ | ||||||
|  | 			case QSE_XLI_PAIR: | ||||||
|  | 			{ | ||||||
|  | 				int i; | ||||||
|  | 				qse_xli_pair_t* pair = (qse_xli_pair_t*)curatom; | ||||||
|  | 				 | ||||||
|  | 				for (i = 0; i < depth; i++) qse_printf (QSE_T("\t")); | ||||||
|  | 				qse_printf (QSE_T("%s"), pair->key); | ||||||
|  | 				if (pair->name) qse_printf (QSE_T(" \"%s\""), pair->name); | ||||||
|  |  | ||||||
|  | 				switch (pair->val->type) | ||||||
|  | 				{ | ||||||
|  | 					case QSE_XLI_NIL: | ||||||
|  | 						qse_printf (QSE_T(";\n")); | ||||||
|  | 						break; | ||||||
|  |  | ||||||
|  | 					case QSE_XLI_STR: | ||||||
|  | 					{ | ||||||
|  | 						qse_xli_str_t* str = (qse_xli_str_t*)pair->val; | ||||||
|  | 						qse_printf (QSE_T(" = \"%.*s\";\n"), (int)str->len, str->ptr); | ||||||
|  | 						break;	 | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					case QSE_XLI_LIST: | ||||||
|  | 					{ | ||||||
|  | 						qse_printf (QSE_T("{\n")); | ||||||
|  | 						if (write_list (xli, pair->val, ++depth) <= -1) | ||||||
|  | 						{ | ||||||
|  | 						} | ||||||
|  | 						qse_printf (QSE_T("}\n")); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			case QSE_XLI_TEXT: | ||||||
|  | 				qse_printf (QSE_T("# %s\n"), ((qse_xli_text_t*)curatom)->ptr); | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			case QSE_XLI_FILE: | ||||||
|  | 				/* TODO filename escaping.... */ | ||||||
|  | 				qse_printf (QSE_T("@include \"%s\";\n"),(( qse_xli_file_t*)curatom)->path); | ||||||
|  |  | ||||||
|  | 				/* TODO: open a new stream */ | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io) | int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io) | ||||||
| { | { | ||||||
|  | 	int n; | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| 	if (io == QSE_NULL) | 	if (io == QSE_NULL) | ||||||
| 	{ | 	{ | ||||||
| 		qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); | 		qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	/* TODO: write data to io stream */ | 	QSE_MEMSET (&xli->wio, 0, QSE_SIZEOF(xli->wio)); | ||||||
| 	qse_xli_seterrnum (xli, QSE_XLI_ENOIMPL, QSE_NULL); | 	xli->wio.impl = io; | ||||||
| 	return -1; | 	xli->wio.arg.line = 1; | ||||||
|  | 	xli->wio.arg.colm = 1; | ||||||
|  | 	xli->wio.inp = &xli->wio.arg; | ||||||
|  | 	/*qse_xli_clearwionames (xli);*/ | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  | 	n = xli->wio.impl (xli, QSE_XLI_IO_OPEN, xli->wio.inp, QSE_NULL, 0); | ||||||
|  | 	if (n <= -1) | ||||||
|  | 	{ | ||||||
|  | 		if (xli->errnum == QSE_XLI_ENOERR) | ||||||
|  | 			qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL);  | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	n = write_list (xli, &xli->root, 0); | ||||||
|  | 	QSE_ASSERT (xli->wio.inp == &xli->wio.arg); | ||||||
|  | #if 0 | ||||||
|  | 	close_current_stream (xli); | ||||||
|  | #endif | ||||||
|  | 	return n; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -173,6 +173,13 @@ void qse_xli_freemem (qse_xli_t* xli, void* ptr) | |||||||
| { | { | ||||||
| 	QSE_MMGR_FREE (xli->mmgr, ptr); | 	QSE_MMGR_FREE (xli->mmgr, ptr); | ||||||
| } | } | ||||||
|  | /* ------------------------------------------------------ */ | ||||||
|  |  | ||||||
|  | qse_xli_list_t* qse_xli_getroot (qse_xli_t* xli) | ||||||
|  | { | ||||||
|  | 	return &xli->root; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* ------------------------------------------------------ */ | /* ------------------------------------------------------ */ | ||||||
|  |  | ||||||
|  | |||||||
| @ -57,12 +57,19 @@ struct qse_xli_t | |||||||
| 	qse_xli_tok_t tok; | 	qse_xli_tok_t tok; | ||||||
| 	struct | 	struct | ||||||
| 	{ | 	{ | ||||||
| 		qse_xli_io_impl_t inf; /* input handler */ | 		qse_xli_io_impl_t impl; /* input handler */ | ||||||
| 		qse_xli_io_lxc_t  last;	 | 		qse_xli_io_lxc_t  last;	 | ||||||
| 		qse_xli_io_arg_t  arg; /* for top level */ | 		qse_xli_io_arg_t  arg; /* for top level */ | ||||||
| 		qse_xli_io_arg_t* inp; /* current */ | 		qse_xli_io_arg_t* inp; /* current */ | ||||||
| 	} sio; | 	} sio; | ||||||
| 	qse_link_t* sio_names; | 	qse_link_t* sio_names; | ||||||
|  |  | ||||||
|  | 	struct  | ||||||
|  | 	{ | ||||||
|  | 		qse_xli_io_impl_t impl; /* output handler */ | ||||||
|  | 		qse_xli_io_arg_t  arg; /* for top level */ | ||||||
|  | 		qse_xli_io_arg_t* inp; /* current */ | ||||||
|  | 	} wio; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user