implemented @pragma stack_limit

This commit is contained in:
hyung-hwan 2019-06-09 05:55:36 +00:00
parent ce459fe337
commit dcb4619fec
10 changed files with 140 additions and 96 deletions

View File

@ -601,7 +601,7 @@ struct qse_awk_sio_arg_t
qse_size_t colm; qse_size_t colm;
qse_awk_sio_lxc_t last; 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_PARSE,
QSE_AWK_DEPTH_EXPR_RUN, QSE_AWK_DEPTH_EXPR_RUN,
QSE_AWK_DEPTH_REX_BUILD, 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; 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_ECOMMA, /**< comma expected in place of '${0}' */
QSE_AWK_ESCOLON, /**< semicolon 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_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_ESTMEND, /**< statement not ending with a semicolon */
QSE_AWK_EKWIN, /**< keyword 'in' expected in place of '${0}' */ QSE_AWK_EKWIN, /**< keyword 'in' expected in place of '${0}' */
QSE_AWK_ENOTVAR, /**< right-hand side of 'in' not a variable */ 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 */ QSE_AWK_EXKWEM, /**< @ not followed by a valid word */
/* run time error */ /* run time error */
QSE_AWK_ESTACK, /**< stack error */
QSE_AWK_EDIVBY0, /**< divide by zero */ QSE_AWK_EDIVBY0, /**< divide by zero */
QSE_AWK_EOPERAND, /**< invalid operand */ QSE_AWK_EOPERAND, /**< invalid operand */
QSE_AWK_EPOSIDX, /**< wrong position index */ QSE_AWK_EPOSIDX, /**< wrong position index */

View File

@ -1359,7 +1359,7 @@ int Awk::init_runctx ()
rio.file = fileHandler; rio.file = fileHandler;
rio.console = consoleHandler; 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) if (rtx == QSE_NULL)
{ {
this->retrieveError(); this->retrieveError();
@ -1368,7 +1368,7 @@ int Awk::init_runctx ()
runctx.rtx = rtx; runctx.rtx = rtx;
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); rxtn_t* rxtn = (rxtn_t*)QSE_XTN(rtx);
rxtn->run = &runctx; rxtn->run = &runctx;
return 0; return 0;

View File

@ -74,6 +74,9 @@ typedef struct qse_awk_tree_t qse_awk_tree_t;
#define QSE_AWK_MAX_LCLS 9999 #define QSE_AWK_MAX_LCLS 9999
#define QSE_AWK_MAX_PARAMS 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_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_REALLOC(awk,ptr,size) QSE_MMGR_REALLOC((awk)->mmgr,ptr,size)
#define QSE_AWK_FREE(awk,ptr) QSE_MMGR_FREE((awk)->mmgr,ptr) #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; qse_size_t rex_match;
} s; } s;
} depth; } depth;
qse_size_t rtx_stack_limit;
} opt; } opt;
/* parse tree */ /* parse tree */
@ -217,7 +222,11 @@ struct qse_awk_t
} depth; } depth;
/* current pragma values */ /* current pragma values */
int pragmas; struct
{
int trait;
qse_size_t rtx_stack_limit;
} pragma;
/* function calls */ /* function calls */
qse_htb_t* funs; 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_GBL(rtx,n) ((rtx)->stack[(n)])
#define RTX_STACK_RETVAL_GBL(rtx) ((rtx)->stack[(rtx)->awk->tree.ngbls+2]) #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 struct qse_awk_rtx_t
{ {
QSE_AWK_RTX_HDR; QSE_AWK_RTX_HDR;

View File

@ -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__) #if defined(__OS2__) || defined(_WIN32) || defined(__DOS__)
awk->opt.trait |= QSE_AWK_CRLF; awk->opt.trait |= QSE_AWK_CRLF;
#endif #endif
awk->opt.rtx_stack_limit = QSE_AWK_DFL_RTX_STACK_LIMIT;
awk->tree.ngbls = 0; awk->tree.ngbls = 0;
awk->tree.ngbls_base = 0; awk->tree.ngbls_base = 0;
@ -321,7 +322,9 @@ void qse_awk_clear (qse_awk_t* awk)
qse_awk_ecb_t* ecb; qse_awk_ecb_t* ecb;
for (ecb = awk->ecb; ecb; ecb = ecb->next) for (ecb = awk->ecb; ecb; ecb = ecb->next)
{
if (ecb->clear) ecb->clear (awk); if (ecb->clear) ecb->clear (awk);
}
awk->stopall = 0; awk->stopall = 0;
@ -349,7 +352,8 @@ void qse_awk_clear (qse_awk_t* awk)
awk->parse.depth.loop = 0; awk->parse.depth.loop = 0;
awk->parse.depth.expr = 0; awk->parse.depth.expr = 0;
awk->parse.depth.incl = 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; 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: case QSE_AWK_DEPTH_REX_MATCH:
awk->opt.depth.a[id - QSE_AWK_DEPTH_INCLUDE] = *(const qse_size_t*)value; awk->opt.depth.a[id - QSE_AWK_DEPTH_INCLUDE] = *(const qse_size_t*)value;
return 0; 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); 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: case QSE_AWK_DEPTH_REX_MATCH:
*(qse_size_t*)value = awk->opt.depth.a[id - QSE_AWK_DEPTH_INCLUDE]; *(qse_size_t*)value = awk->opt.depth.a[id - QSE_AWK_DEPTH_INCLUDE];
return 0; 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); qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);

View File

@ -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("comma expected in place of '${0}'"),
QSE_T("semicolon expected in place of '${0}'"), QSE_T("semicolon expected in place of '${0}'"),
QSE_T("colon 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("statement not ending with a semicolon"),
QSE_T("keyword 'in' expected in place of '${0}'"), QSE_T("keyword 'in' expected in place of '${0}'"),
QSE_T("right-hand side of 'in' not a variable"), 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("'${0}' not recognized"),
QSE_T("@ not followed by a valid word"), QSE_T("@ not followed by a valid word"),
QSE_T("stack error"),
QSE_T("divide by zero"), QSE_T("divide by zero"),
QSE_T("invalid operand"), QSE_T("invalid operand"),
QSE_T("wrong position index"), QSE_T("wrong position index"),

View File

@ -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.last.c = QSE_CHAR_EOF;
awk->sio.arg.line = 1; awk->sio.arg.line = 1;
awk->sio.arg.colm = 1; awk->sio.arg.colm = 1;
awk->sio.arg.pragmas = 0; awk->sio.arg.pragma_trait = 0;
awk->sio.inp = &awk->sio.arg; awk->sio.inp = &awk->sio.arg;
n = parse(awk); n = parse(awk);
@ -728,7 +728,7 @@ static int end_include (qse_awk_t* awk)
QSE_ASSERT (cur->name != QSE_NULL); QSE_ASSERT (cur->name != QSE_NULL);
/* restore the pragma values */ /* restore the pragma values */
awk->parse.pragmas = cur->pragmas; awk->parse.pragma.trait = cur->pragma_trait;
qse_awk_freemem (awk, cur); qse_awk_freemem (awk, cur);
awk->parse.depth.incl--; awk->parse.depth.incl--;
@ -835,10 +835,10 @@ static int begin_include (qse_awk_t* awk, int once)
} }
/* store the pragma value */ /* store the pragma value */
arg->pragmas = awk->parse.pragmas; arg->pragma_trait = awk->parse.pragma.trait;
/* but don't change awk->parse.pragmas. it means the included file inherits /* but don't change awk->parse.pragma.trait. it means the included file inherits
* the existing progma values. * 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 */ /* 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) 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 (get_token(awk) <= -1) return -1;
if (!MATCH(awk, TOK_IDENT)) 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); name.ptr = QSE_STR_PTR(awk->tok.name);
if (qse_strxcmp(name.ptr, name.len, QSE_T("on")) == 0) 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) 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 else
{ {
goto error_ident_on_off_expected_for_implicit; 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 else
{ {
qse_awk_seterrfmt (awk, QSE_AWK_EIDENT, &awk->ptok.loc, QSE_T("unknown @pragma identifier - %.*s"), (int)name.len, name.ptr); 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->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, /* if the name is followed by ( without spaces,
* it's considered a function call though the name * 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->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); int fnname = isfnname(awk, name);
switch (fnname) switch (fnname)

View File

@ -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 */ * the field spaces are resized */
tmp = qse_awk_rtx_reallocmem(run, run->inrec.flds, QSE_SIZEOF(*run->inrec.flds) * max); 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.flds = tmp;
run->inrec.maxflds = max; run->inrec.maxflds = max;

View File

@ -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_SIZER_DEFAULT,
QSE_HTB_HASHER_DEFAULT QSE_HTB_HASHER_DEFAULT
}; };
qse_size_t stack_limit;
rtx->awk = awk; rtx->awk = awk;
CLRERR (rtx); 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_top = 0;
rtx->stack_base = 0; rtx->stack_base = 0;
rtx->stack_limit = 0; rtx->stack_limit = stack_limit;
rtx->exit_level = EXIT_NONE; 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.maxflds = 0;
rtx->inrec.d0 = qse_awk_val_nil; 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.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_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_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_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_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.out, MMGR(rtx), 256) <= -1) goto oops_6;
if (qse_mbs_init(&rtx->formatmbs.fmt, 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); 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_awk_rtx_t**)QSE_XTN(rtx->named) = rtx;
qse_htb_setstyle (rtx->named, &style_for_named); 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)); 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.len = 4096;
rtx->format.tmp.inc = 4096 * 2; rtx->format.tmp.inc = 4096 * 2;
rtx->formatmbs.tmp.ptr = (qse_mchar_t*)qse_awk_rtx_allocmem(rtx, 4096 * QSE_SIZEOF(qse_mchar_t)); 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.len = 4096;
rtx->formatmbs.tmp.inc = 4096 * 2; rtx->formatmbs.tmp.inc = 4096 * 2;
if (rtx->awk->tree.chain_size > 0) 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)); 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)); QSE_MEMSET (rtx->pattern_range_state, 0, rtx->awk->tree.chain_size * QSE_SIZEOF(qse_byte_t));
} }
else rtx->pattern_range_state = QSE_NULL; 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; return 0;
oops_10: oops_11:
qse_awk_rtx_freemem (rtx, rtx->formatmbs.tmp.ptr); qse_awk_rtx_freemem (rtx, rtx->formatmbs.tmp.ptr);
oops_9: oops_10:
qse_awk_rtx_freemem (rtx, rtx->format.tmp.ptr); qse_awk_rtx_freemem (rtx, rtx->format.tmp.ptr);
oops_8: oops_9:
qse_htb_close (rtx->named); qse_htb_close (rtx->named);
oops_7: oops_8:
qse_mbs_fini (&rtx->formatmbs.fmt); qse_mbs_fini (&rtx->formatmbs.fmt);
oops_6: oops_7:
qse_mbs_fini (&rtx->formatmbs.out); qse_mbs_fini (&rtx->formatmbs.out);
oops_5: oops_6:
qse_str_fini (&rtx->format.fmt); qse_str_fini (&rtx->format.fmt);
oops_4: oops_5:
qse_str_fini (&rtx->format.out); qse_str_fini (&rtx->format.out);
oops_3: oops_4:
qse_str_fini (&rtx->inrec.lineg); qse_str_fini (&rtx->inrec.lineg);
oops_2: oops_3:
qse_str_fini (&rtx->inrec.linew); qse_str_fini (&rtx->inrec.linew);
oops_1: oops_2:
qse_str_fini (&rtx->inrec.line); qse_str_fini (&rtx->inrec.line);
oops_1:
qse_awk_freemem (rtx, rtx->stack);
oops_0: oops_0:
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return -1; return -1;
@ -1378,8 +1384,8 @@ static void exit_stack_frame (qse_awk_rtx_t* run)
* the 4 entries pushed in enter_stack_frame(). */ * the 4 entries pushed in enter_stack_frame(). */
QSE_ASSERT ((run->stack_top-run->stack_base) == 4); QSE_ASSERT ((run->stack_top-run->stack_base) == 4);
run->stack_top = (qse_size_t)run->stack[run->stack_base+1]; 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_base = (qse_size_t)run->stack[run->stack_base + 0];
} }
static qse_awk_val_t* run_bpae_loop (qse_awk_rtx_t* rtx) 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); qse_awk_rtx_refupval (rtx, v1);
if (qse_awk_rtx_valtobool (rtx, v1)) if (qse_awk_rtx_valtobool(rtx, v1))
{ {
rtx->active_block = blk; rtx->active_block = blk;
if (run_block (rtx, blk) == -1) 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; if (v1 == QSE_NULL) return -1;
qse_awk_rtx_refupval (rtx, v1); qse_awk_rtx_refupval (rtx, v1);
if (qse_awk_rtx_valtobool (rtx, v1)) if (qse_awk_rtx_valtobool(rtx, v1))
{ {
rtx->active_block = blk; rtx->active_block = blk;
if (run_block (rtx, blk) == -1) 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; rtx->active_block = blk;
if (run_block (rtx, blk) == -1) if (run_block (rtx, blk) == -1)
{ {
qse_awk_rtx_refdownval (rtx, v2); qse_awk_rtx_refdownval(rtx, v2);
return -1; return -1;
} }
@ -1814,7 +1820,7 @@ static int run_block (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde)
} }
rtx->depth.block++; rtx->depth.block++;
n = run_block0 (rtx, nde); n = run_block0(rtx, nde);
rtx->depth.block--; rtx->depth.block--;
return n; 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*/ /* blockless pattern - execute print $0*/
qse_awk_rtx_refupval (rtx, rtx->inrec.d0); qse_awk_rtx_refupval (rtx, rtx->inrec.d0);
n = qse_awk_rtx_writeiostr (rtx, n = qse_awk_rtx_writeiostr(rtx, QSE_AWK_OUT_CONSOLE, QSE_T(""), QSE_STR_PTR(&rtx->inrec.line), QSE_STR_LEN(&rtx->inrec.line));
QSE_AWK_OUT_CONSOLE, QSE_T(""), if (n <= -1)
QSE_STR_PTR(&rtx->inrec.line),
QSE_STR_LEN(&rtx->inrec.line));
if (n == -1)
{ {
qse_awk_rtx_refdownval (rtx, rtx->inrec.d0); qse_awk_rtx_refdownval (rtx, rtx->inrec.d0);
ADJERR_LOC (rtx, &nde->loc); ADJERR_LOC (rtx, &nde->loc);
return -1; return -1;
} }
n = qse_awk_rtx_writeiostr ( n = qse_awk_rtx_writeiostr(rtx, QSE_AWK_OUT_CONSOLE, QSE_T(""), rtx->gbl.ors.ptr, rtx->gbl.ors.len);
rtx, QSE_AWK_OUT_CONSOLE, QSE_T(""), if (n <= -1)
rtx->gbl.ors.ptr, rtx->gbl.ors.len);
if (n == -1)
{ {
qse_awk_rtx_refdownval (rtx, rtx->inrec.d0); qse_awk_rtx_refdownval (rtx, rtx->inrec.d0);
ADJERR_LOC (rtx, &nde->loc); 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) while (nlcls > 0)
{ {
--nlcls; --nlcls;
if (__raw_push(rtx,qse_awk_val_nil) == -1) if (__raw_push(rtx,qse_awk_val_nil) <= -1)
{ {
/* restore stack top */ /* restore stack top */
rtx->stack_top = saved_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) while (p != QSE_NULL && rtx->exit_level == EXIT_NONE)
{ {
if (run_statement (rtx, p) == -1) if (run_statement(rtx, p) <= -1)
{ {
n = -1; n = -1;
break; 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; if (test == QSE_NULL) return -1;
qse_awk_rtx_refupval (rtx, test); 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?*/ 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); ON_STATEMENT (rtx, nde->test);
test = eval_expression (rtx, nde->test); test = eval_expression(rtx, nde->test);
if (test == QSE_NULL) return -1; if (!test) return -1;
qse_awk_rtx_refupval (rtx, test); 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); qse_awk_rtx_refdownval (rtx, test);
return -1; return -1;
@ -2097,7 +2098,7 @@ static int run_while (qse_awk_rtx_t* rtx, qse_awk_nde_while_t* nde)
do 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) if (rtx->exit_level == EXIT_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); ON_STATEMENT (rtx, nde->test);
test = eval_expression (rtx, nde->test); test = eval_expression(rtx, nde->test);
if (test == QSE_NULL) return -1; if (!test) return -1;
qse_awk_rtx_refupval (rtx, test); 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); qse_awk_rtx_refdownval (rtx, test);
break; 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; if (test == QSE_NULL) return -1;
qse_awk_rtx_refupval (rtx, test); 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)
{ {
@ -3915,7 +3916,7 @@ static qse_awk_val_t* eval_binop_lor (
if (lv == QSE_NULL) return QSE_NULL; if (lv == QSE_NULL) return QSE_NULL;
qse_awk_rtx_refupval (run, lv); 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; 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; if (lv == QSE_NULL) return QSE_NULL;
qse_awk_rtx_refupval (run, lv); 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; 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_awk_rtx_refupval (run, tv);
QSE_ASSERT (cnd->left->next == QSE_NULL && cnd->right->next == QSE_NULL); 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); qse_awk_rtx_refdownval (run, tv);
return v; 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 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; qse_awk_nde_t* p = call->args;
for (i = 0; i < nargs; i++) 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_t** ref;
qse_awk_val_ref_t refv; qse_awk_val_ref_t refv;
/* UGLY */ /* if an argument passed is a local variable or a parameter to the previous caller,
rtx->stack_base = prev_stack_base; * 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 */ get_reference (rtx, p, &ref); /* no failure check as it must succeed here for the check done above */
rtx->stack_base = cur_stack_base; rtx->stack_base = cur_stack_base; /* UGLY */
/* 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_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)); 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); qse_awk_rtx_refdownval_nofree (rtx, v);
} }
rtx->stack_top = (qse_size_t)rtx->stack[rtx->stack_base+1]; 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_base = (qse_size_t)rtx->stack[rtx->stack_base + 0];
if (rtx->exit_level == EXIT_FUNCTION) rtx->exit_level = EXIT_NONE; 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) if (rtx->stack_top >= rtx->stack_limit)
{ {
/*
void** tmp; void** tmp;
qse_size_t n; qse_size_t n;
@ -6798,6 +6804,9 @@ static int __raw_push (qse_awk_rtx_t* rtx, void* val)
rtx->stack = tmp; rtx->stack = tmp;
rtx->stack_limit = n; 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; rtx->stack[rtx->stack_top++] = val;

View File

@ -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; prm.modsym = qse_awk_stdmodsym;
/* create an object */ /* create an object */
awk = qse_awk_open (mmgr, QSE_SIZEOF(xtn_t) + xtnsize, &prm, errnum); awk = qse_awk_open(mmgr, QSE_SIZEOF(xtn_t) + xtnsize, &prm, errnum);
if (awk == QSE_NULL) return QSE_NULL; if (!awk) return QSE_NULL;
#if defined(USE_DLFCN) #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));*/ * QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn));*/
/* add intrinsic global variables and functions */ /* 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); if (errnum) *errnum = qse_awk_geterrnum(awk);
goto oops; goto oops;
} }
if (qse_awk_stdmodstartup (awk) <= -1) if (qse_awk_stdmodstartup(awk) <= -1)
{ {
xtn->stdmod_up = 0; xtn->stdmod_up = 0;
/* carry on regardless of failure */ /* carry on regardless of failure */

View File

@ -578,7 +578,6 @@ static int fnc_autocommit (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
int v; int v;
v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); 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); 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; int v;
v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); 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); 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; int v;
v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); 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); ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node);