diff --git a/ase/awk/func.c b/ase/awk/func.c index 05be2f7d..75903a2d 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.47 2006-09-08 15:26:49 bacon Exp $ + * $Id: func.c,v 1.48 2006-09-11 14:29:22 bacon Exp $ */ #include @@ -24,6 +24,7 @@ static int __bfn_substr (xp_awk_t* awk, void* run); static int __bfn_split (xp_awk_t* awk, void* run); static int __bfn_tolower (xp_awk_t* awk, void* run); static int __bfn_toupper (xp_awk_t* awk, void* run); +static int __bfn_gsub (xp_awk_t* awk, void* run); static int __bfn_system (xp_awk_t* awk, void* run); static int __bfn_sin (xp_awk_t* awk, void* run); @@ -41,7 +42,7 @@ static xp_awk_bfn_t __sys_bfn[] = { XP_T("split"), 5, 0, 2, 3, XP_T("vrv"), __bfn_split }, { XP_T("tolower"), 7, 0, 1, 1, XP_NULL, __bfn_tolower }, { XP_T("toupper"), 7, 0, 1, 1, XP_NULL, __bfn_toupper }, - //{ XP_T("gsub"), 4, 0, 2, 3, XP_T("vrr"), __bfn_gsub }, + { XP_T("gsub"), 4, 0, 2, 3, XP_T("vvr"), __bfn_gsub }, /* TODO: remove these two functions */ { XP_T("system"), 6, 0, 1, 1, XP_NULL, __bfn_system }, @@ -796,6 +797,70 @@ static int __bfn_toupper (xp_awk_t* awk, void* run) return 0; } +static int __bfn_gsub (xp_awk_t* awk, void* run) +{ + xp_size_t nargs; + xp_awk_val_t* a0, * a1, * a2; + xp_char_t* a0_ptr, * a1_ptr; + xp_size_t a0_len, a1_len; + xp_char_t* a0_ptr_free = XP_NULL; + xp_char_t* a1_ptr_free = XP_NULL; + + nargs = xp_awk_getnargs (run); + xp_assert (nargs >= 2 && nargs <= 3); + + a0 = xp_awk_getarg (run, 0); + a1 = xp_awk_getarg (run, 1); + a2 = (nargs >= 3)? xp_awk_getarg (run, 2): XP_NULL; + + xp_assert (a2 == XP_NULL || a2->type == XP_AWK_VAL_REF); + + if (a0->type == XP_AWK_VAL_STR) + { + a0_ptr = ((xp_awk_val_str_t*)a0)->buf; + a0_len = ((xp_awk_val_str_t*)a0)->len; + } + else + { + a0_ptr = xp_awk_valtostr (run, a0, xp_true, XP_NULL, &a0_len); + if (a0_ptr == XP_NULL) return -1; + a0_ptr_free = a0_ptr; + } + + if (a1->type == XP_AWK_VAL_STR) + { + a1_ptr = ((xp_awk_val_str_t*)a1)->buf; + a1_len = ((xp_awk_val_str_t*)a1)->len; + } + else + { + a1_ptr = xp_awk_valtostr (run, a1, xp_true, XP_NULL, &a1_len); + if (a1_ptr == XP_NULL) + { + if (a0_ptr_free != XP_NULL) + XP_AWK_FREE (awk, a0_ptr_free); + return -1; + } + a1_ptr_free = a1_ptr; + } + +/* TODO: */ + if (a2 == XP_NULL) + { + /* operation is on $0 */ + } + else + { + /* operation is on a2 */ + } + + + if (a1_ptr_free != XP_NULL) XP_AWK_FREE (awk, a1_ptr_free); + if (a0_ptr_free != XP_NULL) XP_AWK_FREE (awk, a0_ptr_free); + + return 0; +} + static int __bfn_system (xp_awk_t* awk, void* run) { xp_size_t nargs; diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 8693666a..16c607fa 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.179 2006-09-02 14:58:28 bacon Exp $ + * $Id: parse.c,v 1.180 2006-09-11 14:29:22 bacon Exp $ */ #include @@ -1941,6 +1941,15 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) nde->next = XP_NULL; nde->val = xp_awk_strtolong ( awk, XP_AWK_STR_BUF(&awk->token.name), 0, XP_NULL); + nde->str = xp_awk_strxdup (awk, + XP_AWK_STR_BUF(&awk->token.name), + XP_AWK_STR_LEN(&awk->token.name)); + if (nde->str == XP_NULL) + { + XP_AWK_FREE (awk, nde); + return XP_NULL; + } + nde->len = XP_AWK_STR_LEN(&awk->token.name); xp_assert ( XP_AWK_STR_LEN(&awk->token.name) == @@ -1966,6 +1975,15 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) nde->next = XP_NULL; nde->val = xp_awk_strtoreal ( awk, XP_AWK_STR_BUF(&awk->token.name)); + nde->str = xp_awk_strxdup (awk, + XP_AWK_STR_BUF(&awk->token.name), + XP_AWK_STR_LEN(&awk->token.name)); + if (nde->str == XP_NULL) + { + XP_AWK_FREE (awk, nde); + return XP_NULL; + } + nde->len = XP_AWK_STR_LEN(&awk->token.name); xp_assert ( XP_AWK_STR_LEN(&awk->token.name) == diff --git a/ase/awk/tree.c b/ase/awk/tree.c index 10719405..7154c79b 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.73 2006-09-02 14:58:28 bacon Exp $ + * $Id: tree.c,v 1.74 2006-09-11 14:29:22 bacon Exp $ */ #include @@ -989,12 +989,14 @@ void xp_awk_clrpt (xp_awk_t* awk, xp_awk_nde_t* tree) case XP_AWK_NDE_INT: { + XP_AWK_FREE (awk, ((xp_awk_nde_int_t*)p)->str); XP_AWK_FREE (awk, p); break; } case XP_AWK_NDE_REAL: { + XP_AWK_FREE (awk, ((xp_awk_nde_real_t*)p)->str); XP_AWK_FREE (awk, p); break; } diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 92adf18b..183218ef 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.71 2006-09-01 03:44:21 bacon Exp $ + * $Id: tree.h,v 1.72 2006-09-11 14:29:23 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -191,6 +191,8 @@ struct xp_awk_nde_int_t { XP_AWK_NDE_HDR; xp_long_t val; + xp_char_t* str; + xp_size_t len; }; /* XP_AWK_NDE_REAL */ @@ -198,6 +200,8 @@ struct xp_awk_nde_real_t { XP_AWK_NDE_HDR; xp_real_t val; + xp_char_t* str; + xp_size_t len; }; /* XP_AWK_NDE_STR */