-added Awk::Value::getFirstIndex() & Awk::Value::getNextIndex()

-fixed a few bugs in the Awk::Value class
This commit is contained in:
2009-07-14 02:51:23 +00:00
parent 814ed89e53
commit 9b6eb94664
11 changed files with 1077 additions and 730 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: Awk.cpp 229 2009-07-12 13:06:01Z hyunghwan.chung $
* $Id: Awk.cpp 230 2009-07-13 08:51:23Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -170,6 +170,51 @@ Awk::Console::Mode Awk::Console::getMode () const
//////////////////////////////////////////////////////////////////
const Awk::char_t* Awk::Value::EMPTY_STRING = QSE_T("");
Awk::Value::IndexIterator Awk::Value::IndexIterator::END;
Awk::Value::IntIndex::IntIndex (long_t x)
{
ptr = buf;
len = 0;
#define NTOC(n) ((n) + QSE_T('0'))
int base = 10;
long_t last = x % base;
long_t y = 0;
int dig = 0;
if (x < 0) buf[len++] = QSE_T('-');
x = x / base;
if (x < 0) x = -x;
while (x > 0)
{
y = y * base + (x % base);
x = x / base;
dig++;
}
while (y > 0)
{
buf[len++] = NTOC (y % base);
y = y / base;
dig--;
}
while (dig > 0)
{
dig--;
buf[len++] = QSE_T('0');
}
if (last < 0) last = -last;
buf[len++] = NTOC(last);
buf[len] = QSE_T('\0');
#undef NTOC
}
void* Awk::Value::operator new (size_t n, Run* run) throw ()
{
@ -326,7 +371,11 @@ int Awk::Value::getInt (long_t* v) const
{
real_t rv;
int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv);
if (n <= -1) return -1;
if (n <= -1)
{
run->awk->retrieveError (run->rtx);
return -1;
}
if (n >= 1) lv = rv;
}
@ -346,7 +395,11 @@ int Awk::Value::getReal (real_t* v) const
{
long_t lv;
int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv);
if (n <= -1) return -1;
if (n <= -1)
{
run->awk->retrieveError (run->rtx);
return -1;
}
if (n == 0) rv = lv;
}
@ -379,6 +432,7 @@ int Awk::Value::getStr (const char_t** str, size_t* len) const
if (qse_awk_rtx_valtostr (
run->rtx, val, &out) == QSE_NULL)
{
run->awk->retrieveError (run->rtx);
return -1;
}
@ -440,7 +494,11 @@ int Awk::Value::setInt (Run* r, long_t v)
{
val_t* tmp;
tmp = qse_awk_rtx_makeintval (r->rtx, v);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp);
QSE_ASSERT (n == 0);
@ -457,7 +515,11 @@ int Awk::Value::setReal (Run* r, real_t v)
{
val_t* tmp;
tmp = qse_awk_rtx_makerealval (r->rtx, v);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp);
QSE_ASSERT (n == 0);
@ -474,7 +536,11 @@ int Awk::Value::setStr (Run* r, const char_t* str, size_t len)
{
val_t* tmp;
tmp = qse_awk_rtx_makestrval (r->rtx, str, len);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp);
QSE_ASSERT (n == 0);
@ -491,27 +557,37 @@ int Awk::Value::setStr (Run* r, const char_t* str)
{
val_t* tmp;
tmp = qse_awk_rtx_makestrval0 (r->rtx, str);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp);
QSE_ASSERT (n == 0);
return n;
}
int Awk::Value::setIndexedVal (const char_t* idx, size_t isz, val_t* v)
int Awk::Value::setIndexedVal (const Index& idx, val_t* v)
{
if (run == QSE_NULL) return -1;
return setIndexedVal (run, idx, isz, v);
return setIndexedVal (run, idx, v);
}
int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v)
{
QSE_ASSERT (r != QSE_NULL);
if (val->type != QSE_AWK_VAL_MAP)
{
/* the previous value is not a map.
* a new map value needs to be created first */
val_t* map = qse_awk_rtx_makemapval (run->rtx);
if (map == QSE_NULL) return -1;
val_t* map = qse_awk_rtx_makemapval (r->rtx);
if (map == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, map);
qse_awk_rtx_refupval (r->rtx, v);
@ -519,12 +595,13 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
/* update the map with a given value */
pair_t* pair = qse_map_upsert (
((qse_awk_val_map_t*)map)->map,
(char_t*)idx, isz, v, 0);
(char_t*)idx.ptr, idx.len, v, 0);
if (pair == QSE_NULL)
{
qse_awk_rtx_refdownval (r->rtx, v);
qse_awk_rtx_refdownval (r->rtx, map);
run->setError (ERR_NOMEM, 0, QSE_NULL, 0);
r->setError (ERR_NOMEM, 0, QSE_NULL, 0);
r->awk->retrieveError (r->rtx);
return -1;
}
@ -545,6 +622,7 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
{
// it can't span across multiple runtime contexts
run->setError (ERR_INVAL);
run->awk->retrieveError (run->rtx);
return -1;
}
@ -552,11 +630,12 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
pair_t* pair = qse_map_upsert (
((qse_awk_val_map_t*)val)->map,
(char_t*)idx, isz, v, 0);
(char_t*)idx.ptr, idx.len, v, 0);
if (pair == QSE_NULL)
{
qse_awk_rtx_refdownval (r->rtx, v);
run->setError (ERR_NOMEM);
run->awk->retrieveError (run->rtx);
return -1;
}
}
@ -564,79 +643,94 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
return 0;
}
int Awk::Value::setIndexedInt (const char_t* idx, size_t isz, long_t v)
int Awk::Value::setIndexedInt (const Index& idx, long_t v)
{
if (run == QSE_NULL) return -1;
return setIndexedInt (run, idx, isz, v);
return setIndexedInt (run, idx, v);
}
int Awk::Value::setIndexedInt (Run* r, const char_t* idx, size_t isz, long_t v)
int Awk::Value::setIndexedInt (Run* r, const Index& idx, long_t v)
{
val_t* tmp;
tmp = qse_awk_rtx_makeintval (r->rtx, v);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp);
int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Awk::Value::setIndexedReal (const char_t* idx, size_t isz, real_t v)
int Awk::Value::setIndexedReal (const Index& idx, real_t v)
{
if (run == QSE_NULL) return -1;
return setIndexedReal (run, idx, isz, v);
return setIndexedReal (run, idx, v);
}
int Awk::Value::setIndexedReal (Run* r, const char_t* idx, size_t isz, real_t v)
int Awk::Value::setIndexedReal (Run* r, const Index& idx, real_t v)
{
val_t* tmp;
tmp = qse_awk_rtx_makerealval (r->rtx, v);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp);
int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Awk::Value::setIndexedStr (const char_t* idx, size_t isz, const char_t* str, size_t len)
int Awk::Value::setIndexedStr (const Index& idx, const char_t* str, size_t len)
{
if (run == QSE_NULL) return -1;
return setIndexedStr (run, idx, isz, str, len);
return setIndexedStr (run, idx, str, len);
}
int Awk::Value::setIndexedStr (
Run* r, const char_t* idx, size_t isz, const char_t* str, size_t len)
Run* r, const Index& idx, const char_t* str, size_t len)
{
val_t* tmp;
tmp = qse_awk_rtx_makestrval (r->rtx, str, len);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp);
int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Awk::Value::setIndexedStr (const char_t* idx, size_t isz, const char_t* str)
int Awk::Value::setIndexedStr (const Index& idx, const char_t* str)
{
if (run == QSE_NULL) return -1;
return setIndexedStr (run, idx, isz, str);
return setIndexedStr (run, idx, str);
}
int Awk::Value::setIndexedStr (
Run* r, const char_t* idx, size_t isz, const char_t* str)
int Awk::Value::setIndexedStr (Run* r, const Index& idx, const char_t* str)
{
val_t* tmp;
tmp = qse_awk_rtx_makestrval0 (r->rtx, str);
if (tmp == QSE_NULL) return -1;
if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp);
int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp);
return n;
@ -649,30 +743,68 @@ bool Awk::Value::isIndexed () const
return val->type == QSE_AWK_VAL_MAP;
}
int Awk::Value::getIndexed (const char_t* idx, size_t isz, Value& v) const
int Awk::Value::getIndexed (const Index& idx, Value* v) const
{
QSE_ASSERT (val != QSE_NULL);
// not a map. v is just nil. not an error
if (val->type != QSE_AWK_VAL_MAP)
{
v.clear ();
v->clear ();
return 0;
}
// get the value from the map.
qse_awk_val_map_t* m = (qse_awk_val_map_t*)val;
pair_t* pair = qse_map_search (m->map, idx, isz);
pair_t* pair = qse_map_search (m->map, idx.ptr, idx.len);
// the key is not found. it is not an error. v is just nil
if (pair == QSE_NULL)
{
v.clear ();
v->clear ();
return 0;
}
// if v.set fails, it should return an error
return v.setVal (run, (val_t*)QSE_MAP_VPTR(pair));
return v->setVal (run, (val_t*)QSE_MAP_VPTR(pair));
}
Awk::Value::IndexIterator Awk::Value::getFirstIndex (Index* idx) const
{
QSE_ASSERT (val != QSE_NULL);
if (val->type != QSE_AWK_VAL_MAP) return IndexIterator::END;
size_t buckno;
qse_awk_val_map_t* m = (qse_awk_val_map_t*)val;
pair_t* pair = qse_map_getfirstpair (m->map, &buckno);
if (pair == QSE_NULL) return IndexIterator::END; // no more key
idx->ptr = (const char_t*)QSE_MAP_KPTR(pair);
idx->len = QSE_MAP_KLEN(pair);
return IndexIterator (pair, buckno);
}
Awk::Value::IndexIterator Awk::Value::getNextIndex (
Index* idx, const IndexIterator& iter) const
{
QSE_ASSERT (val != QSE_NULL);
if (val->type != QSE_AWK_VAL_MAP) return IndexIterator::END;
qse_awk_val_map_t* m = (qse_awk_val_map_t*)val;
pair_t* pair = (pair_t*)iter.pair;
size_t buckno = iter.buckno;
pair = qse_map_getnextpair (m->map, pair, &buckno);
if (pair == QSE_NULL) return IndexIterator::END;
idx->ptr = (const char_t*)QSE_MAP_KPTR(pair);
idx->len = QSE_MAP_KLEN(pair);
return IndexIterator (pair, buckno);
}
#if 0
@ -724,35 +856,6 @@ int Awk::Argument::getNextIndex (Awk::Argument& val) const
return 1;
}
int Awk::Return::setIndexed (long_t idx, real_t v)
{
if (this->run == QSE_NULL) return -1;
char_t ri[128];
int rl = Awk::sprintf (
(awk_t*)this->run->awk, ri, QSE_COUNTOF(ri),
#if QSE_SIZEOF_LONG_LONG > 0
QSE_T("%lld"), (long long)idx
#elif QSE_SIZEOF___INT64 > 0
QSE_T("%I64d"), (__int64)idx
#elif QSE_SIZEOF_LONG > 0
QSE_T("%ld"), (long)idx
#elif QSE_SIZEOF_INT > 0
QSE_T("%d"), (int)idx
#else
#error unsupported size
#endif
);
if (rl < 0)
{
this->run->setError (ERR_INTERN, 0, QSE_NULL, 0);
return -1;
}
return setIndexed (ri, rl, v);
}
#endif
//////////////////////////////////////////////////////////////////
@ -1270,6 +1373,7 @@ int Awk::call (const char_t* name, Value* ret, const Value* args, size_t nargs)
if (ptr == QSE_NULL)
{
runctx.setError (ERR_NOMEM);
retrieveError (runctx.rtx);
return -1;
}
}

View File

@ -1,5 +1,5 @@
/*
* $Id: misc.c 220 2009-07-01 13:14:39Z hyunghwan.chung $
* $Id: misc.c 230 2009-07-13 08:51:23Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -983,6 +983,11 @@ void* qse_awk_rtx_alloc (qse_awk_rtx_t* rtx, qse_size_t size)
return qse_awk_alloc (rtx->awk, size);
}
void* qse_awk_rtx_realloc (qse_awk_rtx_t* rtx, void* ptr, qse_size_t size)
{
return qse_awk_realloc (rtx->awk, ptr, size);
}
void qse_awk_rtx_free (qse_awk_rtx_t* rtx, void* ptr)
{
qse_awk_free (rtx->awk, ptr);

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c 228 2009-07-11 03:01:36Z hyunghwan.chung $
* $Id: run.c 230 2009-07-13 08:51:23Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -243,6 +243,9 @@ typedef qse_awk_val_t* (*binop_func_t) (
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
typedef qse_awk_val_t* (*eval_expr_t) (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
#ifdef NDEBUG
#define xstr_to_cstr(x) ((qse_cstr_t*)x)
#else
static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr)
{
/* i use this function to typecast qse_cstr_t* to
@ -252,6 +255,7 @@ static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr)
* haved changed to something else. */
return (qse_cstr_t*)xstr;
}
#endif
qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run)
{
@ -3328,7 +3332,6 @@ static qse_awk_val_t* do_assignment (
goto exit_on_error;
}
ret = do_assignment_pos (run, (qse_awk_nde_pos_t*)var, val);
}
else
@ -3463,7 +3466,7 @@ static qse_awk_val_t* do_assignment_map (
(var->type == QSE_AWK_NDE_LCLIDX)?
(qse_awk_val_map_t*)STACK_LCL(run,var->id.idxa):
(qse_awk_val_map_t*)STACK_ARG(run,var->id.idxa);
}
}
if (map->type == QSE_AWK_VAL_NIL)
{