diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 84ac0033..72e365b1 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 455 2011-05-09 16:11:13Z hyunghwan.chung $ + * $Id: awk.c 456 2011-05-12 14:55:53Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 49477119..3e057b98 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: awk.h 456 2011-05-12 14:55:53Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -1898,6 +1898,34 @@ qse_awk_val_t* qse_awk_rtx_makemapval ( qse_awk_rtx_t* rtx ); + +/** + * The qse_awk_rtx_setmapvalfld() function sets a field value in a map. + * You must make sure that the type of @a map is #QSE_AWK_VAL_MAP. + * @return value @a v on success, #QSE_NULL on failure. + */ +qse_awk_val_t* qse_awk_rtx_setmapvalfld ( + qse_awk_rtx_t* rtx, + qse_awk_val_t* map, + qse_char_t* kptr, + qse_size_t klen, + qse_awk_val_t* v +); + +/** + * The qse_awk_rtx_setmapvalfld() function gets the field value in a map. + * You must make sure that the type of @a map is #QSE_AWK_VAL_MAP. + * If the field is not found, the function fails and sets the error number + * to #QSE_AWK_EINVAL. + * @return field value on success, #QSE_NULL on failure. + */ +qse_awk_val_t* qse_awk_rtx_getmapvalfld ( + qse_awk_rtx_t* rtx, + qse_awk_val_t* map, + qse_char_t* kptr, + qse_size_t klen +); + /** * The qse_awk_rtx_makerefval() function creates a reference value. * @return value on success, QSE_NULL on failure diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 0d8ac1d2..6e22c74a 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: Awk.cpp 456 2011-05-12 14:55:53Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -604,6 +604,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, v); +/* TODO: use qse_awk_rtx_setmapvalfld() */ /* update the map with a given value */ pair_t* pair = qse_htb_upsert ( ((qse_awk_val_map_t*)map)->map, @@ -640,6 +641,7 @@ int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v) qse_awk_rtx_refupval (r->rtx, v); +/* TODO: use qse_awk_rtx_setmapvalfld() */ pair_t* pair = qse_htb_upsert ( ((qse_awk_val_map_t*)val)->map, (char_t*)idx.ptr, idx.len, v, 0); @@ -748,7 +750,6 @@ int Awk::Value::setIndexedStr (Run* r, const Index& idx, const char_t* str) return n; } - bool Awk::Value::isIndexed () const { QSE_ASSERT (val != QSE_NULL); @@ -767,6 +768,19 @@ int Awk::Value::getIndexed (const Index& idx, Value* v) const } // get the value from the map. + val_t* fv = qse_awk_rtx_getmapvalfld (val, idx.ptr, idx.len); + + // the key is not found. it is not an error. v is just nil + if (fv == QSE_NULL) + { + v->clear (); + return 0; + } + + // if v.set fails, it should return an error + return v->setVal (run, fv); + +#if 0 qse_awk_val_map_t* m = (qse_awk_val_map_t*)val; pair_t* pair = qse_htb_search (m->map, idx.ptr, idx.len); @@ -779,6 +793,7 @@ int Awk::Value::getIndexed (const Index& idx, Value* v) const // if v.set fails, it should return an error return v->setVal (run, (val_t*)QSE_HTB_VPTR(pair)); +#endif } Awk::Value::IndexIterator Awk::Value::getFirstIndex (Index* idx) const diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 564314a0..cbe7e6ec 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: val.c 456 2011-05-12 14:55:53Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -388,7 +388,6 @@ static void same_mapval (qse_htb_t* map, void* dptr, qse_size_t dlen) qse_awk_val_t* qse_awk_rtx_makemapval (qse_awk_rtx_t* rtx) { - qse_awk_val_map_t* val; static qse_htb_mancbs_t mancbs = { /* the key is copied inline into a pair and is freed when the pair @@ -408,6 +407,7 @@ qse_awk_val_t* qse_awk_rtx_makemapval (qse_awk_rtx_t* rtx) QSE_HTB_SIZER_DEFAULT, QSE_HTB_HASHER_DEFAULT }; + qse_awk_val_map_t* val; /* CHECK */ /* @@ -464,6 +464,69 @@ qse_awk_val_t* qse_awk_rtx_makemapval (qse_awk_rtx_t* rtx) return (qse_awk_val_t*)val; } +qse_awk_val_t* qse_awk_rtx_setmapvalfld ( + qse_awk_rtx_t* rtx, qse_awk_val_t* map, + qse_char_t* kptr, qse_size_t klen, qse_awk_val_t* v) +{ + QSE_ASSERT (map->type == QSE_AWK_VAL_MAP); + +#if 0 + if (map->type != QSE_AWK_VAL_MAP) + { + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOTIDX, QSE_NULL); + return QSE_NULL; + } +#endif + + if (qse_htb_upsert ( + ((qse_awk_val_map_t*)map)->map, + kptr, klen, v, 0) == QSE_NULL) + { + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); + return QSE_NULL; + } + + /* the value is passed in by an external party. we can't refup() + * and refdown() the value if htb_upsert() fails. that way, the value + * can be destroyed if it was passed with the reference count of 0. + * so we increment the reference count when htb_upsert() is complete */ + qse_awk_rtx_refupval (rtx, v); + + return v; +} + +qse_awk_val_t* qse_awk_rtx_getmapvalfld ( + qse_awk_rtx_t* rtx, qse_awk_val_t* map, + qse_char_t* kptr, qse_size_t klen) +{ + qse_htb_pair_t* pair; + + QSE_ASSERT (map->type == QSE_AWK_VAL_MAP); + +#if 0 + if (map->type != QSE_AWK_VAL_MAP) + { + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOTIDX, QSE_NULL); + return QSE_NULL; + } +#endif + + pair = qse_htb_search (((qse_awk_val_map_t*)map)->map, kptr, klen); + if (pair == QSE_NULL) + { + /* the given key is not found in the map. + * we return NULL here as this function is called by + * a user unlike the awk statement accessing the map key. + * so you can easily determine if the key is found by + * checking the error number. + */ + qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL); + return QSE_NULL; + } + + return QSE_HTB_VPTR(pair); +} + qse_awk_val_t* qse_awk_rtx_makerefval ( qse_awk_rtx_t* rtx, int id, qse_awk_val_t** adr) {