enhanced qse_awk_rtx_valtostr()

This commit is contained in:
2011-05-25 09:14:58 +00:00
parent 8497ddae25
commit 26427dd4c3
13 changed files with 246 additions and 161 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c 477 2011-05-24 04:22:40Z hyunghwan.chung $
* $Id: run.c 479 2011-05-24 15:14:58Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -2536,9 +2536,9 @@ static int delete_indexed (
qse_awk_rtx_valtostr_out_t out;
/* try with a fixed-size buffer */
out.type = QSE_AWK_RTX_VALTOSTR_CPL;
out.u.cpl.ptr = buf;
out.u.cpl.len = QSE_COUNTOF(buf);
out.type = QSE_AWK_RTX_VALTOSTR_CPLCP;
out.u.cplcp.ptr = buf;
out.u.cplcp.len = QSE_COUNTOF(buf);
key = qse_awk_rtx_valtostr (rtx, idx, &out);
if (key == QSE_NULL)
{
@ -2556,8 +2556,8 @@ static int delete_indexed (
return -1;
}
keylen = (out.type == QSE_AWK_RTX_VALTOSTR_CPL)?
out.u.cpl.len: out.u.cpldup.len;
keylen = (out.type == QSE_AWK_RTX_VALTOSTR_CPLCP)?
out.u.cplcp.len: out.u.cpldup.len;
qse_htb_delete (map, key, keylen);
@ -6601,14 +6601,14 @@ static qse_char_t* idxnde_to_str (
if (buf != QSE_NULL)
{
/* try with a fixed-size buffer if given */
out.type = QSE_AWK_RTX_VALTOSTR_CPL;
out.u.cpl.ptr = buf;
out.u.cpl.len = *len;
out.type = QSE_AWK_RTX_VALTOSTR_CPLCP;
out.u.cplcp.ptr = buf;
out.u.cplcp.len = *len;
if (qse_awk_rtx_valtostr (run, idx, &out) != QSE_NULL)
{
str = out.u.cpl.ptr;
*len = out.u.cpl.len;
str = out.u.cplcp.ptr;
*len = out.u.cplcp.len;
QSE_ASSERT (str == buf);
}
}

View File

@ -1,5 +1,5 @@
/*
* $Id: val.c 462 2011-05-18 14:36:40Z hyunghwan.chung $
* $Id: val.c 479 2011-05-24 15:14:58Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -725,7 +725,7 @@ void qse_awk_rtx_freevalchunk (qse_awk_rtx_t* rtx, qse_awk_val_chunk_t* chunk)
}
}
qse_bool_t qse_awk_rtx_valtobool (qse_awk_rtx_t* run, qse_awk_val_t* val)
qse_bool_t qse_awk_rtx_valtobool (qse_awk_rtx_t* run, const qse_awk_val_t* val)
{
if (val == QSE_NULL) return QSE_FALSE;
@ -763,16 +763,23 @@ static qse_char_t* str_to_str (
{
case QSE_AWK_RTX_VALTOSTR_CPL:
{
if (str_len >= out->u.cpl.len)
out->u.cpl.len = str_len;
out->u.cpl.ptr = str;
return out->u.cpl.ptr;
}
case QSE_AWK_RTX_VALTOSTR_CPLCP:
{
if (str_len >= out->u.cplcp.len)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
out->u.cpl.len = str_len + 1;
out->u.cplcp.len = str_len + 1;
return QSE_NULL;
}
out->u.cpl.len =
qse_strncpy (out->u.cpl.ptr, str, str_len);
return out->u.cpl.ptr;
out->u.cplcp.len =
qse_strncpy (out->u.cplcp.ptr, str, str_len);
return out->u.cplcp.ptr;
}
case QSE_AWK_RTX_VALTOSTR_CPLDUP:
@ -826,7 +833,7 @@ static qse_char_t* str_to_str (
}
static qse_char_t* val_int_to_str (
qse_awk_rtx_t* rtx, qse_awk_val_int_t* v,
qse_awk_rtx_t* rtx, const qse_awk_val_int_t* v,
qse_awk_rtx_valtostr_out_t* out)
{
qse_char_t* tmp;
@ -841,18 +848,25 @@ static qse_char_t* val_int_to_str (
switch (type)
{
case QSE_AWK_RTX_VALTOSTR_CPL:
if (out->u.cpl.len <= 1)
/* CPL and CPLCP behave the same for int_t.
* i just fall through assuming that cplcp
* and cpl are the same type. the following
* assertion at least ensure that they have
* the same size. */
QSE_ASSERT (QSE_SIZEOF(out->u.cpl) == QSE_SIZEOF(out->u.cplcp));
case QSE_AWK_RTX_VALTOSTR_CPLCP:
if (out->u.cplcp.len <= 1)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
/* store the buffer size needed */
out->u.cpl.len = 2;
out->u.cplcp.len = 2;
return QSE_NULL;
}
out->u.cpl.len = 1; /* actual length */
out->u.cpl.ptr[0] = QSE_T('0');
out->u.cpl.ptr[1] = QSE_T('\0');
return out->u.cpl.ptr;
out->u.cplcp.len = 1; /* actual length */
out->u.cplcp.ptr[0] = QSE_T('0');
out->u.cplcp.ptr[1] = QSE_T('\0');
return out->u.cplcp.ptr;
case QSE_AWK_RTX_VALTOSTR_CPLDUP:
tmp = QSE_AWK_ALLOC (
@ -899,17 +913,25 @@ static qse_char_t* val_int_to_str (
switch (type)
{
case QSE_AWK_RTX_VALTOSTR_CPL:
if (rlen >= out->u.cpl.len)
/* CPL and CPLCP behave the same for int_t.
* i just fall through assuming that cplcp
* and cpl are the same type. the following
* assertion at least ensure that they have
* the same size. */
QSE_ASSERT (QSE_SIZEOF(out->u.cpl) == QSE_SIZEOF(out->u.cplcp));
case QSE_AWK_RTX_VALTOSTR_CPLCP:
if (rlen >= out->u.cplcp.len)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
/* store the buffer size needed */
out->u.cpl.len = rlen + 1;
out->u.cplcp.len = rlen + 1;
return QSE_NULL;
}
tmp = out->u.cpl.ptr;
tmp = out->u.cplcp.ptr;
tmp[rlen] = QSE_T('\0');
out->u.cpl.len = rlen;
out->u.cplcp.len = rlen;
break;
case QSE_AWK_RTX_VALTOSTR_CPLDUP:
@ -988,7 +1010,7 @@ static qse_char_t* val_int_to_str (
}
static qse_char_t* val_real_to_str (
qse_awk_rtx_t* rtx, qse_awk_val_real_t* v,
qse_awk_rtx_t* rtx, const qse_awk_val_real_t* v,
qse_awk_rtx_valtostr_out_t* out)
{
qse_char_t* tmp;
@ -1032,20 +1054,27 @@ static qse_char_t* val_real_to_str (
switch (type)
{
case QSE_AWK_RTX_VALTOSTR_CPL:
/* CPL and CPLCP behave the same for real_t.
* i just fall through assuming that cplcp
* and cpl are the same type. the following
* assertion at least ensure that they have
* the same size. */
QSE_ASSERT (QSE_SIZEOF(out->u.cpl) == QSE_SIZEOF(out->u.cplcp));
if (out->u.cpl.len <= tmp_len)
case QSE_AWK_RTX_VALTOSTR_CPLCP:
if (out->u.cplcp.len <= tmp_len)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
/* store the buffer size required */
out->u.cpl.len = tmp_len + 1;
out->u.cplcp.len = tmp_len + 1;
qse_str_close (&fbu);
qse_str_close (&buf);
return QSE_NULL;
}
qse_strncpy (out->u.cpl.ptr, tmp, tmp_len);
out->u.cpl.len = tmp_len;
tmp = out->u.cpl.ptr;
qse_strncpy (out->u.cplcp.ptr, tmp, tmp_len);
out->u.cplcp.len = tmp_len;
tmp = out->u.cplcp.ptr;
qse_str_fini (&fbu);
qse_str_fini (&buf);
@ -1111,20 +1140,27 @@ static qse_char_t* val_real_to_str (
}
qse_char_t* qse_awk_rtx_valtostr (
qse_awk_rtx_t* rtx, qse_awk_val_t* v, qse_awk_rtx_valtostr_out_t* out)
qse_awk_rtx_t* rtx, const qse_awk_val_t* v,
qse_awk_rtx_valtostr_out_t* out)
{
switch (v->type)
{
case QSE_AWK_VAL_NIL:
{
return str_to_str (rtx, QSE_T(""), 0, out);
}
case QSE_AWK_VAL_INT:
{
return val_int_to_str (
rtx, (qse_awk_val_int_t*)v, out);
}
case QSE_AWK_VAL_REAL:
{
return val_real_to_str (
rtx, (qse_awk_val_real_t*)v, out);
}
case QSE_AWK_VAL_STR:
{
@ -1144,7 +1180,7 @@ qse_char_t* qse_awk_rtx_valtostr (
}
qse_char_t* qse_awk_rtx_valtocpldup (
qse_awk_rtx_t* rtx, qse_awk_val_t* v, qse_size_t* len)
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_size_t* len)
{
qse_awk_rtx_valtostr_out_t out;
@ -1156,7 +1192,7 @@ qse_char_t* qse_awk_rtx_valtocpldup (
}
int qse_awk_rtx_valtonum (
qse_awk_rtx_t* rtx, qse_awk_val_t* v, qse_long_t* l, qse_real_t* r)
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_long_t* l, qse_real_t* r)
{
if (v->type == QSE_AWK_VAL_NIL)
{

View File

@ -1,5 +1,5 @@
/*
* $Id: lda.c 474 2011-05-23 16:52:37Z hyunghwan.chung $
* $Id: lda.c 479 2011-05-24 15:14:58Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -36,8 +36,8 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (lda)
#define size_t qse_size_t
#define TOB(lda,len) ((len)*(lda)->scale)
#define DPTR(node) ((node)->val.ptr)
#define DLEN(node) ((node)->val.len)
#define DPTR(slot) ((slot)->val.ptr)
#define DLEN(slot) ((slot)->val.len)
static int default_comparator (lda_t* lda,
const void* dptr1, size_t dlen1,
@ -58,7 +58,7 @@ static int default_comparator (lda_t* lda,
return n;
}
static QSE_INLINE slot_t* alloc_node (lda_t* lda, void* dptr, size_t dlen)
static QSE_INLINE slot_t* alloc_slot (lda_t* lda, void* dptr, size_t dlen)
{
slot_t* n;
@ -135,7 +135,7 @@ lda_t* qse_lda_init (lda_t* lda, mmgr_t* mmgr, size_t capa)
lda->mmgr = mmgr;
lda->size = 0;
lda->capa = 0;
lda->node = QSE_NULL;
lda->slot = QSE_NULL;
lda->copier = QSE_LDA_COPIER_SIMPLE;
lda->comper = default_comparator;
@ -148,10 +148,10 @@ void qse_lda_fini (lda_t* lda)
{
qse_lda_clear (lda);
if (lda->node != QSE_NULL)
if (lda->slot != QSE_NULL)
{
QSE_MMGR_FREE (lda->mmgr, lda->node);
lda->node = QSE_NULL;
QSE_MMGR_FREE (lda->mmgr, lda->slot);
lda->slot = QSE_NULL;
lda->capa = 0;
}
}
@ -250,41 +250,41 @@ lda_t* qse_lda_setcapa (lda_t* lda, size_t capa)
if (capa > 0)
{
if (lda->mmgr->realloc != QSE_NULL && lda->node != QSE_NULL)
if (lda->mmgr->realloc != QSE_NULL && lda->slot != QSE_NULL)
{
tmp = (slot_t**) QSE_MMGR_REALLOC (
lda->mmgr, lda->node,
QSE_SIZEOF(*lda->node)*capa);
lda->mmgr, lda->slot,
QSE_SIZEOF(*lda->slot)*capa);
if (tmp == QSE_NULL) return QSE_NULL;
}
else
{
tmp = (slot_t**) QSE_MMGR_ALLOC (
lda->mmgr, QSE_SIZEOF(*lda->node)*capa);
lda->mmgr, QSE_SIZEOF(*lda->slot)*capa);
if (tmp == QSE_NULL) return QSE_NULL;
if (lda->node != QSE_NULL)
if (lda->slot != QSE_NULL)
{
size_t x;
x = (capa > lda->capa)? lda->capa: capa;
QSE_MEMCPY (tmp, lda->node,
QSE_SIZEOF(*lda->node)*x);
QSE_MMGR_FREE (lda->mmgr, lda->node);
QSE_MEMCPY (tmp, lda->slot,
QSE_SIZEOF(*lda->slot)*x);
QSE_MMGR_FREE (lda->mmgr, lda->slot);
}
}
}
else
{
if (lda->node != QSE_NULL)
if (lda->slot != QSE_NULL)
{
qse_lda_clear (lda);
QSE_MMGR_FREE (lda->mmgr, lda->node);
QSE_MMGR_FREE (lda->mmgr, lda->slot);
}
tmp = QSE_NULL;
}
lda->node = tmp;
lda->slot = tmp;
lda->capa = capa;
return lda;
@ -296,10 +296,10 @@ size_t qse_lda_search (lda_t* lda, size_t pos, const void* dptr, size_t dlen)
for (i = pos; i < lda->size; i++)
{
if (lda->node[i] == QSE_NULL) continue;
if (lda->slot[i] == QSE_NULL) continue;
if (lda->comper (lda,
DPTR(lda->node[i]), DLEN(lda->node[i]),
DPTR(lda->slot[i]), DLEN(lda->slot[i]),
dptr, dlen) == 0) return i;
}
@ -316,10 +316,10 @@ size_t qse_lda_rsearch (lda_t* lda, size_t pos, const void* dptr, size_t dlen)
for (i = pos + 1; i-- > 0; )
{
if (lda->node[i] == QSE_NULL) continue;
if (lda->slot[i] == QSE_NULL) continue;
if (lda->comper (lda,
DPTR(lda->node[i]), DLEN(lda->node[i]),
DPTR(lda->slot[i]), DLEN(lda->slot[i]),
dptr, dlen) == 0) return i;
}
}
@ -336,14 +336,14 @@ size_t qse_lda_upsert (lda_t* lda, size_t pos, void* dptr, size_t dlen)
size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen)
{
size_t i;
slot_t* node;
slot_t* slot;
/* allocate the node first */
node = alloc_node (lda, dptr, dlen);
if (node == QSE_NULL) return QSE_LDA_NIL;
/* allocate the slot first */
slot = alloc_slot (lda, dptr, dlen);
if (slot == QSE_NULL) return QSE_LDA_NIL;
/* do resizeing if necessary.
* resizing is performed after node allocation because that way, it
* resizing is performed after slot allocation because that way, it
* doesn't modify lda on any errors */
if (pos >= lda->capa || lda->size >= lda->capa)
{
@ -377,8 +377,8 @@ size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen)
if (capa <= mincapa)
{
if (lda->freeer)
lda->freeer (lda, DPTR(node), DLEN(node));
QSE_MMGR_FREE (lda->mmgr, node);
lda->freeer (lda, DPTR(slot), DLEN(slot));
QSE_MMGR_FREE (lda->mmgr, slot);
return QSE_LDA_NIL;
}
@ -391,19 +391,19 @@ size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen)
{
/* the buffer is not still enough after resizing */
if (lda->freeer)
lda->freeer (lda, DPTR(node), DLEN(node));
QSE_MMGR_FREE (lda->mmgr, node);
lda->freeer (lda, DPTR(slot), DLEN(slot));
QSE_MMGR_FREE (lda->mmgr, slot);
return QSE_LDA_NIL;
}
/* fill in the gap with QSE_NULL */
for (i = lda->size; i < pos; i++) lda->node[i] = QSE_NULL;
for (i = lda->size; i < pos; i++) lda->slot[i] = QSE_NULL;
/* shift values to the next cell */
for (i = lda->size; i > pos; i--) lda->node[i] = lda->node[i-1];
for (i = lda->size; i > pos; i--) lda->slot[i] = lda->slot[i-1];
/* set the value */
lda->node[pos] = node;
lda->slot[pos] = slot;
if (pos > lda->size) lda->size = pos + 1;
else lda->size++;
@ -417,12 +417,12 @@ size_t qse_lda_update (lda_t* lda, size_t pos, void* dptr, size_t dlen)
if (pos >= lda->size) return QSE_LDA_NIL;
c = lda->node[pos];
c = lda->slot[pos];
if (c == QSE_NULL)
{
/* no previous data */
lda->node[pos] = alloc_node (lda, dptr, dlen);
if (lda->node[pos] == QSE_NULL) return QSE_LDA_NIL;
lda->slot[pos] = alloc_slot (lda, dptr, dlen);
if (lda->slot[pos] == QSE_NULL) return QSE_LDA_NIL;
}
else
{
@ -434,14 +434,14 @@ size_t qse_lda_update (lda_t* lda, size_t pos, void* dptr, size_t dlen)
else
{
/* updated to different data */
slot_t* node = alloc_node (lda, dptr, dlen);
if (node == QSE_NULL) return QSE_LDA_NIL;
slot_t* slot = alloc_slot (lda, dptr, dlen);
if (slot == QSE_NULL) return QSE_LDA_NIL;
if (lda->freeer != QSE_NULL)
lda->freeer (lda, DPTR(c), DLEN(c));
QSE_MMGR_FREE (lda->mmgr, c);
lda->node[pos] = node;
lda->slot[pos] = slot;
}
}
@ -459,7 +459,7 @@ size_t qse_lda_delete (lda_t* lda, size_t index, size_t count)
for (i = index; i < index + count; i++)
{
slot_t* c = lda->node[i];
slot_t* c = lda->slot[i];
if (c != QSE_NULL)
{
@ -467,15 +467,15 @@ size_t qse_lda_delete (lda_t* lda, size_t index, size_t count)
lda->freeer (lda, DPTR(c), DLEN(c));
QSE_MMGR_FREE (lda->mmgr, c);
lda->node[i] = QSE_NULL;
lda->slot[i] = QSE_NULL;
}
}
for (i = index + count; i < lda->size; i++)
{
lda->node[i-count] = lda->node[i];
lda->slot[i-count] = lda->slot[i];
}
lda->node[lda->size-1] = QSE_NULL;
lda->slot[lda->size-1] = QSE_NULL;
lda->size -= count;
return count;
@ -492,7 +492,7 @@ size_t qse_lda_uplete (lda_t* lda, size_t index, size_t count)
for (i = index; i < index + count; i++)
{
slot_t* c = lda->node[i];
slot_t* c = lda->slot[i];
if (c != QSE_NULL)
{
@ -500,7 +500,7 @@ size_t qse_lda_uplete (lda_t* lda, size_t index, size_t count)
lda->freeer (lda, DPTR(c), DLEN(c));
QSE_MMGR_FREE (lda->mmgr, c);
lda->node[i] = QSE_NULL;
lda->slot[i] = QSE_NULL;
}
}
@ -513,13 +513,13 @@ void qse_lda_clear (lda_t* lda)
for (i = 0; i < lda->size; i++)
{
slot_t* c = lda->node[i];
slot_t* c = lda->slot[i];
if (c != QSE_NULL)
{
if (lda->freeer)
lda->freeer (lda, DPTR(c), DLEN(c));
QSE_MMGR_FREE (lda->mmgr, c);
lda->node[i] = QSE_NULL;
lda->slot[i] = QSE_NULL;
}
}
@ -535,7 +535,7 @@ size_t qse_lda_walk (lda_t* lda, walker_t walker, void* ctx)
while (1)
{
if (lda->node[i] != QSE_NULL)
if (lda->slot[i] != QSE_NULL)
{
w = walker (lda, i, ctx);
nwalks++;
@ -568,7 +568,7 @@ size_t qse_lda_rwalk (lda_t* lda, walker_t walker, void* ctx)
while (1)
{
if (lda->node[i] != QSE_NULL)
if (lda->slot[i] != QSE_NULL)
{
w = walker (lda, i, ctx);
nwalks++;
@ -623,14 +623,14 @@ size_t qse_lda_pushheap (lda_t* lda, void* dptr, size_t dlen)
/* compare with the parent */
par = HEAP_PARENT(cur);
n = lda->comper (lda,
DPTR(lda->node[cur]), DLEN(lda->node[cur]),
DPTR(lda->node[par]), DLEN(lda->node[par]));
DPTR(lda->slot[cur]), DLEN(lda->slot[cur]),
DPTR(lda->slot[par]), DLEN(lda->slot[par]));
if (n <= 0) break; /* ok */
/* swap the current with the parent */
tmp = lda->node[cur];
lda->node[cur] = lda->node[par];
lda->node[par] = tmp;
tmp = lda->slot[cur];
lda->slot[cur] = lda->slot[par];
lda->slot[par] = tmp;
cur = par;
}
@ -646,12 +646,12 @@ void qse_lda_popheap (lda_t* lda)
QSE_ASSERT (lda->size > 0);
/* destroy the top */
tmp = lda->node[0];
tmp = lda->slot[0];
if (lda->freeer) lda->freeer (lda, DPTR(tmp), DLEN(tmp));
QSE_MMGR_FREE (lda->mmgr, tmp);
/* move the last item to the top position also shrink the size */
lda->node[0] = lda->node[--lda->size];
lda->slot[0] = lda->slot[--lda->size];
if (lda->size <= 1) return; /* only 1 element. nothing further to do */
@ -679,20 +679,20 @@ void qse_lda_popheap (lda_t* lda)
{
/* get the larger child of the two */
n = lda->comper (lda,
DPTR(lda->node[left]), DLEN(lda->node[left]),
DPTR(lda->node[right]), DLEN(lda->node[right]));
DPTR(lda->slot[left]), DLEN(lda->slot[left]),
DPTR(lda->slot[right]), DLEN(lda->slot[right]));
child = (n > 0)? left: right;
}
/* compare the current one with the child */
n = lda->comper (lda,
DPTR(lda->node[cur]), DLEN(lda->node[cur]),
DPTR(lda->node[child]), DLEN(lda->node[child]));
DPTR(lda->slot[cur]), DLEN(lda->slot[cur]),
DPTR(lda->slot[child]), DLEN(lda->slot[child]));
if (n > 0) break; /* current one is larger. stop exchange */
/* swap the current with the child */
tmp = lda->node[cur];
lda->node[cur] = lda->node[child];
lda->node[child] = tmp;
tmp = lda->slot[cur];
lda->slot[cur] = lda->slot[child];
lda->slot[child] = tmp;
}
}