diff --git a/ase/awk/awk.dsp b/ase/awk/awk.dsp index 089c77d9..8e7b71f6 100644 --- a/ase/awk/awk.dsp +++ b/ase/awk/awk.dsp @@ -223,6 +223,10 @@ SOURCE=.\parse.c # End Source File # Begin Source File +SOURCE=.\rec.c +# End Source File +# Begin Source File + SOURCE=.\rex.c # End Source File # Begin Source File diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 6e5e38dd..569e63fe 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.119 2006-10-02 14:53:44 bacon Exp $ + * $Id: awk.h,v 1.120 2006-10-03 14:38:26 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -9,6 +9,7 @@ #include typedef struct xp_awk_t xp_awk_t; +typedef struct xp_awk_run_t xp_awk_run_t; typedef struct xp_awk_val_t xp_awk_val_t; typedef struct xp_awk_extio_t xp_awk_extio_t; @@ -40,14 +41,6 @@ struct xp_awk_extio_t xp_awk_extio_t* next; }; -/* -struct xp_awk_thrlks_t -{ - xp_awk_lk_t lock; - xp_awk_lk_t unlock; - void* custom_data; -}; -*/ struct xp_awk_syscas_t { /* memory */ @@ -339,22 +332,21 @@ int xp_awk_parse (xp_awk_t* awk, xp_awk_srcios_t* srcios); int xp_awk_run (xp_awk_t* awk, xp_awk_runios_t* runios, xp_awk_runcbs_t* runcbs); -int xp_awk_stop (xp_awk_t* awk, void* run); +int xp_awk_stop (xp_awk_t* awk, xp_awk_run_t* run); void xp_awk_stopall (xp_awk_t* awk); -int xp_awk_getrunerrnum (xp_awk_t* awk, void* run, int* errnum); +int xp_awk_getrunerrnum (xp_awk_t* awk, xp_awk_run_t* run, int* errnum); /* functions to access internal stack structure */ -xp_size_t xp_awk_getnargs (void* run); -xp_awk_val_t* xp_awk_getarg (void* run, xp_size_t idx); -xp_awk_val_t* xp_awk_getglobal (void* run, xp_size_t idx); -int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val); -void xp_awk_seterrnum (void* run, int errnum); -void xp_awk_setretval (void* run, xp_awk_val_t* val); +xp_size_t xp_awk_getnargs (xp_awk_run_t* run); +xp_awk_val_t* xp_awk_getarg (xp_awk_run_t* run, xp_size_t idx); +xp_awk_val_t* xp_awk_getglobal (xp_awk_run_t* run, xp_size_t idx); +int xp_awk_setglobal (xp_awk_run_t* run, xp_size_t idx, xp_awk_val_t* val); +void xp_awk_seterrnum (xp_awk_run_t* run, int errnum); +void xp_awk_setretval (xp_awk_run_t* run, xp_awk_val_t* val); -int xp_awk_setrecord ( - void* run, const xp_char_t* str, xp_size_t len); -int xp_awk_setfield ( - void* run, xp_size_t idx, const xp_char_t* str, xp_size_t len); +/* record and field functions */ +int xp_awk_clrrec (xp_awk_run_t* run, xp_bool_t skip_inrec_line); +int xp_awk_setrec (xp_awk_run_t* run, xp_size_t idx, const xp_char_t* str, xp_size_t len); /* utility functions exported by awk.h */ xp_long_t xp_awk_strtolong ( diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index c00c547c..810fc65e 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -1,12 +1,11 @@ /* - * $Id: awk_i.h,v 1.61 2006-09-29 11:18:13 bacon Exp $ + * $Id: awk_i.h,v 1.62 2006-10-03 14:38:26 bacon Exp $ */ #ifndef _XP_AWK_AWKI_H_ #define _XP_AWK_AWKI_H_ typedef struct xp_awk_chain_t xp_awk_chain_t; -typedef struct xp_awk_run_t xp_awk_run_t; typedef struct xp_awk_tree_t xp_awk_tree_t; #include diff --git a/ase/awk/func.c b/ase/awk/func.c index 531268d1..ae6f32c0 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.55 2006-10-02 14:53:44 bacon Exp $ + * $Id: func.c,v 1.56 2006-10-03 14:38:26 bacon Exp $ */ #include @@ -1042,7 +1042,7 @@ static int __substitute (xp_awk_t* awk, void* run, xp_long_t max_count) { if (a2 == XP_NULL) { - if (xp_awk_setrecord (run, + if (xp_awk_setrec (run, 0, XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new)) == -1) { xp_awk_str_close (&new); @@ -1053,19 +1053,10 @@ static int __substitute (xp_awk_t* awk, void* run, xp_long_t max_count) else if (((xp_awk_val_ref_t*)a2)->id == XP_AWK_VAL_REF_POS) { int n; - xp_size_t idx; - idx = (xp_size_t)((xp_awk_val_ref_t*)a2)->adr; - if (idx == 0) - { - n = xp_awk_setrecord (run, - XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new)); - } - else - { - n = xp_awk_setfield (run, idx, - XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new)); - } + n = xp_awk_setrec ( + run, (xp_size_t)((xp_awk_val_ref_t*)a2)->adr, + XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new)); if (n == -1) { diff --git a/ase/awk/makefile.cl b/ase/awk/makefile.cl index fbb3e9f9..898d8e35 100644 --- a/ase/awk/makefile.cl +++ b/ase/awk/makefile.cl @@ -1,6 +1,6 @@ SRCS = \ awk.c err.c tree.c str.c tab.c map.c parse.c \ - run.c val.c func.c misc.c extio.c rex.c + run.c rec.c val.c func.c misc.c extio.c rex.c OBJS = $(SRCS:.c=.obj) OUT = xpawk diff --git a/ase/awk/run.c b/ase/awk/run.c index b8a09334..28e1cbde 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.216 2006-10-02 14:53:44 bacon Exp $ + * $Id: run.c,v 1.217 2006-10-03 14:38:26 bacon Exp $ */ #include @@ -194,13 +194,6 @@ static int __raw_push (xp_awk_run_t* run, void* val); static void __raw_pop_times (xp_awk_run_t* run, xp_size_t times); static int __read_record (xp_awk_run_t* run); -static int __set_record ( - xp_awk_run_t* run, const xp_char_t* str, xp_size_t len); -static int __split_record (xp_awk_run_t* run); -static int __clear_record (xp_awk_run_t* run, xp_bool_t noline); -static int __recomp_record_fields ( - xp_awk_run_t* run, xp_size_t lv, - const xp_char_t* str, xp_size_t len); static int __shorten_record (xp_awk_run_t* run, xp_size_t nflds); static xp_char_t* __idxnde_to_str ( @@ -219,31 +212,29 @@ static int __printval (xp_awk_pair_t* pair, void* arg) return 0; } -xp_size_t xp_awk_getnargs (void* run) +xp_size_t xp_awk_getnargs (xp_awk_run_t* run) { - return (xp_size_t) STACK_NARGS ((xp_awk_run_t*)run); + return (xp_size_t) STACK_NARGS (run); } -xp_awk_val_t* xp_awk_getarg (void* run, xp_size_t idx) +xp_awk_val_t* xp_awk_getarg (xp_awk_run_t* run, xp_size_t idx) { - return STACK_ARG ((xp_awk_run_t*)run, idx); + return STACK_ARG (run, idx); } -xp_awk_val_t* xp_awk_getglobal (void* run, xp_size_t idx) +xp_awk_val_t* xp_awk_getglobal (xp_awk_run_t* run, xp_size_t idx) { - return STACK_GLOBAL(((xp_awk_run_t*)run),idx); + return STACK_GLOBAL (run, idx); } -int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) +int xp_awk_setglobal (xp_awk_run_t* run, xp_size_t idx, xp_awk_val_t* val) { - xp_awk_run_t* r = (xp_awk_run_t*)run; - - xp_awk_val_t* old = STACK_GLOBAL(r,idx); + xp_awk_val_t* old = STACK_GLOBAL (run, idx); if (old->type == XP_AWK_VAL_MAP) { /* once a variable becomes an array, * it cannot be changed to a scalar variable */ - PANIC_I (r, XP_AWK_EMAPTOSCALAR); + PANIC_I (run, XP_AWK_EMAPTOSCALAR); } /* TODO: is this correct?? */ @@ -252,7 +243,7 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) idx != XP_AWK_GLOBAL_ARGV) { /* TODO: better error code */ - PANIC_I (r, XP_AWK_ESCALARTOMAP); + PANIC_I (run, XP_AWK_ESCALARTOMAP); } if (idx == XP_AWK_GLOBAL_FS) @@ -283,26 +274,22 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) /* compile the regular expression */ /* TODO: use safebuild */ rex = xp_awk_buildrex ( - ((xp_awk_run_t*)run)->awk, - fs_ptr, fs_len, &r->errnum); + run->awk, fs_ptr, fs_len, &run->errnum); if (rex == XP_NULL) { if (val->type != XP_AWK_VAL_STR) - XP_AWK_FREE (((xp_awk_run_t*)run)->awk, fs_ptr); + XP_AWK_FREE (run->awk, fs_ptr); return -1; } - if (r->global.fs != XP_NULL) + if (run->global.fs != XP_NULL) { - xp_awk_freerex ( - ((xp_awk_run_t*)run)->awk, - r->global.fs); + xp_awk_freerex (run->awk, run->global.fs); } - r->global.fs = rex; + run->global.fs = rex; } - if (val->type != XP_AWK_VAL_STR) - XP_AWK_FREE (((xp_awk_run_t*)run)->awk, fs_ptr); + if (val->type != XP_AWK_VAL_STR) XP_AWK_FREE (run->awk, fs_ptr); } else if (idx == XP_AWK_GLOBAL_IGNORECASE) { @@ -313,11 +300,11 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) (val->type == XP_AWK_VAL_STR && ((xp_awk_val_str_t*)val)->len == 0)) { - ((xp_awk_run_t*)run)->global.ignorecase = 0; + run->global.ignorecase = 0; } else { - ((xp_awk_run_t*)run)->global.ignorecase = 1; + run->global.ignorecase = 1; } } else if (idx == XP_AWK_GLOBAL_NF) @@ -330,9 +317,9 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) if (n == -1) return -1; if (n == 1) lv = (xp_long_t)rv; - if (lv < r->inrec.nflds) + if (lv < run->inrec.nflds) { - if (__shorten_record (r, (xp_size_t)lv) == -1) return -1; + if (__shorten_record (run, (xp_size_t)lv) == -1) return -1; } } else if (idx == XP_AWK_GLOBAL_OFMT) @@ -344,8 +331,8 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) run, val, xp_true, XP_NULL, &ofmt_len); if (ofmt_ptr == XP_NULL) return -1; - r->global.ofmt.ptr = ofmt_ptr; - r->global.ofmt.len = ofmt_len; + run->global.ofmt.ptr = ofmt_ptr; + run->global.ofmt.len = ofmt_len; } else if (idx == XP_AWK_GLOBAL_OFS) { @@ -356,8 +343,8 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) run, val, xp_true, XP_NULL, &ofs_len); if (ofs_ptr == XP_NULL) return -1; - r->global.ofs.ptr = ofs_ptr; - r->global.ofs.len = ofs_len; + run->global.ofs.ptr = ofs_ptr; + run->global.ofs.len = ofs_len; } else if (idx == XP_AWK_GLOBAL_ORS) { @@ -368,8 +355,8 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) run, val, xp_true, XP_NULL, &ors_len); if (ors_ptr == XP_NULL) return -1; - r->global.ors.ptr = ors_ptr; - r->global.ors.len = ors_len; + run->global.ors.ptr = ors_ptr; + run->global.ors.len = ors_len; } else if (idx == XP_AWK_GLOBAL_RS) { @@ -399,26 +386,22 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) /* compile the regular expression */ /* TODO: use safebuild */ rex = xp_awk_buildrex ( - ((xp_awk_run_t*)run)->awk, - rs_ptr, rs_len, &r->errnum); + run->awk, rs_ptr, rs_len, &run->errnum); if (rex == XP_NULL) { if (val->type != XP_AWK_VAL_STR) - XP_AWK_FREE (((xp_awk_run_t*)run)->awk, rs_ptr); + XP_AWK_FREE (run->awk, rs_ptr); return -1; } - if (r->global.rs != XP_NULL) + if (run->global.rs != XP_NULL) { - xp_awk_freerex ( - ((xp_awk_run_t*)run)->awk, - r->global.rs); + xp_awk_freerex (run->awk, run->global.rs); } - r->global.rs = rex; + run->global.rs = rex; } - if (val->type != XP_AWK_VAL_STR) - XP_AWK_FREE (((xp_awk_run_t*)run)->awk, rs_ptr); + if (val->type != XP_AWK_VAL_STR) XP_AWK_FREE (run->awk, rs_ptr); } else if (idx == XP_AWK_GLOBAL_SUBSEP) { @@ -429,28 +412,26 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) run, val, xp_true, XP_NULL, &subsep_len); if (subsep_ptr == XP_NULL) return -1; - r->global.subsep.ptr = subsep_ptr; - r->global.subsep.len = subsep_len; + run->global.subsep.ptr = subsep_ptr; + run->global.subsep.len = subsep_len; } - xp_awk_refdownval (r, old); - STACK_GLOBAL(r,idx) = val; + xp_awk_refdownval (run, old); + STACK_GLOBAL(run,idx) = val; xp_awk_refupval (val); return 0; } -void xp_awk_seterrnum (void* run, int errnum) +void xp_awk_seterrnum (xp_awk_run_t* run, int errnum) { - xp_awk_run_t* r = (xp_awk_run_t*)run; - r->errnum = errnum; + run->errnum = errnum; } -void xp_awk_setretval (void* run, xp_awk_val_t* val) +void xp_awk_setretval (xp_awk_run_t* run, xp_awk_val_t* val) { - xp_awk_run_t* r = (xp_awk_run_t*)run; - xp_awk_refdownval (r, STACK_RETVAL(r)); - STACK_RETVAL(r) = val; + xp_awk_refdownval (run, STACK_RETVAL(run)); + STACK_RETVAL(run) = val; /* should use the same trick as __run_return_statement */ xp_awk_refupval (val); } @@ -509,7 +490,7 @@ int xp_awk_run (xp_awk_t* awk, xp_awk_runios_t* runios, xp_awk_runcbs_t* runcbs) return n; } -int xp_awk_stop (xp_awk_t* awk, void* run) +int xp_awk_stop (xp_awk_t* awk, xp_awk_run_t* run) { xp_awk_run_t* r; int n = 0; @@ -554,7 +535,7 @@ void xp_awk_stopall (xp_awk_t* awk) XP_AWK_UNLOCK (awk); } -int xp_awk_getrunerrnum (xp_awk_t* awk, void* run, int* errnum) +int xp_awk_getrunerrnum (xp_awk_t* awk, xp_awk_run_t* run, int* errnum) { xp_awk_run_t* r; int n = 0; @@ -624,8 +605,7 @@ static void __del_run (xp_awk_t* awk, xp_awk_run_t* run) XP_AWK_UNLOCK (awk); } -static int __init_run ( - xp_awk_run_t* run, xp_awk_runios_t* runios, int* errnum) +static int __init_run (xp_awk_run_t* run, xp_awk_runios_t* runios, int* errnum) { run->stack = XP_NULL; run->stack_top = 0; @@ -747,10 +727,10 @@ static void __deinit_run (xp_awk_run_t* run) run->global.subsep.len = 0; } - /* destroy input record. __clear_record should be called + /* destroy input record. xp_awk_clrrec should be called * before the run stack has been destroyed because it may try * to change the value to XP_AWK_GLOBAL_NF. */ - __clear_record (run, xp_false); + xp_awk_clrrec (run, xp_false); if (run->inrec.flds != XP_NULL) { XP_AWK_FREE (run->awk, run->inrec.flds); @@ -2445,7 +2425,7 @@ static xp_awk_val_t* __do_assignment_pos ( xp_real_t rv; xp_char_t* str; xp_size_t len; - int n, errnum; + int n; /* get the position number */ v = __eval_expression (run, pos->val); @@ -2459,24 +2439,45 @@ static xp_awk_val_t* __do_assignment_pos ( if (n == 1) lv = (xp_long_t)rv; if (!IS_VALID_POSIDX(lv)) PANIC (run, XP_AWK_EPOSIDX); + if (val->type == XP_AWK_VAL_STR) + { + str = ((xp_awk_val_str_t*)val)->buf; + len = ((xp_awk_val_str_t*)val)->len; + } + else + { + str = xp_awk_valtostr (run, val, xp_true, XP_NULL, &len); + if (str == XP_NULL) return XP_NULL; + } + + n = xp_awk_setrec (run, (xp_size_t)lv, str, len); + + if (val->type != XP_AWK_VAL_STR) XP_AWK_FREE (run->awk, str); + + if (n == -1) return XP_NULL; + return (lv == 0)? run->inrec.d0: run->inrec.flds[lv-1].val; + +#if 0 /* convert the value to the string */ str = xp_awk_valtostr (run, val, xp_true, XP_NULL, &len); if (str == XP_NULL) return XP_NULL; if (lv == 0) { - if (__clear_record (run, xp_false) == -1) + if (xp_awk_clrrec (run, xp_false) == -1) { - XP_AWK_FREE (run->awk, str); + if (val->type != XP_AWK_VAL_STR) + XP_AWK_FREE (run->awk, str); return XP_NULL; } if (xp_awk_str_ncpy (&run->inrec.line, str, len) == (xp_size_t)-1) { - XP_AWK_FREE (run->awk, str); + if (val->type != XP_AWK_VAL_STR) + XP_AWK_FREE (run->awk, str); PANIC (run, XP_AWK_ENOMEM); } - XP_AWK_FREE (run->awk, str); + if (val->type == XP_AWK_VAL_STR) { @@ -2486,13 +2487,15 @@ static xp_awk_val_t* __do_assignment_pos ( } else { + XP_AWK_FREE (run->awk, str); + v = xp_awk_makestrval ( run, XP_AWK_STR_BUF(&run->inrec.line), XP_AWK_STR_LEN(&run->inrec.line)); if (v == XP_NULL) { - __clear_record (run, xp_false); + xp_awk_clrrec (run, xp_false); PANIC (run, XP_AWK_ENOMEM); } @@ -2506,7 +2509,7 @@ static xp_awk_val_t* __do_assignment_pos ( if (__split_record (run) == -1) { errnum = run->errnum; - __clear_record (run, xp_false); + xp_awk_clrrec (run, xp_false); run->errnum = errnum; return XP_NULL; } @@ -2517,7 +2520,7 @@ static xp_awk_val_t* __do_assignment_pos ( { errnum = run->errnum; XP_AWK_FREE (run->awk, str); - __clear_record (run, xp_false); + xp_awk_clrrec (run, xp_false); run->errnum = errnum; return XP_NULL; } @@ -2530,7 +2533,7 @@ static xp_awk_val_t* __do_assignment_pos ( XP_AWK_STR_LEN(&run->inrec.line)); if (v == XP_NULL) { - __clear_record (run, xp_false); + xp_awk_clrrec (run, xp_false); PANIC (run, XP_AWK_ENOMEM); } @@ -2543,6 +2546,7 @@ static xp_awk_val_t* __do_assignment_pos ( } return val; +#endif } static xp_awk_val_t* __eval_binary (xp_awk_run_t* run, xp_awk_nde_t* nde) @@ -4726,8 +4730,8 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) if (p->var == XP_NULL) { /* set $0 with the input value */ - if (xp_awk_setrecord (run, - XP_AWK_STR_BUF(&buf), + if (xp_awk_setrec (run, 0, + XP_AWK_STR_BUF(&buf), XP_AWK_STR_LEN(&buf)) == -1) { xp_awk_str_close (&buf); @@ -4742,12 +4746,10 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) v = xp_awk_makestrval ( run, XP_AWK_STR_BUF(&buf), XP_AWK_STR_LEN(&buf)); - xp_awk_str_close (&buf); - if (v == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + xp_awk_refupval (v); - if (__do_assignment(run, p->var, v) == XP_NULL) { xp_awk_refdownval (run, v); @@ -4762,7 +4764,7 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) } skip_read: - res = xp_awk_makeintval (run, n); + res = xp_awk_makeintval (run, n); if (res == XP_NULL) PANIC (run, XP_AWK_ENOMEM); return res; @@ -4816,14 +4818,14 @@ static int __read_record (xp_awk_run_t* run) { xp_ssize_t n; - if (__clear_record (run, xp_false) == -1) return -1; + if (xp_awk_clrrec (run, xp_false) == -1) return -1; n = xp_awk_readextio ( run, XP_AWK_IN_CONSOLE, XP_T(""), &run->inrec.line); if (n < 0) { int errnum = run->errnum; - __clear_record (run, xp_false); + xp_awk_clrrec (run, xp_false); run->errnum = (errnum == XP_AWK_EIOHANDLER)? XP_AWK_ECONINDATA: errnum; @@ -4835,441 +4837,13 @@ static int __read_record (xp_awk_run_t* run) return 0; } - if (__set_record (run, + if (xp_awk_setrec (run, 0, XP_AWK_STR_BUF(&run->inrec.line), XP_AWK_STR_LEN(&run->inrec.line)) == -1) return -1; return 1; } -int xp_awk_setrecord (void* run, const xp_char_t* str, xp_size_t len) -{ - xp_awk_run_t* r = (xp_awk_run_t*)run; - - if (__clear_record (r, xp_false) == -1) return -1; - - if (xp_awk_str_ncpy (&r->inrec.line, str, len) == (xp_size_t)-1) - { - __clear_record (run, xp_false); - r->errnum = XP_AWK_ENOMEM; - return -1; - } - - return __set_record (run, str, len); -} - -int xp_awk_setfield ( - void* run, xp_size_t idx, const xp_char_t* str, xp_size_t len) -{ - xp_awk_run_t* r = (xp_awk_run_t*)run; - xp_awk_val_t* v; - int errnum; - - if (!IS_VALID_POSIDX(idx)) - { - r->errnum = XP_AWK_EPOSIDX; - return -1; - } - - if (idx == 0) return xp_awk_setrecord (run, str, len); - - if (__recomp_record_fields (r, idx, str, len) == -1) - { - errnum = r->errnum; - __clear_record (r, xp_false); - r->errnum = errnum; - return -1; - } - - /* recompose $0 */ - v = xp_awk_makestrval (r, - XP_AWK_STR_BUF(&r->inrec.line), - XP_AWK_STR_LEN(&r->inrec.line)); - if (v == XP_NULL) - { - __clear_record (run, xp_false); - r->errnum = XP_AWK_ENOMEM; - return -1; - } - - xp_awk_refdownval (run, r->inrec.d0); - r->inrec.d0 = v; - xp_awk_refupval (v); - - return 0; -} - -static int __set_record ( - xp_awk_run_t* run, const xp_char_t* str, xp_size_t len) -{ - xp_awk_val_t* v; - int errnum; - - v = xp_awk_makestrval (run, str, len); - if (v == XP_NULL) - { - __clear_record (run, xp_false); - PANIC_I (run, XP_AWK_ENOMEM); - } - - xp_assert (run->inrec.d0->type == XP_AWK_VAL_NIL); - /* the record should be clear cleared before this function is called - * as it doesn't call xp_awk_refdownval on run->inrec.d0 */ - run->inrec.d0 = v; - xp_awk_refupval (v); - - if (__split_record (run) == -1) - { - errnum = run->errnum; - __clear_record (run, xp_false); - run->errnum = errnum; - return -1; - } - - return 0; /* success */ -} - -static int __split_record (xp_awk_run_t* run) -{ - xp_char_t* p, * tok; - xp_size_t len, tok_len, nflds; - xp_awk_val_t* v, * fs; - xp_char_t* fs_ptr, * fs_free; - xp_size_t fs_len; - int errnum; - - /* inrec should be cleared before __split_record is called */ - xp_assert (run->inrec.nflds == 0); - - /* get FS */ - fs = xp_awk_getglobal (run, XP_AWK_GLOBAL_FS); - if (fs->type == XP_AWK_VAL_NIL) - { - fs_ptr = XP_T(" "); - fs_len = 1; - fs_free = XP_NULL; - } - else if (fs->type == XP_AWK_VAL_STR) - { - fs_ptr = ((xp_awk_val_str_t*)fs)->buf; - fs_len = ((xp_awk_val_str_t*)fs)->len; - fs_free = XP_NULL; - } - else - { - fs_ptr = xp_awk_valtostr ( - run, fs, xp_true, XP_NULL, &fs_len); - if (fs_ptr == XP_NULL) return -1; - fs_free = fs_ptr; - } - - /* scan the input record to count the fields */ - p = XP_AWK_STR_BUF(&run->inrec.line); - len = XP_AWK_STR_LEN(&run->inrec.line); - - nflds = 0; - while (p != XP_NULL) - { - if (fs_len <= 1) - { - p = xp_awk_strxntok (run, - p, len, fs_ptr, fs_len, &tok, &tok_len); - } - else - { - p = xp_awk_strxntokbyrex (run, p, len, - run->global.fs, &tok, &tok_len, &errnum); - if (p == XP_NULL && errnum != XP_AWK_ENOERR) - { - if (fs_free != XP_NULL) - XP_AWK_FREE (run->awk, fs_free); - PANIC_I (run, errnum); - } - } - - if (nflds == 0 && p == XP_NULL && tok_len == 0) - { - /* there are no fields. it can just return here - * as __clear_record has been called before this */ - if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free); - return 0; - } - - xp_assert ((tok != XP_NULL && tok_len > 0) || tok_len == 0); - - nflds++; - len = XP_AWK_STR_LEN(&run->inrec.line) - - (p - XP_AWK_STR_BUF(&run->inrec.line)); - } - - /* allocate space */ - if (nflds > run->inrec.maxflds) - { - void* tmp = XP_AWK_MALLOC ( - run->awk, xp_sizeof(*run->inrec.flds) * nflds); - if (tmp == XP_NULL) - { - if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free); - PANIC_I (run, XP_AWK_ENOMEM); - } - - if (run->inrec.flds != XP_NULL) - XP_AWK_FREE (run->awk, run->inrec.flds); - run->inrec.flds = tmp; - run->inrec.maxflds = nflds; - } - - /* scan again and split it */ - p = XP_AWK_STR_BUF(&run->inrec.line); - len = XP_AWK_STR_LEN(&run->inrec.line); - - while (p != XP_NULL) - { - if (fs_len <= 1) - { - p = xp_awk_strxntok ( - run, p, len, fs_ptr, fs_len, &tok, &tok_len); - } - else - { - p = xp_awk_strxntokbyrex (run, p, len, - run->global.fs, &tok, &tok_len, &errnum); - if (p == XP_NULL && errnum != XP_AWK_ENOERR) - { - if (fs_free != XP_NULL) - XP_AWK_FREE (run->awk, fs_free); - PANIC_I (run, errnum); - } - } - - xp_assert ((tok != XP_NULL && tok_len > 0) || tok_len == 0); - - run->inrec.flds[run->inrec.nflds].ptr = tok; - run->inrec.flds[run->inrec.nflds].len = tok_len; - run->inrec.flds[run->inrec.nflds].val = - xp_awk_makestrval (run, tok, tok_len); - - if (run->inrec.flds[run->inrec.nflds].val == XP_NULL) - { - if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free); - PANIC_I (run, XP_AWK_ENOMEM); - } - - xp_awk_refupval (run->inrec.flds[run->inrec.nflds].val); - run->inrec.nflds++; - - len = XP_AWK_STR_LEN(&run->inrec.line) - - (p - XP_AWK_STR_BUF(&run->inrec.line)); - } - - if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free); - - /* set the number of fields */ - v = xp_awk_makeintval (run, (xp_long_t)nflds); - if (v == XP_NULL) PANIC_I (run, XP_AWK_ENOMEM); - if (xp_awk_setglobal (run, XP_AWK_GLOBAL_NF, v) == -1) return -1; - - xp_assert (nflds == run->inrec.nflds); - return 0; -} - -static int __clear_record (xp_awk_run_t* run, xp_bool_t noline) -{ - xp_size_t i; - int n = 0; - - xp_awk_refdownval (run, run->inrec.d0); - run->inrec.d0 = xp_awk_val_nil; - - if (run->inrec.nflds > 0) - { - xp_assert (run->inrec.flds != XP_NULL); - - for (i = 0; i < run->inrec.nflds; i++) - { - xp_assert (run->inrec.flds[i].val != XP_NULL); - xp_awk_refdownval (run, run->inrec.flds[i].val); - } - run->inrec.nflds = 0; - - if (xp_awk_setglobal ( - run, XP_AWK_GLOBAL_NF, xp_awk_val_zero) == -1) - { - /* first of all, this should never happen. - * if it happened, it would return an error - * after all the clearance tasks */ - n = -1; - } - } - - xp_assert (run->inrec.nflds == 0); - if (!noline) xp_awk_str_clear (&run->inrec.line); - - return n; -} - -static int __recomp_record_fields ( - xp_awk_run_t* run, xp_size_t lv, - const xp_char_t* str, xp_size_t len) -{ - xp_awk_val_t* v; - xp_size_t max, i, nflds; - - /* recomposes the record and the fields when $N has been assigned - * a new value and recomputes NF accordingly */ - - xp_assert (lv > 0); - max = (lv > run->inrec.nflds)? lv: run->inrec.nflds; - - nflds = run->inrec.nflds; - if (max > run->inrec.maxflds) - { - void* tmp; - - /* if the given field number is greater than the maximum - * number of fields that the current record can hold, - * the field spaces are resized */ - - if (run->awk->syscas->realloc != XP_NULL) - { - tmp = XP_AWK_REALLOC ( - run->awk, run->inrec.flds, - xp_sizeof(*run->inrec.flds) * max); - if (tmp == XP_NULL) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - } - else - { - tmp = XP_AWK_MALLOC ( - run->awk, xp_sizeof(*run->inrec.flds) * max); - if (tmp == XP_NULL) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - if (run->inrec.flds != XP_NULL) - { - XP_AWK_MEMCPY (run->awk, tmp, run->inrec.flds, - xp_sizeof(*run->inrec.flds) * run->inrec.maxflds); - XP_AWK_FREE (run->awk, run->inrec.flds); - } - } - - run->inrec.flds = tmp; - run->inrec.maxflds = max; - } - - lv = lv - 1; /* adjust the value to 0-based index */ - - xp_awk_str_clear (&run->inrec.line); - - for (i = 0; i < max; i++) - { - if (i > 0) - { - if (xp_awk_str_ncat ( - &run->inrec.line, - run->global.ofs.ptr, - run->global.ofs.len) == (xp_size_t)-1) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - } - - if (i == lv) - { - xp_awk_val_t* tmp; - - run->inrec.flds[i].ptr = - XP_AWK_STR_BUF(&run->inrec.line) + - XP_AWK_STR_LEN(&run->inrec.line); - run->inrec.flds[i].len = len; - - if (xp_awk_str_ncat ( - &run->inrec.line, str, len) == (xp_size_t)-1) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - - tmp = xp_awk_makestrval (run, str,len); - if (tmp == XP_NULL) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - - if (i < nflds) - xp_awk_refdownval (run, run->inrec.flds[i].val); - else run->inrec.nflds++; - - run->inrec.flds[i].val = tmp; - xp_awk_refupval (tmp); - } - else if (i >= nflds) - { - run->inrec.flds[i].ptr = - XP_AWK_STR_BUF(&run->inrec.line) + - XP_AWK_STR_LEN(&run->inrec.line); - run->inrec.flds[i].len = 0; - - if (xp_awk_str_cat ( - &run->inrec.line, XP_T("")) == (xp_size_t)-1) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - - /* xp_awk_refdownval should not be called over - * run->inrec.flds[i].val as it is not initialized - * to any valid values */ - /*xp_awk_refdownval (run, run->inrec.flds[i].val);*/ - run->inrec.flds[i].val = xp_awk_val_zls; - xp_awk_refupval (xp_awk_val_zls); - run->inrec.nflds++; - } - else - { - xp_awk_val_str_t* tmp; - - tmp = (xp_awk_val_str_t*)run->inrec.flds[i].val; - - run->inrec.flds[i].ptr = - XP_AWK_STR_BUF(&run->inrec.line) + - XP_AWK_STR_LEN(&run->inrec.line); - run->inrec.flds[i].len = tmp->len; - - if (xp_awk_str_ncat (&run->inrec.line, - tmp->buf, tmp->len) == (xp_size_t)-1) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - } - } - - v = STACK_GLOBAL(run, XP_AWK_GLOBAL_NF); - xp_assert (v->type == XP_AWK_VAL_INT); - if (((xp_awk_val_int_t*)v)->val != max) - { - v = xp_awk_makeintval (run, (xp_long_t)max); - if (v == XP_NULL) - { - run->errnum = XP_AWK_ENOMEM; - return -1; - } - - if (xp_awk_setglobal ( - run, XP_AWK_GLOBAL_NF, v) == -1) return -1; - } - - return 0; -} - static int __shorten_record (xp_awk_run_t* run, xp_size_t nflds) { xp_awk_val_t* v;