Added asorti() to awk
This commit is contained in:
parent
3737a28cd3
commit
df47611d9d
@ -35,6 +35,7 @@ static int fnc_typename (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
|
||||
static int fnc_isnil (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
|
||||
static int fnc_ismap (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
|
||||
static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
|
||||
static int fnc_asorti (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
|
||||
|
||||
#define A_MAX QSE_TYPE_MAX(int)
|
||||
|
||||
@ -66,8 +67,9 @@ static qse_awk_fnc_t sysfnctab[] =
|
||||
{ {QSE_T("ismap"), 5}, 0, { {1, 1, QSE_NULL}, fnc_ismap, 0 }, QSE_NULL},
|
||||
{ {QSE_T("typename"), 8}, 0, { {1, 1, QSE_NULL}, fnc_typename, 0 }, QSE_NULL},
|
||||
|
||||
/* array sort */
|
||||
/* map(array) sort */
|
||||
{ {QSE_T("asort"), 5}, 0, { {1, 3, QSE_T("rrv")}, fnc_asort, 0 }, QSE_NULL},
|
||||
{ {QSE_T("asorti"), 6}, 0, { {1, 3, QSE_T("rrv")}, fnc_asorti, 0 }, QSE_NULL},
|
||||
|
||||
/* string functions */
|
||||
{ {QSE_T("gsub"), 4}, 0, { {2, 3, QSE_T("xvr")}, qse_awk_fnc_gsub, 0 }, QSE_NULL},
|
||||
@ -1555,7 +1557,7 @@ static QSE_INLINE int asort_compare_ud (const void* x1, const void* x2, void* ct
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
static QSE_INLINE int __fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, int sort_keys)
|
||||
{
|
||||
qse_size_t nargs;
|
||||
qse_awk_val_t* a0, * a0_val, * a1, * a2;
|
||||
@ -1617,7 +1619,6 @@ static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
a1 = a0; /* let a0 be the destination. a0 is both source and destination */
|
||||
}
|
||||
|
||||
|
||||
if (!qse_awk_rtx_getfirstmapvalitr(rtx, a0_val, &itr)) goto done; /* map empty */
|
||||
|
||||
msz = qse_htb_getsize(((qse_awk_val_map_t*)a0_val)->map);
|
||||
@ -1625,13 +1626,35 @@ static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
|
||||
va = (qse_awk_val_t**)qse_awk_rtx_allocmem(rtx, msz * QSE_SIZEOF(*va));
|
||||
if (!va) return -1;
|
||||
|
||||
i = 0;
|
||||
if (sort_keys)
|
||||
{
|
||||
do
|
||||
{
|
||||
const qse_cstr_t* key = QSE_AWK_VAL_MAP_ITR_KEY(&itr);
|
||||
va[i] = qse_awk_rtx_makestrvalwithxstr(rtx, key);
|
||||
if (!va[i])
|
||||
{
|
||||
while (i > 0)
|
||||
{
|
||||
--i;
|
||||
qse_awk_rtx_freeval (rtx, va[i], 0);
|
||||
}
|
||||
qse_awk_rtx_freemem (rtx, va);
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (qse_awk_rtx_getnextmapvalitr(rtx, a0_val, &itr));
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
va[i++] = (qse_awk_val_t*)QSE_AWK_VAL_MAP_ITR_VAL(&itr);
|
||||
}
|
||||
while (qse_awk_rtx_getnextmapvalitr(rtx, a0_val, &itr));
|
||||
}
|
||||
|
||||
if (fun)
|
||||
{
|
||||
@ -1645,15 +1668,12 @@ static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
x = qse_qsortx(va, msz, QSE_SIZEOF(*va), asort_compare, rtx);
|
||||
}
|
||||
|
||||
if (x <= -1)
|
||||
if (x <= -1 || !(rmap = qse_awk_rtx_makemapval(rtx)))
|
||||
{
|
||||
qse_awk_rtx_freemem (rtx, va);
|
||||
return -1;
|
||||
if (sort_keys)
|
||||
{
|
||||
for (i = 0; i < msz; i++) qse_awk_rtx_freeval (rtx, va[i], 0);
|
||||
}
|
||||
|
||||
rmap = qse_awk_rtx_makemapval(rtx);
|
||||
if (!rmap)
|
||||
{
|
||||
qse_awk_rtx_freemem (rtx, va);
|
||||
return -1;
|
||||
}
|
||||
@ -1675,7 +1695,17 @@ static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
|
||||
if (qse_awk_rtx_setmapvalfld(rtx, rmap, ridx, ridx_len, va[i]) == QSE_NULL)
|
||||
{
|
||||
qse_awk_rtx_freeval (rtx, rmap, 0);
|
||||
qse_awk_rtx_freeval (rtx, rmap, 0); /* this delete the elements added. */
|
||||
if (sort_keys)
|
||||
{
|
||||
/* delete the elements not added yet */
|
||||
do
|
||||
{
|
||||
qse_awk_rtx_freeval(rtx, va[i], 0);
|
||||
i++;
|
||||
}
|
||||
while (i < msz);
|
||||
}
|
||||
qse_awk_rtx_freemem (rtx, va);
|
||||
return -1;
|
||||
}
|
||||
@ -1694,3 +1724,13 @@ done:
|
||||
qse_awk_rtx_setretval (rtx, r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
{
|
||||
return __fnc_asort(rtx, fi, 0);
|
||||
}
|
||||
|
||||
static int fnc_asorti (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
{
|
||||
return __fnc_asort(rtx, fi, 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user