added partial code to support close ("name", "r or w")
This commit is contained in:
		| @ -1,4 +1,68 @@ | |||||||
| /** @page awk AWK | /** @page awk AWK | ||||||
|  |  | ||||||
| AWK Interpreter | AWK Interpreter | ||||||
|  |  | ||||||
|  | VARIABLE DECLARATION | ||||||
|  |  | ||||||
|  | QSE_AWK_EXPLICIT enables variable declaration. Variables declared are accessed | ||||||
|  | directly bypassing the global named map that stores undeclared variables. | ||||||
|  | The keyword global introduces a global variable and the keyword local introduces | ||||||
|  | a local variable. Local variable declaraion in a block should be located before | ||||||
|  | an expression or a statement appears. | ||||||
|  |  | ||||||
|  | @code | ||||||
|  | global g1, g2; #declares two global variables g1 and g2 | ||||||
|  |  | ||||||
|  | BEGIN { | ||||||
|  | 	local a1, a2, a3; # declares three local variables  | ||||||
|  |  | ||||||
|  | 	g1 = 300; a1 = 200; | ||||||
|  |  | ||||||
|  | 	{ | ||||||
|  | 		local a1; # this a1 hides the a1 at the outer scope | ||||||
|  | 		local g1; # this g1 hides the global g1 | ||||||
|  | 		a1 = 10; g1 = 5; | ||||||
|  | 		print a1, g1; # it prints 10 and 5 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	print a1, g1; # it prints 200 and 300 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @endcode | ||||||
|  |  | ||||||
|  | However, turning on QSE_AWK_EXPLICIT does not disable named variables. | ||||||
|  | To disable named variables, you must turn off QSE_AWK_IMPLICIT. | ||||||
|  |  | ||||||
|  | INCLUDE | ||||||
|  |  | ||||||
|  | The \@include directive inserts the contents of the object specified in the | ||||||
|  | following string, typically a file name, as if they appeared in the source | ||||||
|  | stream being processed. The directive can only be used at the outmost scope  | ||||||
|  | where global variable declarations, BEGIN, END, and/or pattern-action blocks | ||||||
|  | appear. To use @include, you must turn on QSE_AWK_INCLUDE. | ||||||
|  |  | ||||||
|  | @code | ||||||
|  | @include "abc.awk" | ||||||
|  | BEGIN { func_in_abc (); } | ||||||
|  | @endcode | ||||||
|  |  | ||||||
|  | TWO-WAY PIPE | ||||||
|  |  | ||||||
|  | The two-way pipe indicated by '||' is supproted, in addition to the one-way  | ||||||
|  | pipe indicated by '|'. Turn on QSE_AWK_RWPIPE to enable the two-way pipe. | ||||||
|  |  | ||||||
|  | @code | ||||||
|  | BEGIN { | ||||||
|  | 	print "15" || "sort"; | ||||||
|  | 	print "14" || "sort"; | ||||||
|  | 	print "13" || "sort"; | ||||||
|  | 	print "12" || "sort"; | ||||||
|  | 	print "11" || "sort"; | ||||||
|  | 	#close the input as sort emits when the input is closed | ||||||
|  | 	close ("sort", "r"); | ||||||
|  | 	while (("sort" || getline x) > 0) print x;  | ||||||
|  | } | ||||||
|  | @endcode | ||||||
|  |  | ||||||
| */ | */ | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: awk.h 267 2009-08-25 09:50:07Z hyunghwan.chung $ |  * $Id: awk.h 270 2009-08-26 12:59:08Z hyunghwan.chung $ | ||||||
|  * |  * | ||||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. |    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||||
|  |  | ||||||
| @ -351,6 +351,12 @@ enum qse_awk_rio_mode_t | |||||||
| }; | }; | ||||||
| typedef enum qse_awk_rio_mode_t qse_awk_rio_mode_t; | typedef enum qse_awk_rio_mode_t qse_awk_rio_mode_t; | ||||||
|  |  | ||||||
|  | enum qse_awk_rio_close_opt_t | ||||||
|  | { | ||||||
|  | 	QSE_AWK_RIO_CLOSE_R = (1 << 0), | ||||||
|  | 	QSE_AWK_RIO_CLOSE_W = (1 << 1) | ||||||
|  | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The qse_awk_rio_arg_t defines the data structure passed to a runtime  |  * The qse_awk_rio_arg_t defines the data structure passed to a runtime  | ||||||
|  * I/O handler. An I/O handler should inspect the @a mode field and the  |  * I/O handler. An I/O handler should inspect the @a mode field and the  | ||||||
| @ -361,9 +367,10 @@ typedef enum qse_awk_rio_mode_t qse_awk_rio_mode_t; | |||||||
| typedef struct qse_awk_rio_arg_t qse_awk_rio_arg_t; | typedef struct qse_awk_rio_arg_t qse_awk_rio_arg_t; | ||||||
| struct qse_awk_rio_arg_t  | struct qse_awk_rio_arg_t  | ||||||
| { | { | ||||||
| 	qse_awk_rio_mode_t mode;  /**< [IN] I/O mode */ | 	qse_awk_rio_mode_t      mode;   /**< [IN] I/O mode */ | ||||||
| 	qse_char_t* name;         /**< [IN] name of I/O object */ | 	qse_char_t*             name;   /**< [IN] name of I/O object */ | ||||||
| 	void* handle;             /**< [OUT] I/O handle set by a handler */ | 	int                     copt;   /**< [IN] closing option */ | ||||||
|  | 	void*                   handle; /**< [OUT] I/O handle set by a handler */ | ||||||
|  |  | ||||||
| 	/*--  from here down, internal use only --*/ | 	/*--  from here down, internal use only --*/ | ||||||
| 	int type;  | 	int type;  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: fnc.c 259 2009-08-20 11:28:03Z hyunghwan.chung $ |  * $Id: fnc.c 270 2009-08-26 12:59:08Z hyunghwan.chung $ | ||||||
|  * |  * | ||||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. |    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||||
|  |  | ||||||
| @ -37,7 +37,7 @@ static int fnc_sprintf (qse_awk_rtx_t*, const qse_cstr_t*); | |||||||
| static qse_awk_fnc_t sys_fnc[] =  | static qse_awk_fnc_t sys_fnc[] =  | ||||||
| { | { | ||||||
| 	/* io functions */ | 	/* io functions */ | ||||||
| 	{ {QSE_T("close"),   5}, 0, QSE_AWK_RIO, {1, 1, QSE_NULL}, fnc_close}, | 	{ {QSE_T("close"),   5}, 0, QSE_AWK_RIO, {1, 2, QSE_NULL}, fnc_close}, | ||||||
| 	{ {QSE_T("fflush"),  6}, 0, QSE_AWK_RIO, {0, 1, QSE_NULL}, fnc_fflush}, | 	{ {QSE_T("fflush"),  6}, 0, QSE_AWK_RIO, {0, 1, QSE_NULL}, fnc_fflush}, | ||||||
|  |  | ||||||
| 	/* string functions */ | 	/* string functions */ | ||||||
| @ -227,20 +227,20 @@ qse_awk_fnc_t* qse_awk_getfnc ( | |||||||
| 	return fnc; | 	return fnc; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int fnc_close (qse_awk_rtx_t* run, const qse_cstr_t* fnm) | static int fnc_close (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm) | ||||||
| { | { | ||||||
| 	qse_size_t nargs; | 	qse_size_t nargs; | ||||||
| 	qse_awk_val_t* v, * a0; | 	qse_awk_val_t* v, * a0, * a1 = QSE_NULL; | ||||||
| 	int n; | 	int n; | ||||||
|  |  | ||||||
| 	qse_char_t* name; | 	qse_char_t* name, * opt = QSE_NULL; | ||||||
| 	qse_size_t len; | 	qse_size_t len, optlen = 0; | ||||||
|         |         | ||||||
| 	nargs = qse_awk_rtx_getnargs (run); | 	nargs = qse_awk_rtx_getnargs (rtx); | ||||||
| 	QSE_ASSERT (nargs == 1); | 	QSE_ASSERT (nargs == 1 || nargs == 2); | ||||||
| /* TODO: support close (xxx, "to"/"from"/"rw"/"r"/"w"/????) */ |  | ||||||
|  |  | ||||||
| 	a0 = qse_awk_rtx_getarg (run, 0); | 	a0 = qse_awk_rtx_getarg (rtx, 0); | ||||||
|  | 	a1 = qse_awk_rtx_getarg (rtx, 1); | ||||||
| 	QSE_ASSERT (a0 != QSE_NULL); | 	QSE_ASSERT (a0 != QSE_NULL); | ||||||
|  |  | ||||||
| 	if (a0->type == QSE_AWK_VAL_STR) | 	if (a0->type == QSE_AWK_VAL_STR) | ||||||
| @ -250,10 +250,29 @@ static int fnc_close (qse_awk_rtx_t* run, const qse_cstr_t* fnm) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		name = qse_awk_rtx_valtocpldup (run, a0, &len); | 		name = qse_awk_rtx_valtocpldup (rtx, a0, &len); | ||||||
| 		if (name == QSE_NULL) return -1; | 		if (name == QSE_NULL) return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (a1 != QSE_NULL) | ||||||
|  | 	{ | ||||||
|  | 		if (a1->type == QSE_AWK_VAL_STR) | ||||||
|  | 		{ | ||||||
|  | 			opt = ((qse_awk_val_str_t*)a1)->ptr; | ||||||
|  | 			optlen = ((qse_awk_val_str_t*)a1)->len; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			opt = qse_awk_rtx_valtocpldup (rtx, a1, &optlen); | ||||||
|  | 			if (opt == QSE_NULL)  | ||||||
|  | 			{ | ||||||
|  | 				if (a1->type != QSE_AWK_VAL_STR) | ||||||
|  | 					QSE_AWK_FREE (rtx->awk, name); | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (len == 0) | 	if (len == 0) | ||||||
| 	{ | 	{ | ||||||
| 		/* getline or print doesn't allow an emptry for the  | 		/* getline or print doesn't allow an emptry for the  | ||||||
| @ -272,30 +291,44 @@ static int fnc_close (qse_awk_rtx_t* run, const qse_cstr_t* fnm) | |||||||
| 	{ | 	{ | ||||||
| 		if (name[--len] == QSE_T('\0')) | 		if (name[--len] == QSE_T('\0')) | ||||||
| 		{ | 		{ | ||||||
| 			/* the name contains a null string.  | 			/* the name contains a null charater.  | ||||||
| 			 * make close return -1 */ | 			 * make close return -1 */ | ||||||
| 			n = -1; | 			n = -1; | ||||||
| 			goto skip_close; | 			goto skip_close; | ||||||
| 		} | 		} | ||||||
| 	}	 | 	}	 | ||||||
|  |  | ||||||
| 	n = qse_awk_rtx_closeio (run, name); | 	if (opt != QSE_NULL) | ||||||
| 	/* | 	{ | ||||||
| 	if (n == -1 && run->errinf.num != QSE_AWK_EIONMNF) | 		if (optlen != 1 ||  | ||||||
|  | 		    (opt[0] != QSE_T('r') && opt[0] != QSE_T('w'))) | ||||||
|  | 		{ | ||||||
|  | 			n = -1; | ||||||
|  | 			goto skip_close; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	n = qse_awk_rtx_closeio (rtx, name, opt); | ||||||
|  | 	/* failure to close is not a critical error. instead, that is | ||||||
|  | 	 * flagged by the return value of close(). | ||||||
|  | 	if (n == -1 && rtx->errinf.num != QSE_AWK_EIONMNF) | ||||||
| 	{ | 	{ | ||||||
| 		if (a0->type != QSE_AWK_VAL_STR)  | 		if (a0->type != QSE_AWK_VAL_STR)  | ||||||
| 			QSE_AWK_FREE (run->awk, name); | 			QSE_AWK_FREE (rtx->awk, name); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 	*/ | 	*/ | ||||||
|  |  | ||||||
| skip_close: | skip_close: | ||||||
| 	if (a0->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, name); | 	if (a1 != QSE_NULL && a1->type != QSE_AWK_VAL_STR)  | ||||||
|  | 		QSE_AWK_FREE (rtx->awk, opt); | ||||||
|  |  | ||||||
| 	v = qse_awk_rtx_makeintval (run, (qse_long_t)n); | 	if (a0->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, name); | ||||||
|  |  | ||||||
|  | 	v = qse_awk_rtx_makeintval (rtx, (qse_long_t)n); | ||||||
| 	if (v == QSE_NULL) return -1; | 	if (v == QSE_NULL) return -1; | ||||||
|  |  | ||||||
| 	qse_awk_rtx_setretval (run, v); | 	qse_awk_rtx_setretval (rtx, v); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: rio.c 256 2009-08-16 13:44:20Z hyunghwan.chung $ |  * $Id: rio.c 270 2009-08-26 12:59:08Z hyunghwan.chung $ | ||||||
|  * |  * | ||||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. |    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||||
|  |  | ||||||
| @ -904,9 +904,10 @@ int qse_awk_rtx_closio_write ( | |||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name) | int qse_awk_rtx_closeio ( | ||||||
|  | 	qse_awk_rtx_t* rtx, const qse_char_t* name, const qse_char_t* opt) | ||||||
| { | { | ||||||
| 	qse_awk_rio_arg_t* p = run->rio.chain, * px = QSE_NULL; | 	qse_awk_rio_arg_t* p = rtx->rio.chain, * px = QSE_NULL; | ||||||
|  |  | ||||||
| 	while (p != QSE_NULL) | 	while (p != QSE_NULL) | ||||||
| 	{ | 	{ | ||||||
| @ -915,34 +916,58 @@ int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name) | |||||||
| 		if (qse_strcmp (p->name, name) == 0)  | 		if (qse_strcmp (p->name, name) == 0)  | ||||||
| 		{ | 		{ | ||||||
| 			qse_awk_rio_fun_t handler; | 			qse_awk_rio_fun_t handler; | ||||||
| 		        | 			int copt = QSE_AWK_RIO_CLOSE_R | QSE_AWK_RIO_CLOSE_W; | ||||||
| 			handler = run->rio.handler[p->type & MASK_CLEAR]; |  | ||||||
| 			if (handler != QSE_NULL) | 			if (opt != QSE_NULL) | ||||||
| 			{ | 			{ | ||||||
| 				qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL); | 				if (opt[0] == QSE_T('r')) | ||||||
| 				if (handler (run, QSE_AWK_RIO_CLOSE, p, QSE_NULL, 0) <= -1) |  | ||||||
| 				{ | 				{ | ||||||
| 					/* this is not a run-time error.*/ | 					if (p->type & MASK_RDWR) copt = QSE_AWK_RIO_CLOSE_R; | ||||||
| 					if (run->errinf.num == QSE_AWK_ENOERR) | 					else if (!(p->type & MASK_READ)) goto skip; | ||||||
| 						qse_awk_rtx_seterrnum (run, QSE_AWK_EIOIMPL, QSE_NULL); | 				} | ||||||
| 					return -1; | 				else | ||||||
|  | 				{ | ||||||
|  | 					QSE_ASSERT (opt[0] == QSE_T('w')); | ||||||
|  | 					if (p->type & MASK_RDWR) copt = QSE_AWK_RIO_CLOSE_W; | ||||||
|  | 					else if (!(p->type & MASK_WRITE)) goto skip; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (px != QSE_NULL) px->next = p->next; | 			handler = rtx->rio.handler[p->type & MASK_CLEAR]; | ||||||
| 			else run->rio.chain = p->next; | 			if (handler != QSE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR, QSE_NULL); | ||||||
|  | 				p->copt = copt; | ||||||
|  | 				if (handler (rtx, QSE_AWK_RIO_CLOSE, p, QSE_NULL, 0) <= -1) | ||||||
|  | 				{ | ||||||
|  | 					/* this is not a run-time error.*/ | ||||||
|  | 					if (rtx->errinf.num == QSE_AWK_ENOERR) | ||||||
|  | 						qse_awk_rtx_seterrnum (rtx, QSE_AWK_EIOIMPL, QSE_NULL); | ||||||
|  | 					return -1; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | /* TODO: | ||||||
|  | if (p->type & MASK_RDWR) | ||||||
|  | { | ||||||
|  | 	if partially closed don't destroy it yet... | ||||||
|  | } | ||||||
|  | */ | ||||||
|  |  | ||||||
| 			QSE_AWK_FREE (run->awk, p->name); | 			if (px != QSE_NULL) px->next = p->next; | ||||||
| 			QSE_AWK_FREE (run->awk, p); | 			else rtx->rio.chain = p->next; | ||||||
|  |  | ||||||
|  | 			QSE_AWK_FREE (rtx->awk, p->name); | ||||||
|  | 			QSE_AWK_FREE (rtx->awk, p); | ||||||
|  |  | ||||||
| 			return 0; | 			return 0; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 	skip: | ||||||
| 		px = p; | 		px = p; | ||||||
| 		p = p->next; | 		p = p->next; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	qse_awk_rtx_seterrnum (run, QSE_AWK_EIONMNF, QSE_NULL); | 	qse_awk_rtx_seterrnum (rtx, QSE_AWK_EIONMNF, QSE_NULL); | ||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: rio.h 196 2009-06-11 07:44:44Z hyunghwan.chung $ |  * $Id: rio.h 270 2009-08-26 12:59:08Z hyunghwan.chung $ | ||||||
|  * |  * | ||||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. |    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||||
|  |  | ||||||
| @ -44,7 +44,12 @@ int qse_awk_rtx_nextio_read ( | |||||||
| int qse_awk_rtx_nextio_write ( | int qse_awk_rtx_nextio_write ( | ||||||
| 	qse_awk_rtx_t* run, int out_type, const qse_char_t* name); | 	qse_awk_rtx_t* run, int out_type, const qse_char_t* name); | ||||||
|  |  | ||||||
| int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name); | int qse_awk_rtx_closeio ( | ||||||
|  | 	qse_awk_rtx_t*    run, | ||||||
|  | 	const qse_char_t* name, | ||||||
|  | 	const qse_char_t* opt | ||||||
|  | ); | ||||||
|  |  | ||||||
| void qse_awk_rtx_cleario (qse_awk_rtx_t* run); | void qse_awk_rtx_cleario (qse_awk_rtx_t* run); | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user