diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 1c60a837..28eac025 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -601,7 +601,7 @@ struct qse_awk_sio_arg_t qse_size_t colm; qse_awk_sio_lxc_t last; - int pragmas; + int pragma_trait; }; /** @@ -1087,7 +1087,9 @@ enum qse_awk_opt_t QSE_AWK_DEPTH_EXPR_PARSE, QSE_AWK_DEPTH_EXPR_RUN, QSE_AWK_DEPTH_REX_BUILD, - QSE_AWK_DEPTH_REX_MATCH + QSE_AWK_DEPTH_REX_MATCH, + + QSE_AWK_RTX_STACK_LIMIT }; typedef enum qse_awk_opt_t qse_awk_opt_t; @@ -1256,6 +1258,7 @@ enum qse_awk_errnum_t QSE_AWK_ECOMMA, /**< comma expected in place of '${0}' */ QSE_AWK_ESCOLON, /**< semicolon expected in place of '${0}' */ QSE_AWK_ECOLON, /**< colon expected in place of '${0}' */ + QSE_AWK_EINTLIT, /**< integer literal expected in place of '${0}' */ QSE_AWK_ESTMEND, /**< statement not ending with a semicolon */ QSE_AWK_EKWIN, /**< keyword 'in' expected in place of '${0}' */ QSE_AWK_ENOTVAR, /**< right-hand side of 'in' not a variable */ @@ -1303,6 +1306,7 @@ enum qse_awk_errnum_t QSE_AWK_EXKWEM, /**< @ not followed by a valid word */ /* run time error */ + QSE_AWK_ESTACK, /**< stack error */ QSE_AWK_EDIVBY0, /**< divide by zero */ QSE_AWK_EOPERAND, /**< invalid operand */ QSE_AWK_EPOSIDX, /**< wrong position index */ diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 7d9c1c21..b9c755e4 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1359,7 +1359,7 @@ int Awk::init_runctx () rio.file = fileHandler; rio.console = consoleHandler; - rtx_t* rtx = qse_awk_rtx_open (awk, QSE_SIZEOF(rxtn_t), &rio); + rtx_t* rtx = qse_awk_rtx_open(awk, QSE_SIZEOF(rxtn_t), &rio); if (rtx == QSE_NULL) { this->retrieveError(); @@ -1368,7 +1368,7 @@ int Awk::init_runctx () runctx.rtx = rtx; - rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); + rxtn_t* rxtn = (rxtn_t*)QSE_XTN(rtx); rxtn->run = &runctx; return 0; diff --git a/qse/lib/awk/awk-prv.h b/qse/lib/awk/awk-prv.h index a54b4828..bfe7ea7c 100644 --- a/qse/lib/awk/awk-prv.h +++ b/qse/lib/awk/awk-prv.h @@ -74,6 +74,9 @@ typedef struct qse_awk_tree_t qse_awk_tree_t; #define QSE_AWK_MAX_LCLS 9999 #define QSE_AWK_MAX_PARAMS 9999 +#define QSE_AWK_DFL_RTX_STACK_LIMIT 5120 +#define QSE_AWK_MIN_RTX_STACK_LIMIT 512 + #define QSE_AWK_ALLOC(awk,size) QSE_MMGR_ALLOC((awk)->mmgr,size) #define QSE_AWK_REALLOC(awk,ptr,size) QSE_MMGR_REALLOC((awk)->mmgr,ptr,size) #define QSE_AWK_FREE(awk,ptr) QSE_MMGR_FREE((awk)->mmgr,ptr) @@ -193,6 +196,8 @@ struct qse_awk_t qse_size_t rex_match; } s; } depth; + + qse_size_t rtx_stack_limit; } opt; /* parse tree */ @@ -217,7 +222,11 @@ struct qse_awk_t } depth; /* current pragma values */ - int pragmas; + struct + { + int trait; + qse_size_t rtx_stack_limit; + } pragma; /* function calls */ qse_htb_t* funs; @@ -313,12 +322,6 @@ struct qse_awk_chain_t #define RTX_STACK_GBL(rtx,n) ((rtx)->stack[(n)]) #define RTX_STACK_RETVAL_GBL(rtx) ((rtx)->stack[(rtx)->awk->tree.ngbls+2]) -#define RTX_STACK_AT_OVER_BASE(rtx,_base,n) ((rtx)->stack[(_base)+(n)]) -#define RTX_STACK_NARGS_OVER_BASE(rtx,_base) RTX_STACK_AT_OVER_BASE(rtx,_base,3) -#define RTX_STACK_ARG_OVER_BASE(rtx,_base,n) RTX_STACK_AT_OVER_BASE(rtx,_base,3+1+(n)) -#define RTX_STACK_LCL_OVER_BASE(rtx,_base,n) RTX_STACK_AT_OVER_BASE(rtx,_base,3+(qse_size_t)RTX_STACK_NARGS(rtx)+1+(n)) -#define RTX_STACK_RETVAL_OVER_BASE(rtx,_base) RTX_STACK_AT_OVER_BASE(rtx,_base,2) - struct qse_awk_rtx_t { QSE_AWK_RTX_HDR; diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index b1f142dc..e9ee6bb0 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -181,6 +181,7 @@ int qse_awk_init (qse_awk_t* awk, qse_mmgr_t* mmgr, const qse_awk_prm_t* prm) #if defined(__OS2__) || defined(_WIN32) || defined(__DOS__) awk->opt.trait |= QSE_AWK_CRLF; #endif + awk->opt.rtx_stack_limit = QSE_AWK_DFL_RTX_STACK_LIMIT; awk->tree.ngbls = 0; awk->tree.ngbls_base = 0; @@ -321,7 +322,9 @@ void qse_awk_clear (qse_awk_t* awk) qse_awk_ecb_t* ecb; for (ecb = awk->ecb; ecb; ecb = ecb->next) + { if (ecb->clear) ecb->clear (awk); + } awk->stopall = 0; @@ -349,7 +352,8 @@ void qse_awk_clear (qse_awk_t* awk) awk->parse.depth.loop = 0; awk->parse.depth.expr = 0; awk->parse.depth.incl = 0; - awk->parse.pragmas = (awk->opt.trait & QSE_AWK_IMPLICIT); + awk->parse.pragma.trait = (awk->opt.trait & QSE_AWK_IMPLICIT); + awk->parse.pragma.rtx_stack_limit = 0; awk->parse.incl_hist.count =0; @@ -477,6 +481,10 @@ int qse_awk_setopt (qse_awk_t* awk, qse_awk_opt_t id, const void* value) case QSE_AWK_DEPTH_REX_MATCH: awk->opt.depth.a[id - QSE_AWK_DEPTH_INCLUDE] = *(const qse_size_t*)value; return 0; + + case QSE_AWK_RTX_STACK_LIMIT: + awk->opt.rtx_stack_limit = *(const qse_size_t*)value; + return 0; } qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); @@ -509,6 +517,10 @@ int qse_awk_getopt (qse_awk_t* awk, qse_awk_opt_t id, void* value) case QSE_AWK_DEPTH_REX_MATCH: *(qse_size_t*)value = awk->opt.depth.a[id - QSE_AWK_DEPTH_INCLUDE]; return 0; + + case QSE_AWK_RTX_STACK_LIMIT: + *(qse_size_t*)value = awk->opt.rtx_stack_limit; + return 0; }; qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); diff --git a/qse/lib/awk/err.c b/qse/lib/awk/err.c index d3fb0036..d2c6cd38 100644 --- a/qse/lib/awk/err.c +++ b/qse/lib/awk/err.c @@ -67,6 +67,7 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn QSE_T("comma expected in place of '${0}'"), QSE_T("semicolon expected in place of '${0}'"), QSE_T("colon expected in place of '${0}'"), + QSE_T("integer literal expected in place of '${0}'"), QSE_T("statement not ending with a semicolon"), QSE_T("keyword 'in' expected in place of '${0}'"), QSE_T("right-hand side of 'in' not a variable"), @@ -113,6 +114,7 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn QSE_T("'${0}' not recognized"), QSE_T("@ not followed by a valid word"), + QSE_T("stack error"), QSE_T("divide by zero"), QSE_T("invalid operand"), QSE_T("wrong position index"), diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index eecfecfc..9606e479 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -692,7 +692,7 @@ int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio) awk->sio.last.c = QSE_CHAR_EOF; awk->sio.arg.line = 1; awk->sio.arg.colm = 1; - awk->sio.arg.pragmas = 0; + awk->sio.arg.pragma_trait = 0; awk->sio.inp = &awk->sio.arg; n = parse(awk); @@ -728,7 +728,7 @@ static int end_include (qse_awk_t* awk) QSE_ASSERT (cur->name != QSE_NULL); /* restore the pragma values */ - awk->parse.pragmas = cur->pragmas; + awk->parse.pragma.trait = cur->pragma_trait; qse_awk_freemem (awk, cur); awk->parse.depth.incl--; @@ -835,10 +835,10 @@ static int begin_include (qse_awk_t* awk, int once) } /* store the pragma value */ - arg->pragmas = awk->parse.pragmas; - /* but don't change awk->parse.pragmas. it means the included file inherits + arg->pragma_trait = awk->parse.pragma.trait; + /* but don't change awk->parse.pragma.trait. it means the included file inherits * the existing progma values. - awk->parse.pragmas = (awk->option.trait & QSE_AWK_IMPLICIT); + awk->parse.pragma.trait = (awk->opt.trait & QSE_AWK_IMPLICIT); */ /* i update the current pointer after opening is successful */ @@ -952,7 +952,8 @@ static int parse_progunit (qse_awk_t* awk) if (qse_strxcmp(name.ptr, name.len, QSE_T("implicit")) == 0) { - + /* @pragma implicit on + * @pragma implicit off */ if (get_token(awk) <= -1) return -1; if (!MATCH(awk, TOK_IDENT)) { @@ -965,17 +966,33 @@ static int parse_progunit (qse_awk_t* awk) name.ptr = QSE_STR_PTR(awk->tok.name); if (qse_strxcmp(name.ptr, name.len, QSE_T("on")) == 0) { - awk->parse.pragmas |= QSE_AWK_IMPLICIT; + awk->parse.pragma.trait |= QSE_AWK_IMPLICIT; } else if (qse_strxcmp(name.ptr, name.len, QSE_T("off")) == 0) { - awk->parse.pragmas &= ~QSE_AWK_IMPLICIT; + awk->parse.pragma.trait &= ~QSE_AWK_IMPLICIT; } else { goto error_ident_on_off_expected_for_implicit; } } + else if (qse_strxcmp(name.ptr, name.len, QSE_T("stack_limit")) == 0) + { + qse_long_t sl; + + /* @pragma stack_limit 99999 */ + if (get_token(awk) <= -1) return -1; + if (!MATCH(awk, TOK_INT)) + { + SETERR_TOK (awk, QSE_AWK_EINTLIT); + return -1; + } + + sl = qse_strxtolong(QSE_STR_PTR(awk->tok.name), QSE_STR_LEN(awk->tok.name), 10, QSE_NULL); + /* take the specified value if it's greater than the existing value */ + if (sl > awk->parse.pragma.rtx_stack_limit) awk->parse.pragma.rtx_stack_limit = sl; + } else { qse_awk_seterrfmt (awk, QSE_AWK_EIDENT, &awk->ptok.loc, QSE_T("unknown @pragma identifier - %.*s"), (int)name.len, name.ptr); @@ -5167,7 +5184,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l } } /*else if (awk->opt.trait & QSE_AWK_IMPLICIT) */ - else if (awk->parse.pragmas & QSE_AWK_IMPLICIT) + else if (awk->parse.pragma.trait & QSE_AWK_IMPLICIT) { /* if the name is followed by ( without spaces, * it's considered a function call though the name @@ -5489,7 +5506,7 @@ static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, con } /*if (awk->opt.trait & QSE_AWK_IMPLICIT) */ - if (awk->parse.pragmas & QSE_AWK_IMPLICIT) + if (awk->parse.pragma.trait & QSE_AWK_IMPLICIT) { int fnname = isfnname(awk, name); switch (fnname) diff --git a/qse/lib/awk/rec.c b/qse/lib/awk/rec.c index 4de0c76c..49f0a32a 100644 --- a/qse/lib/awk/rec.c +++ b/qse/lib/awk/rec.c @@ -410,7 +410,7 @@ static int recomp_record_fields (qse_awk_rtx_t* run, qse_size_t lv, const qse_cs * the field spaces are resized */ tmp = qse_awk_rtx_reallocmem(run, run->inrec.flds, QSE_SIZEOF(*run->inrec.flds) * max); - if (!tmp == QSE_NULL) return -1; + if (!tmp) return -1; run->inrec.flds = tmp; run->inrec.maxflds = max; diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 2e8bdd48..9f9ddcac 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -922,15 +922,19 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio) QSE_HTB_SIZER_DEFAULT, QSE_HTB_HASHER_DEFAULT }; + qse_size_t stack_limit; rtx->awk = awk; CLRERR (rtx); - rtx->stack = QSE_NULL; + stack_limit = awk->parse.pragma.rtx_stack_limit > 0? awk->parse.pragma.rtx_stack_limit: awk->opt.rtx_stack_limit; + if (stack_limit < QSE_AWK_MIN_RTX_STACK_LIMIT) stack_limit = QSE_AWK_MIN_RTX_STACK_LIMIT; + rtx->stack = qse_awk_rtx_allocmem(rtx, stack_limit * QSE_SIZEOF(void*)); + if (!rtx->stack) goto oops_0; rtx->stack_top = 0; rtx->stack_base = 0; - rtx->stack_limit = 0; + rtx->stack_limit = stack_limit; rtx->exit_level = EXIT_NONE; @@ -946,34 +950,34 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio) rtx->inrec.maxflds = 0; rtx->inrec.d0 = qse_awk_val_nil; - if (qse_str_init(&rtx->inrec.line, MMGR(rtx), DEF_BUF_CAPA) <= -1) goto oops_0; - if (qse_str_init(&rtx->inrec.linew, MMGR(rtx), DEF_BUF_CAPA) <= -1) goto oops_1; - if (qse_str_init(&rtx->inrec.lineg, MMGR(rtx), DEF_BUF_CAPA) <= -1) goto oops_2; - if (qse_str_init(&rtx->format.out, MMGR(rtx), 256) <= -1) goto oops_3; - if (qse_str_init(&rtx->format.fmt, MMGR(rtx), 256) <= -1) goto oops_4; + if (qse_str_init(&rtx->inrec.line, MMGR(rtx), DEF_BUF_CAPA) <= -1) goto oops_1; + if (qse_str_init(&rtx->inrec.linew, MMGR(rtx), DEF_BUF_CAPA) <= -1) goto oops_2; + if (qse_str_init(&rtx->inrec.lineg, MMGR(rtx), DEF_BUF_CAPA) <= -1) goto oops_3; + if (qse_str_init(&rtx->format.out, MMGR(rtx), 256) <= -1) goto oops_4; + if (qse_str_init(&rtx->format.fmt, MMGR(rtx), 256) <= -1) goto oops_5; - if (qse_mbs_init(&rtx->formatmbs.out, MMGR(rtx), 256) <= -1) goto oops_5; - if (qse_mbs_init(&rtx->formatmbs.fmt, MMGR(rtx), 256) <= -1) goto oops_6; + if (qse_mbs_init(&rtx->formatmbs.out, MMGR(rtx), 256) <= -1) goto oops_6; + if (qse_mbs_init(&rtx->formatmbs.fmt, MMGR(rtx), 256) <= -1) goto oops_7; rtx->named = qse_htb_open(MMGR(rtx), QSE_SIZEOF(rtx), 1024, 70, QSE_SIZEOF(qse_char_t), 1); - if (!rtx->named) goto oops_7; + if (!rtx->named) goto oops_8; *(qse_awk_rtx_t**)QSE_XTN(rtx->named) = rtx; qse_htb_setstyle (rtx->named, &style_for_named); rtx->format.tmp.ptr = (qse_char_t*)qse_awk_rtx_allocmem(rtx, 4096 * QSE_SIZEOF(qse_char_t)); - if (!rtx->format.tmp.ptr) goto oops_8; /* the error is set on the awk object after this jump is made */ + if (!rtx->format.tmp.ptr) goto oops_9; /* the error is set on the awk object after this jump is made */ rtx->format.tmp.len = 4096; rtx->format.tmp.inc = 4096 * 2; rtx->formatmbs.tmp.ptr = (qse_mchar_t*)qse_awk_rtx_allocmem(rtx, 4096 * QSE_SIZEOF(qse_mchar_t)); - if (!rtx->formatmbs.tmp.ptr) goto oops_9; + if (!rtx->formatmbs.tmp.ptr) goto oops_10; rtx->formatmbs.tmp.len = 4096; rtx->formatmbs.tmp.inc = 4096 * 2; if (rtx->awk->tree.chain_size > 0) { rtx->pattern_range_state = (qse_byte_t*)qse_awk_rtx_allocmem(rtx, rtx->awk->tree.chain_size * QSE_SIZEOF(qse_byte_t)); - if (!rtx->pattern_range_state) goto oops_10; + if (!rtx->pattern_range_state) goto oops_11; QSE_MEMSET (rtx->pattern_range_state, 0, rtx->awk->tree.chain_size * QSE_SIZEOF(qse_byte_t)); } else rtx->pattern_range_state = QSE_NULL; @@ -995,26 +999,28 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio) return 0; -oops_10: +oops_11: qse_awk_rtx_freemem (rtx, rtx->formatmbs.tmp.ptr); -oops_9: +oops_10: qse_awk_rtx_freemem (rtx, rtx->format.tmp.ptr); -oops_8: +oops_9: qse_htb_close (rtx->named); -oops_7: +oops_8: qse_mbs_fini (&rtx->formatmbs.fmt); -oops_6: +oops_7: qse_mbs_fini (&rtx->formatmbs.out); -oops_5: +oops_6: qse_str_fini (&rtx->format.fmt); -oops_4: +oops_5: qse_str_fini (&rtx->format.out); -oops_3: +oops_4: qse_str_fini (&rtx->inrec.lineg); -oops_2: +oops_3: qse_str_fini (&rtx->inrec.linew); -oops_1: +oops_2: qse_str_fini (&rtx->inrec.line); +oops_1: + qse_awk_freemem (rtx, rtx->stack); oops_0: qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); return -1; @@ -1378,8 +1384,8 @@ static void exit_stack_frame (qse_awk_rtx_t* run) * the 4 entries pushed in enter_stack_frame(). */ QSE_ASSERT ((run->stack_top-run->stack_base) == 4); - run->stack_top = (qse_size_t)run->stack[run->stack_base+1]; - run->stack_base = (qse_size_t)run->stack[run->stack_base+0]; + run->stack_top = (qse_size_t)run->stack[run->stack_base + 1]; + run->stack_base = (qse_size_t)run->stack[run->stack_base + 0]; } static qse_awk_val_t* run_bpae_loop (qse_awk_rtx_t* rtx) @@ -1736,7 +1742,7 @@ static int run_pblock (qse_awk_rtx_t* rtx, qse_awk_chain_t* cha, qse_size_t bno) qse_awk_rtx_refupval (rtx, v1); - if (qse_awk_rtx_valtobool (rtx, v1)) + if (qse_awk_rtx_valtobool(rtx, v1)) { rtx->active_block = blk; if (run_block (rtx, blk) == -1) @@ -1762,7 +1768,7 @@ static int run_pblock (qse_awk_rtx_t* rtx, qse_awk_chain_t* cha, qse_size_t bno) if (v1 == QSE_NULL) return -1; qse_awk_rtx_refupval (rtx, v1); - if (qse_awk_rtx_valtobool (rtx, v1)) + if (qse_awk_rtx_valtobool(rtx, v1)) { rtx->active_block = blk; if (run_block (rtx, blk) == -1) @@ -1787,7 +1793,7 @@ static int run_pblock (qse_awk_rtx_t* rtx, qse_awk_chain_t* cha, qse_size_t bno) rtx->active_block = blk; if (run_block (rtx, blk) == -1) { - qse_awk_rtx_refdownval (rtx, v2); + qse_awk_rtx_refdownval(rtx, v2); return -1; } @@ -1814,9 +1820,9 @@ static int run_block (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde) } rtx->depth.block++; - n = run_block0 (rtx, nde); + n = run_block0(rtx, nde); rtx->depth.block--; - + return n; } @@ -1832,21 +1838,16 @@ static int run_block0 (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde) /* blockless pattern - execute print $0*/ qse_awk_rtx_refupval (rtx, rtx->inrec.d0); - n = qse_awk_rtx_writeiostr (rtx, - QSE_AWK_OUT_CONSOLE, QSE_T(""), - QSE_STR_PTR(&rtx->inrec.line), - QSE_STR_LEN(&rtx->inrec.line)); - if (n == -1) + n = qse_awk_rtx_writeiostr(rtx, QSE_AWK_OUT_CONSOLE, QSE_T(""), QSE_STR_PTR(&rtx->inrec.line), QSE_STR_LEN(&rtx->inrec.line)); + if (n <= -1) { qse_awk_rtx_refdownval (rtx, rtx->inrec.d0); ADJERR_LOC (rtx, &nde->loc); return -1; } - n = qse_awk_rtx_writeiostr ( - rtx, QSE_AWK_OUT_CONSOLE, QSE_T(""), - rtx->gbl.ors.ptr, rtx->gbl.ors.len); - if (n == -1) + n = qse_awk_rtx_writeiostr(rtx, QSE_AWK_OUT_CONSOLE, QSE_T(""), rtx->gbl.ors.ptr, rtx->gbl.ors.len); + if (n <= -1) { qse_awk_rtx_refdownval (rtx, rtx->inrec.d0); ADJERR_LOC (rtx, &nde->loc); @@ -1874,7 +1875,7 @@ static int run_block0 (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde) while (nlcls > 0) { --nlcls; - if (__raw_push(rtx,qse_awk_val_nil) == -1) + if (__raw_push(rtx,qse_awk_val_nil) <= -1) { /* restore stack top */ rtx->stack_top = saved_stack_top; @@ -1890,7 +1891,7 @@ static int run_block0 (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde) while (p != QSE_NULL && rtx->exit_level == EXIT_NONE) { - if (run_statement (rtx, p) == -1) + if (run_statement(rtx, p) <= -1) { n = -1; break; @@ -2028,13 +2029,13 @@ static int run_if (qse_awk_rtx_t* rtx, qse_awk_nde_if_t* nde) if (test == QSE_NULL) return -1; qse_awk_rtx_refupval (rtx, test); - if (qse_awk_rtx_valtobool (rtx, test)) + if (qse_awk_rtx_valtobool(rtx, test)) { - n = run_statement (rtx, nde->then_part); + n = run_statement(rtx, nde->then_part); } - else if (nde->else_part != QSE_NULL) + else if (nde->else_part) { - n = run_statement (rtx, nde->else_part); + n = run_statement(rtx, nde->else_part); } qse_awk_rtx_refdownval (rtx, test); /* TODO: is this correct?*/ @@ -2055,14 +2056,14 @@ static int run_while (qse_awk_rtx_t* rtx, qse_awk_nde_while_t* nde) { ON_STATEMENT (rtx, nde->test); - test = eval_expression (rtx, nde->test); - if (test == QSE_NULL) return -1; + test = eval_expression(rtx, nde->test); + if (!test) return -1; qse_awk_rtx_refupval (rtx, test); - if (qse_awk_rtx_valtobool (rtx, test)) + if (qse_awk_rtx_valtobool(rtx, test)) { - if (run_statement(rtx,nde->body) == -1) + if (run_statement(rtx,nde->body) <= -1) { qse_awk_rtx_refdownval (rtx, test); return -1; @@ -2077,7 +2078,7 @@ static int run_while (qse_awk_rtx_t* rtx, qse_awk_nde_while_t* nde) qse_awk_rtx_refdownval (rtx, test); if (rtx->exit_level == EXIT_BREAK) - { + { rtx->exit_level = EXIT_NONE; break; } @@ -2097,10 +2098,10 @@ static int run_while (qse_awk_rtx_t* rtx, qse_awk_nde_while_t* nde) do { - if (run_statement(rtx,nde->body) == -1) return -1; + if (run_statement(rtx,nde->body) <= -1) return -1; if (rtx->exit_level == EXIT_BREAK) - { + { rtx->exit_level = EXIT_NONE; break; } @@ -2112,12 +2113,12 @@ static int run_while (qse_awk_rtx_t* rtx, qse_awk_nde_while_t* nde) ON_STATEMENT (rtx, nde->test); - test = eval_expression (rtx, nde->test); - if (test == QSE_NULL) return -1; + test = eval_expression(rtx, nde->test); + if (!test) return -1; qse_awk_rtx_refupval (rtx, test); - if (!qse_awk_rtx_valtobool (rtx, test)) + if (!qse_awk_rtx_valtobool(rtx, test)) { qse_awk_rtx_refdownval (rtx, test); break; @@ -2162,7 +2163,7 @@ static int run_for (qse_awk_rtx_t* rtx, qse_awk_nde_for_t* nde) if (test == QSE_NULL) return -1; qse_awk_rtx_refupval (rtx, test); - if (qse_awk_rtx_valtobool (rtx, test)) + if (qse_awk_rtx_valtobool(rtx, test)) { if (run_statement(rtx,nde->body) == -1) { @@ -3915,7 +3916,7 @@ static qse_awk_val_t* eval_binop_lor ( if (lv == QSE_NULL) return QSE_NULL; qse_awk_rtx_refupval (run, lv); - if (qse_awk_rtx_valtobool (run, lv)) + if (qse_awk_rtx_valtobool(run, lv)) { res = QSE_AWK_VAL_ONE; } @@ -3967,7 +3968,7 @@ static qse_awk_val_t* eval_binop_land (qse_awk_rtx_t* run, qse_awk_nde_t* left, if (lv == QSE_NULL) return QSE_NULL; qse_awk_rtx_refupval (run, lv); - if (!qse_awk_rtx_valtobool (run, lv)) + if (!qse_awk_rtx_valtobool(run, lv)) { res = QSE_AWK_VAL_ZERO; } @@ -5728,7 +5729,7 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde) qse_awk_rtx_refupval (run, tv); QSE_ASSERT (cnd->left->next == QSE_NULL && cnd->right->next == QSE_NULL); - v = (qse_awk_rtx_valtobool (run, tv))? eval_expression(run, cnd->left): eval_expression(run, cnd->right); + v = (qse_awk_rtx_valtobool(run, tv))? eval_expression(run, cnd->left): eval_expression(run, cnd->right); qse_awk_rtx_refdownval (run, tv); return v; @@ -6055,7 +6056,7 @@ static qse_awk_val_t* __eval_call ( */ qse_size_t cur_stack_base = rtx->stack_base; - qse_size_t prev_stack_base = (qse_size_t)rtx->stack[rtx->stack_base+0]; + qse_size_t prev_stack_base = (qse_size_t)rtx->stack[rtx->stack_base + 0]; qse_awk_nde_t* p = call->args; for (i = 0; i < nargs; i++) @@ -6065,11 +6066,15 @@ static qse_awk_val_t* __eval_call ( qse_awk_val_t** ref; qse_awk_val_ref_t refv; - /* UGLY */ - rtx->stack_base = prev_stack_base; + /* if an argument passed is a local variable or a parameter to the previous caller, + * the argument node information stored is relative to the previous stack frame. + * i revert rtx->stack_base to the previous stack frame base before calling + * get_reference() and restors it back to the current base. this tactic + * is very ugly because the assumptions for this is dependent on get_reference() + * implementation */ + rtx->stack_base = prev_stack_base; /* UGLY */ get_reference (rtx, p, &ref); /* no failure check as it must succeed here for the check done above */ - rtx->stack_base = cur_stack_base; - /* UGLY */ + rtx->stack_base = cur_stack_base; /* UGLY */ QSE_AWK_RTX_INIT_REF_VAL (&refv, p->type - QSE_AWK_NDE_NAMED, ref, 9); /* initialize a fake reference variable. 9 chosen randomly */ qse_awk_rtx_setrefval (rtx, &refv, RTX_STACK_ARG(rtx, i)); @@ -6140,8 +6145,8 @@ static qse_awk_val_t* __eval_call ( qse_awk_rtx_refdownval_nofree (rtx, v); } - rtx->stack_top = (qse_size_t)rtx->stack[rtx->stack_base+1]; - rtx->stack_base = (qse_size_t)rtx->stack[rtx->stack_base+0]; + rtx->stack_top = (qse_size_t)rtx->stack[rtx->stack_base + 1]; + rtx->stack_base = (qse_size_t)rtx->stack[rtx->stack_base + 0]; if (rtx->exit_level == EXIT_FUNCTION) rtx->exit_level = EXIT_NONE; @@ -6788,6 +6793,7 @@ static int __raw_push (qse_awk_rtx_t* rtx, void* val) { if (rtx->stack_top >= rtx->stack_limit) { + /* void** tmp; qse_size_t n; @@ -6798,6 +6804,9 @@ static int __raw_push (qse_awk_rtx_t* rtx, void* val) rtx->stack = tmp; rtx->stack_limit = n; + */ + qse_awk_rtx_seterrfmt (rtx, QSE_AWK_ESTACK, QSE_NULL, QSE_T("runtime stack full")); + return -1; } rtx->stack[rtx->stack_top++] = val; diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index aa1caec2..83ca33e2 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -515,8 +515,8 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_aw prm.modsym = qse_awk_stdmodsym; /* create an object */ - awk = qse_awk_open (mmgr, QSE_SIZEOF(xtn_t) + xtnsize, &prm, errnum); - if (awk == QSE_NULL) return QSE_NULL; + awk = qse_awk_open(mmgr, QSE_SIZEOF(xtn_t) + xtnsize, &prm, errnum); + if (!awk) return QSE_NULL; #if defined(USE_DLFCN) @@ -533,13 +533,13 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_aw * QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn));*/ /* add intrinsic global variables and functions */ - if (add_globals(awk) <= -1 || add_functions (awk) <= -1) + if (add_globals(awk) <= -1 || add_functions(awk) <= -1) { if (errnum) *errnum = qse_awk_geterrnum(awk); goto oops; } - if (qse_awk_stdmodstartup (awk) <= -1) + if (qse_awk_stdmodstartup(awk) <= -1) { xtn->stdmod_up = 0; /* carry on regardless of failure */ diff --git a/qse/lib/awkmod/mod-mysql.c b/qse/lib/awkmod/mod-mysql.c index 72937a29..db243b3a 100644 --- a/qse/lib/awkmod/mod-mysql.c +++ b/qse/lib/awkmod/mod-mysql.c @@ -578,7 +578,6 @@ static int fnc_autocommit (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) int v; v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); - if (v <= -1) { take_rtx_err = 1; goto oops; } ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); @@ -614,7 +613,6 @@ static int fnc_commit (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) int v; v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); - if (v <= -1) { take_rtx_err = 1; goto oops; } ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); @@ -650,7 +648,6 @@ static int fnc_rollback (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) int v; v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); - if (v <= -1) { take_rtx_err = 1; goto oops; } ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node);