*** empty log message ***
This commit is contained in:
parent
593c0ee800
commit
2ec4920092
106
ase/awk/func.c
106
ase/awk/func.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: func.c,v 1.49 2006-09-12 15:20:18 bacon Exp $
|
||||
* $Id: func.c,v 1.50 2006-09-13 14:16:13 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk_i.h>
|
||||
@ -42,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("vvr"), __bfn_gsub },
|
||||
{ XP_T("gsub"), 4, 0, 2, 3, XP_T("xvr"), __bfn_gsub },
|
||||
|
||||
/* TODO: remove these two functions */
|
||||
{ XP_T("system"), 6, 0, 1, 1, XP_NULL, __bfn_system },
|
||||
@ -500,7 +500,7 @@ static int __bfn_substr (xp_awk_t* awk, void* run)
|
||||
static int __bfn_split (xp_awk_t* awk, void* run)
|
||||
{
|
||||
xp_size_t nargs;
|
||||
xp_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1ref;
|
||||
xp_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1_ref;
|
||||
xp_char_t* str, * str_free, * p, * tok;
|
||||
xp_size_t str_len, str_left, tok_len;
|
||||
xp_long_t num;
|
||||
@ -529,9 +529,9 @@ static int __bfn_split (xp_awk_t* awk, void* run)
|
||||
return -1;
|
||||
}
|
||||
|
||||
a1ref = (xp_awk_val_t**)((xp_awk_val_ref_t*)a1)->adr;
|
||||
if ((*a1ref)->type != XP_AWK_VAL_NIL &&
|
||||
(*a1ref)->type != XP_AWK_VAL_MAP)
|
||||
a1_ref = (xp_awk_val_t**)((xp_awk_val_ref_t*)a1)->adr;
|
||||
if ((*a1_ref)->type != XP_AWK_VAL_NIL &&
|
||||
(*a1_ref)->type != XP_AWK_VAL_MAP)
|
||||
{
|
||||
/* cannot change a scalar value to a map */
|
||||
xp_awk_seterrnum (run, XP_AWK_ESCALARTOMAP);
|
||||
@ -633,9 +633,9 @@ static int __bfn_split (xp_awk_t* awk, void* run)
|
||||
return -1;
|
||||
}
|
||||
|
||||
xp_awk_refdownval (run, *a1ref);
|
||||
*a1ref = t1;
|
||||
xp_awk_refupval (*a1ref);
|
||||
xp_awk_refdownval (run, *a1_ref);
|
||||
*a1_ref = t1;
|
||||
xp_awk_refupval (*a1_ref);
|
||||
|
||||
p = str; str_left = str_len; num = 0;
|
||||
while (p != XP_NULL)
|
||||
@ -800,7 +800,7 @@ static int __bfn_toupper (xp_awk_t* awk, void* run)
|
||||
static int __bfn_gsub (xp_awk_t* awk, void* run)
|
||||
{
|
||||
xp_size_t nargs;
|
||||
xp_awk_val_t* a0, * a1, * a2;
|
||||
xp_awk_val_t* a0, * a1, * a2, ** a2_ref, * v;
|
||||
xp_char_t* a0_ptr, * a1_ptr, * a2_ptr;
|
||||
xp_size_t a0_len, a1_len, a2_len;
|
||||
xp_char_t* a0_ptr_free = XP_NULL;
|
||||
@ -811,6 +811,7 @@ static int __bfn_gsub (xp_awk_t* awk, void* run)
|
||||
const xp_char_t* cur_ptr, * match_ptr;
|
||||
xp_size_t cur_len, match_len;
|
||||
xp_awk_str_t new;
|
||||
xp_long_t sub_count;
|
||||
|
||||
nargs = xp_awk_getnargs (run);
|
||||
xp_assert (nargs >= 2 && nargs <= 3);
|
||||
@ -821,7 +822,11 @@ static int __bfn_gsub (xp_awk_t* awk, void* run)
|
||||
|
||||
xp_assert (a2 == XP_NULL || a2->type == XP_AWK_VAL_REF);
|
||||
|
||||
if (a0->type == XP_AWK_VAL_STR)
|
||||
if (a0->type == XP_AWK_VAL_REX)
|
||||
{
|
||||
rex = ((xp_awk_val_rex_t*)a0)->code;
|
||||
}
|
||||
else 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;
|
||||
@ -859,23 +864,48 @@ static int __bfn_gsub (xp_awk_t* awk, void* run)
|
||||
else
|
||||
{
|
||||
/* operation is on a2 */
|
||||
a2_ref = (xp_awk_val_t**)((xp_awk_val_ref_t*)a2)->adr;
|
||||
/*
|
||||
a2ref = (xp_awk_val_t**)((xp_awk_val_ref_t*)a2)->adr;
|
||||
if ((*a2ref)->type != XP_AWK_VAL_NIL &&
|
||||
(*a2ref)->type != XP_AWK_VAL_MAP)
|
||||
if ((*a2_ref)->type != XP_AWK_VAL_NIL &&
|
||||
(*a2_ref)->type != XP_AWK_VAL_MAP)
|
||||
{
|
||||
}
|
||||
*/
|
||||
if ((*a2_ref)->type == XP_AWK_VAL_STR)
|
||||
{
|
||||
a2_ptr = ((xp_awk_val_str_t*)(*a2_ref))->buf;
|
||||
a2_len = ((xp_awk_val_str_t*)(*a2_ref))->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
a2_ptr = xp_awk_valtostr (
|
||||
run, *a2_ref, xp_true, XP_NULL, &a2_len);
|
||||
if (a2_ptr == XP_NULL)
|
||||
{
|
||||
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 -1;
|
||||
}
|
||||
a2_ptr_free = a2_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
rex = xp_awk_buildrex (awk,
|
||||
a0_ptr, a0_len, &((xp_awk_run_t*)run)->errnum);
|
||||
if (rex == XP_NULL)
|
||||
if (a0->type != XP_AWK_VAL_REX)
|
||||
{
|
||||
if (a2_ptr_free != XP_NULL) XP_AWK_FREE (awk, a2_ptr_free);
|
||||
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 -1;
|
||||
rex = xp_awk_buildrex (awk,
|
||||
a0_ptr, a0_len, &((xp_awk_run_t*)run)->errnum);
|
||||
if (rex == XP_NULL)
|
||||
{
|
||||
if (a2_ptr_free != XP_NULL)
|
||||
XP_AWK_FREE (awk, a2_ptr_free);
|
||||
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 -1;
|
||||
}
|
||||
}
|
||||
|
||||
opt = (((xp_awk_run_t*)run)->rex.ignorecase)? XP_AWK_REX_IGNORECASE: 0;
|
||||
@ -892,6 +922,8 @@ static int __bfn_gsub (xp_awk_t* awk, void* run)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sub_count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
n = xp_awk_matchrex (
|
||||
@ -942,7 +974,7 @@ static int __bfn_gsub (xp_awk_t* awk, void* run)
|
||||
XP_AWK_FREE (awk, a0_ptr_free);
|
||||
return -1;
|
||||
}
|
||||
/*TODO: handle & */
|
||||
/*TODO: handle & */
|
||||
if (xp_awk_str_ncat (&new, a1_ptr, a1_len) == (xp_size_t)-1)
|
||||
{
|
||||
xp_awk_str_close (&new);
|
||||
@ -956,13 +988,13 @@ static int __bfn_gsub (xp_awk_t* awk, void* run)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sub_count++;
|
||||
cur_ptr = match_ptr + match_len;
|
||||
cur_len = cur_len - ((match_ptr - cur_ptr) + match_len);
|
||||
}
|
||||
|
||||
xp_awk_freerex (awk, rex);
|
||||
if (a0->type != XP_AWK_VAL_REX) xp_awk_freerex (awk, rex);
|
||||
|
||||
xp_printf (XP_T("NEW STRING [%s]\n"), XP_AWK_STR_BUF(&new));
|
||||
if (a2 == XP_NULL)
|
||||
{
|
||||
if (xp_awk_setrecord (run,
|
||||
@ -980,7 +1012,23 @@ xp_printf (XP_T("NEW STRING [%s]\n"), XP_AWK_STR_BUF(&new));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: */
|
||||
v = xp_awk_makestrval (run,
|
||||
XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new));
|
||||
if (v == XP_NULL)
|
||||
{
|
||||
xp_awk_str_close (&new);
|
||||
if (a2_ptr_free != XP_NULL)
|
||||
XP_AWK_FREE (awk, a2_ptr_free);
|
||||
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 -1;
|
||||
}
|
||||
|
||||
xp_awk_refdownval (run, *a2_ref);
|
||||
*a2_ref = v;
|
||||
xp_awk_refupval (*a2_ref);
|
||||
}
|
||||
|
||||
xp_awk_str_close (&new);
|
||||
@ -989,6 +1037,14 @@ xp_printf (XP_T("NEW STRING [%s]\n"), XP_AWK_STR_BUF(&new));
|
||||
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);
|
||||
|
||||
v = xp_awk_makeintval (run, sub_count);
|
||||
if (v == XP_NULL)
|
||||
{
|
||||
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
xp_awk_setretval (run, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c,v 1.202 2006-09-12 15:21:32 bacon Exp $
|
||||
* $Id: run.c,v 1.203 2006-09-13 14:16:13 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk_i.h>
|
||||
@ -4163,52 +4163,60 @@ static xp_awk_val_t* __eval_call (
|
||||
p = call->args;
|
||||
while (p != XP_NULL)
|
||||
{
|
||||
v = __eval_expression (run, p);
|
||||
xp_assert (bfn_arg_spec == XP_NULL ||
|
||||
(bfn_arg_spec != XP_NULL &&
|
||||
xp_awk_strlen(bfn_arg_spec) > nargs));
|
||||
|
||||
if (bfn_arg_spec != XP_NULL &&
|
||||
bfn_arg_spec[nargs] == XP_T('x'))
|
||||
{
|
||||
/* a regular expression is passed to
|
||||
* the function as it is */
|
||||
v = __eval_expression0 (run, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
v = __eval_expression (run, p);
|
||||
}
|
||||
if (v == XP_NULL)
|
||||
{
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
if (bfn_arg_spec != XP_NULL)
|
||||
if (bfn_arg_spec != XP_NULL &&
|
||||
bfn_arg_spec[nargs] == XP_T('r'))
|
||||
{
|
||||
xp_char_t spec;
|
||||
|
||||
/* TODO: spec length check */
|
||||
spec = bfn_arg_spec[nargs];
|
||||
if (spec == XP_T('r'))
|
||||
xp_awk_val_t** ref;
|
||||
xp_awk_val_t* tmp;
|
||||
|
||||
ref = __get_reference (run, p);
|
||||
if (ref == XP_NULL)
|
||||
{
|
||||
xp_awk_val_t** ref;
|
||||
xp_awk_val_t* tmp;
|
||||
|
||||
ref = __get_reference (run, p);
|
||||
if (ref == XP_NULL)
|
||||
{
|
||||
xp_awk_refupval (v);
|
||||
xp_awk_refdownval (run, v);
|
||||
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
/* p->type-XP_AWK_NDE_NAMED assumes that the
|
||||
* derived value matches XP_AWK_VAL_REF_XXX */
|
||||
tmp = xp_awk_makerefval (
|
||||
run, p->type-XP_AWK_NDE_NAMED, ref);
|
||||
if (tmp == XP_NULL)
|
||||
{
|
||||
xp_awk_refupval (v);
|
||||
xp_awk_refdownval (run, v);
|
||||
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
PANIC (run, XP_AWK_ENOMEM);
|
||||
}
|
||||
|
||||
xp_awk_refupval (v);
|
||||
xp_awk_refdownval (run, v);
|
||||
|
||||
v = tmp;
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
/* p->type-XP_AWK_NDE_NAMED assumes that the
|
||||
* derived value matches XP_AWK_VAL_REF_XXX */
|
||||
tmp = xp_awk_makerefval (
|
||||
run, p->type-XP_AWK_NDE_NAMED, ref);
|
||||
if (tmp == XP_NULL)
|
||||
{
|
||||
xp_awk_refupval (v);
|
||||
xp_awk_refdownval (run, v);
|
||||
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
PANIC (run, XP_AWK_ENOMEM);
|
||||
}
|
||||
|
||||
xp_awk_refupval (v);
|
||||
xp_awk_refdownval (run, v);
|
||||
|
||||
v = tmp;
|
||||
}
|
||||
|
||||
if (__raw_push(run,v) == -1)
|
||||
|
@ -1,2 +1,3 @@
|
||||
#BEGIN { t = "abc"; gsub ("abc", "[&]", t); print t; }
|
||||
{ gsub ("abc", "ABC"); print $0; }
|
||||
{ gsub (/ABC/, "XYZ"); print $0; }
|
||||
|
3
ase/test/awk/t44.awk
Normal file
3
ase/test/awk/t44.awk
Normal file
@ -0,0 +1,3 @@
|
||||
#BEGIN { t = "abc"; gsub ("abc", "[&]", t); print t; }
|
||||
{ c=$0; print gsub ("abc", "ABC", c); print c; }
|
||||
{ gsub (/ABC/, "XYZ", c); print c; }
|
Loading…
x
Reference in New Issue
Block a user