| 
									
										
										
										
											2008-05-25 07:05:11 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * $Id$ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <ase/tgp/tgp.h>
 | 
					
						
							| 
									
										
										
										
											2008-08-21 03:58:42 +00:00
										 |  |  | #include "../cmn/mem.h"
 | 
					
						
							| 
									
										
										
										
											2008-05-25 07:05:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct ase_tgp_t | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	ase_mmgr_t mmgr; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 	void* assoc_data; | 
					
						
							| 
									
										
										
										
											2008-05-25 07:07:30 +00:00
										 |  |  | 	int errnum; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_tgp_io_t func; | 
					
						
							|  |  |  | 		void* arg; | 
					
						
							|  |  |  | 	} ih; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_tgp_io_t func; | 
					
						
							|  |  |  | 		void* arg; | 
					
						
							|  |  |  | 	} oh; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	struct  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_tgp_io_t func; | 
					
						
							|  |  |  | 		void* arg; | 
					
						
							|  |  |  | 	} rh; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_size_t pos; | 
					
						
							|  |  |  | 		ase_size_t len; | 
					
						
							|  |  |  | 		ase_char_t ptr[512]; | 
					
						
							|  |  |  | 	} ib; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_size_t len; | 
					
						
							|  |  |  | 		ase_char_t ptr[512]; | 
					
						
							|  |  |  | 	} ob; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_size_t len; | 
					
						
							|  |  |  | 		ase_char_t ptr[512]; | 
					
						
							|  |  |  | 	} rb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int (*read) (ase_tgp_t* tgp, ase_char_t* buf, int len); | 
					
						
							|  |  |  | 	int (*write) (ase_tgp_t* tgp, const ase_char_t* buf, int len); | 
					
						
							|  |  |  | 	int (*run) (ase_tgp_t* tgp, const ase_char_t* buf, int len); | 
					
						
							| 
									
										
										
										
											2008-05-25 07:05:11 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ase_tgp_t* ase_tgp_open (ase_mmgr_t* mmgr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ase_tgp_t* tgp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	if (mmgr == ASE_NULL) mmgr = ASE_GETMMGR(); | 
					
						
							|  |  |  | 	if (mmgr == ASE_NULL)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ASE_ASSERTX (mmgr != ASE_NULL,  | 
					
						
							|  |  |  | 			"Provide the memory manager or set the global memory manager with ASE_SETMMGR()"); | 
					
						
							|  |  |  | 		return ASE_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											2008-05-25 07:05:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-21 03:58:42 +00:00
										 |  |  | 	tgp = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(*tgp)); | 
					
						
							| 
									
										
										
										
											2008-05-25 07:05:11 +00:00
										 |  |  | 	if (tgp == ASE_NULL) return ASE_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-21 03:58:42 +00:00
										 |  |  | 	ASE_MEMSET (tgp, 0, ASE_SIZEOF(*tgp)); | 
					
						
							|  |  |  | 	ASE_MEMCPY (&tgp->mmgr, mmgr, ASE_SIZEOF(*mmgr)); | 
					
						
							| 
									
										
										
										
											2008-05-25 07:05:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return tgp; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ase_tgp_close (ase_tgp_t* tgp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-08-21 03:58:42 +00:00
										 |  |  | 	ASE_MMGR_FREE (&tgp->mmgr, tgp); | 
					
						
							| 
									
										
										
										
											2008-05-25 07:05:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | void ase_tgp_setassocdata (ase_tgp_t* tgp, void* data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	tgp->assoc_data = data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void* ase_tgp_getassocdata (ase_tgp_t* tgp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return tgp->assoc_data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-25 07:07:30 +00:00
										 |  |  | int ase_tgp_geterrnum (ase_tgp_t* tgp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return tgp->errnum; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | static int getc (ase_tgp_t* tgp, ase_char_t* c) | 
					
						
							| 
									
										
										
										
											2008-05-25 07:07:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	if (tgp->ib.pos >= tgp->ib.len)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_ssize_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 		n = tgp->ih.func (ASE_TGP_IO_READ, tgp->ih.arg, tgp->ib.ptr, ASE_COUNTOF(tgp->ib.ptr)); | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 		if (n < 0) return -1; | 
					
						
							|  |  |  | 		else if (n == 0)  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			*c = ASE_CHAR_EOF; | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			tgp->ib.pos = 0; | 
					
						
							|  |  |  | 			tgp->ib.len = n;	 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*c = tgp->ib.ptr[tgp->ib.pos++]; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2008-05-25 07:07:30 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-06-04 02:14:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | static int putc (ase_tgp_t* tgp, ase_char_t c) | 
					
						
							| 
									
										
										
										
											2008-06-04 02:14:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	if (tgp->ob.len >= ASE_COUNTOF(tgp->ob.ptr)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_ssize_t n; | 
					
						
							| 
									
										
										
										
											2008-06-04 02:14:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 		/* TODO: submit on a newline as well */ | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 		n = tgp->oh.func (ASE_TGP_IO_WRITE, tgp->oh.arg, tgp->ob.ptr, ASE_COUNTOF(tgp->ob.ptr)); | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 		if (n < 0) return -1; | 
					
						
							|  |  |  | 		else if (n == 0) return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-04 02:14:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	tgp->ob.ptr[tgp->ob.len++] = c; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2008-06-04 02:14:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | static int runc (ase_tgp_t* tgp, ase_char_t c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (tgp->rb.len >= ASE_COUNTOF(tgp->rb.ptr)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ase_ssize_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 		n = tgp->rh.func (ASE_TGP_IO_WRITE, tgp->rh.arg, tgp->rb.ptr, tgp->rb.len); | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 		if (n < 0) return -1; | 
					
						
							|  |  |  | 		else if (n == 0) return 0; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 		tgp->rh.func (ASE_TGP_IO_READ, tgp->rh.arg, tgp->rb.ptr, tgp->rb.len); | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tgp->rb.ptr[tgp->rb.len++] = c; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ase_tgp_run (ase_tgp_t* tgp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ase_bool_t in_tag = ASE_FALSE; | 
					
						
							|  |  |  | 	ase_char_t c; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tgp->ib.pos = 0; | 
					
						
							|  |  |  | 	tgp->ib.len = 0; | 
					
						
							|  |  |  | 	tgp->ob.len = 0; | 
					
						
							|  |  |  | 	tgp->rb.len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 	n = tgp->ih.func (ASE_TGP_IO_OPEN, tgp->ih.arg, ASE_NULL, 0); | 
					
						
							|  |  |  | 	if (n == -1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* error */ | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (n == 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* reached end of input upon opening the file... */ | 
					
						
							|  |  |  | 		tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	n = tgp->oh.func (ASE_TGP_IO_OPEN, tgp->oh.arg, ASE_NULL, 0); | 
					
						
							|  |  |  | 	if (n == -1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (n == 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* reached end of input upon opening the file... */ | 
					
						
							|  |  |  | 		tgp->oh.func (ASE_TGP_IO_CLOSE, tgp->oh.arg, ASE_NULL, 0); | 
					
						
							|  |  |  | 		tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	while (1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		n = getc (tgp, &c); | 
					
						
							|  |  |  | 		if (n == -1) return -1; | 
					
						
							|  |  |  | 		if (n == 0) break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (c == ASE_T('<'))  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			n = getc (tgp, &c); | 
					
						
							|  |  |  | 			if (n == -1) return -1; | 
					
						
							|  |  |  | 			if (n == 0)  | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				putc (tgp, ASE_T('<')); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (c == ASE_T('?')) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (in_tag) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					/* ERROR - netsted tag */ | 
					
						
							|  |  |  | 					return -1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else in_tag = ASE_TRUE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else  | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (putc (tgp, ASE_T('<')) <= 0) return -1; | 
					
						
							|  |  |  | 				if (putc (tgp, c) <= 0) return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c == ASE_T('?')) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			n = getc (tgp, &c); | 
					
						
							|  |  |  | 			if (n == -1) return -1; | 
					
						
							|  |  |  | 			if (n == 0)  | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (putc (tgp, ASE_T('<')) <= 0) return -1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (c == ASE_T('>')) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (in_tag) in_tag = ASE_FALSE; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					/* ERROR - unpaired tag close */ | 
					
						
							|  |  |  | 					return -1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (putc (tgp, ASE_T('?')) <= 0) return -1; | 
					
						
							|  |  |  | 				if (putc (tgp, c) <= 0) return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (in_tag) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			runc (tgp, c); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (putc (tgp, c) <= 0) return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 	tgp->oh.func (ASE_TGP_IO_CLOSE, tgp->oh.arg, ASE_NULL, 0); | 
					
						
							|  |  |  | 	tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0); | 
					
						
							| 
									
										
										
										
											2008-06-27 04:46:39 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | void ase_tgp_attachin (ase_tgp_t* tgp, ase_tgp_io_t io, void* arg) | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	tgp->ih.func = io; | 
					
						
							|  |  |  | 	tgp->ih.arg = arg; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ase_tgp_detachin (ase_tgp_t* tgp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	tgp->ih.func = ASE_NULL; | 
					
						
							|  |  |  | 	tgp->ih.arg = ASE_NULL; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | void ase_tgp_attachout (ase_tgp_t* tgp, ase_tgp_io_t io, void* arg) | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	tgp->oh.func = io; | 
					
						
							|  |  |  | 	tgp->oh.arg = arg; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ase_tgp_detachout (ase_tgp_t* tgp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	tgp->oh.func = ASE_NULL; | 
					
						
							|  |  |  | 	tgp->oh.arg = ASE_NULL; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | void ase_tgp_attachexec (ase_tgp_t* tgp, ase_tgp_io_t io, void* arg) | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	tgp->rh.func = io; | 
					
						
							|  |  |  | 	tgp->rh.arg = arg; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | void ase_tgp_detachexec (ase_tgp_t* tgp) | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-06 01:25:54 +00:00
										 |  |  | 	tgp->rh.func = ASE_NULL; | 
					
						
							|  |  |  | 	tgp->rh.arg = ASE_NULL; | 
					
						
							| 
									
										
										
										
											2008-06-30 07:41:11 +00:00
										 |  |  | } |