added qse_awk_rtx_ecb_gblset_t.

fixed a bug of returning an error when it must not in get_reference() in awk/run.c
This commit is contained in:
hyung-hwan 2013-04-15 13:18:03 +00:00
parent d6208e893e
commit d5cca9d524
3 changed files with 132 additions and 117 deletions

View File

@ -972,7 +972,8 @@ static int awk_main (int argc, qse_char_t* argv[])
static qse_awk_rtx_ecb_t rtx_ecb = static qse_awk_rtx_ecb_t rtx_ecb =
{ {
QSE_FV(.close, QSE_NULL), QSE_FV(.close, QSE_NULL),
QSE_FV(.stmt, on_statement) QSE_FV(.stmt, on_statement),
QSE_FV(.gblset, QSE_NULL)
}; };
#endif #endif

View File

@ -947,6 +947,16 @@ typedef void (*qse_awk_rtx_ecb_stmt_t) (
qse_awk_nde_t* nde /**< node */ qse_awk_nde_t* nde /**< node */
); );
/**
* The qse_awk_rtx_ecb_gblset_t type defines the callback function
* executed when a global variable is set with a value.
*/
typedef void (*qse_awk_rtx_ecb_gblset_t) (
qse_awk_rtx_t* rtx, /**< runtime context */
qse_size_t idx, /**< global variable index */
qse_awk_val_t* val /**< value */
);
/** /**
* The qse_awk_rtx_ecb_t type defines an event callback set for a * The qse_awk_rtx_ecb_t type defines an event callback set for a
* runtime context. You can register a callback function set with * runtime context. You can register a callback function set with
@ -967,6 +977,11 @@ struct qse_awk_rtx_ecb_t
*/ */
qse_awk_rtx_ecb_stmt_t stmt; qse_awk_rtx_ecb_stmt_t stmt;
/**
* called when a global variable is set with a value.
*/
qse_awk_rtx_ecb_gblset_t gblset;
/* internal use only. don't touch this field */ /* internal use only. don't touch this field */
qse_awk_rtx_ecb_t* next; qse_awk_rtx_ecb_t* next;
}; };

View File

@ -312,6 +312,7 @@ static int set_global (
qse_awk_nde_var_t* var, qse_awk_val_t* val) qse_awk_nde_var_t* var, qse_awk_val_t* val)
{ {
qse_awk_val_t* old; qse_awk_val_t* old;
qse_awk_rtx_ecb_t* ecb;
old = STACK_GBL (rtx, idx); old = STACK_GBL (rtx, idx);
if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP) && old->type == QSE_AWK_VAL_MAP) if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP) && old->type == QSE_AWK_VAL_MAP)
@ -331,7 +332,7 @@ static int set_global (
} }
else else
{ {
/* qse_awk_rtx_setgbl has been called */ /* qse_awk_rtx_setgbl() has been called */
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = qse_awk_getgblname (rtx->awk, idx, &ea.len); ea.ptr = qse_awk_getgblname (rtx->awk, idx, &ea.len);
SETERR_ARGX (rtx, QSE_AWK_EMAPNRA, &ea); SETERR_ARGX (rtx, QSE_AWK_EMAPNRA, &ea);
@ -468,8 +469,7 @@ static int set_global (
if (shorten_record (rtx, (qse_size_t)lv) == -1) if (shorten_record (rtx, (qse_size_t)lv) == -1)
{ {
/* adjust the error line */ /* adjust the error line */
if (var != QSE_NULL) if (var) ADJERR_LOC (rtx, &var->loc);
ADJERR_LOC (rtx, &var->loc);
return -1; return -1;
} }
} }
@ -621,6 +621,9 @@ static int set_global (
STACK_GBL(rtx,idx) = val; STACK_GBL(rtx,idx) = val;
qse_awk_rtx_refupval (rtx, val); qse_awk_rtx_refupval (rtx, val);
for (ecb = (rtx)->ecb; ecb; ecb = ecb->next)
if (ecb->gblset) ecb->gblset (rtx, idx, val);
return 0; return 0;
} }
@ -5956,7 +5959,9 @@ static int get_reference (
/* refer to eval_indexed for application of a similar concept */ /* refer to eval_indexed for application of a similar concept */
if (nde->type == QSE_AWK_NDE_NAMED) switch (nde->type)
{
case QSE_AWK_NDE_NAMED:
{ {
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
@ -5981,25 +5986,19 @@ static int get_reference (
return 0; return 0;
} }
if (nde->type == QSE_AWK_NDE_GBL) case QSE_AWK_NDE_GBL:
{
*ref = (qse_awk_val_t**)&STACK_GBL(run,tgt->id.idxa); *ref = (qse_awk_val_t**)&STACK_GBL(run,tgt->id.idxa);
return 0; return 0;
}
if (nde->type == QSE_AWK_NDE_LCL) case QSE_AWK_NDE_LCL:
{
*ref = (qse_awk_val_t**)&STACK_LCL(run,tgt->id.idxa); *ref = (qse_awk_val_t**)&STACK_LCL(run,tgt->id.idxa);
return 0; return 0;
}
if (nde->type == QSE_AWK_NDE_ARG) case QSE_AWK_NDE_ARG:
{
*ref = (qse_awk_val_t**)&STACK_ARG(run,tgt->id.idxa); *ref = (qse_awk_val_t**)&STACK_ARG(run,tgt->id.idxa);
return 0; return 0;
}
if (nde->type == QSE_AWK_NDE_NAMEDIDX) case QSE_AWK_NDE_NAMEDIDX:
{ {
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
@ -6021,33 +6020,31 @@ static int get_reference (
run, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair)); run, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0;
} }
if (nde->type == QSE_AWK_NDE_GBLIDX) case QSE_AWK_NDE_GBLIDX:
{
tmp = get_reference_indexed (run, tgt, tmp = get_reference_indexed (run, tgt,
(qse_awk_val_t**)&STACK_GBL(run,tgt->id.idxa)); (qse_awk_val_t**)&STACK_GBL(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
} return 0;
if (nde->type == QSE_AWK_NDE_LCLIDX) case QSE_AWK_NDE_LCLIDX:
{
tmp = get_reference_indexed (run, tgt, tmp = get_reference_indexed (run, tgt,
(qse_awk_val_t**)&STACK_LCL(run,tgt->id.idxa)); (qse_awk_val_t**)&STACK_LCL(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
} return 0;
if (nde->type == QSE_AWK_NDE_ARGIDX) case QSE_AWK_NDE_ARGIDX:
{
tmp = get_reference_indexed (run, tgt, tmp = get_reference_indexed (run, tgt,
(qse_awk_val_t**)&STACK_ARG(run,tgt->id.idxa)); (qse_awk_val_t**)&STACK_ARG(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
} return 0;
if (nde->type == QSE_AWK_NDE_POS) case QSE_AWK_NDE_POS:
{ {
int n; int n;
qse_long_t lv; qse_long_t lv;
@ -6078,9 +6075,11 @@ static int get_reference (
return 0; return 0;
} }
default:
SETERR_LOC (run, QSE_AWK_ENOTREF, &nde->loc); SETERR_LOC (run, QSE_AWK_ENOTREF, &nde->loc);
return -1; return -1;
} }
}
static qse_awk_val_t** get_reference_indexed ( static qse_awk_val_t** get_reference_indexed (
qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val) qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val)