fixed minor bugs and cleaned up code

This commit is contained in:
hyung-hwan 2009-02-13 04:55:25 +00:00
parent 924f940fba
commit 464f43b821
8 changed files with 294 additions and 219 deletions

View File

@ -611,7 +611,7 @@ static int awk_main (int argc, qse_char_t* argv[])
if (awk == QSE_NULL) return -1;
if (qse_awk_parsesimple (awk, ao.isp, ao.ist, ao.osf) == -1)
if (qse_awk_parsesimple (awk, ao.ist, ao.isp, ao.osf) == -1)
{
qse_printf (
QSE_T("PARSE ERROR: CODE [%d] LINE [%u] %s\n"),

View File

@ -424,7 +424,7 @@ public:
enum ErrorCode
{
ERR_NOERR = QSE_AWK_ENOERR,
ERR_CUSTOM = QSE_AWK_ECUSTOM,
ERR_UNKNOWN = QSE_AWK_EUNKNOWN,
ERR_INVAL = QSE_AWK_EINVAL,
ERR_NOMEM = QSE_AWK_ENOMEM,
ERR_NOSUP = QSE_AWK_ENOSUP,

View File

@ -121,7 +121,7 @@ struct qse_awk_sio_t
{
qse_awk_io_t in;
qse_awk_io_t out;
void* data;
void* data;
};
struct qse_awk_rio_t
@ -129,7 +129,7 @@ struct qse_awk_rio_t
qse_awk_io_t pipe;
qse_awk_io_t file;
qse_awk_io_t console;
void* data;
void* data;
};
struct qse_awk_rcb_t
@ -261,8 +261,9 @@ enum qse_awk_option_t
enum qse_awk_errnum_t
{
QSE_AWK_ENOERR, /* no error */
QSE_AWK_ECUSTOM, /* custom error */
QSE_AWK_EUNKNOWN, /* unknown error */
/* common errors */
QSE_AWK_EINVAL, /* invalid parameter or data */
QSE_AWK_ENOMEM, /* out of memory */
QSE_AWK_ENOSUP, /* not supported */
@ -279,6 +280,7 @@ enum qse_awk_errnum_t
QSE_AWK_EISDIR, /* is a directory */
QSE_AWK_EIOERR, /* i/o error */
/* mostly parse errors */
QSE_AWK_EOPEN, /* cannot open */
QSE_AWK_EREAD, /* cannot read */
QSE_AWK_EWRITE, /* cannot write */
@ -643,8 +645,8 @@ extern qse_awk_val_t* qse_awk_val_one;
* SYNOPSIS
*/
qse_awk_t* qse_awk_open (
qse_mmgr_t* mmgr /* a memory manager */,
qse_size_t xtnsize /* the size of extension in bytes */
qse_mmgr_t* mmgr /* a memory manager */,
qse_size_t xtn /* the size of extension in bytes */
);
/******/
@ -975,53 +977,6 @@ int qse_awk_parse (
);
/******/
/****f* AWK/qse_awk_opensimple
* NAME
* qse_awk_opensimple - create an awk object
* SYNOPSIS
*/
qse_awk_t* qse_awk_opensimple (
qse_size_t xtnsize /* size of extension area in bytes */
);
/******/
/****f* AWK/qse_awk_parsesimple
* NAME
* qse_awk_parsesimple - parse source code
* SYNOPSIS
*/
int qse_awk_parsesimple (
qse_awk_t* awk,
const void* isp /* source file names or source string */,
int ist /* QSE_AWK_PARSE_FILES, QSE_AWK_PARSE_STRING */,
const qse_char_t* osf /* an output source file name */
);
/******/
/****f* AWK/qse_awk_runsimple
* NAME
* qse_awk_runsimple - run a parsed program
* DESCRIPTION
* A runtime context is required for it to start running the program.
* Once a runtime context is created, the program starts to run.
* The failure of context creation is reported by the return value of -1.
* However, the runtime error after context creation is reported differently
* depending on the callbacks specified. When no callback is specified
* (i.e. rcb is QSE_NULL), the qse_awk_run() function returns -1 on an
* error and awk->errnum is set accordingly. If a callback is specified
* (i.e. rcb is not QSE_NULL), the qse_awk_run() returns 0 on both success
* and failure. Instead, the on_end handler of the callback is triggered with
* the relevant error number. The third parameter to on_end is the error
* number.
* SYNOPSIS
*/
int qse_awk_runsimple (
qse_awk_t* awk,
qse_char_t** icf /* input console files */,
qse_awk_rcb_t* cbs /* callbacks */
);
/******/
/****f* AWK/qse_awk_alloc
* NAME
* qse_awk_alloc - allocate dynamic memory
@ -1114,10 +1069,10 @@ qse_size_t qse_awk_longtostr (
*/
qse_awk_rtx_t* qse_awk_rtx_open (
qse_awk_t* awk,
qse_size_t xtn,
qse_awk_rio_t* rio,
qse_awk_rcb_t* rcb,
const qse_cstr_t* arg,
void* data
const qse_cstr_t* arg
);
/******/
@ -1331,12 +1286,12 @@ qse_mmgr_t* qse_awk_rtx_getmmgr (
);
/******/
/****f* AWK/qse_awk_rtx_getdata
/****f* AWK/qse_awk_rtx_getxtn
* NAME
* qse_awk_rtx_getdata - get the user-specified data for a runtime context
* qse_awk_rtx_getxtn - get the pointer to extension space
* SYNOPSIS
*/
void* qse_awk_rtx_getdata (
void* qse_awk_rtx_getxtn (
qse_awk_rtx_t* rtx
);
/******/
@ -1545,6 +1500,59 @@ int qse_awk_rtx_strtonum (
);
/******/
/****f* AWK/qse_awk_opensimple
* NAME
* qse_awk_opensimple - create an awk object
* SYNOPSIS
*/
qse_awk_t* qse_awk_opensimple (
qse_size_t xtn /* size of extension area in bytes */
);
/******/
/****f* AWK/qse_awk_parsesimple
* NAME
* qse_awk_parsesimple - parse source code
* DESCRIPTION
* If 'ist' is QSE_AWK_PARSE_STRING, 'isp' should be a null-terminated string
* of the type 'const qse_char_t*'; If 'ist' is QSE_AWK_PARSE_FILES, 'isp'
* should be an array of null-terminated strings whose last element is a
* null pointer.
* SYNOPSIS
*/
int qse_awk_parsesimple (
qse_awk_t* awk,
int ist /* QSE_AWK_PARSE_FILES, QSE_AWK_PARSE_STRING */,
const void* isp /* source file names or source string */,
const qse_char_t* osf /* an output source file name */
);
/******/
/****f* AWK/qse_awk_runsimple
* NAME
* qse_awk_runsimple - run a parsed program
* DESCRIPTION
* A runtime context is required for it to start running the program.
* Once a runtime context is created, the program starts to run.
* The failure of context creation is reported by the return value of -1.
* However, the runtime error after context creation is reported differently
* depending on the callbacks specified. When no callback is specified
* (i.e. rcb is QSE_NULL), the qse_awk_run() function returns -1 on an
* error and awk->errnum is set accordingly. If a callback is specified
* (i.e. rcb is not QSE_NULL), the qse_awk_run() returns 0 on both success
* and failure. Instead, the on_end handler of the callback is triggered with
* the relevant error number. The third parameter to on_end is the error
* number.
* SYNOPSIS
*/
int qse_awk_runsimple (
qse_awk_t* awk,
qse_char_t** icf /* input console files */,
qse_awk_rcb_t* cbs /* callbacks */
);
/******/
#ifdef __cplusplus
}
#endif

View File

@ -1383,11 +1383,32 @@ int Awk::run (const char_t** args, size_t nargs)
runarg[i].len = 0;
}
int n = 0;
qse_awk_rtx_t* rtx = qse_awk_rtx_open (
awk, QSE_SIZEOF(Run*), &rio, &rcb, (qse_cstr_t*)runarg);
if (rtx == QSE_NULL)
{
retrieveError();
n = -1;
}
else
{
Run** xtn = (Run**)qse_awk_rtx_getxtn (rtx);
*xtn = &runctx;
runctx.run = rtx;
n = qse_awk_rtx_loop (rtx);
if (n == -1) retrieveError ();
qse_awk_rtx_close (rtx);
}
#if 0
int n = qse_awk_run (
awk, &rio, &rcb,
(qse_cstr_t*)runarg, &runctx
);
if (n == -1) retrieveError ();
#endif
if (runarg != QSE_NULL)
{
@ -1708,7 +1729,7 @@ Awk::ssize_t Awk::consoleHandler (
int Awk::functionHandler (
run_t* run, const char_t* name, size_t len)
{
Run* ctx = (Run*) qse_awk_rtx_getdata (run);
Run* ctx = *(Run**)qse_awk_rtx_getxtn (run);
Awk* awk = ctx->awk;
return awk->dispatchFunction (ctx, name, len);
}

View File

@ -373,8 +373,6 @@ struct qse_awk_rtx_t
qse_size_t errlin;
qse_char_t errmsg[256];
void* data;
qse_awk_t* awk;
qse_awk_rcb_t* cbs;
};

View File

@ -23,7 +23,7 @@ static const qse_char_t* __geterrstr (int errnum)
static const qse_char_t* errstr[] =
{
QSE_T("no error"),
QSE_T("custom error"),
QSE_T("unknown error"),
QSE_T("invalid parameter or data"),
QSE_T("out of memory"),

View File

@ -77,9 +77,7 @@ struct pafv
static qse_size_t push_arg_from_vals (
qse_awk_rtx_t* rtx, qse_awk_nde_call_t* call, void* data);
static int init_rtx (
qse_awk_rtx_t* rtx, qse_awk_t* awk,
qse_awk_rio_t* rio, void* data);
static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio);
static void fini_rtx (qse_awk_rtx_t* rtx);
static int init_globals (qse_awk_rtx_t* rtx, const qse_cstr_t* arg);
@ -617,29 +615,30 @@ int qse_awk_rtx_setofilename (
return n;
}
qse_awk_t* qse_awk_rtx_getawk (qse_awk_rtx_t* run)
void* qse_awk_rtx_getxtn (qse_awk_rtx_t* rtx)
{
return run->awk;
return (void*)(rtx + 1);
}
qse_mmgr_t* qse_awk_rtx_getmmgr (qse_awk_rtx_t* run)
qse_awk_t* qse_awk_rtx_getawk (qse_awk_rtx_t* rtx)
{
return run->awk->mmgr;
return rtx->awk;
}
void* qse_awk_rtx_getdata (qse_awk_rtx_t* rtx)
qse_mmgr_t* qse_awk_rtx_getmmgr (qse_awk_rtx_t* rtx)
{
return rtx->data;
return rtx->awk->mmgr;
}
qse_map_t* qse_awk_rtx_getnvmap (qse_awk_rtx_t* rtx)
{
return rtx->named;
}
qse_awk_rtx_t* qse_awk_rtx_open (
qse_awk_t* awk, qse_awk_rio_t* ios,
qse_awk_rcb_t* cbs, const qse_cstr_t* arg, void* data)
qse_awk_t* awk, qse_size_t xtn, qse_awk_rio_t* rio,
qse_awk_rcb_t* cbs, const qse_cstr_t* arg)
{
qse_awk_rtx_t* rtx;
@ -661,7 +660,7 @@ qse_awk_rtx_t* qse_awk_rtx_open (
}
/* allocate the storage for the rtx object */
rtx = (qse_awk_rtx_t*) QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_rtx_t));
rtx = (qse_awk_rtx_t*) QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_rtx_t) + xtn);
if (rtx == QSE_NULL)
{
/* if it fails, the failure is reported thru
@ -670,11 +669,9 @@ qse_awk_rtx_t* qse_awk_rtx_open (
return QSE_NULL;
}
/* clear the rtx object space */
QSE_MEMSET (rtx, 0, QSE_SIZEOF(qse_awk_rtx_t));
/* initialize the run object */
if (init_rtx (rtx, awk, ios, data) == -1)
if (init_rtx (rtx, awk, rio) == -1)
{
QSE_AWK_FREE (awk, rtx);
return QSE_NULL;
@ -725,128 +722,128 @@ static void same_namedval (qse_map_t* map, void* dptr, qse_size_t dlen)
*(qse_awk_rtx_t**)qse_map_getxtn(map), dptr);
}
static int init_rtx (
qse_awk_rtx_t* run, qse_awk_t* awk,
qse_awk_rio_t* rio, void* data)
static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio)
{
run->awk = awk;
run->data = data;
/* zero out the runtime context excluding the extension */
QSE_MEMSET (rtx, 0, QSE_SIZEOF(qse_awk_rtx_t));
run->stack = QSE_NULL;
run->stack_top = 0;
run->stack_base = 0;
run->stack_limit = 0;
rtx->awk = awk;
run->exit_level = EXIT_NONE;
rtx->stack = QSE_NULL;
rtx->stack_top = 0;
rtx->stack_base = 0;
rtx->stack_limit = 0;
run->fcache_count = 0;
/*run->scache32_count = 0;
run->scache64_count = 0;*/
run->vmgr.ichunk = QSE_NULL;
run->vmgr.ifree = QSE_NULL;
run->vmgr.rchunk = QSE_NULL;
run->vmgr.rfree = QSE_NULL;
rtx->exit_level = EXIT_NONE;
run->errnum = QSE_AWK_ENOERR;
run->errlin = 0;
run->errmsg[0] = QSE_T('\0');
rtx->fcache_count = 0;
/*rtx->scache32_count = 0;
rtx->scache64_count = 0;*/
rtx->vmgr.ichunk = QSE_NULL;
rtx->vmgr.ifree = QSE_NULL;
rtx->vmgr.rchunk = QSE_NULL;
rtx->vmgr.rfree = QSE_NULL;
run->inrec.buf_pos = 0;
run->inrec.buf_len = 0;
run->inrec.flds = QSE_NULL;
run->inrec.nflds = 0;
run->inrec.maxflds = 0;
run->inrec.d0 = qse_awk_val_nil;
rtx->errnum = QSE_AWK_ENOERR;
rtx->errlin = 0;
rtx->errmsg[0] = QSE_T('\0');
rtx->inrec.buf_pos = 0;
rtx->inrec.buf_len = 0;
rtx->inrec.flds = QSE_NULL;
rtx->inrec.nflds = 0;
rtx->inrec.maxflds = 0;
rtx->inrec.d0 = qse_awk_val_nil;
if (qse_str_init (
&run->inrec.line, MMGR(run), DEF_BUF_CAPA) == QSE_NULL)
&rtx->inrec.line, MMGR(rtx), DEF_BUF_CAPA) == QSE_NULL)
{
qse_awk_seterror (awk, QSE_AWK_ENOMEM, 0, QSE_NULL, 0);
return -1;
}
if (qse_str_init (&run->format.out, MMGR(run), 256) == QSE_NULL)
if (qse_str_init (&rtx->format.out, MMGR(rtx), 256) == QSE_NULL)
{
qse_str_fini (&run->inrec.line);
qse_str_fini (&rtx->inrec.line);
qse_awk_seterror (awk, QSE_AWK_ENOMEM, 0, QSE_NULL, 0);
return -1;
}
if (qse_str_init (&run->format.fmt, MMGR(run), 256) == QSE_NULL)
if (qse_str_init (&rtx->format.fmt, MMGR(rtx), 256) == QSE_NULL)
{
qse_str_fini (&run->format.out);
qse_str_fini (&run->inrec.line);
qse_str_fini (&rtx->format.out);
qse_str_fini (&rtx->inrec.line);
qse_awk_seterror (awk, QSE_AWK_ENOMEM, 0, QSE_NULL, 0);
return -1;
}
run->named = qse_map_open (
MMGR(run), QSE_SIZEOF(run), 1024, 70);
if (run->named == QSE_NULL)
rtx->named = qse_map_open (
MMGR(rtx), QSE_SIZEOF(rtx), 1024, 70);
if (rtx->named == QSE_NULL)
{
qse_str_fini (&run->format.fmt);
qse_str_fini (&run->format.out);
qse_str_fini (&run->inrec.line);
qse_str_fini (&rtx->format.fmt);
qse_str_fini (&rtx->format.out);
qse_str_fini (&rtx->inrec.line);
qse_awk_seterror (awk, QSE_AWK_ENOMEM, 0, QSE_NULL, 0);
return -1;
}
*(qse_awk_rtx_t**)qse_map_getxtn(run->named) = run;
qse_map_setcopier (run->named, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
qse_map_setfreeer (run->named, QSE_MAP_VAL, free_namedval);
qse_map_setkeeper (run->named, same_namedval);
qse_map_setscale (run->named, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
*(qse_awk_rtx_t**)qse_map_getxtn(rtx->named) = rtx;
qse_map_setcopier (rtx->named, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
qse_map_setfreeer (rtx->named, QSE_MAP_VAL, free_namedval);
qse_map_setkeeper (rtx->named, same_namedval);
qse_map_setscale (rtx->named, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
run->format.tmp.ptr = (qse_char_t*)
QSE_AWK_ALLOC (run->awk, 4096*QSE_SIZEOF(qse_char_t*));
if (run->format.tmp.ptr == QSE_NULL)
rtx->format.tmp.ptr = (qse_char_t*)
QSE_AWK_ALLOC (rtx->awk, 4096*QSE_SIZEOF(qse_char_t*));
if (rtx->format.tmp.ptr == QSE_NULL)
{
qse_map_close (run->named);
qse_str_fini (&run->format.fmt);
qse_str_fini (&run->format.out);
qse_str_fini (&run->inrec.line);
qse_map_close (rtx->named);
qse_str_fini (&rtx->format.fmt);
qse_str_fini (&rtx->format.out);
qse_str_fini (&rtx->inrec.line);
qse_awk_seterror (awk, QSE_AWK_ENOMEM, 0, QSE_NULL, 0);
return -1;
}
run->format.tmp.len = 4096;
run->format.tmp.inc = 4096*2;
rtx->format.tmp.len = 4096;
rtx->format.tmp.inc = 4096*2;
if (run->awk->tree.chain_size > 0)
if (rtx->awk->tree.chain_size > 0)
{
run->pattern_range_state = (qse_byte_t*) QSE_AWK_ALLOC (
run->awk, run->awk->tree.chain_size*QSE_SIZEOF(qse_byte_t));
if (run->pattern_range_state == QSE_NULL)
rtx->pattern_range_state = (qse_byte_t*) QSE_AWK_ALLOC (
rtx->awk, rtx->awk->tree.chain_size*QSE_SIZEOF(qse_byte_t));
if (rtx->pattern_range_state == QSE_NULL)
{
QSE_AWK_FREE (run->awk, run->format.tmp.ptr);
qse_map_close (run->named);
qse_str_fini (&run->format.fmt);
qse_str_fini (&run->format.out);
qse_str_fini (&run->inrec.line);
QSE_AWK_FREE (rtx->awk, rtx->format.tmp.ptr);
qse_map_close (rtx->named);
qse_str_fini (&rtx->format.fmt);
qse_str_fini (&rtx->format.out);
qse_str_fini (&rtx->inrec.line);
qse_awk_seterror (awk, QSE_AWK_ENOMEM, 0, QSE_NULL, 0);
return -1;
}
QSE_MEMSET (
run->pattern_range_state, 0,
run->awk->tree.chain_size * QSE_SIZEOF(qse_byte_t));
rtx->pattern_range_state, 0,
rtx->awk->tree.chain_size * QSE_SIZEOF(qse_byte_t));
}
else run->pattern_range_state = QSE_NULL;
else rtx->pattern_range_state = QSE_NULL;
if (rio != QSE_NULL)
{
run->eio.handler[QSE_AWK_EIO_PIPE] = rio->pipe;
run->eio.handler[QSE_AWK_EIO_FILE] = rio->file;
run->eio.handler[QSE_AWK_EIO_CONSOLE] = rio->console;
run->eio.data = rio->data;
run->eio.chain = QSE_NULL;
rtx->eio.handler[QSE_AWK_EIO_PIPE] = rio->pipe;
rtx->eio.handler[QSE_AWK_EIO_FILE] = rio->file;
rtx->eio.handler[QSE_AWK_EIO_CONSOLE] = rio->console;
rtx->eio.data = rio->data;
rtx->eio.chain = QSE_NULL;
}
run->gbl.rs = QSE_NULL;
run->gbl.fs = QSE_NULL;
run->gbl.ignorecase = 0;
rtx->gbl.rs = QSE_NULL;
rtx->gbl.fs = QSE_NULL;
rtx->gbl.ignorecase = 0;
run->depth.max.block = awk->run.depth.max.block;
run->depth.max.expr = awk->run.depth.max.expr;
run->depth.cur.block = 0;
run->depth.cur.expr = 0;
rtx->depth.max.block = awk->run.depth.max.block;
rtx->depth.max.expr = awk->run.depth.max.expr;
rtx->depth.cur.block = 0;
rtx->depth.cur.expr = 0;
return 0;
}
@ -1316,7 +1313,7 @@ static void exit_stack_frame (qse_awk_rtx_t* run)
run->stack_base = (qse_size_t)run->stack[run->stack_base+0];
}
static int run_bpae_loop (qse_awk_rtx_t* run)
static int run_bpae_loop (qse_awk_rtx_t* rtx)
{
qse_awk_nde_t* nde;
qse_size_t nargs, i;
@ -1325,18 +1322,24 @@ static int run_bpae_loop (qse_awk_rtx_t* run)
/* set nargs to zero */
nargs = 0;
STACK_NARGS(run) = (void*)nargs;
STACK_NARGS(rtx) = (void*)nargs;
/* call the callback */
if (run->cbs != QSE_NULL && run->cbs->on_enter != QSE_NULL)
if (rtx->cbs != QSE_NULL && rtx->cbs->on_enter != QSE_NULL)
{
ret = run->cbs->on_enter (run, run->cbs->data);
if (ret <= -1) ret = -1;
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR);
ret = rtx->cbs->on_enter (rtx, rtx->cbs->data);
if (ret <= -1)
{
if (rtx->errnum == QSE_AWK_ENOMEM)
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EUNKNOWN);
ret = -1;
}
}
/* execute the BEGIN block */
for (nde = run->awk->tree.begin;
ret == 0 && nde != QSE_NULL && run->exit_level < EXIT_GLOBAL;
for (nde = rtx->awk->tree.begin;
ret == 0 && nde != QSE_NULL && rtx->exit_level < EXIT_GLOBAL;
nde = nde->next)
{
qse_awk_nde_blk_t* blk;
@ -1344,46 +1347,46 @@ static int run_bpae_loop (qse_awk_rtx_t* run)
blk = (qse_awk_nde_blk_t*)nde;
QSE_ASSERT (blk->type == QSE_AWK_NDE_BLK);
run->active_block = blk;
run->exit_level = EXIT_NONE;
if (run_block (run, blk) == -1) ret = -1;
rtx->active_block = blk;
rtx->exit_level = EXIT_NONE;
if (run_block (rtx, blk) == -1) ret = -1;
}
if (ret == -1 && run->errnum == QSE_AWK_ENOERR)
if (ret == -1 && rtx->errnum == QSE_AWK_ENOERR)
{
/* an error is returned with no error number set.
* this feature is used by eval_expression to
* abort the evaluation when exit() is executed
* during function evaluation */
ret = 0;
run->errlin = 0;
run->errmsg[0] = QSE_T('\0');
rtx->errlin = 0;
rtx->errmsg[0] = QSE_T('\0');
}
/* run pattern block loops */
if (ret == 0 &&
(run->awk->tree.chain != QSE_NULL ||
run->awk->tree.end != QSE_NULL) &&
run->exit_level < EXIT_GLOBAL)
(rtx->awk->tree.chain != QSE_NULL ||
rtx->awk->tree.end != QSE_NULL) &&
rtx->exit_level < EXIT_GLOBAL)
{
if (run_pattern_blocks(run) == -1) ret = -1;
if (run_pattern_blocks(rtx) == -1) ret = -1;
}
if (ret == -1 && run->errnum == QSE_AWK_ENOERR)
if (ret == -1 && rtx->errnum == QSE_AWK_ENOERR)
{
/* an error is returned with no error number set.
* this feature is used by eval_expression to
* abort the evaluation when exit() is executed
* during function evaluation */
ret = 0;
run->errlin = 0;
run->errmsg[0] = QSE_T('\0');
rtx->errlin = 0;
rtx->errmsg[0] = QSE_T('\0');
}
/* execute END blocks. the first END block is executed if the
* program is not explicitly aborted with qse_awk_rtx_stop().*/
for (nde = run->awk->tree.end;
ret == 0 && nde != QSE_NULL && run->exit_level < EXIT_ABORT;
for (nde = rtx->awk->tree.end;
ret == 0 && nde != QSE_NULL && rtx->exit_level < EXIT_ABORT;
nde = nde->next)
{
qse_awk_nde_blk_t* blk;
@ -1391,10 +1394,10 @@ static int run_bpae_loop (qse_awk_rtx_t* run)
blk = (qse_awk_nde_blk_t*)nde;
QSE_ASSERT (blk->type == QSE_AWK_NDE_BLK);
run->active_block = blk;
run->exit_level = EXIT_NONE;
if (run_block (run, blk) == -1) ret = -1;
else if (run->exit_level >= EXIT_GLOBAL)
rtx->active_block = blk;
rtx->exit_level = EXIT_NONE;
if (run_block (rtx, blk) == -1) ret = -1;
else if (rtx->exit_level >= EXIT_GLOBAL)
{
/* once exit is called inside one of END blocks,
* subsequent END blocks must not be executed */
@ -1402,33 +1405,33 @@ static int run_bpae_loop (qse_awk_rtx_t* run)
}
}
if (ret == -1 && run->errnum == QSE_AWK_ENOERR)
if (ret == -1 && rtx->errnum == QSE_AWK_ENOERR)
{
/* an error is returned with no error number set.
* this feature is used by eval_expression to
* abort the evaluation when exit() is executed
* during function evaluation */
ret = 0;
run->errlin = 0;
run->errmsg[0] = QSE_T('\0');
rtx->errlin = 0;
rtx->errmsg[0] = QSE_T('\0');
}
/* derefrence all arguments. however, there should be no arguments
* pushed to the stack as asserted below. we didn't push any arguments
* for BEGIN/pattern action/END block execution.*/
nargs = (qse_size_t)STACK_NARGS(run);
nargs = (qse_size_t)STACK_NARGS(rtx);
QSE_ASSERT (nargs == 0);
for (i = 0; i < nargs; i++) qse_awk_rtx_refdownval (run, STACK_ARG(run,i));
for (i = 0; i < nargs; i++) qse_awk_rtx_refdownval (rtx, STACK_ARG(rtx,i));
/* get the return value in the current stack frame */
v = STACK_RETVAL(run);
v = STACK_RETVAL(rtx);
if (ret == 0)
{
if (run->cbs != QSE_NULL && run->cbs->on_exit != QSE_NULL)
run->cbs->on_exit (run, v, run->cbs->data);
if (rtx->cbs != QSE_NULL && rtx->cbs->on_exit != QSE_NULL)
rtx->cbs->on_exit (rtx, v, rtx->cbs->data);
}
/* end the life of the gbl return value */
qse_awk_rtx_refdownval (run, v);
qse_awk_rtx_refdownval (rtx, v);
return ret;
}

View File

@ -66,20 +66,20 @@ static int custom_awk_sprintf (
static int add_functions (qse_awk_t* awk);
qse_awk_t* qse_awk_opensimple (qse_size_t xtnsize)
qse_awk_t* qse_awk_opensimple (qse_size_t xtn)
{
qse_awk_t* awk;
xtn_t* xtn;
xtn_t* x;
awk = qse_awk_open (QSE_MMGR_GETDFL(), xtnsize + QSE_SIZEOF(xtn_t));
awk = qse_awk_open (QSE_MMGR_GETDFL(), xtn + QSE_SIZEOF(xtn_t));
qse_awk_setccls (awk, QSE_CCLS_GETDFL());
xtn = (xtn_t*)((qse_byte_t*)qse_awk_getxtn(awk) + xtnsize);
x = (xtn_t*)((qse_byte_t*)qse_awk_getxtn(awk) + xtn);
xtn->prm.pow = custom_awk_pow;
xtn->prm.sprintf = custom_awk_sprintf;
xtn->prm.data = QSE_NULL;
qse_awk_setprm (awk, &xtn->prm);
x->prm.pow = custom_awk_pow;
x->prm.sprintf = custom_awk_sprintf;
x->prm.data = QSE_NULL;
qse_awk_setprm (awk, &x->prm);
qse_awk_setoption (awk,
QSE_AWK_IMPLICIT | QSE_AWK_EIO | QSE_AWK_NEWLINE |
@ -285,7 +285,7 @@ static qse_ssize_t sf_out (int cmd, void* arg, qse_char_t* data, qse_size_t size
}
int qse_awk_parsesimple (
qse_awk_t* awk, const void* isp, int ist, const qse_char_t* osf)
qse_awk_t* awk, int ist, const void* isp, const qse_char_t* osf)
{
sf_t sf;
qse_awk_sio_t sio;
@ -327,14 +327,14 @@ int qse_awk_parsesimple (
/*** RUNSIMPLE ***/
typedef struct runio_data_t
typedef struct rio_data_t
{
struct
{
qse_char_t** files;
qse_size_t index;
} ic; /* input console */
} runio_data_t;
} rio_data_t;
static qse_ssize_t awk_eio_pipe (
int cmd, void* arg, qse_char_t* data, qse_size_t size)
@ -519,7 +519,7 @@ static qse_ssize_t awk_eio_file (
static int open_eio_console (qse_awk_eio_t* epa)
{
runio_data_t* rd = (runio_data_t*)epa->data;
rio_data_t* rd = (rio_data_t*)epa->data;
/*dprint (QSE_T("opening console[%s] of type %x\n"), epa->name, epa->type);*/
@ -595,7 +595,7 @@ static qse_ssize_t awk_eio_console (
int cmd, void* arg, qse_char_t* data, qse_size_t size)
{
qse_awk_eio_t* epa = (qse_awk_eio_t*)arg;
runio_data_t* rd = (runio_data_t*)epa->data;
rio_data_t* rd = (rio_data_t*)epa->data;
if (cmd == QSE_AWK_IO_OPEN)
{
@ -738,41 +738,85 @@ static qse_ssize_t awk_eio_console (
return -1;
}
int qse_awk_runsimple (qse_awk_t* awk, qse_char_t** icf, qse_awk_rcb_t* rcb)
#if 0
qse_awk_rtx_t* qse_awk_opensimple (qse_awk_t* awk, qse_char_t** icf, qse_awk_rcb_t* rcb)
{
qse_awk_rtx_t* rtx;
qse_awk_rio_t ios;
runio_data_t rd;
rxtn_t rxtn;
qse_awk_rio_t rio;
rio_data_t rd;
rxtn_t* rxtn;
qse_ntime_t now;
int n;
rd.ic.files = icf;
rd.ic.index = 0;
ios.pipe = awk_eio_pipe;
ios.file = awk_eio_file;
ios.console = awk_eio_console;
ios.data = &rd;
rio.pipe = awk_eio_pipe;
rio.file = awk_eio_file;
rio.console = awk_eio_console;
rio.data = &rd;
if (qse_gettime (&now) == -1) rxtn.seed = 0;
else rxtn.seed = (unsigned int)now;
srand (rxtn.seed);
rtx = qse_awk_rtx_open (
awk,
&ios,
QSE_SIZEOF(rxtn),
&rio,
rcb,
QSE_NULL/*runarg*/,
&rxtn/*QSE_NULL*/
QSE_NULL/*runarg*/
);
if (rtx == QSE_NULL) return QSE_NULL;
rxtn = (rxtn_t*)qse_awk_rtx_getxtn (rtx);
if (qse_gettime (&now) == -1) rxtn->seed = 0;
else rxtn->seed = (unsigned int)now;
srand (rxtn->seed);
return rtx;
}
#endif
int qse_awk_runsimple (qse_awk_t* awk, qse_char_t** icf, qse_awk_rcb_t* rcb)
{
qse_awk_rtx_t* rtx;
qse_awk_rio_t rio;
rio_data_t rd;
rxtn_t* rxtn;
qse_ntime_t now;
int n;
rd.ic.files = icf;
rd.ic.index = 0;
rio.pipe = awk_eio_pipe;
rio.file = awk_eio_file;
rio.console = awk_eio_console;
rio.data = &rd;
rtx = qse_awk_rtx_open (
awk,
QSE_SIZEOF(rxtn),
&rio,
rcb,
QSE_NULL/*runarg*/
);
if (rtx == QSE_NULL) return -1;
rxtn = (rxtn_t*)qse_awk_rtx_getxtn (rtx);
if (qse_gettime (&now) == -1) rxtn->seed = 0;
else rxtn->seed = (unsigned int)now;
srand (rxtn->seed);
/* execute the start callback if it exists */
if (rcb != QSE_NULL && rcb->on_start != QSE_NULL)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR);
n = rcb->on_start (rtx, rcb->data);
if (n <= -1) n = -1; // TODO: something doesn't make send here...
if (n <= -1)
{
if (rtx->errnum == QSE_AWK_ENOERR)
qse_awk_seterrnum (awk, QSE_AWK_EUNKNOWN);
n = -1;
goto oops;
}
}
n = qse_awk_rtx_loop (rtx);
@ -813,6 +857,7 @@ int qse_awk_runsimple (qse_awk_t* awk, qse_char_t** icf, qse_awk_rcb_t* rcb)
n = 0;
}
oops:
qse_awk_rtx_close (rtx);
return n;
}
@ -1108,7 +1153,7 @@ static int fnc_srand (qse_awk_rtx_t* run, const qse_char_t* fnm, qse_size_t fnl)
unsigned int prev;
rxtn_t* rxtn;
rxtn = (rxtn_t*)qse_awk_rtx_getdata (run);
rxtn = (rxtn_t*)qse_awk_rtx_getxtn (run);
nargs = qse_awk_rtx_getnargs (run);
QSE_ASSERT (nargs == 0 || nargs == 1);