fixed a bug in qse_awk_rtx_call()
This commit is contained in:
		@ -12,4 +12,4 @@ Cross compiling for WIN32 with MINGW32
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Generate the API documents with robodoc.
 | 
					Generate the API documents with robodoc.
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	robodoc --rc doc/robodoc.rc --css doc/robodoc.css --src include/qse --doc ./doc/qse --multidoc --index --html --source_line_numbers --nopre
 | 
						robodoc --rc doc/robodoc.rc --css doc/robodoc.css --src include/qse --src test --doc ./doc/qse --multidoc --index --html --source_line_numbers --nopre
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
items:
 | 
					items:
 | 
				
			||||||
	NAME
 | 
						NAME
 | 
				
			||||||
	SYNOPSIS
 | 
						SYNOPSIS
 | 
				
			||||||
 | 
						SOURCE
 | 
				
			||||||
	DESCRIPTION
 | 
						DESCRIPTION
 | 
				
			||||||
	INPUT
 | 
						INPUT
 | 
				
			||||||
	INPUTS
 | 
						INPUTS
 | 
				
			||||||
@ -30,6 +31,7 @@ item order:
 | 
				
			|||||||
	NOTES
 | 
						NOTES
 | 
				
			||||||
	BUGS
 | 
						BUGS
 | 
				
			||||||
	SEE ALSO
 | 
						SEE ALSO
 | 
				
			||||||
 | 
						SOURCE
 | 
				
			||||||
remark begin markers:
 | 
					remark begin markers:
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
remark end markers:
 | 
					remark end markers:
 | 
				
			||||||
@ -37,7 +39,8 @@ remark end markers:
 | 
				
			|||||||
ignore files:
 | 
					ignore files:
 | 
				
			||||||
	.svn
 | 
						.svn
 | 
				
			||||||
headertypes:
 | 
					headertypes:
 | 
				
			||||||
	o     "Overview"       robo_overview     10
 | 
						o     "Overview"    robo_overview     10
 | 
				
			||||||
 | 
						S     "Sample Code" robo_sample       11
 | 
				
			||||||
options:
 | 
					options:
 | 
				
			||||||
	--cmode
 | 
						--cmode
 | 
				
			||||||
	--nopre
 | 
						--nopre
 | 
				
			||||||
 | 
				
			|||||||
@ -165,6 +165,7 @@ struct qse_awk_riod_t
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	qse_awk_riod_t* next;
 | 
						qse_awk_riod_t* next;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					/******/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct qse_awk_prm_t
 | 
					struct qse_awk_prm_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -558,6 +559,8 @@ enum qse_awk_parse_ist_t
 | 
				
			|||||||
	QSE_AWK_PARSE_STRING = 1
 | 
						QSE_AWK_PARSE_STRING = 1
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum qse_awk_errnum_t qse_awk_errnum_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct qse_awk_val_nil_t  qse_awk_val_nil_t;
 | 
					typedef struct qse_awk_val_nil_t  qse_awk_val_nil_t;
 | 
				
			||||||
typedef struct qse_awk_val_int_t  qse_awk_val_int_t;
 | 
					typedef struct qse_awk_val_int_t  qse_awk_val_int_t;
 | 
				
			||||||
typedef struct qse_awk_val_real_t qse_awk_val_real_t;
 | 
					typedef struct qse_awk_val_real_t qse_awk_val_real_t;
 | 
				
			||||||
@ -774,11 +777,16 @@ qse_awk_prm_t* qse_awk_getprm (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/****f* AWK/qse_awk_getccls
 | 
					/****f* AWK/qse_awk_getccls
 | 
				
			||||||
 * NAME
 | 
					 * NAME
 | 
				
			||||||
 *  qse_awk_getcclas - get the character classifier
 | 
					 *  qse_awk_getccls - get the character classifier
 | 
				
			||||||
 | 
					 * DESCRIPTION
 | 
				
			||||||
 | 
					 *  The qse_awk_getccls() function returns the character classifier composed
 | 
				
			||||||
 | 
					 *  from the primitive functions in a call to qse_awk_open(). The data field
 | 
				
			||||||
 | 
					 *  is set to the awk object. The classifier returned is valid while the 
 | 
				
			||||||
 | 
					 *  associated awk object is alive.
 | 
				
			||||||
 * SYNOPSIS
 | 
					 * SYNOPSIS
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
qse_ccls_t* qse_awk_getccls (
 | 
					qse_ccls_t* qse_awk_getccls (
 | 
				
			||||||
	qse_awk_t* ccls
 | 
						qse_awk_t* awk
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
/******/
 | 
					/******/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -807,8 +815,8 @@ int qse_awk_clear (
 | 
				
			|||||||
 * SYNOPSIS
 | 
					 * SYNOPSIS
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
const qse_char_t* qse_awk_geterrstr (
 | 
					const qse_char_t* qse_awk_geterrstr (
 | 
				
			||||||
	qse_awk_t* awk,
 | 
						qse_awk_t*       awk,
 | 
				
			||||||
	int        num
 | 
						qse_awk_errnum_t num
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
/******/
 | 
					/******/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -823,7 +831,7 @@ const qse_char_t* qse_awk_geterrstr (
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
int qse_awk_seterrstr (
 | 
					int qse_awk_seterrstr (
 | 
				
			||||||
	qse_awk_t*        awk,
 | 
						qse_awk_t*        awk,
 | 
				
			||||||
	int               num,
 | 
						qse_awk_errnum_t  num,
 | 
				
			||||||
	const qse_char_t* str
 | 
						const qse_char_t* str
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
/******/
 | 
					/******/
 | 
				
			||||||
@ -1518,14 +1526,16 @@ qse_char_t* qse_awk_rtx_valtostr (
 | 
				
			|||||||
 *  The qse_awk_rtx_valtonum() function returns -1 on error, 0 if the converted
 | 
					 *  The qse_awk_rtx_valtonum() function returns -1 on error, 0 if the converted
 | 
				
			||||||
 *  number is a long number and 1 if it is a real number.
 | 
					 *  number is a long number and 1 if it is a real number.
 | 
				
			||||||
 * EXAMPLES
 | 
					 * EXAMPLES
 | 
				
			||||||
 *  qse_long_t l;
 | 
					 *  The following example show how to convert a value to a number and
 | 
				
			||||||
 *  qse_real_t r;
 | 
					 *  determine if it is an integer or a floating-point number.
 | 
				
			||||||
 *  int n;
 | 
					 *      qse_long_t l;
 | 
				
			||||||
 | 
					 *      qse_real_t r;
 | 
				
			||||||
 | 
					 *      int n;
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  n = qse_awk_rtx_valtonum (v, &l, &r);
 | 
					 *      n = qse_awk_rtx_valtonum (v, &l, &r);
 | 
				
			||||||
 *  if (n == -1) error ();
 | 
					 *      if (n == -1) error ();
 | 
				
			||||||
 *  else if (n == 0) do_long (l);
 | 
					 *      else if (n == 0) do_long (l);
 | 
				
			||||||
 *  else if (n == 1) do_real (r);
 | 
					 *      else if (n == 1) do_real (r);
 | 
				
			||||||
 * SYNOPSIS
 | 
					 * SYNOPSIS
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int qse_awk_rtx_valtonum (
 | 
					int qse_awk_rtx_valtonum (
 | 
				
			||||||
 | 
				
			|||||||
@ -172,14 +172,15 @@ static const qse_char_t* __geterrstr (int errnum)
 | 
				
			|||||||
	return QSE_T("unknown error");
 | 
						return QSE_T("unknown error");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const qse_char_t* qse_awk_geterrstr (qse_awk_t* awk, int num)
 | 
					const qse_char_t* qse_awk_geterrstr (qse_awk_t* awk, qse_awk_errnum_t num)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (awk != QSE_NULL && 
 | 
						if (awk != QSE_NULL && 
 | 
				
			||||||
	    awk->errstr[num] != QSE_NULL) return awk->errstr[num];
 | 
						    awk->errstr[num] != QSE_NULL) return awk->errstr[num];
 | 
				
			||||||
	return __geterrstr (num);
 | 
						return __geterrstr (num);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int qse_awk_seterrstr (qse_awk_t* awk, int num, const qse_char_t* str)
 | 
					int qse_awk_seterrstr (
 | 
				
			||||||
 | 
						qse_awk_t* awk, qse_awk_errnum_t num, const qse_char_t* str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qse_char_t* dup;
 | 
						qse_char_t* dup;
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
 | 
				
			|||||||
@ -1474,7 +1474,7 @@ int qse_awk_rtx_call (
 | 
				
			|||||||
	qse_awk_rtx_t* rtx, const qse_char_t* name, 
 | 
						qse_awk_rtx_t* rtx, const qse_char_t* name, 
 | 
				
			||||||
	qse_awk_val_t** args, qse_size_t nargs)
 | 
						qse_awk_val_t** args, qse_size_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret = 0;
 | 
				
			||||||
	qse_map_pair_t* pair;
 | 
						qse_map_pair_t* pair;
 | 
				
			||||||
	qse_awk_fun_t* fun;
 | 
						qse_awk_fun_t* fun;
 | 
				
			||||||
	struct capture_retval_data_t crdata;
 | 
						struct capture_retval_data_t crdata;
 | 
				
			||||||
@ -1543,29 +1543,37 @@ int qse_awk_rtx_call (
 | 
				
			|||||||
		if (crdata.val == QSE_NULL) 
 | 
							if (crdata.val == QSE_NULL) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			QSE_ASSERT (rtx->errnum != QSE_AWK_ENOERR);
 | 
								QSE_ASSERT (rtx->errnum != QSE_AWK_ENOERR);
 | 
				
			||||||
 | 
								v = qse_awk_val_nil; /* defaults to nil */
 | 
				
			||||||
			ret = -1;
 | 
								ret = -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else 
 | 
							else 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (rtx->errnum == QSE_AWK_ENOERR)
 | 
								if (rtx->errnum == QSE_AWK_ENOERR)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (rtx->rcb.on_exit != QSE_NULL)
 | 
									/* exiting with exit() */
 | 
				
			||||||
					rtx->rcb.on_exit (rtx, crdata.val, rtx->rcb.data);
 | 
									v = crdata.val;
 | 
				
			||||||
 | 
									/* no need to ref-up as it is done in 
 | 
				
			||||||
 | 
									 * capture_retval_on_exit() */
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else 
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									v = qse_awk_val_nil; /* defaults to nil */
 | 
				
			||||||
 | 
									ret = -1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else ret = -1;
 | 
					 | 
				
			||||||
			qse_awk_rtx_refdownval(rtx, crdata.val);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else 
 | 
				
			||||||
	{
 | 
						{	
 | 
				
			||||||
 | 
							/* the reference count of crdata.val is updated in 
 | 
				
			||||||
 | 
							 * capture_retval_on_exit(). update reference count of 
 | 
				
			||||||
 | 
							 * v here to balance it */
 | 
				
			||||||
		qse_awk_rtx_refupval (rtx, v);
 | 
							qse_awk_rtx_refupval (rtx, v);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (rtx->rcb.on_exit != QSE_NULL)
 | 
					 | 
				
			||||||
			rtx->rcb.on_exit (rtx, v, rtx->rcb.data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		qse_awk_rtx_refdownval (rtx, v);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rtx->rcb.on_exit != QSE_NULL)
 | 
				
			||||||
 | 
							rtx->rcb.on_exit (rtx, v, rtx->rcb.data);
 | 
				
			||||||
 | 
						qse_awk_rtx_refdownval (rtx, v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,26 +1,44 @@
 | 
				
			|||||||
 | 
					/****S* Sample/AWK
 | 
				
			||||||
 | 
					 * DESCRIPTION
 | 
				
			||||||
 | 
					 *  This program demonstrates how to use qse_awk_rtx_call().
 | 
				
			||||||
 | 
					 * SOURCE
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <qse/awk/awk.h>
 | 
					#include <qse/awk/awk.h>
 | 
				
			||||||
#include <qse/utl/stdio.h>
 | 
					#include <qse/utl/stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const qse_char_t* src = QSE_T(
 | 
					const qse_char_t* src = QSE_T(
 | 
				
			||||||
	"function init() { a = 20; }"
 | 
						"function init() { a = 20; }"
 | 
				
			||||||
	"function main() { a++; }"
 | 
						"function main() { a++; }"
 | 
				
			||||||
	"function fini() { output (a); }"
 | 
						"function fini() { print a; }"
 | 
				
			||||||
	"function output(x) { print x; }"
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const qse_char_t* f[] = 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						QSE_T("init"),
 | 
				
			||||||
 | 
						QSE_T("main"),
 | 
				
			||||||
 | 
						QSE_T("main"),
 | 
				
			||||||
 | 
						QSE_T("main"),
 | 
				
			||||||
 | 
						QSE_T("main"),
 | 
				
			||||||
 | 
						QSE_T("fini"),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main ()
 | 
					int main ()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qse_awk_t* awk = QSE_NULL;
 | 
						qse_awk_t* awk = QSE_NULL;
 | 
				
			||||||
	qse_awk_rtx_t* rtx = QSE_NULL;
 | 
						qse_awk_rtx_t* rtx = QSE_NULL;
 | 
				
			||||||
	int ret;
 | 
						int ret, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	awk = qse_awk_opensimple ();
 | 
						awk = qse_awk_opensimple ();
 | 
				
			||||||
	if (awk == QSE_NULL)  
 | 
						if (awk == QSE_NULL)  
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: cannot open awk\n"));
 | 
							qse_fprintf (QSE_STDERR, QSE_T("error: cannot open awk\n"));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* don't allow BEGIN, END, pattern-action blocks */
 | 
				
			||||||
 | 
						qse_awk_setoption (awk, qse_awk_getoption(awk) & ~QSE_AWK_PABLOCK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = qse_awk_parsesimple (
 | 
						ret = qse_awk_parsesimple (
 | 
				
			||||||
		awk,
 | 
							awk,
 | 
				
			||||||
		QSE_AWK_PARSE_STRING, src, /* parse AWK source in a string */
 | 
							QSE_AWK_PARSE_STRING, src, /* parse AWK source in a string */
 | 
				
			||||||
@ -41,17 +59,23 @@ int main ()
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
							qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
				
			||||||
			qse_awk_geterrmsg(awk));
 | 
								qse_awk_geterrmsg(awk));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	qse_awk_rtx_call (rtx, QSE_T("init"), QSE_NULL, 0);
 | 
						for (i = 0; i < QSE_COUNTOF(f); i++)
 | 
				
			||||||
	qse_awk_rtx_call (rtx, QSE_T("main"), QSE_NULL, 0);
 | 
						{
 | 
				
			||||||
	qse_awk_rtx_call (rtx, QSE_T("main"), QSE_NULL, 0);
 | 
							ret = qse_awk_rtx_call (rtx, f[i], QSE_NULL, 0);
 | 
				
			||||||
	qse_awk_rtx_call (rtx, QSE_T("main"), QSE_NULL, 0);
 | 
							if (ret == -1)
 | 
				
			||||||
	qse_awk_rtx_call (rtx, QSE_T("fini"), QSE_NULL, 0);
 | 
							{
 | 
				
			||||||
 | 
								qse_fprintf (QSE_STDERR, QSE_T("%d error: %s\n"), 
 | 
				
			||||||
 | 
									i, qse_awk_rtx_geterrmsg(rtx));
 | 
				
			||||||
 | 
								goto oops;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oops:
 | 
					oops:
 | 
				
			||||||
	if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
 | 
						if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
 | 
				
			||||||
	if (awk != QSE_NULL) qse_awk_close (awk);
 | 
						if (awk != QSE_NULL) qse_awk_close (awk);
 | 
				
			||||||
	return -1;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					/******/
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user