From 356e4c07920fcc77aa672be7a82879355375b45f Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 11 Jul 2009 21:01:36 +0000 Subject: [PATCH] cleaned up run_delete() in awk/run.c improved Awk::Value --- qse/include/qse/awk/Awk.hpp | 29 +++-- qse/include/qse/awk/awk.h | 7 +- qse/lib/awk/Awk.cpp | 128 +++++++++++++++++--- qse/lib/awk/run.c | 231 ++++++++++++++++-------------------- qse/lib/awk/val.c | 10 +- 5 files changed, 244 insertions(+), 161 deletions(-) diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index ccea688c..474d14fe 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp 227 2009-07-10 14:05:51Z hyunghwan.chung $ + * $Id: Awk.hpp 228 2009-07-11 03:01:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -238,17 +238,28 @@ public: Value& operator= (const Value& v); + operator val_t* () const { return val; } + operator long_t () const; + operator real_t () const; + operator const char_t* () const; + void clear (); - int setValue (val_t* v); - int setValue (Run* r, val_t* v); + int get (long_t* v) const; + int get (real_t* v) const; + int get (const char_t** str, size_t* len) const; - int setInt (long_t v); - int setInt (Run* r, long_t v); - int setReal (real_t v); - int setReal (Run* r, real_t v); - int setStr (const char_t* str, size_t len); - int setStr (Run* r, const char_t* str, size_t len); + int set (val_t* v); + int set (Run* r, val_t* v); + + int set (long_t v); + int set (Run* r, long_t v); + int set (real_t v); + int set (Run* r, real_t v); + int set (const char_t* str, size_t len); + int set (Run* r, const char_t* str, size_t len); + int set (const char_t* str); + int set (Run* r, const char_t* str); int setIndexed (const char_t* idx, size_t isz, val_t* v); int setIndexed (Run* r, const char_t* idx, size_t isz, val_t* v); diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index e84ca40c..3174d6d0 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 220 2009-07-01 13:14:39Z hyunghwan.chung $ + * $Id: awk.h 228 2009-07-11 03:01:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -1712,6 +1712,10 @@ qse_bool_t qse_awk_rtx_valtobool ( * the same as QSE_AWK_RTX_VALTOSTR_STRP except that you have to use the * u.strpcat field instead of the u.strp field. * + * In the context where @a val is determined to be of the type + * #QSE_AWK_VAL_STR, you may access its string pointer and length directly + * instead of calling this function. + * * @return the pointer to a string converted on success, #QSE_NULL on failure */ qse_char_t* qse_awk_rtx_valtostr ( @@ -1747,6 +1751,7 @@ qse_char_t* qse_awk_rtx_valtocpldup ( * If the value is converted to a long number, it is stored in the memory * pointed to by l and 0 is returned. If the value is converted to a real * number, it is stored in the memory pointed to by r and 1 is returned. + * The function never fails as long as @a val points to a valid value. * * The code below shows how to convert a value to a number and determine * if it is an integer or a floating-point number. diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 5f64b358..cb4f29e0 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 227 2009-07-10 14:05:51Z hyunghwan.chung $ + * $Id: Awk.cpp 228 2009-07-11 03:01:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -206,13 +206,88 @@ void Awk::Value::clear () } } -int Awk::Value::setValue (val_t* v) +Awk::Value::operator Awk::long_t () const { - if (run == QSE_NULL) return -1; - return setValue (run, v); + long_t v; + if (get (&v) <= -1) v = 0; + return v; } -int Awk::Value::setValue (Run* r, val_t* v) +Awk::Value::operator Awk::real_t () const +{ + real_t v; + if (get (&v) <= -1) v = 0.0; + return v; +} + +Awk::Value::operator const Awk::char_t* () const +{ + const char_t* ptr; + size_t len; + if (get (&ptr, &len) <= -1) ptr = QSE_T(""); + return ptr; +} + +int Awk::Value::get (long_t* v) const +{ + long_t lv = 0; + + if (run != QSE_NULL) + { + real_t rv; + int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv); + if (n <= -1) return -1; + if (n >= 1) lv = rv; + } + + *v = lv; + return 0; +} + +int Awk::Value::get (real_t* v) const +{ + real_t rv = 0; + + if (run != QSE_NULL) + { + long_t lv; + int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv); + if (n <= -1) return -1; + if (n == 0) rv = lv; + } + + *v = rv; + return 0; +} + +int Awk::Value::get (const char_t** str, size_t* len) const +{ +#if 0 +if v is a string, return the pointer and the length. +otherwise call valtostr.... how can i handle free then??? + + real_t rv = 0; + + if (run != QSE_NULL) + { + long_t lv; + int n = qse_awk_rtx_valtostr (run->rtx, val, &lv, &rv); + if (n <= -1) return -1; + if (n == 0) rv = lv; + } + + *v = rv; + return 0; +#endif +} + +int Awk::Value::set (val_t* v) +{ + if (run == QSE_NULL) return -1; + return set (run, v); +} + +int Awk::Value::set (Run* r, val_t* v) { if (run != QSE_NULL) qse_awk_rtx_refdownval (run->rtx, val); @@ -224,53 +299,70 @@ int Awk::Value::setValue (Run* r, val_t* v) return 0; } -int Awk::Value::setInt (long_t v) +int Awk::Value::set (long_t v) { if (run == QSE_NULL) return -1; - return setInt (run, v); + return set (run, v); } -int Awk::Value::setInt (Run* r, long_t v) +int Awk::Value::set (Run* r, long_t v) { val_t* tmp; tmp = qse_awk_rtx_makeintval (r->rtx, v); if (tmp == QSE_NULL) return -1; - int n = setValue (r, tmp); + int n = set (r, tmp); QSE_ASSERT (n == 0); return n; } -int Awk::Value::setReal (real_t v) +int Awk::Value::set (real_t v) { if (run == QSE_NULL) return -1; - return setReal (run, v); + return set (run, v); } -int Awk::Value::setReal (Run* r, real_t v) +int Awk::Value::set (Run* r, real_t v) { val_t* tmp; tmp = qse_awk_rtx_makerealval (r->rtx, v); if (tmp == QSE_NULL) return -1; - int n = setValue (r, tmp); + int n = set (r, tmp); QSE_ASSERT (n == 0); return n; } -int Awk::Value::setStr (const char_t* str, size_t len) +int Awk::Value::set (const char_t* str, size_t len) { if (run == QSE_NULL) return -1; - return setStr (run, str, len); + return set (run, str, len); } -int Awk::Value::setStr (Run* r, const char_t* str, size_t len) +int Awk::Value::set (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; - int n = setValue (r, tmp); + int n = set (r, tmp); + QSE_ASSERT (n == 0); + return n; +} + +int Awk::Value::set (const char_t* str) +{ + if (run == QSE_NULL) return -1; + return set (run, str); +} + +int Awk::Value::set (Run* r, const char_t* str) +{ + val_t* tmp; + tmp = qse_awk_rtx_makestrval0 (r->rtx, str); + if (tmp == QSE_NULL) return -1; + + int n = set (r, tmp); QSE_ASSERT (n == 0); return n; } @@ -427,7 +519,7 @@ int Awk::Value::getIndexed (const char_t* idx, size_t isz, Value& v) const } // if v.set fails, it should return an error - return v.setValue (run, (val_t*)QSE_MAP_VPTR(pair)); + return v.set (run, (val_t*)QSE_MAP_VPTR(pair)); } ////////////////////////////////////////////////////////////////// diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index c5a0268b..54468133 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 224 2009-07-07 13:05:10Z hyunghwan.chung $ + * $Id: run.c 228 2009-07-11 03:01:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -243,6 +243,16 @@ 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); +static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr) +{ + /* i use this function to typecast qse_cstr_t* to + * qse_xstr_t* instead of direct typecasting. + * it is just to let the compiler emit some warnings + * if the data type of the actual parameter happened to + * haved changed to something else. */ + return (qse_cstr_t*)xstr; +} + qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run) { return (qse_size_t) STACK_NARGS (run); @@ -277,13 +287,11 @@ static int set_global ( if (var != QSE_NULL) { /* global variable */ - qse_cstr_t errarg; - - errarg.ptr = var->id.name.ptr; - errarg.len = var->id.name.len; - - qse_awk_rtx_seterror (run, - QSE_AWK_EMAPTOSCALAR, var->line, &errarg); + qse_awk_rtx_seterror ( + run, + QSE_AWK_EMAPTOSCALAR, + var->line, xstr_to_cstr(&var->id.name) + ); } else { @@ -1492,12 +1500,9 @@ qse_awk_val_t* qse_awk_rtx_call ( ); if (pair == QSE_NULL) { - qse_cstr_t errarg; - - errarg.ptr = call.what.fun.name.ptr; - errarg.len = call.what.fun.name.len; - - qse_awk_rtx_seterror (rtx, QSE_AWK_EFUNNF, 0, &errarg); + qse_awk_rtx_seterror ( + rtx, QSE_AWK_EFUNNF, + 0, xstr_to_cstr(&call.what.fun.name)); return QSE_NULL; } @@ -2439,6 +2444,70 @@ static int run_nextfile (qse_awk_rtx_t* run, qse_awk_nde_nextfile_t* nde) run_nextinfile (run, nde); } +static int delete_indexed ( + qse_awk_rtx_t* rtx, qse_map_t* map, qse_awk_nde_var_t* var) +{ + qse_awk_val_t* idx; + + QSE_ASSERT (var->idx != QSE_NULL); + + idx = eval_expression (rtx, var->idx); + if (idx == QSE_NULL) return -1; + + qse_awk_rtx_refupval (rtx, idx); + + if (idx->type == QSE_AWK_VAL_STR) + { + /* delete x["abc"] */ + + qse_map_delete ( + map, + ((qse_awk_val_str_t*)idx)->ptr, + ((qse_awk_val_str_t*)idx)->len + ); + qse_awk_rtx_refdownval (rtx, idx); + } + else + { + /* delete x[20] */ + + qse_char_t* key; + qse_size_t keylen; + qse_char_t buf[IDXBUFSIZE]; + 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); + key = qse_awk_rtx_valtostr (rtx, idx, &out); + if (key == QSE_NULL) + { + /* retry it in dynamic mode */ + out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; + key = qse_awk_rtx_valtostr (rtx, idx, &out); + } + + qse_awk_rtx_refdownval (rtx, idx); + + if (key == QSE_NULL) + { + /* change the error line */ + rtx->errinf.lin = var->line; + return -1; + } + + keylen = (out.type == QSE_AWK_RTX_VALTOSTR_CPL)? + out.u.cpl.len: out.u.cpldup.len; + + qse_map_delete (map, key, keylen); + + if (key != buf) QSE_AWK_FREE (rtx->awk, key); + } + + return 0; +} + static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde) { qse_awk_nde_var_t* var; @@ -2498,59 +2567,19 @@ static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde) if (val->type != QSE_AWK_VAL_MAP) { - qse_cstr_t errarg; - - errarg.ptr = var->id.name.ptr; - errarg.len = var->id.name.len; - qse_awk_rtx_seterror ( - run, QSE_AWK_ENOTDEL, var->line, &errarg); + run, QSE_AWK_ENOTDEL, + var->line, xstr_to_cstr(&var->id.name)); return -1; } map = ((qse_awk_val_map_t*)val)->map; if (var->type == QSE_AWK_NDE_NAMEDIDX) { - qse_char_t* key; - qse_size_t keylen; - qse_awk_val_t* idx; - qse_char_t buf[IDXBUFSIZE]; - qse_awk_rtx_valtostr_out_t out; - - QSE_ASSERT (var->idx != QSE_NULL); - - idx = eval_expression (run, var->idx); - if (idx == QSE_NULL) return -1; - - qse_awk_rtx_refupval (run, idx); - - /* 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); - key = qse_awk_rtx_valtostr (run, idx, &out); - if (key == QSE_NULL) + if (delete_indexed (run, map, var) <= -1) { - /* retry it in dynamic mode */ - out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - key = qse_awk_rtx_valtostr (run, idx, &out); - } - - qse_awk_rtx_refdownval (run, idx); - - if (key == QSE_NULL) - { - /* change the error line */ - run->errinf.lin = var->line; return -1; } - - keylen = (out.type == QSE_AWK_RTX_VALTOSTR_CPL)? - out.u.cpl.len: out.u.cpldup.len; - - qse_map_delete (map, key, keylen); - - if (key != buf) QSE_AWK_FREE (run->awk, key); } else { @@ -2625,13 +2654,9 @@ static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde) if (val->type != QSE_AWK_VAL_MAP) { - qse_cstr_t errarg; - - errarg.ptr = var->id.name.ptr; - errarg.len = var->id.name.len; - qse_awk_rtx_seterror ( - run, QSE_AWK_ENOTDEL, var->line, &errarg); + run, QSE_AWK_ENOTDEL, + var->line, xstr_to_cstr(&var->id.name)); return -1; } @@ -2640,45 +2665,10 @@ static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde) var->type == QSE_AWK_NDE_LCLIDX || var->type == QSE_AWK_NDE_ARGIDX) { - qse_char_t* key; - qse_size_t keylen; - qse_awk_val_t* idx; - qse_char_t buf[IDXBUFSIZE]; - qse_awk_rtx_valtostr_out_t out; - - QSE_ASSERT (var->idx != QSE_NULL); - - idx = eval_expression (run, var->idx); - if (idx == QSE_NULL) return -1; - - qse_awk_rtx_refupval (run, idx); - - /* 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); - key = qse_awk_rtx_valtostr (run, idx, &out); - if (key == QSE_NULL) + if (delete_indexed (run, map, var) <= -1) { - /* retry it in the dynamic mode */ - out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - key = qse_awk_rtx_valtostr (run, idx, &out); - } - - qse_awk_rtx_refdownval (run, idx); - - if (key == QSE_NULL) - { - run->errinf.lin = var->line; return -1; } - - keylen = (out.type == QSE_AWK_RTX_VALTOSTR_CPL)? - out.u.cpl.len: out.u.cpldup.len; - - qse_map_delete (map, key, keylen); - - if (key != buf) QSE_AWK_FREE (run->awk, key); } else { @@ -3379,13 +3369,9 @@ static qse_awk_val_t* do_assignment_scalar ( { /* once a variable becomes a map, * it cannot be changed to a scalar variable */ - qse_cstr_t errarg; - - errarg.ptr = var->id.name.ptr; - errarg.len = var->id.name.len; - - qse_awk_rtx_seterror (run, - QSE_AWK_EMAPTOSCALAR, var->line, &errarg); + qse_awk_rtx_seterror ( + run, QSE_AWK_EMAPTOSCALAR, + var->line, xstr_to_cstr(&var->id.name)); return QSE_NULL; } @@ -3415,13 +3401,9 @@ static qse_awk_val_t* do_assignment_scalar ( { /* once the variable becomes a map, * it cannot be changed to a scalar variable */ - qse_cstr_t errarg; - - errarg.ptr = var->id.name.ptr; - errarg.len = var->id.name.len; - - qse_awk_rtx_seterror (run, - QSE_AWK_EMAPTOSCALAR, var->line, &errarg); + qse_awk_rtx_seterror ( + run, QSE_AWK_EMAPTOSCALAR, + var->line, xstr_to_cstr(&var->id.name)); return QSE_NULL; } @@ -3436,13 +3418,9 @@ static qse_awk_val_t* do_assignment_scalar ( { /* once the variable becomes a map, * it cannot be changed to a scalar variable */ - qse_cstr_t errarg; - - errarg.ptr = var->id.name.ptr; - errarg.len = var->id.name.len; - - qse_awk_rtx_seterror (run, - QSE_AWK_EMAPTOSCALAR, var->line, &errarg); + qse_awk_rtx_seterror ( + run, QSE_AWK_EMAPTOSCALAR, + var->line, xstr_to_cstr(&var->id.name)); return QSE_NULL; } @@ -3516,7 +3494,8 @@ static qse_awk_val_t* do_assignment_map ( qse_awk_rtx_refdownval (run, tmp); qse_awk_rtx_seterror ( - run, QSE_AWK_ENOMEM, var->line, QSE_NULL); + run, QSE_AWK_ENOMEM, + var->line, QSE_NULL); return QSE_NULL; } @@ -5502,13 +5481,9 @@ static qse_awk_val_t* eval_fun_ex ( call->what.fun.name.ptr, call->what.fun.name.len); if (pair == QSE_NULL) { - qse_cstr_t errarg; - - errarg.ptr = call->what.fun.name.ptr; - errarg.len = call->what.fun.name.len, - - qse_awk_rtx_seterror (run, - QSE_AWK_EFUNNF, nde->line, &errarg); + qse_awk_rtx_seterror ( + run, QSE_AWK_EFUNNF, + nde->line, xstr_to_cstr(&call->what.fun.name)); return QSE_NULL; } diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 89a52b7a..10cb007b 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c 205 2009-06-20 12:47:34Z hyunghwan.chung $ + * $Id: val.c 228 2009-07-11 03:01:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -1168,7 +1168,7 @@ qse_char_t* qse_awk_rtx_valtocpldup ( } int qse_awk_rtx_valtonum ( - qse_awk_rtx_t* run, qse_awk_val_t* v, qse_long_t* l, qse_real_t* r) + qse_awk_rtx_t* rtx, qse_awk_val_t* v, qse_long_t* l, qse_real_t* r) { if (v->type == QSE_AWK_VAL_NIL) { @@ -1191,7 +1191,7 @@ int qse_awk_rtx_valtonum ( if (v->type == QSE_AWK_VAL_STR) { return qse_awk_rtx_strtonum ( - run, 0, + rtx, 0, ((qse_awk_val_str_t*)v)->ptr, ((qse_awk_val_str_t*)v)->len, l, r @@ -1200,11 +1200,11 @@ int qse_awk_rtx_valtonum ( #ifdef DEBUG_VAL qse_dprintf ( - QSE_T("ERROR: WRONG VALUE TYPE [%d] in qse_awk_rtx_valtonum\n"), + QSE_T("ERROR: WRONG VALUE TYPE [%d] in qse_awk_rtx_valtonum\n"), v->type); #endif - qse_awk_rtx_seterror (run, QSE_AWK_EVALTYPE, 0, QSE_NULL); + qse_awk_rtx_seterror (rtx, QSE_AWK_EVALTYPE, 0, QSE_NULL); return -1; /* error */ }