*** empty log message ***
This commit is contained in:
parent
cccbcc2f0a
commit
38407c1dac
116
ase/awk/func.c
116
ase/awk/func.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: func.c,v 1.21 2006-08-18 07:52:20 bacon Exp $
|
||||
* $Id: func.c,v 1.22 2006-08-18 17:46:07 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk_i.h>
|
||||
@ -408,6 +408,7 @@ static int __bfn_substr (xp_awk_t* awk, void* run)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int __bfn_split (xp_awk_t* awk, void* run)
|
||||
{
|
||||
xp_size_t nargs;
|
||||
@ -509,6 +510,119 @@ static int __bfn_split (xp_awk_t* awk, void* run)
|
||||
xp_awk_setretval (run, r);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static int __bfn_split (xp_awk_t* awk, void* run)
|
||||
{
|
||||
xp_size_t nargs;
|
||||
xp_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1r;
|
||||
xp_char_t* str, * p, * tok;
|
||||
xp_size_t len, left, tok_len;
|
||||
xp_long_t num;
|
||||
int errnum;
|
||||
xp_char_t key[32];
|
||||
|
||||
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;
|
||||
|
||||
if (a0->type == XP_AWK_VAL_STR)
|
||||
{
|
||||
str = ((xp_awk_val_str_t*)a0)->buf;
|
||||
len = ((xp_awk_val_str_t*)a0)->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = xp_awk_valtostr (a0, &errnum, xp_true, XP_NULL, &len);
|
||||
if (str == XP_NULL)
|
||||
{
|
||||
xp_awk_seterrnum (run, errnum);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
xp_assert (a1->type == XP_AWK_VAL_INT);
|
||||
a1r = (xp_awk_val_t**)((xp_awk_val_int_t*)a1)->val;
|
||||
|
||||
/* TODO: error handling... */
|
||||
t1 = xp_awk_makemapval (run);
|
||||
if (t1 == XP_NULL)
|
||||
{
|
||||
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = str; left = len; num = 0;
|
||||
while (p != XP_NULL)
|
||||
{
|
||||
/* TODO: use FS when a2 is missing. apply a difference scheme */
|
||||
p = xp_strxtok (p, left, XP_T(" \t"), &tok, &tok_len);
|
||||
|
||||
if (num == 0 && p == XP_NULL && tok_len == 0)
|
||||
{
|
||||
/* no field at all*/
|
||||
break;
|
||||
}
|
||||
|
||||
xp_assert ((tok != XP_NULL && tok_len > 0) || tok_len == 0);
|
||||
|
||||
/* create the field string */
|
||||
t2 = xp_awk_makestrval (tok, tok_len);
|
||||
if (t2 == XP_NULL)
|
||||
{
|
||||
if (a0->type != XP_AWK_VAL_STR) xp_free (str);
|
||||
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* put it into the map */
|
||||
/* TODO: remove dependency on xp_sprintf */
|
||||
#if defined(__LCC__)
|
||||
xp_sprintf (key, xp_countof(key), XP_T("%lld"), (long long)num);
|
||||
#elif defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
xp_sprintf (key, xp_countof(key), XP_T("%I64d"), (__int64)num);
|
||||
#elif defined(vax) || defined(__vax) || defined(_SCO_DS)
|
||||
xp_sprintf (key, xp_countof(key), XP_T("%ld"), (long)num);
|
||||
#else
|
||||
xp_sprintf (key, xp_countof(key), XP_T("%lld"), (long long)num);
|
||||
#endif
|
||||
|
||||
if (xp_awk_map_putx (
|
||||
((xp_awk_val_map_t*)t1)->map,
|
||||
key, xp_strlen(key), t2, XP_NULL) == -1)
|
||||
{
|
||||
if (a0->type != XP_AWK_VAL_STR) xp_free (str);
|
||||
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't forget to update the reference count
|
||||
* when you handle the assignment-like situation
|
||||
* with the internal data structures */
|
||||
xp_awk_refupval (t2);
|
||||
|
||||
num++;
|
||||
len = len - (p - str);
|
||||
}
|
||||
|
||||
if (a0->type != XP_AWK_VAL_STR) xp_free (str);
|
||||
|
||||
xp_awk_refdownval (run, *a1r);
|
||||
*a1r = t1;
|
||||
xp_awk_refupval (*a1r);
|
||||
|
||||
t1 = xp_awk_makeintval (run, num);
|
||||
if (t1 == XP_NULL)
|
||||
{
|
||||
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
xp_awk_setretval (run, t1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __bfn_tolower (xp_awk_t* awk, void* run)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c,v 1.169 2006-08-18 07:52:20 bacon Exp $
|
||||
* $Id: run.c,v 1.170 2006-08-18 17:46:07 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk_i.h>
|
||||
@ -23,7 +23,6 @@
|
||||
#define STACK_LOCAL(run,n) STACK_AT(run,3+(xp_size_t)STACK_NARGS(run)+1+(n))
|
||||
#define STACK_RETVAL(run) STACK_AT(run,2)
|
||||
#define STACK_GLOBAL(run,n) ((run)->stack[(n)])
|
||||
/*#define STACK_RETVAL_GLOBAL(run) ((run)->stack[(run)->nglobals+2])*/
|
||||
#define STACK_RETVAL_GLOBAL(run) ((run)->stack[(run)->awk->tree.nglobals+2])
|
||||
|
||||
enum
|
||||
@ -1337,7 +1336,7 @@ static int __run_return (xp_awk_run_t* run, xp_awk_nde_return_t* nde)
|
||||
xp_assert (nde->val->next == XP_NULL);
|
||||
|
||||
/*xp_printf (XP_T("returning....\n"));*/
|
||||
val = __eval_expression(run, nde->val);
|
||||
val = __eval_expression (run, nde->val);
|
||||
if (val == XP_NULL) return -1;
|
||||
|
||||
xp_awk_refdownval (run, STACK_RETVAL(run));
|
||||
@ -1360,7 +1359,7 @@ static int __run_exit (xp_awk_run_t* run, xp_awk_nde_exit_t* nde)
|
||||
* by the parser first of all */
|
||||
xp_assert (nde->val->next == XP_NULL);
|
||||
|
||||
val = __eval_expression(run, nde->val);
|
||||
val = __eval_expression (run, nde->val);
|
||||
if (val == XP_NULL) return -1;
|
||||
|
||||
xp_awk_refdownval (run, STACK_RETVAL_GLOBAL(run));
|
||||
@ -3852,7 +3851,7 @@ static xp_awk_val_t* __eval_call (
|
||||
p = call->args;
|
||||
while (p != XP_NULL)
|
||||
{
|
||||
v = __eval_expression(run,p);
|
||||
v = __eval_expression (run, p);
|
||||
if (v == XP_NULL)
|
||||
{
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
@ -3863,26 +3862,90 @@ static xp_awk_val_t* __eval_call (
|
||||
{
|
||||
xp_char_t spec;
|
||||
|
||||
/* TODO: spec length check */
|
||||
/* TODO: spec length check */
|
||||
spec = bfn_arg_spec[nargs];
|
||||
if (spec == XP_T('m'))
|
||||
{
|
||||
/*if (v->type == XP_AWK_VAL_NIL)
|
||||
/* reference required */
|
||||
if (p->type != XP_AWK_NDE_NAMED &&
|
||||
p->type != XP_AWK_NDE_GLOBAL &&
|
||||
p->type != XP_AWK_NDE_LOCAL &&
|
||||
p->type != XP_AWK_NDE_ARG &&
|
||||
p->type != XP_AWK_NDE_NAMEDIDX &&
|
||||
p->type != XP_AWK_NDE_GLOBALIDX &&
|
||||
p->type != XP_AWK_NDE_LOCALIDX &&
|
||||
p->type != XP_AWK_NDE_ARGIDX)
|
||||
{
|
||||
convert it to a map...
|
||||
do assignment if the value is by the variable
|
||||
}
|
||||
else*/ if (v->type != XP_AWK_VAL_MAP)
|
||||
{
|
||||
/* trigger an error */
|
||||
xp_awk_refupval (v);
|
||||
xp_awk_refdownval (run, v);
|
||||
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
/* TODO: change the error code */
|
||||
/* TODO: change error code */
|
||||
PANIC (run, XP_AWK_EVALTYPE);
|
||||
}
|
||||
|
||||
if (p->type == XP_AWK_NDE_GLOBAL)
|
||||
{
|
||||
xp_awk_val_t* tmp;
|
||||
xp_awk_nde_var_t* tgt =
|
||||
(xp_awk_nde_var_t*)p;
|
||||
|
||||
tmp = xp_awk_makeintval (
|
||||
run, (xp_long_t)&STACK_GLOBAL(run,tgt->id.idxa));
|
||||
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 0
|
||||
if (spec == XP_T('m'))
|
||||
{
|
||||
if (v->type == XP_AWK_VAL_NIL)
|
||||
{
|
||||
xp_awk_val_t* tmp;
|
||||
|
||||
tmp = xp_awk_makemapval (run);
|
||||
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;
|
||||
}
|
||||
else if (v->type != XP_AWK_VAL_MAP)
|
||||
{
|
||||
xp_awk_refupval (v);
|
||||
xp_awk_refdownval (run, v);
|
||||
|
||||
UNWIND_RUN_STACK (run, nargs);
|
||||
/* TODO: change the error code */
|
||||
PANIC (run, XP_AWK_EVALTYPE);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (spec = XP_T('s'))
|
||||
{
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
if (__raw_push(run,v) == -1)
|
||||
@ -3943,9 +4006,7 @@ static xp_awk_val_t* __eval_call (
|
||||
call->nargs <= call->what.bfn.max_args);
|
||||
|
||||
if (call->what.bfn.handler != XP_NULL)
|
||||
{
|
||||
n = call->what.bfn.handler (run->awk, run);
|
||||
}
|
||||
}
|
||||
|
||||
/*xp_printf (XP_T("block run complete\n")); */
|
||||
@ -3970,10 +4031,7 @@ static xp_awk_val_t* __eval_call (
|
||||
run->stack_top = (xp_size_t)run->stack[run->stack_base+1];
|
||||
run->stack_base = (xp_size_t)run->stack[run->stack_base+0];
|
||||
|
||||
if (run->exit_level == EXIT_FUNCTION)
|
||||
{
|
||||
run->exit_level = EXIT_NONE;
|
||||
}
|
||||
if (run->exit_level == EXIT_FUNCTION) run->exit_level = EXIT_NONE;
|
||||
|
||||
/*xp_printf (XP_T("returning from function stack_top=%ld, stack_base=%ld\n"), run->stack_top, run->stack_base); */
|
||||
return (n == -1)? XP_NULL: v;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: tree.h,v 1.68 2006-08-13 16:04:32 bacon Exp $
|
||||
* $Id: tree.h,v 1.69 2006-08-18 17:46:07 bacon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _XP_AWK_TREE_H_
|
||||
@ -226,8 +226,8 @@ struct xp_awk_nde_var_t
|
||||
struct
|
||||
{
|
||||
xp_char_t* name;
|
||||
xp_size_t name_len;
|
||||
xp_size_t idxa;
|
||||
xp_size_t name_len;
|
||||
xp_size_t idxa;
|
||||
} id;
|
||||
xp_awk_nde_t* idx; /* XP_NULL for non-XXXXIDX */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user