added qse_xli_getroot() and started implementing qse_xli_write()
This commit is contained in:
		| @ -25,11 +25,11 @@ static int get_char (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 close_stream (qse_xli_t* xli) | ||||
| static int close_current_stream (qse_xli_t* xli) | ||||
| { | ||||
| 	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 (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) | ||||
| 	{ | ||||
| 		n = xli->sio.inf ( | ||||
| 		n = xli->sio.impl ( | ||||
| 			xli, QSE_XLI_IO_READ, xli->sio.inp, | ||||
| 			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; | ||||
| } | ||||
|  | ||||
| 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; | ||||
|  | ||||
| 	if (c == QSE_T('#')) | ||||
| 	{ | ||||
| 		 | ||||
| 		/* skip up to \n */ | ||||
| 		/* TODO: support a different line terminator */ | ||||
| 		do { GET_CHAR_TO (xli, c); } | ||||
| 		while (c != QSE_T('\n') && c != QSE_CHAR_EOF); | ||||
| 		qse_str_clear (tok->name); | ||||
|  | ||||
| 		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 */ | ||||
| 		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 | ||||
| 	 * retry to read a character from an outer file */ | ||||
|  | ||||
| 	x = xli->sio.inf ( | ||||
| 	x = xli->sio.impl ( | ||||
| 		xli, QSE_XLI_IO_CLOSE,  | ||||
| 		xli->sio.inp, QSE_NULL, 0); | ||||
|  | ||||
| @ -302,7 +315,7 @@ static int begin_include (qse_xli_t* xli) | ||||
| 	qse_link_t* link; | ||||
| 	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)); | ||||
| 	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 */ | ||||
| 	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) | ||||
| 			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: | ||||
| 	do  | ||||
| 	{ | ||||
| 		if (skip_spaces(xli) <= -1) return -1; | ||||
| 		if ((n = skip_comment(xli)) <= -1) return -1;  | ||||
| 		if (skip_spaces (xli) <= -1) return -1; | ||||
| 		if ((n = skip_comment (xli, tok)) <= -1) return -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)); | ||||
| 	xli->sio.inf = io; | ||||
| 	xli->sio.impl = io; | ||||
| 	xli->sio.arg.line = 1; | ||||
| 	xli->sio.arg.colm = 1; | ||||
| 	xli->sio.inp = &xli->sio.arg; | ||||
| 	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 (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); | ||||
| 	close_stream (xli); | ||||
| 	close_current_stream (xli); | ||||
| 	return 0; | ||||
|  | ||||
| oops: | ||||
| @ -780,7 +793,7 @@ oops: | ||||
| 		qse_xli_io_arg_t* prev; | ||||
|  | ||||
| 		/* nothing much to do about a close error */ | ||||
| 		close_stream (xli); | ||||
| 		close_current_stream (xli); | ||||
|  | ||||
| 		prev = xli->sio.inp->prev; | ||||
| 		QSE_ASSERT (xli->sio.inp->name != QSE_NULL); | ||||
| @ -788,6 +801,6 @@ oops: | ||||
| 		xli->sio.inp = prev; | ||||
| 	} | ||||
| 	 | ||||
| 	close_stream (xli); | ||||
| 	close_current_stream (xli); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| @ -20,16 +20,117 @@ | ||||
|  | ||||
| #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 n; | ||||
|  | ||||
| #if 0 | ||||
| 	if (io == QSE_NULL) | ||||
| 	{ | ||||
| 		qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); | ||||
| 		return -1; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	/* TODO: write data to io stream */ | ||||
| 	qse_xli_seterrnum (xli, QSE_XLI_ENOIMPL, QSE_NULL); | ||||
| 	return -1; | ||||
| 	QSE_MEMSET (&xli->wio, 0, QSE_SIZEOF(xli->wio)); | ||||
| 	xli->wio.impl = io; | ||||
| 	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_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; | ||||
| 	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_arg_t  arg; /* for top level */ | ||||
| 		qse_xli_io_arg_t* inp; /* current */ | ||||
| 	} sio; | ||||
| 	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