added qse_awk_seterrfmt()/qse_awk_rtx_seterrfmt()
fixed wrong reference counting in __fnc_asort()
This commit is contained in:
parent
df47611d9d
commit
2e19b848e5
@ -1681,6 +1681,14 @@ QSE_EXPORT void qse_awk_seterrnum (
|
|||||||
* an error message */
|
* an error message */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT void qse_awk_seterrfmt (
|
||||||
|
qse_awk_t* awk,
|
||||||
|
qse_awk_errnum_t errnum,
|
||||||
|
qse_awk_loc_t* errloc,
|
||||||
|
const qse_char_t* msgfmt,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_awk_seterrinf() function sets the error information. This function
|
* The qse_awk_seterrinf() function sets the error information. This function
|
||||||
* may be useful if you want to set a custom error message rather than letting
|
* may be useful if you want to set a custom error message rather than letting
|
||||||
@ -1691,6 +1699,7 @@ QSE_EXPORT void qse_awk_seterrinf (
|
|||||||
const qse_awk_errinf_t* errinf /**< error information */
|
const qse_awk_errinf_t* errinf /**< error information */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_awk_geterror() function gets error information via parameters.
|
* The qse_awk_geterror() function gets error information via parameters.
|
||||||
*/
|
*/
|
||||||
@ -2367,6 +2376,14 @@ QSE_EXPORT void qse_awk_rtx_seterrinf (
|
|||||||
const qse_awk_errinf_t* errinf /**< error information */
|
const qse_awk_errinf_t* errinf /**< error information */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT void qse_awk_rtx_seterrfmt (
|
||||||
|
qse_awk_rtx_t* rtx,
|
||||||
|
qse_awk_errnum_t errnum,
|
||||||
|
const qse_awk_loc_t* errloc,
|
||||||
|
const qse_char_t* errfmt,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_awk_rtx_seterror() function sets error information.
|
* The qse_awk_rtx_seterror() function sets error information.
|
||||||
*/
|
*/
|
||||||
|
@ -652,7 +652,7 @@ int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v)
|
|||||||
{
|
{
|
||||||
QSE_ASSERT (r != QSE_NULL);
|
QSE_ASSERT (r != QSE_NULL);
|
||||||
|
|
||||||
if (QSE_AWK_RTX_GETVALTYPE (r->rtx, val) != QSE_AWK_VAL_MAP)
|
if (QSE_AWK_RTX_GETVALTYPE (r->rtx, this->val) != QSE_AWK_VAL_MAP)
|
||||||
{
|
{
|
||||||
// the previous value is not a map.
|
// the previous value is not a map.
|
||||||
// a new map value needs to be created first.
|
// a new map value needs to be created first.
|
||||||
@ -666,8 +666,7 @@ int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v)
|
|||||||
qse_awk_rtx_refupval (r->rtx, map);
|
qse_awk_rtx_refupval (r->rtx, map);
|
||||||
|
|
||||||
// update the map with a given value
|
// update the map with a given value
|
||||||
if (qse_awk_rtx_setmapvalfld (
|
if (qse_awk_rtx_setmapvalfld(r->rtx, map, idx.ptr, idx.len, v) == QSE_NULL)
|
||||||
r->rtx, map, idx.ptr, idx.len, v) == QSE_NULL)
|
|
||||||
{
|
{
|
||||||
qse_awk_rtx_refdownval (r->rtx, map);
|
qse_awk_rtx_refdownval (r->rtx, map);
|
||||||
r->awk->retrieveError (r);
|
r->awk->retrieveError (r);
|
||||||
@ -678,7 +677,7 @@ int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v)
|
|||||||
if (this->run)
|
if (this->run)
|
||||||
{
|
{
|
||||||
// if val is not nil, this->run can't be NULL
|
// if val is not nil, this->run can't be NULL
|
||||||
qse_awk_rtx_refdownval (this->run->rtx, val);
|
qse_awk_rtx_refdownval (this->run->rtx, this->val);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->run = r;
|
this->run = r;
|
||||||
@ -700,8 +699,7 @@ int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update the map with a given value
|
// update the map with a given value
|
||||||
if (qse_awk_rtx_setmapvalfld (
|
if (qse_awk_rtx_setmapvalfld(r->rtx, val, idx.ptr, idx.len, v) == QSE_NULL)
|
||||||
r->rtx, val, idx.ptr, idx.len, v) == QSE_NULL)
|
|
||||||
{
|
{
|
||||||
r->awk->retrieveError (r);
|
r->awk->retrieveError (r);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -207,22 +207,21 @@ void qse_awk_geterrinf (const qse_awk_t* awk, qse_awk_errinf_t* errinf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qse_awk_geterror (
|
void qse_awk_geterror (const qse_awk_t* awk, qse_awk_errnum_t* errnum, const qse_char_t** errmsg, qse_awk_loc_t* errloc)
|
||||||
const qse_awk_t* awk, qse_awk_errnum_t* errnum,
|
|
||||||
const qse_char_t** errmsg, qse_awk_loc_t* errloc)
|
|
||||||
{
|
{
|
||||||
if (errnum != QSE_NULL) *errnum = awk->errinf.num;
|
if (errnum) *errnum = awk->errinf.num;
|
||||||
if (errmsg != QSE_NULL)
|
if (errmsg)
|
||||||
{
|
{
|
||||||
*errmsg = (awk->errinf.msg[0] == QSE_T('\0'))?
|
*errmsg = (awk->errinf.msg[0] == QSE_T('\0'))?
|
||||||
qse_awk_geterrstr(awk)(awk,awk->errinf.num):
|
qse_awk_geterrstr(awk)(awk,awk->errinf.num):
|
||||||
awk->errinf.msg;
|
awk->errinf.msg;
|
||||||
}
|
}
|
||||||
if (errloc != QSE_NULL) *errloc = awk->errinf.loc;
|
if (errloc) *errloc = awk->errinf.loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qse_awk_seterrnum (
|
|
||||||
qse_awk_t* awk, qse_awk_errnum_t errnum, const qse_cstr_t* errarg)
|
|
||||||
|
void qse_awk_seterrnum (qse_awk_t* awk, qse_awk_errnum_t errnum, const qse_cstr_t* errarg)
|
||||||
{
|
{
|
||||||
qse_awk_seterror (awk, errnum, errarg, QSE_NULL);
|
qse_awk_seterror (awk, errnum, errarg, QSE_NULL);
|
||||||
}
|
}
|
||||||
@ -232,9 +231,21 @@ void qse_awk_seterrinf (qse_awk_t* awk, const qse_awk_errinf_t* errinf)
|
|||||||
QSE_MEMCPY (&awk->errinf, errinf, QSE_SIZEOF(*errinf));
|
QSE_MEMCPY (&awk->errinf, errinf, QSE_SIZEOF(*errinf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void qse_awk_seterror (
|
void qse_awk_seterrfmt (qse_awk_t* awk, qse_awk_errnum_t errnum, qse_awk_loc_t* errloc, const qse_char_t* errfmt, ...)
|
||||||
qse_awk_t* awk, qse_awk_errnum_t errnum, const qse_cstr_t* errarg,
|
{
|
||||||
const qse_awk_loc_t* errloc)
|
va_list ap;
|
||||||
|
|
||||||
|
QSE_MEMSET (&awk->errinf, 0, QSE_SIZEOF(awk->errinf));
|
||||||
|
awk->errinf.num = errnum;
|
||||||
|
|
||||||
|
va_start (ap, errfmt);
|
||||||
|
qse_strxvfmt (awk->errinf.msg, QSE_COUNTOF(awk->errinf.msg), errfmt, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
if (errloc) awk->errinf.loc = *errloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_awk_seterror (qse_awk_t* awk, qse_awk_errnum_t errnum, const qse_cstr_t* errarg, const qse_awk_loc_t* errloc)
|
||||||
{
|
{
|
||||||
const qse_char_t* errfmt;
|
const qse_char_t* errfmt;
|
||||||
|
|
||||||
@ -243,14 +254,12 @@ void qse_awk_seterror (
|
|||||||
|
|
||||||
errfmt = qse_awk_geterrstr(awk)(awk,errnum);
|
errfmt = qse_awk_geterrstr(awk)(awk,errnum);
|
||||||
QSE_ASSERT (errfmt != QSE_NULL);
|
QSE_ASSERT (errfmt != QSE_NULL);
|
||||||
qse_strxfncpy (
|
qse_strxfncpy (awk->errinf.msg, QSE_COUNTOF(awk->errinf.msg), errfmt, errarg);
|
||||||
awk->errinf.msg, QSE_COUNTOF(awk->errinf.msg),
|
|
||||||
errfmt, errarg
|
|
||||||
);
|
|
||||||
|
|
||||||
if (errloc != QSE_NULL) awk->errinf.loc = *errloc;
|
if (errloc != QSE_NULL) awk->errinf.loc = *errloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
qse_awk_errnum_t qse_awk_rtx_geterrnum (const qse_awk_rtx_t* rtx)
|
qse_awk_errnum_t qse_awk_rtx_geterrnum (const qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
return rtx->errinf.num;
|
return rtx->errinf.num;
|
||||||
@ -301,9 +310,22 @@ void qse_awk_rtx_seterrinf (qse_awk_rtx_t* rtx, const qse_awk_errinf_t* errinf)
|
|||||||
QSE_MEMCPY (&rtx->errinf, errinf, QSE_SIZEOF(*errinf));
|
QSE_MEMCPY (&rtx->errinf, errinf, QSE_SIZEOF(*errinf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void qse_awk_rtx_seterror (
|
void qse_awk_rtx_seterrfmt (qse_awk_rtx_t* rtx, qse_awk_errnum_t errnum, const qse_awk_loc_t* errloc, const qse_char_t* errfmt, ...)
|
||||||
qse_awk_rtx_t* rtx, qse_awk_errnum_t errnum, const qse_cstr_t* errarg,
|
{
|
||||||
const qse_awk_loc_t* errloc)
|
va_list ap;
|
||||||
|
|
||||||
|
QSE_MEMSET (&rtx->errinf, 0, QSE_SIZEOF(rtx->errinf));
|
||||||
|
rtx->errinf.num = errnum;
|
||||||
|
|
||||||
|
va_start (ap, errfmt);
|
||||||
|
qse_strxvfmt (rtx->errinf.msg, QSE_COUNTOF(rtx->errinf.msg), errfmt, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
if (errloc) rtx->errinf.loc = *errloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void qse_awk_rtx_seterror (qse_awk_rtx_t* rtx, qse_awk_errnum_t errnum, const qse_cstr_t* errarg, const qse_awk_loc_t* errloc)
|
||||||
{
|
{
|
||||||
const qse_char_t* errfmt;
|
const qse_char_t* errfmt;
|
||||||
|
|
||||||
|
@ -1562,7 +1562,7 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
qse_size_t nargs;
|
qse_size_t nargs;
|
||||||
qse_awk_val_t* a0, * a0_val, * a1, * a2;
|
qse_awk_val_t* a0, * a0_val, * a1, * a2;
|
||||||
qse_awk_val_type_t a0_type, v_type;
|
qse_awk_val_type_t a0_type, v_type;
|
||||||
qse_awk_val_t* r, * rmap;
|
qse_awk_val_t* r, * rmap = QSE_NULL;
|
||||||
qse_awk_int_t rv = 0; /* as if no element in the map */
|
qse_awk_int_t rv = 0; /* as if no element in the map */
|
||||||
qse_awk_val_map_itr_t itr;
|
qse_awk_val_map_itr_t itr;
|
||||||
qse_awk_fun_t* fun = QSE_NULL;
|
qse_awk_fun_t* fun = QSE_NULL;
|
||||||
@ -1585,7 +1585,7 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOTMAP, QSE_NULL);
|
qse_awk_rtx_seterrfmt (rtx, QSE_AWK_ENOTMAP, QSE_NULL, QSE_T("source not a map"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1601,7 +1601,7 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
a2 = qse_awk_rtx_getarg(rtx, 2);
|
a2 = qse_awk_rtx_getarg(rtx, 2);
|
||||||
if (QSE_AWK_RTX_GETVALTYPE(rtx, a2) != QSE_AWK_VAL_FUN)
|
if (QSE_AWK_RTX_GETVALTYPE(rtx, a2) != QSE_AWK_VAL_FUN)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
qse_awk_rtx_seterrfmt (rtx, QSE_AWK_EINVAL, QSE_NULL, QSE_T("comparator not a function"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1609,7 +1609,7 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
if (fun->nargs < 2)
|
if (fun->nargs < 2)
|
||||||
{
|
{
|
||||||
/* the comparison accepts less than 2 arguments */
|
/* the comparison accepts less than 2 arguments */
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
qse_awk_rtx_seterrfmt (rtx, QSE_AWK_EINVAL, QSE_NULL, QSE_T("%.*s not accepting 2 arguments"), (int)fun->name.len, fun->name.ptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1638,11 +1638,12 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
--i;
|
--i;
|
||||||
qse_awk_rtx_freeval (rtx, va[i], 0);
|
qse_awk_rtx_refdownval (rtx, va[i]);
|
||||||
}
|
}
|
||||||
qse_awk_rtx_freemem (rtx, va);
|
qse_awk_rtx_freemem (rtx, va);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
qse_awk_rtx_refupval (rtx, va[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
while (qse_awk_rtx_getnextmapvalitr(rtx, a0_val, &itr));
|
while (qse_awk_rtx_getnextmapvalitr(rtx, a0_val, &itr));
|
||||||
@ -1651,7 +1652,9 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
va[i++] = (qse_awk_val_t*)QSE_AWK_VAL_MAP_ITR_VAL(&itr);
|
va[i] = (qse_awk_val_t*)QSE_AWK_VAL_MAP_ITR_VAL(&itr);
|
||||||
|
qse_awk_rtx_refupval (rtx, va[i]);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
while (qse_awk_rtx_getnextmapvalitr(rtx, a0_val, &itr));
|
while (qse_awk_rtx_getnextmapvalitr(rtx, a0_val, &itr));
|
||||||
}
|
}
|
||||||
@ -1670,17 +1673,14 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
|
|
||||||
if (x <= -1 || !(rmap = qse_awk_rtx_makemapval(rtx)))
|
if (x <= -1 || !(rmap = qse_awk_rtx_makemapval(rtx)))
|
||||||
{
|
{
|
||||||
if (sort_keys)
|
for (i = 0; i < msz; i++) qse_awk_rtx_refdownval (rtx, va[i]);
|
||||||
{
|
|
||||||
for (i = 0; i < msz; i++) qse_awk_rtx_freeval (rtx, va[i], 0);
|
|
||||||
}
|
|
||||||
qse_awk_rtx_freemem (rtx, va);
|
qse_awk_rtx_freemem (rtx, va);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < msz; i++)
|
for (i = 0; i < msz; i++)
|
||||||
{
|
{
|
||||||
qse_char_t ridx[128];
|
qse_char_t ridx[128]; /* TODO: make it dynamic? can overflow? */
|
||||||
qse_size_t ridx_len;
|
qse_size_t ridx_len;
|
||||||
|
|
||||||
ridx_len = qse_fmtuintmax (
|
ridx_len = qse_fmtuintmax (
|
||||||
@ -1695,32 +1695,42 @@ static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t*
|
|||||||
|
|
||||||
if (qse_awk_rtx_setmapvalfld(rtx, rmap, ridx, ridx_len, va[i]) == QSE_NULL)
|
if (qse_awk_rtx_setmapvalfld(rtx, rmap, ridx, ridx_len, va[i]) == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_freeval (rtx, rmap, 0); /* this delete the elements added. */
|
/* decrement the reference count of the values not added to the map */
|
||||||
if (sort_keys)
|
do
|
||||||
{
|
{
|
||||||
/* delete the elements not added yet */
|
qse_awk_rtx_refdownval (rtx, va[i]);
|
||||||
do
|
i++;
|
||||||
{
|
|
||||||
qse_awk_rtx_freeval(rtx, va[i], 0);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while (i < msz);
|
|
||||||
}
|
}
|
||||||
|
while (i < msz);
|
||||||
|
qse_awk_rtx_freeval (rtx, rmap, 0); /* this derefs the elements added. */
|
||||||
qse_awk_rtx_freemem (rtx, va);
|
qse_awk_rtx_freemem (rtx, va);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qse_awk_rtx_refdownval (rtx, va[i]); /* deref it as it has been added to the map */
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = msz;
|
rv = msz;
|
||||||
qse_awk_rtx_freemem (rtx, va);
|
qse_awk_rtx_freemem (rtx, va);
|
||||||
|
|
||||||
qse_awk_rtx_refupval (rtx, rmap);
|
|
||||||
x = qse_awk_rtx_setrefval (rtx, (qse_awk_val_ref_t*)a1, rmap);
|
|
||||||
qse_awk_rtx_refdownval (rtx, rmap);
|
|
||||||
if (x <= -1) return -1;
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
r = qse_awk_rtx_makeintval(rtx, rv);
|
r = qse_awk_rtx_makeintval(rtx, rv);
|
||||||
|
if (!r) return -1;
|
||||||
|
|
||||||
|
if (rmap)
|
||||||
|
{
|
||||||
|
/* rmap can be NULL when a jump has been made for an empty source
|
||||||
|
* at the beginning of this fucntion */
|
||||||
|
qse_awk_rtx_refupval (rtx, rmap);
|
||||||
|
x = qse_awk_rtx_setrefval (rtx, (qse_awk_val_ref_t*)a1, rmap);
|
||||||
|
qse_awk_rtx_refdownval (rtx, rmap);
|
||||||
|
if (x <= -1)
|
||||||
|
{
|
||||||
|
qse_awk_rtx_freeval (rtx, r, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qse_awk_rtx_setretval (rtx, r);
|
qse_awk_rtx_setretval (rtx, r);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1197,10 +1197,8 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals)
|
|||||||
{
|
{
|
||||||
while (rtx->scache_count[i] > 0)
|
while (rtx->scache_count[i] > 0)
|
||||||
{
|
{
|
||||||
qse_awk_val_str_t* t =
|
qse_awk_val_str_t* t = rtx->scache[i][--rtx->scache_count[i]];
|
||||||
rtx->scache[i][--rtx->scache_count[i]];
|
qse_awk_rtx_freeval (rtx, (qse_awk_val_t*)t, 0);
|
||||||
qse_awk_rtx_freeval (
|
|
||||||
rtx, (qse_awk_val_t*)t, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user