enhanced qse_awk_rtx_setrefval() to handle references properly

enhanced qse_awk_rtx_valtostr() and qse_awk_rtx_valtonum() to handle references more correctly.
changed some awk error codes.
This commit is contained in:
hyung-hwan 2013-04-16 10:09:24 +00:00
parent d5cca9d524
commit 23d316a659
11 changed files with 550 additions and 468 deletions

View File

@ -250,7 +250,7 @@ static qse_htb_walk_t print_awk_value (
str = qse_awk_rtx_valtostrdup (rtx, QSE_HTB_VPTR(pair), &len); str = qse_awk_rtx_valtostrdup (rtx, QSE_HTB_VPTR(pair), &len);
if (str == QSE_NULL) if (str == QSE_NULL)
{ {
if (qse_awk_rtx_geterrnum(rtx) == QSE_AWK_EVALTYPE) if (qse_awk_rtx_geterrnum(rtx) == QSE_AWK_EVALTOSTR)
{ {
dprint (QSE_T("%.*s = [not printable]\n"), dprint (QSE_T("%.*s = [not printable]\n"),
(int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair)); (int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair));

View File

@ -949,7 +949,9 @@ typedef void (*qse_awk_rtx_ecb_stmt_t) (
/** /**
* The qse_awk_rtx_ecb_gblset_t type defines the callback function * The qse_awk_rtx_ecb_gblset_t type defines the callback function
* executed when a global variable is set with a value. * executed when a global variable is set with a value. It is not
* called when a global variable is changed implicitly. For example,
* it is not called when FNR is updated for each record read.
*/ */
typedef void (*qse_awk_rtx_ecb_gblset_t) ( typedef void (*qse_awk_rtx_ecb_gblset_t) (
qse_awk_rtx_t* rtx, /**< runtime context */ qse_awk_rtx_t* rtx, /**< runtime context */
@ -1239,9 +1241,12 @@ enum qse_awk_errnum_t
QSE_AWK_EMAPNA, /**< map cannot be assigned to variable */ QSE_AWK_EMAPNA, /**< map cannot be assigned to variable */
QSE_AWK_EMAPNRA, /**< map '${0}' cannot be reassigned */ QSE_AWK_EMAPNRA, /**< map '${0}' cannot be reassigned */
QSE_AWK_EMAPUR, /**< map unreturnable */ QSE_AWK_EMAPUR, /**< map unreturnable */
QSE_AWK_EMAPPH, /**< map prohibited */ QSE_AWK_EMAPTOSCALAR, /**< cannot change a map to a scalar value */
QSE_AWK_ESCALARTOMAP, /**< cannot change a scalar value to a map */ QSE_AWK_ESCALARTOMAP, /**< cannot change a scalar value to a map */
QSE_AWK_EVALTYPE, /**< invalid value type */ QSE_AWK_EVALTOSTR, /**< invalid value to convert to a string */
QSE_AWK_EVALTONUM, /**< invalid value to convert to a number */
QSE_AWK_EVALTOCHR, /**< invalid value to convert to a character */
QSE_AWK_EHASHVAL, /**< invalid value to hash */
QSE_AWK_ERNEXTBEG, /**< 'next' called from BEGIN block */ QSE_AWK_ERNEXTBEG, /**< 'next' called from BEGIN block */
QSE_AWK_ERNEXTEND, /**< 'next' called from END block */ QSE_AWK_ERNEXTEND, /**< 'next' called from END block */
QSE_AWK_ERNEXTFBEG, /**< 'nextfile' called from BEGIN block */ QSE_AWK_ERNEXTFBEG, /**< 'nextfile' called from BEGIN block */

View File

@ -241,6 +241,14 @@ struct qse_awk_chain_t
qse_awk_chain_t* next; qse_awk_chain_t* next;
}; };
#define RTX_STACK_AT(rtx,n) ((rtx)->stack[(rtx)->stack_base+(n)])
#define RTX_STACK_NARGS(rtx) (RTX_STACK_AT(rtx,3))
#define RTX_STACK_ARG(rtx,n) RTX_STACK_AT(rtx,3+1+(n))
#define RTX_STACK_LCL(rtx,n) RTX_STACK_AT(rtx,3+(qse_size_t)RTX_STACK_NARGS(rtx)+1+(n))
#define RTX_STACK_RETVAL(rtx) RTX_STACK_AT(rtx,2)
#define RTX_STACK_GBL(rtx,n) ((rtx)->stack[(n)])
#define RTX_STACK_RETVAL_GBL(rtx) ((rtx)->stack[(rtx)->awk->tree.ngbls+2])
struct qse_awk_rtx_t struct qse_awk_rtx_t
{ {
int id; int id;

View File

@ -118,14 +118,17 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
QSE_T("right-hand side of the 'in' operator not a map"), QSE_T("right-hand side of the 'in' operator not a map"),
QSE_T("right-hand side of the 'in' operator not a map nor nil"), QSE_T("right-hand side of the 'in' operator not a map nor nil"),
QSE_T("value not referenceable"), QSE_T("value not referenceable"),
QSE_T("indexed value cannot be a map"), QSE_T("indexed variable cannot be assigned a map"),
QSE_T("positional value cannot be a map"), QSE_T("positional cannot be assigned a map"),
QSE_T("map cannot be assigned to variable"), QSE_T("map cannot be assigned to variable"),
QSE_T("map '${0}' cannot be reassigned"), QSE_T("map '${0}' cannot be reassigned"),
QSE_T("map cannot be returned"), QSE_T("map cannot be returned"),
QSE_T("map prohibited"), QSE_T("cannot change a map to a scalar value"),
QSE_T("cannot change a scalar value to a map"), QSE_T("cannot change a scalar value to a map"),
QSE_T("invalid value type"), QSE_T("invalid value to convert to a string"),
QSE_T("invalid value to convert to a number"),
QSE_T("invalid value to a character"),
QSE_T("invalid value for hashing"),
QSE_T("'next' called from BEGIN block"), QSE_T("'next' called from BEGIN block"),
QSE_T("'next' called from END block"), QSE_T("'next' called from END block"),
QSE_T("'nextfile' called from BEGIN block"), QSE_T("'nextfile' called from BEGIN block"),

View File

@ -627,7 +627,7 @@ static int fnc_substr (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi) static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
{ {
qse_size_t nargs; qse_size_t nargs;
qse_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1_ref; qse_awk_val_t* a0, * a1, * a2, * t1, * t2;
qse_cstr_t str, fs; qse_cstr_t str, fs;
qse_char_t* str_free = QSE_NULL, * fs_free = QSE_NULL; qse_char_t* str_free = QSE_NULL, * fs_free = QSE_NULL;
@ -640,6 +640,7 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
qse_long_t nflds; qse_long_t nflds;
qse_awk_errnum_t errnum; qse_awk_errnum_t errnum;
int x;
nargs = qse_awk_rtx_getnargs (run); nargs = qse_awk_rtx_getnargs (run);
QSE_ASSERT (nargs >= 2 && nargs <= 3); QSE_ASSERT (nargs >= 2 && nargs <= 3);
@ -650,33 +651,6 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
QSE_ASSERT (a1->type == QSE_AWK_VAL_REF); QSE_ASSERT (a1->type == QSE_AWK_VAL_REF);
if (((qse_awk_val_ref_t*)a1)->id >= QSE_AWK_VAL_REF_NAMEDIDX &&
((qse_awk_val_ref_t*)a1)->id <= QSE_AWK_VAL_REF_ARGIDX)
{
/* an indexed value should not be assigned another map */
qse_awk_rtx_seterrnum (run, QSE_AWK_EIDXVALMAP, QSE_NULL);
return -1;
}
if (((qse_awk_val_ref_t*)a1)->id == QSE_AWK_VAL_REF_POS)
{
/* a positional should not be assigned a map */
qse_awk_rtx_seterrnum (run, QSE_AWK_EPOSVALMAP, QSE_NULL);
return -1;
}
a1_ref = (qse_awk_val_t**)((qse_awk_val_ref_t*)a1)->adr;
if ((*a1_ref)->type != QSE_AWK_VAL_NIL &&
(*a1_ref)->type != QSE_AWK_VAL_MAP)
{
if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP))
{
/* cannot change a scalar value to a map */
qse_awk_rtx_seterrnum (run, QSE_AWK_ESCALARTOMAP, QSE_NULL);
return -1;
}
}
if (a0->type == QSE_AWK_VAL_STR) if (a0->type == QSE_AWK_VAL_STR)
{ {
str.ptr = ((qse_awk_val_str_t*)a0)->val.ptr; str.ptr = ((qse_awk_val_str_t*)a0)->val.ptr;
@ -752,14 +726,12 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
t1 = qse_awk_rtx_makemapval (run); t1 = qse_awk_rtx_makemapval (run);
if (t1 == QSE_NULL) goto oops; if (t1 == QSE_NULL) goto oops;
/* use the following 3 lines intead of qse_awk_rtx_refupval (run, t1);
* qse_awk_rtx_setrefval (run, a1, t1); x = qse_awk_rtx_setrefval (run, a1, t1);
* just for less overhead. qse_awk_rtx_refdownval (run, t1);
*/ if (x <= -1) goto oops;
qse_awk_rtx_refdownval (run, *a1_ref);
*a1_ref = t1;
qse_awk_rtx_refupval (run, *a1_ref);
/* fill the map with actual values */
p = str.ptr; str_left = str.len; org_len = str.len; p = str.ptr; str_left = str.len; org_len = str.len;
nflds = 0; nflds = 0;
@ -907,6 +879,7 @@ static int fnc_toupper (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
return 0; return 0;
} }
static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count) static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
{ {
qse_size_t nargs; qse_size_t nargs;
@ -972,54 +945,11 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
s2.ptr = QSE_STR_PTR(&run->inrec.line); s2.ptr = QSE_STR_PTR(&run->inrec.line);
s2.len = QSE_STR_LEN(&run->inrec.line); s2.len = QSE_STR_LEN(&run->inrec.line);
} }
else if (((qse_awk_val_ref_t*)a2)->id == QSE_AWK_VAL_REF_POS)
{
qse_size_t idx;
idx = (qse_size_t)((qse_awk_val_ref_t*)a2)->adr;
if (idx == 0)
{
s2.ptr = QSE_STR_PTR(&run->inrec.line);
s2.len = QSE_STR_LEN(&run->inrec.line);
}
else if (idx <= run->inrec.nflds)
{
s2.ptr = run->inrec.flds[idx-1].ptr;
s2.len = run->inrec.flds[idx-1].len;
}
else
{
s2.ptr = QSE_T("");
s2.len = 0;
}
}
else else
{ {
a2_ref = (qse_awk_val_t**)((qse_awk_val_ref_t*)a2)->adr; s2.ptr = qse_awk_rtx_valtostrdup (run, a2, &s2.len);
if (s2.ptr == QSE_NULL) goto oops;
if ((*a2_ref)->type == QSE_AWK_VAL_MAP) s2_free = (qse_char_t*)s2.ptr;
{
/* a map is not allowed as the third parameter.
* this is a prohibited condition regardless of QSE_AWK_FLEXMAP.
* i don't accept this.
*
* TODO: can i extend to replace something in a map???
*/
qse_awk_rtx_seterrnum (run, QSE_AWK_EMAPPH, QSE_NULL);
goto oops;
}
if ((*a2_ref)->type == QSE_AWK_VAL_STR)
{
s2.ptr = ((qse_awk_val_str_t*)(*a2_ref))->val.ptr;
s2.len = ((qse_awk_val_str_t*)(*a2_ref))->val.len;
}
else
{
s2.ptr = qse_awk_rtx_valtostrdup (run, *a2_ref, &s2.len);
if (s2.ptr == QSE_NULL) goto oops;
s2_free = (qse_char_t*)s2.ptr;
}
} }
if (qse_str_init (&new, run->awk->mmgr, s2.len) <= -1) if (qse_str_init (&new, run->awk->mmgr, s2.len) <= -1)
@ -1165,24 +1095,16 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
n = qse_awk_rtx_setrec (run, 0, QSE_STR_CSTR(&new)); n = qse_awk_rtx_setrec (run, 0, QSE_STR_CSTR(&new));
if (n <= -1) goto oops; if (n <= -1) goto oops;
} }
else if (((qse_awk_val_ref_t*)a2)->id == QSE_AWK_VAL_REF_POS) else
{ {
int n; int n;
n = qse_awk_rtx_setrec (
run, (qse_size_t)((qse_awk_val_ref_t*)a2)->adr,
QSE_STR_CSTR(&new));
if (n <= -1) goto oops;
}
else
{
v = qse_awk_rtx_makestrvalwithcstr (run, QSE_STR_CSTR(&new)); v = qse_awk_rtx_makestrvalwithcstr (run, QSE_STR_CSTR(&new));
if (v == QSE_NULL) goto oops; if (v == QSE_NULL) goto oops;
qse_awk_rtx_refupval (run, v);
qse_awk_rtx_refdownval (run, *a2_ref); n = qse_awk_rtx_setrefval (run, a2, v);
*a2_ref = v; qse_awk_rtx_refdownval (run, v);
qse_awk_rtx_refupval (run, *a2_ref); if (n <= -1) goto oops;
} }
} }

View File

@ -275,21 +275,28 @@ static int read_byid (qse_awk_rtx_t* rtx, dir_list_t* list, qse_long_t id, qse_a
return -1; return -1;
} }
if (y == 0) return 0; if (y == 0) return 0; /* no more entry */
tmp = qse_awk_rtx_makestrvalwithstr (rtx, ent.name); tmp = qse_awk_rtx_makestrvalwithstr (rtx, ent.name);
if (!tmp || qse_awk_rtx_setrefval (rtx, ref, tmp) <= -1) if (!tmp)
{ {
list->errnum = awk_err_to_errnum (qse_awk_rtx_geterrnum (rtx)); list->errnum = awk_err_to_errnum (qse_awk_rtx_geterrnum (rtx));
if (tmp)
{
qse_awk_rtx_refupval (rtx, tmp);
qse_awk_rtx_refdownval (rtx, tmp);
}
return -1; return -1;
} }
else
{
int n;
qse_awk_rtx_refupval (rtx, tmp);
n = qse_awk_rtx_setrefval (rtx, ref, tmp);
qse_awk_rtx_refdownval (rtx, tmp);
if (n <= -1)
{
list->errnum = awk_err_to_errnum (qse_awk_rtx_geterrnum (rtx));
return -1;
}
}
return 0; return 1; /* has entry */
} }
else else
{ {

View File

@ -567,12 +567,11 @@ static int fnc_getnwifcfg (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
tmp = qse_awk_rtx_makemapvalwithdata (rtx, md); tmp = qse_awk_rtx_makemapvalwithdata (rtx, md);
if (tmp) if (tmp)
{ {
if (qse_awk_rtx_setrefval (rtx, qse_awk_rtx_getarg (rtx, 2), tmp) <= -1) int x;
{ qse_awk_rtx_refupval (rtx, tmp);
qse_awk_rtx_refupval (rtx, tmp); x = qse_awk_rtx_setrefval (rtx, qse_awk_rtx_getarg (rtx, 2), tmp);
qse_awk_rtx_refdownval (rtx, tmp); qse_awk_rtx_refdownval (rtx, tmp);
} if (x >= 0) ret = 0;
else ret = 0;
} }
} }
} }

View File

@ -471,12 +471,11 @@ static int getsection_byid (
tmp = qse_awk_rtx_makemapvalwithdata (rtx, md); tmp = qse_awk_rtx_makemapvalwithdata (rtx, md);
if (tmp) if (tmp)
{ {
if (qse_awk_rtx_setrefval (rtx, ref, tmp) <= -1) int n;
{ qse_awk_rtx_refupval (rtx, tmp);
qse_awk_rtx_refupval (rtx, tmp); n = qse_awk_rtx_setrefval (rtx, ref, tmp);
qse_awk_rtx_refdownval (rtx, tmp); qse_awk_rtx_refdownval (rtx, tmp);
x = UCI_ERR_MEM; if (n <= -1) x = UCI_ERR_MEM; /* this is not a correct error code. who cares? */
}
} }
else x = UCI_ERR_MEM; else x = UCI_ERR_MEM;
} }
@ -534,10 +533,12 @@ static int getoption_byid (
map = qse_awk_rtx_makemapvalwithdata (rtx, md); map = qse_awk_rtx_makemapvalwithdata (rtx, md);
if (map) if (map)
{ {
if (qse_awk_rtx_setrefval (rtx, ref, map) <= -1) int n;
qse_awk_rtx_refupval (rtx, map);
n = qse_awk_rtx_setrefval (rtx, ref, map);
qse_awk_rtx_refdownval (rtx, map);
if (n <= -1)
{ {
qse_awk_rtx_refupval (rtx, map);
qse_awk_rtx_refdownval (rtx, map);
map = QSE_NULL; map = QSE_NULL;
x = UCI_ERR_MEM; x = UCI_ERR_MEM;
} }

View File

@ -29,20 +29,12 @@
#define CMP_ERROR -99 #define CMP_ERROR -99
#define DEF_BUF_CAPA 256 #define DEF_BUF_CAPA 256
#define STACK_INCREMENT 512 #define RTX_STACK_INCREMENT 512
#define IDXBUFSIZE 64 #define IDXBUFSIZE 64
#define MMGR(rtx) ((rtx)->awk->mmgr) #define MMGR(rtx) ((rtx)->awk->mmgr)
#define STACK_AT(rtx,n) ((rtx)->stack[(rtx)->stack_base+(n)])
#define STACK_NARGS(rtx) (STACK_AT(rtx,3))
#define STACK_ARG(rtx,n) STACK_AT(rtx,3+1+(n))
#define STACK_LCL(rtx,n) STACK_AT(rtx,3+(qse_size_t)STACK_NARGS(rtx)+1+(n))
#define STACK_RETVAL(rtx) STACK_AT(rtx,2)
#define STACK_GBL(rtx,n) ((rtx)->stack[(n)])
#define STACK_RETVAL_GBL(rtx) ((rtx)->stack[(rtx)->awk->tree.ngbls+2])
enum exit_level_t enum exit_level_t
{ {
EXIT_NONE, EXIT_NONE,
@ -285,18 +277,18 @@ static QSE_INLINE qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr)
QSE_INLINE qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run) QSE_INLINE qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run)
{ {
return (qse_size_t) STACK_NARGS (run); return (qse_size_t) RTX_STACK_NARGS (run);
} }
QSE_INLINE qse_awk_val_t* qse_awk_rtx_getarg (qse_awk_rtx_t* run, qse_size_t idx) QSE_INLINE qse_awk_val_t* qse_awk_rtx_getarg (qse_awk_rtx_t* run, qse_size_t idx)
{ {
return STACK_ARG (run, idx); return RTX_STACK_ARG (run, idx);
} }
QSE_INLINE qse_awk_val_t* qse_awk_rtx_getgbl (qse_awk_rtx_t* run, int id) QSE_INLINE qse_awk_val_t* qse_awk_rtx_getgbl (qse_awk_rtx_t* run, int id)
{ {
QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(run->awk->parse.gbls)); QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(run->awk->parse.gbls));
return STACK_GBL (run, id); return RTX_STACK_GBL (run, id);
} }
const qse_xstr_t* qse_awk_rtx_getsubsep (qse_awk_rtx_t* run) const qse_xstr_t* qse_awk_rtx_getsubsep (qse_awk_rtx_t* run)
@ -308,49 +300,70 @@ const qse_xstr_t* qse_awk_rtx_getsubsep (qse_awk_rtx_t* run)
* this function can handle a few special global variables that * this function can handle a few special global variables that
* require special treatment. */ * require special treatment. */
static int set_global ( static int set_global (
qse_awk_rtx_t* rtx, qse_size_t idx, qse_awk_rtx_t* rtx, int idx,
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; qse_awk_rtx_ecb_t* ecb;
old = STACK_GBL (rtx, idx); old = RTX_STACK_GBL (rtx, idx);
if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP) && old->type == QSE_AWK_VAL_MAP) if (old == val) return 0; /* the old value is the same as the new value. nothing to do */
{
/* once a variable becomes a map, if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP))
* it cannot be assigned with another value. {
* you can only add a member using indexing. */ qse_awk_errnum_t errnum = QSE_AWK_ENOERR;
if (var)
if (old->type == QSE_AWK_VAL_MAP && val->type != QSE_AWK_VAL_MAP)
errnum = QSE_AWK_EMAPNRA;
if (val->type == QSE_AWK_VAL_MAP)
{ {
/* global variable */ if (old->type != QSE_AWK_VAL_NIL)
SETERR_ARGX_LOC ( errnum = QSE_AWK_EMAPNA;
rtx,
QSE_AWK_EMAPNRA,
xstr_to_cstr(&var->id.name),
&var->loc
);
} }
else else
{ {
/* qse_awk_rtx_setgbl() has been called */ if (old->type == QSE_AWK_VAL_MAP) errnum = QSE_AWK_EMAPNRA;
qse_cstr_t ea;
ea.ptr = qse_awk_getgblname (rtx->awk, idx, &ea.len);
SETERR_ARGX (rtx, QSE_AWK_EMAPNRA, &ea);
} }
if (errnum != QSE_AWK_ENOERR)
{
/* once a variable becomes a map, it cannot be assigned
* others value than another map. you can only add a member
* using indexing. */
if (var)
{
/* global variable */
SETERR_ARGX_LOC (
rtx,
errnum,
xstr_to_cstr(&var->id.name),
&var->loc
);
}
else
{
/* qse_awk_rtx_setgbl() has been called */
qse_cstr_t ea;
ea.ptr = qse_awk_getgblname (rtx->awk, idx, &ea.len);
SETERR_ARGX (rtx, errnum, &ea);
}
return -1; return -1;
}
} }
/* all the basic builtin variables cannot be assigned a map. if (val->type == QSE_AWK_VAL_MAP)
* if you happen to add one and if that's allowed to be a map,
* you may have to change the condition here.
* but is this check really necessary??? */
if (val->type == QSE_AWK_VAL_MAP &&
idx >= QSE_AWK_MIN_GBL_ID && idx <= QSE_AWK_MAX_GBL_ID)
{ {
/* TODO: better error code */ if (idx >= QSE_AWK_MIN_GBL_ID && idx <= QSE_AWK_MAX_GBL_ID)
SETERR_COD (rtx, QSE_AWK_ESCALARTOMAP); {
return -1; /* short-circuit check block to prevent the basic built-in variables
* from being assigned a map. if you happen to add one and if that's
* allowed to be a map, you may have to change the condition here. */
/* TODO: use global variable attribute. can it be a map? can it be a scalar? is it read-only???? */
SETERR_COD (rtx, QSE_AWK_ESCALARTOMAP);
return -1;
}
} }
switch (idx) switch (idx)
@ -469,7 +482,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) ADJERR_LOC (rtx, &var->loc); /*if (var) ADJERR_LOC (rtx, &var->loc);*/
return -1; return -1;
} }
} }
@ -614,11 +627,10 @@ static int set_global (
break; break;
} }
} }
qse_awk_rtx_refdownval (rtx, old); qse_awk_rtx_refdownval (rtx, old);
STACK_GBL(rtx,idx) = val; RTX_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) for (ecb = (rtx)->ecb; ecb; ecb = ecb->next)
@ -630,8 +642,8 @@ static int set_global (
QSE_INLINE void qse_awk_rtx_setretval ( QSE_INLINE void qse_awk_rtx_setretval (
qse_awk_rtx_t* rtx, qse_awk_val_t* val) qse_awk_rtx_t* rtx, qse_awk_val_t* val)
{ {
qse_awk_rtx_refdownval (rtx, STACK_RETVAL(rtx)); qse_awk_rtx_refdownval (rtx, RTX_STACK_RETVAL(rtx));
STACK_RETVAL(rtx) = val; RTX_STACK_RETVAL(rtx) = val;
/* should use the same trick as run_return */ /* should use the same trick as run_return */
qse_awk_rtx_refupval (rtx, val); qse_awk_rtx_refupval (rtx, val);
} }
@ -640,7 +652,7 @@ QSE_INLINE int qse_awk_rtx_setgbl (
qse_awk_rtx_t* rtx, int id, qse_awk_val_t* val) qse_awk_rtx_t* rtx, int id, qse_awk_val_t* val)
{ {
QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(rtx->awk->parse.gbls)); QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(rtx->awk->parse.gbls));
return set_global (rtx, (qse_size_t)id, QSE_NULL, val); return set_global (rtx, id, QSE_NULL, val);
} }
int qse_awk_rtx_setfilename ( int qse_awk_rtx_setfilename (
@ -1251,7 +1263,7 @@ static int defaultify_globals (qse_awk_rtx_t* rtx)
qse_awk_rtx_refupval (rtx, tmp); qse_awk_rtx_refupval (rtx, tmp);
QSE_ASSERT (STACK_GBL(rtx,gtab[i].idx) == qse_awk_val_nil); QSE_ASSERT (RTX_STACK_GBL(rtx,gtab[i].idx) == qse_awk_val_nil);
if (qse_awk_rtx_setgbl (rtx, gtab[i].idx, tmp) == -1) if (qse_awk_rtx_setgbl (rtx, gtab[i].idx, tmp) == -1)
{ {
@ -1279,9 +1291,9 @@ static void refdown_globals (qse_awk_rtx_t* run, int pop)
while (ngbls > 0) while (ngbls > 0)
{ {
--ngbls; --ngbls;
qse_awk_rtx_refdownval (run, STACK_GBL(run,ngbls)); qse_awk_rtx_refdownval (run, RTX_STACK_GBL(run,ngbls));
if (pop) __raw_pop (run); if (pop) __raw_pop (run);
else STACK_GBL(run,ngbls) = qse_awk_val_nil; else RTX_STACK_GBL(run,ngbls) = qse_awk_val_nil;
} }
} }
@ -1312,7 +1324,7 @@ static void capture_retval_on_exit (void* arg)
struct capture_retval_data_t* data; struct capture_retval_data_t* data;
data = (struct capture_retval_data_t*)arg; data = (struct capture_retval_data_t*)arg;
data->val = STACK_RETVAL(data->rtx); data->val = RTX_STACK_RETVAL(data->rtx);
qse_awk_rtx_refupval (data->rtx, data->val); qse_awk_rtx_refupval (data->rtx, data->val);
} }
@ -1332,7 +1344,7 @@ static int enter_stack_frame (qse_awk_rtx_t* rtx)
/* secure space for a return value */ /* secure space for a return value */
if (__raw_push(rtx,qse_awk_val_nil) == -1) goto oops; if (__raw_push(rtx,qse_awk_val_nil) == -1) goto oops;
/* secure space for STACK_NARGS */ /* secure space for RTX_STACK_NARGS */
if (__raw_push(rtx,qse_awk_val_nil) == -1) goto oops; if (__raw_push(rtx,qse_awk_val_nil) == -1) goto oops;
/* let the stack top remembered be the base of a new stack frame */ /* let the stack top remembered be the base of a new stack frame */
@ -1367,7 +1379,7 @@ static qse_awk_val_t* run_bpae_loop (qse_awk_rtx_t* rtx)
/* set nargs to zero */ /* set nargs to zero */
nargs = 0; nargs = 0;
STACK_NARGS(rtx) = (void*)nargs; RTX_STACK_NARGS(rtx) = (void*)nargs;
/* execute the BEGIN block */ /* execute the BEGIN block */
for (nde = rtx->awk->tree.begin; for (nde = rtx->awk->tree.begin;
@ -1448,13 +1460,13 @@ static qse_awk_val_t* run_bpae_loop (qse_awk_rtx_t* rtx)
/* derefrence all arguments. however, there should be no arguments /* derefrence all arguments. however, there should be no arguments
* pushed to the stack as asserted below. we didn't push any arguments * pushed to the stack as asserted below. we didn't push any arguments
* for BEGIN/pattern action/END block execution.*/ * for BEGIN/pattern action/END block execution.*/
nargs = (qse_size_t)STACK_NARGS(rtx); nargs = (qse_size_t)RTX_STACK_NARGS(rtx);
QSE_ASSERT (nargs == 0); QSE_ASSERT (nargs == 0);
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
qse_awk_rtx_refdownval (rtx, STACK_ARG(rtx,i)); qse_awk_rtx_refdownval (rtx, RTX_STACK_ARG(rtx,i));
/* get the return value in the current stack frame */ /* get the return value in the current stack frame */
retv = STACK_RETVAL(rtx); retv = RTX_STACK_RETVAL(rtx);
if (ret <= -1) if (ret <= -1)
{ {
@ -1888,7 +1900,7 @@ static int run_block0 (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde)
while (nlcls > 0) while (nlcls > 0)
{ {
--nlcls; --nlcls;
qse_awk_rtx_refdownval (rtx, STACK_LCL(rtx,nlcls)); qse_awk_rtx_refdownval (rtx, RTX_STACK_LCL(rtx,nlcls));
__raw_pop (rtx); __raw_pop (rtx);
} }
@ -2330,8 +2342,8 @@ static int run_return (qse_awk_rtx_t* run, qse_awk_nde_return_t* nde)
} }
} }
qse_awk_rtx_refdownval (run, STACK_RETVAL(run)); qse_awk_rtx_refdownval (run, RTX_STACK_RETVAL(run));
STACK_RETVAL(run) = val; RTX_STACK_RETVAL(run) = val;
/* NOTE: see eval_call() for the trick */ /* NOTE: see eval_call() for the trick */
qse_awk_rtx_refupval (run, val); qse_awk_rtx_refupval (run, val);
@ -2354,8 +2366,8 @@ static int run_exit (qse_awk_rtx_t* run, qse_awk_nde_exit_t* nde)
val = eval_expression (run, nde->val); val = eval_expression (run, nde->val);
if (val == QSE_NULL) return -1; if (val == QSE_NULL) return -1;
qse_awk_rtx_refdownval (run, STACK_RETVAL_GBL(run)); qse_awk_rtx_refdownval (run, RTX_STACK_RETVAL_GBL(run));
STACK_RETVAL_GBL(run) = val; /* global return value */ RTX_STACK_RETVAL_GBL(run) = val; /* global return value */
qse_awk_rtx_refupval (run, val); qse_awk_rtx_refupval (run, val);
} }
@ -2599,13 +2611,22 @@ static int run_delete_unnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var)
{ {
qse_awk_val_t* val; qse_awk_val_t* val;
if (var->type == QSE_AWK_NDE_GBL || switch (var->type)
var->type == QSE_AWK_NDE_GBLIDX) {
val = STACK_GBL (rtx,var->id.idxa); case QSE_AWK_NDE_GBL:
else if (var->type == QSE_AWK_NDE_LCL || case QSE_AWK_NDE_GBLIDX:
var->type == QSE_AWK_NDE_LCLIDX) val = RTX_STACK_GBL (rtx,var->id.idxa);
val = STACK_LCL (rtx,var->id.idxa); break;
else val = STACK_ARG (rtx,var->id.idxa);
case QSE_AWK_NDE_LCL:
case QSE_AWK_NDE_LCLIDX:
val = RTX_STACK_LCL (rtx,var->id.idxa);
break;
default:
val = RTX_STACK_ARG (rtx,var->id.idxa);
break;
}
QSE_ASSERT (val != QSE_NULL); QSE_ASSERT (val != QSE_NULL);
@ -2625,28 +2646,35 @@ static int run_delete_unnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var)
/* no need to reduce the reference count of /* no need to reduce the reference count of
* the previous value because it was nil. */ * the previous value because it was nil. */
if (var->type == QSE_AWK_NDE_GBL || switch (var->type)
var->type == QSE_AWK_NDE_GBLIDX)
{ {
if (qse_awk_rtx_setgbl ( case QSE_AWK_NDE_GBL:
rtx, (int)var->id.idxa, tmp) == -1) case QSE_AWK_NDE_GBLIDX:
{ {
int x;
qse_awk_rtx_refupval (rtx, tmp); qse_awk_rtx_refupval (rtx, tmp);
x = qse_awk_rtx_setgbl (rtx, (int)var->id.idxa, tmp);
qse_awk_rtx_refdownval (rtx, tmp); qse_awk_rtx_refdownval (rtx, tmp);
ADJERR_LOC (rtx, &var->loc);
return -1; if (x <= -1)
{
ADJERR_LOC (rtx, &var->loc);
return -1;
}
break;
} }
}
else if (var->type == QSE_AWK_NDE_LCL || case QSE_AWK_NDE_LCL:
var->type == QSE_AWK_NDE_LCLIDX) case QSE_AWK_NDE_LCLIDX:
{ RTX_STACK_LCL(rtx,var->id.idxa) = tmp;
STACK_LCL(rtx,var->id.idxa) = tmp; qse_awk_rtx_refupval (rtx, tmp);
qse_awk_rtx_refupval (rtx, tmp); break;
}
else default:
{ RTX_STACK_ARG(rtx,var->id.idxa) = tmp;
STACK_ARG(rtx,var->id.idxa) = tmp; qse_awk_rtx_refupval (rtx, tmp);
qse_awk_rtx_refupval (rtx, tmp); break;
} }
} }
else else
@ -2717,52 +2745,69 @@ static int run_reset (qse_awk_rtx_t* rtx, qse_awk_nde_reset_t* nde)
var = (qse_awk_nde_var_t*) nde->var; var = (qse_awk_nde_var_t*) nde->var;
if (var->type == QSE_AWK_NDE_NAMED) switch (var->type)
{ {
QSE_ASSERTX ( case QSE_AWK_NDE_NAMED:
var->type == QSE_AWK_NDE_NAMED && var->idx == QSE_NULL, QSE_ASSERTX (
"if a named variable has an index part, something is definitely wrong"); var->type == QSE_AWK_NDE_NAMED && var->idx == QSE_NULL,
"if a named variable has an index part, something is definitely wrong");
/* a named variable can be reset if removed from a internal map /* a named variable can be reset if removed from a internal map
to manage it */ to manage it */
qse_htb_delete (rtx->named, var->id.name.ptr, var->id.name.len); qse_htb_delete (rtx->named, var->id.name.ptr, var->id.name.len);
} return 0;
else if (var->type == QSE_AWK_NDE_GBL ||
var->type == QSE_AWK_NDE_LCL ||
var->type == QSE_AWK_NDE_ARG)
{
qse_awk_val_t* val;
if (var->type == QSE_AWK_NDE_GBL) case QSE_AWK_NDE_GBL:
val = STACK_GBL(rtx,var->id.idxa); case QSE_AWK_NDE_LCL:
else if (var->type == QSE_AWK_NDE_LCL) case QSE_AWK_NDE_ARG:
val = STACK_LCL(rtx,var->id.idxa);
else val = STACK_ARG(rtx,var->id.idxa);
QSE_ASSERT (val != QSE_NULL);
if (val->type != QSE_AWK_VAL_NIL)
{ {
qse_awk_rtx_refdownval (rtx, val); qse_awk_val_t* val;
if (var->type == QSE_AWK_NDE_GBL)
STACK_GBL(rtx,var->id.idxa) = qse_awk_val_nil; switch (var->type)
else if (var->type == QSE_AWK_NDE_LCL) {
STACK_LCL(rtx,var->id.idxa) = qse_awk_val_nil; case QSE_AWK_NDE_GBL:
else val = RTX_STACK_GBL(rtx,var->id.idxa);
STACK_ARG(rtx,var->id.idxa) = qse_awk_val_nil; break;
case QSE_AWK_NDE_LCL:
val = RTX_STACK_LCL(rtx,var->id.idxa);
break;
case QSE_AWK_NDE_ARG:
val = RTX_STACK_ARG(rtx,var->id.idxa);
break;
}
QSE_ASSERT (val != QSE_NULL);
if (val->type != QSE_AWK_VAL_NIL)
{
qse_awk_rtx_refdownval (rtx, val);
switch (var->type)
{
case QSE_AWK_NDE_GBL:
RTX_STACK_GBL(rtx,var->id.idxa) = qse_awk_val_nil;
break;
case QSE_AWK_NDE_LCL:
RTX_STACK_LCL(rtx,var->id.idxa) = qse_awk_val_nil;
break;
case QSE_AWK_NDE_ARG:
RTX_STACK_ARG(rtx,var->id.idxa) = qse_awk_val_nil;
break;
}
}
return 0;
} }
}
else
{
QSE_ASSERTX (
!"should never happen - wrong target for reset",
"the reset statement can only be called with plain variables");
SETERR_LOC (rtx, QSE_AWK_EBADARG, &var->loc); default:
return -1; QSE_ASSERTX (
!"should never happen - wrong target for reset",
"the reset statement can only be called with plain variables");
SETERR_LOC (rtx, QSE_AWK_EBADARG, &var->loc);
return -1;
} }
return 0;
} }
static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde) static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
@ -3494,7 +3539,7 @@ static qse_awk_val_t* do_assignment_scalar (
case QSE_AWK_NDE_LCL: case QSE_AWK_NDE_LCL:
{ {
qse_awk_val_t* old = STACK_LCL(run,var->id.idxa); qse_awk_val_t* old = RTX_STACK_LCL(run,var->id.idxa);
if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP) && old->type == QSE_AWK_VAL_MAP) if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP) && old->type == QSE_AWK_VAL_MAP)
{ {
/* once the variable becomes a map, /* once the variable becomes a map,
@ -3506,14 +3551,14 @@ static qse_awk_val_t* do_assignment_scalar (
} }
qse_awk_rtx_refdownval (run, old); qse_awk_rtx_refdownval (run, old);
STACK_LCL(run,var->id.idxa) = val; RTX_STACK_LCL(run,var->id.idxa) = val;
qse_awk_rtx_refupval (run, val); qse_awk_rtx_refupval (run, val);
break; break;
} }
case QSE_AWK_NDE_ARG: case QSE_AWK_NDE_ARG:
{ {
qse_awk_val_t* old = STACK_ARG(run,var->id.idxa); qse_awk_val_t* old = RTX_STACK_ARG(run,var->id.idxa);
if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP) && old->type == QSE_AWK_VAL_MAP) if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP) && old->type == QSE_AWK_VAL_MAP)
{ {
/* once the variable becomes a map, /* once the variable becomes a map,
@ -3525,7 +3570,7 @@ static qse_awk_val_t* do_assignment_scalar (
} }
qse_awk_rtx_refdownval (run, old); qse_awk_rtx_refdownval (run, old);
STACK_ARG(run,var->id.idxa) = val; RTX_STACK_ARG(run,var->id.idxa) = val;
qse_awk_rtx_refupval (run, val); qse_awk_rtx_refupval (run, val);
break; break;
} }
@ -3562,10 +3607,10 @@ static qse_awk_val_t* do_assignment_map (
else else
{ {
map = (var->type == QSE_AWK_NDE_GBLIDX)? map = (var->type == QSE_AWK_NDE_GBLIDX)?
(qse_awk_val_map_t*)STACK_GBL(run,var->id.idxa): (qse_awk_val_map_t*)RTX_STACK_GBL(run,var->id.idxa):
(var->type == QSE_AWK_NDE_LCLIDX)? (var->type == QSE_AWK_NDE_LCLIDX)?
(qse_awk_val_map_t*)STACK_LCL(run,var->id.idxa): (qse_awk_val_map_t*)RTX_STACK_LCL(run,var->id.idxa):
(qse_awk_val_map_t*)STACK_ARG(run,var->id.idxa); (qse_awk_val_map_t*)RTX_STACK_ARG(run,var->id.idxa);
} }
if (map->type == QSE_AWK_VAL_NIL) if (map->type == QSE_AWK_VAL_NIL)
@ -3580,49 +3625,50 @@ static qse_awk_val_t* do_assignment_map (
return QSE_NULL; return QSE_NULL;
} }
if (var->type == QSE_AWK_NDE_NAMEDIDX) switch (var->type)
{ {
/* doesn't have to decrease the reference count case QSE_AWK_NDE_NAMEDIDX:
* of the previous value here as it is done by
* qse_htb_upsert */
if (qse_htb_upsert (
run->named,
var->id.name.ptr,
var->id.name.len,
tmp,
0) == QSE_NULL)
{ {
/* doesn't have to decrease the reference count
* of the previous value here as it is done by
* qse_htb_upsert */
qse_awk_rtx_refupval (run, tmp); qse_awk_rtx_refupval (run, tmp);
qse_awk_rtx_refdownval (run, tmp); if (qse_htb_upsert (run->named, var->id.name.ptr, var->id.name.len, tmp, 0) == QSE_NULL)
{
qse_awk_rtx_refdownval (run, tmp);
SETERR_LOC (run, QSE_AWK_ENOMEM, &var->loc);
return QSE_NULL;
}
SETERR_LOC (run, QSE_AWK_ENOMEM, &var->loc); break;
return QSE_NULL;
} }
qse_awk_rtx_refupval (run, tmp); case QSE_AWK_NDE_GBLIDX:
}
else if (var->type == QSE_AWK_NDE_GBLIDX)
{
qse_awk_rtx_refupval (run, tmp);
if (qse_awk_rtx_setgbl (run, (int)var->id.idxa, tmp) == -1)
{ {
int x;
qse_awk_rtx_refupval (run, tmp);
x = qse_awk_rtx_setgbl (run, (int)var->id.idxa, tmp);
qse_awk_rtx_refdownval (run, tmp); qse_awk_rtx_refdownval (run, tmp);
ADJERR_LOC (run, &var->loc); if (x <= -1)
return QSE_NULL; {
ADJERR_LOC (run, &var->loc);
return QSE_NULL;
}
break;
} }
qse_awk_rtx_refdownval (run, tmp);
} case QSE_AWK_NDE_LCLIDX:
else if (var->type == QSE_AWK_NDE_LCLIDX) qse_awk_rtx_refdownval (run, (qse_awk_val_t*)map);
{ RTX_STACK_LCL(run,var->id.idxa) = tmp;
qse_awk_rtx_refdownval (run, (qse_awk_val_t*)map); qse_awk_rtx_refupval (run, tmp);
STACK_LCL(run,var->id.idxa) = tmp; break;
qse_awk_rtx_refupval (run, tmp);
} default: /* QSE_AWK_NDE_ARGIDX */
else /* if (var->type == QSE_AWK_NDE_ARGIDX) */ qse_awk_rtx_refdownval (run, (qse_awk_val_t*)map);
{ RTX_STACK_ARG(run,var->id.idxa) = tmp;
qse_awk_rtx_refdownval (run, (qse_awk_val_t*)map); qse_awk_rtx_refupval (run, tmp);
STACK_ARG(run,var->id.idxa) = tmp; break;
qse_awk_rtx_refupval (run, tmp);
} }
map = (qse_awk_val_map_t*) tmp; map = (qse_awk_val_map_t*) tmp;
@ -5565,9 +5611,9 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
} }
/* run->stack_base has not been set for this /* run->stack_base has not been set for this
* stack frame. so the STACK_ARG macro cannot be used as in * stack frame. so the RTX_STACK_ARG macro cannot be used as in
* qse_awk_rtx_refdownval (run, STACK_ARG(run,nargs));*/ * qse_awk_rtx_refdownval (run, RTX_STACK_ARG(run,nargs));*/
#define UNWIND_RTX_STACK_ARG(rtx,nargs) \ #define UNWIND_RTX_RTX_STACK_ARG(rtx,nargs) \
do { \ do { \
while ((nargs) > 0) \ while ((nargs) > 0) \
{ \ { \
@ -5577,7 +5623,7 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
} \ } \
} while (0) } while (0)
#define UNWIND_RTX_STACK_BASE(rtx) \ #define UNWIND_RTX_RTX_STACK_BASE(rtx) \
do { \ do { \
__raw_pop (rtx); /* nargs */ \ __raw_pop (rtx); /* nargs */ \
__raw_pop (rtx); /* return */ \ __raw_pop (rtx); /* return */ \
@ -5587,8 +5633,8 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
#define UNWIND_RTX_STACK(rtx,nargs) \ #define UNWIND_RTX_STACK(rtx,nargs) \
do { \ do { \
UNWIND_RTX_STACK_ARG(rtx,nargs); \ UNWIND_RTX_RTX_STACK_ARG(rtx,nargs); \
UNWIND_RTX_STACK_BASE(rtx); \ UNWIND_RTX_RTX_STACK_BASE(rtx); \
} while (0) } while (0)
static qse_awk_val_t* __eval_call ( static qse_awk_val_t* __eval_call (
@ -5692,7 +5738,7 @@ static qse_awk_val_t* __eval_call (
nargs = argpusher (run, call, apdata); nargs = argpusher (run, call, apdata);
if (nargs == (qse_size_t)-1) if (nargs == (qse_size_t)-1)
{ {
UNWIND_RTX_STACK_BASE (run); UNWIND_RTX_RTX_STACK_BASE (run);
return QSE_NULL; return QSE_NULL;
} }
@ -5717,7 +5763,7 @@ static qse_awk_val_t* __eval_call (
} }
run->stack_base = saved_stack_top; run->stack_base = saved_stack_top;
STACK_NARGS(run) = (void*)nargs; RTX_STACK_NARGS(run) = (void*)nargs;
#ifdef DEBUG_RUN #ifdef DEBUG_RUN
qse_dprintf (QSE_T("running function body\n")); qse_dprintf (QSE_T("running function body\n"));
@ -5768,21 +5814,21 @@ static qse_awk_val_t* __eval_call (
} }
/* refdown args in the run.stack */ /* refdown args in the run.stack */
nargs = (qse_size_t)STACK_NARGS(run); nargs = (qse_size_t)RTX_STACK_NARGS(run);
#ifdef DEBUG_RUN #ifdef DEBUG_RUN
qse_dprintf (QSE_T("block run complete nargs = %d\n"), (int)nargs); qse_dprintf (QSE_T("block run complete nargs = %d\n"), (int)nargs);
#endif #endif
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ {
qse_awk_rtx_refdownval (run, STACK_ARG(run,i)); qse_awk_rtx_refdownval (run, RTX_STACK_ARG(run,i));
} }
#ifdef DEBUG_RUN #ifdef DEBUG_RUN
qse_dprintf (QSE_T("got return value\n")); qse_dprintf (QSE_T("got return value\n"));
#endif #endif
v = STACK_RETVAL(run); v = RTX_STACK_RETVAL(run);
if (n == -1) if (n == -1)
{ {
if (run->errinf.num == QSE_AWK_ENOERR && errhandler != QSE_NULL) if (run->errinf.num == QSE_AWK_ENOERR && errhandler != QSE_NULL)
@ -5791,19 +5837,19 @@ static qse_awk_val_t* __eval_call (
* invoked from qse_awk_rtx_call(). Under this * invoked from qse_awk_rtx_call(). Under this
* circumstance, this stack frame is the first * circumstance, this stack frame is the first
* activated and the stack base is the first element * activated and the stack base is the first element
* after the global variables. so STACK_RETVAL(run) * after the global variables. so RTX_STACK_RETVAL(run)
* effectively becomes STACK_RETVAL_GBL(run). * effectively becomes RTX_STACK_RETVAL_GBL(run).
* As __eval_call() returns QSE_NULL on error and * As __eval_call() returns QSE_NULL on error and
* the reference count of STACK_RETVAL(run) should be * the reference count of RTX_STACK_RETVAL(run) should be
* decremented, it can't get the return value * decremented, it can't get the return value
* if it turns out to be terminated by exit(). * if it turns out to be terminated by exit().
* The return value could be destroyed by then. * The return value could be destroyed by then.
* Unlikely, run_bpae_loop() just checks if run->errinf.num * Unlikely, run_bpae_loop() just checks if run->errinf.num
* is QSE_AWK_ENOERR and gets STACK_RETVAL_GBL(run) * is QSE_AWK_ENOERR and gets RTX_STACK_RETVAL_GBL(run)
* to determine if it is terminated by exit(). * to determine if it is terminated by exit().
* *
* The handler capture_retval_on_exit() * The handler capture_retval_on_exit()
* increments the reference of STACK_RETVAL(run) * increments the reference of RTX_STACK_RETVAL(run)
* and stores the pointer into accompanying space. * and stores the pointer into accompanying space.
* This way, the return value is preserved upon * This way, the return value is preserved upon
* termination by exit() out to the caller. * termination by exit() out to the caller.
@ -5815,7 +5861,7 @@ static qse_awk_val_t* __eval_call (
* has to return a error, the return value is just * has to return a error, the return value is just
* destroyed and replaced by nil */ * destroyed and replaced by nil */
qse_awk_rtx_refdownval (run, v); qse_awk_rtx_refdownval (run, v);
STACK_RETVAL(run) = qse_awk_val_nil; RTX_STACK_RETVAL(run) = qse_awk_val_nil;
} }
else else
{ {
@ -5858,7 +5904,7 @@ static qse_size_t push_arg_from_vals (
qse_awk_rtx_refupval (rtx, pafv->args[nargs]); qse_awk_rtx_refupval (rtx, pafv->args[nargs]);
qse_awk_rtx_refdownval (rtx, pafv->args[nargs]); qse_awk_rtx_refdownval (rtx, pafv->args[nargs]);
UNWIND_RTX_STACK_ARG (rtx, nargs); UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
return (qse_size_t)-1; return (qse_size_t)-1;
} }
@ -5892,7 +5938,7 @@ static qse_size_t push_arg_from_nde (
if (get_reference (rtx, p, &ref) == -1) if (get_reference (rtx, p, &ref) == -1)
{ {
UNWIND_RTX_STACK_ARG (rtx, nargs); UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
return (qse_size_t)-1; return (qse_size_t)-1;
} }
@ -5915,7 +5961,7 @@ static qse_size_t push_arg_from_nde (
if (v == QSE_NULL) if (v == QSE_NULL)
{ {
UNWIND_RTX_STACK_ARG (rtx, nargs); UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
return (qse_size_t)-1; return (qse_size_t)-1;
} }
@ -5929,7 +5975,7 @@ static qse_size_t push_arg_from_nde (
qse_awk_rtx_refupval (rtx, v); qse_awk_rtx_refupval (rtx, v);
qse_awk_rtx_refdownval (rtx, v); qse_awk_rtx_refdownval (rtx, v);
UNWIND_RTX_STACK_ARG (rtx, nargs); UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
return (qse_size_t)-1; return (qse_size_t)-1;
} }
@ -5987,15 +6033,16 @@ static int get_reference (
} }
case 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**)&RTX_STACK_GBL(run,tgt->id.idxa); */
*ref = (qse_awk_val_t**)((qse_size_t)tgt->id.idxa);
return 0; return 0;
case 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**)&RTX_STACK_LCL(run,tgt->id.idxa);
return 0; return 0;
case 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**)&RTX_STACK_ARG(run,tgt->id.idxa);
return 0; return 0;
case QSE_AWK_NDE_NAMEDIDX: case QSE_AWK_NDE_NAMEDIDX:
@ -6025,21 +6072,21 @@ static int get_reference (
case 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**)&RTX_STACK_GBL(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0; return 0;
case 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**)&RTX_STACK_LCL(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0; return 0;
case 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**)&RTX_STACK_ARG(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0; return 0;
@ -6199,17 +6246,17 @@ static qse_awk_val_t* eval_named (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_gbl (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_gbl (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
return STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa); return RTX_STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa);
} }
static qse_awk_val_t* eval_lcl (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_lcl (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
return STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa); return RTX_STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa);
} }
static qse_awk_val_t* eval_arg (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_arg (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
return STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa); return RTX_STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa);
} }
static qse_awk_val_t* eval_indexed ( static qse_awk_val_t* eval_indexed (
@ -6281,19 +6328,19 @@ static qse_awk_val_t* eval_namedidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_gblidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_gblidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
return eval_indexed (run, (qse_awk_nde_var_t*)nde, return eval_indexed (run, (qse_awk_nde_var_t*)nde,
(qse_awk_val_t**)&STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa)); (qse_awk_val_t**)&RTX_STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa));
} }
static qse_awk_val_t* eval_lclidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_lclidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
return eval_indexed (run, (qse_awk_nde_var_t*)nde, return eval_indexed (run, (qse_awk_nde_var_t*)nde,
(qse_awk_val_t**)&STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa)); (qse_awk_val_t**)&RTX_STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa));
} }
static qse_awk_val_t* eval_argidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_argidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
return eval_indexed (run, (qse_awk_nde_var_t*)nde, return eval_indexed (run, (qse_awk_nde_var_t*)nde,
(qse_awk_val_t**)&STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa)); (qse_awk_val_t**)&RTX_STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa));
} }
static qse_awk_val_t* eval_pos (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_pos (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
@ -6495,7 +6542,7 @@ static int __raw_push (qse_awk_rtx_t* run, void* val)
void** tmp; void** tmp;
qse_size_t n; qse_size_t n;
n = run->stack_limit + STACK_INCREMENT; n = run->stack_limit + RTX_STACK_INCREMENT;
tmp = (void**) QSE_AWK_REALLOC ( tmp = (void**) QSE_AWK_REALLOC (
run->awk, run->stack, n * QSE_SIZEOF(void*)); run->awk, run->stack, n * QSE_SIZEOF(void*));
@ -6561,7 +6608,7 @@ static int shorten_record (qse_awk_rtx_t* run, qse_size_t nflds)
if (nflds > 1) if (nflds > 1)
{ {
v = STACK_GBL(run, QSE_AWK_GBL_OFS); v = RTX_STACK_GBL(run, QSE_AWK_GBL_OFS);
qse_awk_rtx_refupval (run, v); qse_awk_rtx_refupval (run, v);
if (v->type == QSE_AWK_VAL_NIL) if (v->type == QSE_AWK_VAL_NIL)
@ -7328,36 +7375,37 @@ wp_mod_main:
} }
qse_awk_rtx_refupval (rtx, v); qse_awk_rtx_refupval (rtx, v);
if (v->type == QSE_AWK_VAL_NIL) switch (v->type)
{ {
ch = QSE_T('\0'); case QSE_AWK_VAL_NIL:
ch_len = 0; ch = QSE_T('\0');
} ch_len = 0;
else if (v->type == QSE_AWK_VAL_INT) break;
{
ch = (qse_char_t)((qse_awk_val_int_t*)v)->val; case QSE_AWK_VAL_INT:
ch_len = 1; ch = (qse_char_t)((qse_awk_val_int_t*)v)->val;
}
else if (v->type == QSE_AWK_VAL_FLT)
{
ch = (qse_char_t)((qse_awk_val_flt_t*)v)->val;
ch_len = 1;
}
else if (v->type == QSE_AWK_VAL_STR)
{
ch_len = ((qse_awk_val_str_t*)v)->val.len;
if (ch_len > 0)
{
ch = ((qse_awk_val_str_t*)v)->val.ptr[0];
ch_len = 1; ch_len = 1;
} break;
else ch = QSE_T('\0');
} case QSE_AWK_VAL_FLT:
else ch = (qse_char_t)((qse_awk_val_flt_t*)v)->val;
{ ch_len = 1;
qse_awk_rtx_refdownval (rtx, v); break;
SETERR_COD (rtx, QSE_AWK_EVALTYPE);
return QSE_NULL; case QSE_AWK_VAL_STR:
ch_len = ((qse_awk_val_str_t*)v)->val.len;
if (ch_len > 0)
{
ch = ((qse_awk_val_str_t*)v)->val.ptr[0];
ch_len = 1;
}
else ch = QSE_T('\0');
break;
default:
qse_awk_rtx_refdownval (rtx, v);
SETERR_COD (rtx, QSE_AWK_EVALTOCHR);
return QSE_NULL;
} }
if (wp[WP_PRECISION] == -1 || wp[WP_PRECISION] == 0 || wp[WP_PRECISION] > (qse_long_t)ch_len) if (wp[WP_PRECISION] == -1 || wp[WP_PRECISION] == 0 || wp[WP_PRECISION] > (qse_long_t)ch_len)

View File

@ -2536,14 +2536,20 @@ done:
if (ret >= 0) if (ret >= 0)
{ {
if (rv && qse_awk_rtx_setrefval (rtx, qse_awk_rtx_getarg (rtx, 2), rv) >= 0) qse_awk_val_t* retv;
if (rv)
{ {
qse_awk_rtx_setretval (rtx, qse_awk_val_zero); int x;
} qse_awk_rtx_refupval (rtx, rv);
else x = qse_awk_rtx_setrefval (rtx, qse_awk_rtx_getarg (rtx, 2), rv);
{ qse_awk_rtx_refdownval (rtx, rv);
qse_awk_rtx_setretval (rtx, qse_awk_val_negone); if (x <= -1) retv = qse_awk_val_negone;
else retv = qse_awk_val_zero;
} }
else retv = qse_awk_val_negone;
qse_awk_rtx_setretval (rtx, qse_awk_val_zero);
} }
return ret; return ret;

View File

@ -1296,48 +1296,58 @@ static int val_ref_to_str (
qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref,
qse_awk_rtx_valtostr_out_t* out) qse_awk_rtx_valtostr_out_t* out)
{ {
if (ref->id == QSE_AWK_VAL_REF_POS) switch (ref->id)
{ {
qse_size_t idx; case QSE_AWK_VAL_REF_POS:
{
qse_size_t idx;
/* special case when the reference value is /* special case when the reference value is
* pointing to the positional */ * pointing to the positional */
idx = (qse_size_t)ref->adr; idx = (qse_size_t)ref->adr;
if (idx == 0) if (idx == 0)
{ {
return str_to_str ( return str_to_str (
rtx, rtx,
QSE_STR_PTR(&rtx->inrec.line), QSE_STR_PTR(&rtx->inrec.line),
QSE_STR_LEN(&rtx->inrec.line), QSE_STR_LEN(&rtx->inrec.line),
out out
); );
}
else if (idx <= rtx->inrec.nflds)
{
return str_to_str (
rtx,
rtx->inrec.flds[idx-1].ptr,
rtx->inrec.flds[idx-1].len,
out
);
}
else
{
return str_to_str (rtx, QSE_T(""), 0, out);
}
} }
else if (idx <= rtx->inrec.nflds)
{
return str_to_str (
rtx,
rtx->inrec.flds[idx-1].ptr,
rtx->inrec.flds[idx-1].len,
out
);
}
else
{
return str_to_str (rtx, QSE_T(""), 0, out);
}
}
else
{
qse_awk_val_t** xref = (qse_awk_val_t**)ref->adr;
/* A reference value is not able to point to another case QSE_AWK_VAL_REF_GBL:
* refernce value for the way values are represented {
* in QSEAWK */ qse_size_t idx = (qse_size_t)ref->adr;
QSE_ASSERT ((*xref)->type != QSE_AWK_VAL_REF); return qse_awk_rtx_valtostr (rtx, RTX_STACK_GBL (rtx, idx), out);
}
/* make a recursive call back to the caller */ default:
return qse_awk_rtx_valtostr (rtx, *xref, out); {
qse_awk_val_t** xref = (qse_awk_val_t**)ref->adr;
/* A reference value is not able to point to another
* refernce value for the way values are represented
* in QSEAWK */
QSE_ASSERT ((*xref)->type != QSE_AWK_VAL_REF);
/* make a recursive call back to the caller */
return qse_awk_rtx_valtostr (rtx, *xref, out);
}
} }
} }
@ -1373,7 +1383,9 @@ int qse_awk_rtx_valtostr (
case QSE_AWK_VAL_MAP: case QSE_AWK_VAL_MAP:
{ {
if (rtx->awk->opt.trait & QSE_AWK_FLEXMAP) if (rtx->awk->opt.trait & QSE_AWK_FLEXMAP)
{
return str_to_str (rtx, QSE_T("#MAP"), 4, out); return str_to_str (rtx, QSE_T("#MAP"), 4, out);
}
break; break;
} }
@ -1391,7 +1403,7 @@ int qse_awk_rtx_valtostr (
v->type v->type
); );
#endif #endif
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTYPE, QSE_NULL); qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTOSTR, QSE_NULL);
return -1; return -1;
} }
@ -1458,47 +1470,57 @@ qse_wchar_t* qse_awk_rtx_valtowcsdup (
static int val_ref_to_num ( static int val_ref_to_num (
qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse_long_t* l, qse_flt_t* r) qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse_long_t* l, qse_flt_t* r)
{ {
if (ref->id == QSE_AWK_VAL_REF_POS) switch (ref->id)
{ {
qse_size_t idx; case QSE_AWK_VAL_REF_POS:
{
qse_size_t idx;
idx = (qse_size_t)ref->adr; idx = (qse_size_t)ref->adr;
if (idx == 0) if (idx == 0)
{ {
return qse_awk_rtx_strtonum ( return qse_awk_rtx_strtonum (
rtx, 0, rtx, 0,
QSE_STR_PTR(&rtx->inrec.line), QSE_STR_PTR(&rtx->inrec.line),
QSE_STR_LEN(&rtx->inrec.line), QSE_STR_LEN(&rtx->inrec.line),
l, r l, r
); );
}
else if (idx <= rtx->inrec.nflds)
{
return qse_awk_rtx_strtonum (
rtx, 0,
rtx->inrec.flds[idx-1].ptr,
rtx->inrec.flds[idx-1].len,
l, r
);
}
else
{
return qse_awk_rtx_strtonum (
rtx, 0, QSE_T(""), 0, l, r
);
}
} }
else if (idx <= rtx->inrec.nflds)
{
return qse_awk_rtx_strtonum (
rtx, 0,
rtx->inrec.flds[idx-1].ptr,
rtx->inrec.flds[idx-1].len,
l, r
);
}
else
{
return qse_awk_rtx_strtonum (
rtx, 0, QSE_T(""), 0, l, r
);
}
}
else
{
qse_awk_val_t** xref = (qse_awk_val_t**)ref->adr;
/* A reference value is not able to point to another case QSE_AWK_VAL_REF_GBL:
* refernce value for the way values are represented {
* in QSEAWK */ qse_size_t idx = (qse_size_t)ref->adr;
QSE_ASSERT ((*xref)->type != QSE_AWK_VAL_REF); return qse_awk_rtx_valtonum (rtx, RTX_STACK_GBL (rtx, idx), l, r);
}
/* make a recursive call back to the caller */ default:
return qse_awk_rtx_valtonum (rtx, *xref, l, r); {
qse_awk_val_t** xref = (qse_awk_val_t**)ref->adr;
/* A reference value is not able to point to another
* refernce value for the way values are represented
* in QSEAWK */
QSE_ASSERT ((*xref)->type != QSE_AWK_VAL_REF);
/* make a recursive call back to the caller */
return qse_awk_rtx_valtonum (rtx, *xref, l, r);
}
} }
} }
@ -1549,7 +1571,7 @@ int qse_awk_rtx_valtonum (
); );
#endif #endif
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTYPE, QSE_NULL); qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTONUM, QSE_NULL);
return -1; /* error */ return -1; /* error */
} }
@ -1648,8 +1670,7 @@ qse_long_t qse_awk_rtx_hashval (qse_awk_rtx_t* rtx, qse_awk_val_t* v)
v->type v->type
); );
#endif #endif
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EHASHVAL, QSE_NULL);
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTYPE, QSE_NULL);
return -1; return -1;
} }
@ -1672,45 +1693,107 @@ int qse_awk_rtx_setrefval (qse_awk_rtx_t* rtx, qse_awk_val_ref_t* ref, qse_awk_v
return -1; return -1;
} }
if (ref->id == QSE_AWK_VAL_REF_POS) switch (ref->id)
{ {
if (val->type == QSE_AWK_VAL_STR) case QSE_AWK_VAL_REF_POS:
{ {
return qse_awk_rtx_setrec (
rtx, (qse_size_t)ref->adr, switch (val->type)
&((qse_awk_val_str_t*)val)->val {
); case QSE_AWK_VAL_MAP:
/* a map is assigned to a positional. this is disallowed. */
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EPOSVALMAP, QSE_NULL);
return -1;
case QSE_AWK_VAL_STR:
{
int x;
/* handle this separately from the default case
* for no duplication. jumping to the default case
* and callingqse_awk_rtx_valtostrdup() would also work, anyway. */
qse_awk_rtx_refupval (rtx, val);
x = qse_awk_rtx_setrec (
rtx, (qse_size_t)ref->adr,
&((qse_awk_val_str_t*)val)->val
);
qse_awk_rtx_refdownval (rtx, val);
return x;
}
default:
{
qse_xstr_t str;
int x;
str.ptr = qse_awk_rtx_valtostrdup (rtx, val, &str.len);
qse_awk_rtx_refupval (rtx, val);
x = qse_awk_rtx_setrec (rtx, (qse_size_t)ref->adr, &str);
qse_awk_rtx_refdownval (rtx, val);
QSE_AWK_FREE (rtx->awk, str.ptr);
return x;
}
}
} }
else
case QSE_AWK_VAL_REF_GBL:
return qse_awk_rtx_setgbl (rtx, (int)ref->adr, val);
case QSE_AWK_VAL_REF_NAMEDIDX:
case QSE_AWK_VAL_REF_GBLIDX:
case QSE_AWK_VAL_REF_LCLIDX:
case QSE_AWK_VAL_REF_ARGIDX:
if (val->type == QSE_AWK_VAL_MAP)
{
/* an indexed variable cannot be assigned a map.
* in other cases, it falls down to the default case. */
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EIDXVALMAP, QSE_NULL);
return -1;
}
/* fall through */
default:
{ {
qse_xstr_t str; qse_awk_val_t** rref;
int x;
rref = (qse_awk_val_t**)ref->adr;
str.ptr = qse_awk_rtx_valtostrdup (rtx, val, &str.len); if (val->type == QSE_AWK_VAL_MAP)
x = qse_awk_rtx_setrec (rtx, (qse_size_t)ref->adr, &str); {
QSE_AWK_FREE (rtx->awk, str.ptr); /* new value: map, old value: nil or map => ok */
return x; if ((*rref)->type != QSE_AWK_VAL_NIL &&
(*rref)->type != QSE_AWK_VAL_MAP)
{
if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP))
{
/* cannot change a scalar value to a map */
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ESCALARTOMAP, QSE_NULL);
return -1;
}
}
}
else
{
/* new value: scalar, old value: nil or scalar => ok */
if ((*rref)->type == QSE_AWK_VAL_MAP)
{
if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP))
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EMAPTOSCALAR, QSE_NULL);
return -1;
}
}
}
if (*rref != val)
{
/* if the new value is not the same as the old value */
qse_awk_rtx_refdownval (rtx, *rref);
*rref = val;
qse_awk_rtx_refupval (rtx, *rref);
}
return 0;
} }
} }
else
{
qse_awk_val_t** rref;
/* TODO: handle QSE_AWK_FLEXMAP...
if FLEXMAP is not set.. check if rref is nil or map if value is map.
also check if rref is nil... scalar if valeu is scalar..
but is this really necessary? i feel all these awk quarkiness is nasty..
*/
rref = (qse_awk_val_t**)ref->adr;
if (*rref != val)
{
qse_awk_rtx_refdownval (rtx, *rref);
*rref = val;
qse_awk_rtx_refupval (rtx, *rref);
}
return 0;
}
} }
#if 0 #if 0