fixed a bug in qse_awk_rtx_call()

This commit is contained in:
hyung-hwan 2009-02-17 19:41:53 +00:00
parent b9958d4ff7
commit fed0a952ab
6 changed files with 85 additions and 39 deletions

View File

@ -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

View File

@ -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

View File

@ -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 (

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }
/******/