From 464f43b8216fb8119b8661cf4ff1355bbca6de13 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 13 Feb 2009 04:55:25 +0000 Subject: [PATCH] fixed minor bugs and cleaned up code --- qse/cmd/awk/awk.c | 2 +- qse/include/qse/awk/Awk.hpp | 2 +- qse/include/qse/awk/awk.h | 122 +++++++++-------- qse/lib/awk/Awk.cpp | 23 +++- qse/lib/awk/awk.h | 2 - qse/lib/awk/err.c | 2 +- qse/lib/awk/run.c | 255 ++++++++++++++++++------------------ qse/lib/awk/std.c | 105 ++++++++++----- 8 files changed, 294 insertions(+), 219 deletions(-) diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 38514fe6..a04560da 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -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"), diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index ce343f86..b178131b 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -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, diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index bc9f62e9..5badfece 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -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 diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 964ae4ef..4c383456 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -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); } diff --git a/qse/lib/awk/awk.h b/qse/lib/awk/awk.h index 08ba85b0..7723d73c 100644 --- a/qse/lib/awk/awk.h +++ b/qse/lib/awk/awk.h @@ -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; }; diff --git a/qse/lib/awk/err.c b/qse/lib/awk/err.c index e89f6061..5f99cfa8 100644 --- a/qse/lib/awk/err.c +++ b/qse/lib/awk/err.c @@ -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"), diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 830b2ceb..88a1d9e4 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -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; } diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 0cac7523..6e274379 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -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);