diff --git a/ase/awk/err.c b/ase/awk/err.c index 02eb12c9..5f55b3ae 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.11 2007/10/24 09:57:45 bacon Exp $ + * $Id: err.c,v 1.12 2007/11/06 09:47:12 bacon Exp $ * * {License} */ @@ -281,7 +281,7 @@ void ase_awk_seterror ( awk->prmfns.misc.custom_data, awk->errmsg, ASE_COUNTOF(awk->errmsg), - errfmt, len, tmp); + errfmt, (int)len, tmp); return; } @@ -291,8 +291,8 @@ void ase_awk_seterror ( awk->errmsg, ASE_COUNTOF(awk->errmsg), errfmt, - errarg[0].len, errarg[0].ptr, - errarg[1].len, errarg[1].ptr); + (int)errarg[0].len, errarg[0].ptr, + (int)errarg[1].len, errarg[1].ptr); return; case 3: @@ -301,9 +301,9 @@ void ase_awk_seterror ( awk->errmsg, ASE_COUNTOF(awk->errmsg), errfmt, - errarg[0].len, errarg[0].ptr, - errarg[1].len, errarg[1].ptr, - errarg[2].len, errarg[2].ptr); + (int)errarg[0].len, errarg[0].ptr, + (int)errarg[1].len, errarg[1].ptr, + (int)errarg[2].len, errarg[2].ptr); return; case 4: @@ -312,10 +312,10 @@ void ase_awk_seterror ( awk->errmsg, ASE_COUNTOF(awk->errmsg), errfmt, - errarg[0].len, errarg[0].ptr, - errarg[1].len, errarg[1].ptr, - errarg[2].len, errarg[2].ptr, - errarg[3].len, errarg[3].ptr); + (int)errarg[0].len, errarg[0].ptr, + (int)errarg[1].len, errarg[1].ptr, + (int)errarg[2].len, errarg[2].ptr, + (int)errarg[3].len, errarg[3].ptr); return; case 5: @@ -324,11 +324,11 @@ void ase_awk_seterror ( awk->errmsg, ASE_COUNTOF(awk->errmsg), errfmt, - errarg[0].len, errarg[0].ptr, - errarg[1].len, errarg[1].ptr, - errarg[2].len, errarg[2].ptr, - errarg[3].len, errarg[3].ptr, - errarg[4].len, errarg[4].ptr); + (int)errarg[0].len, errarg[0].ptr, + (int)errarg[1].len, errarg[1].ptr, + (int)errarg[2].len, errarg[2].ptr, + (int)errarg[3].len, errarg[3].ptr, + (int)errarg[4].len, errarg[4].ptr); return; } } diff --git a/ase/awk/func.c b/ase/awk/func.c index 366d709e..aba1bb2f 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.17 2007/11/05 14:59:23 bacon Exp $ + * $Id: func.c,v 1.18 2007/11/06 09:47:12 bacon Exp $ * * {License} */ @@ -169,8 +169,8 @@ ase_awk_bfn_t* ase_awk_getbfn ( } else { - k = bfn->name.ptr; - l = bfn->name.len; + k = name; + l = len; } pair = ase_awk_map_get (awk->bfn.user, k, l); diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 4b3877ca..92559f75 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.26 2007/11/05 14:59:23 bacon Exp $ + * $Id: parse.c,v 1.27 2007/11/06 09:47:12 bacon Exp $ * * {License} */ @@ -132,6 +132,10 @@ static ase_awk_t* parse_progunit (ase_awk_t* awk); static ase_awk_t* collect_globals (ase_awk_t* awk); static void adjust_static_globals (ase_awk_t* awk); +static ase_size_t get_global ( + ase_awk_t* awk, const ase_char_t* name, ase_size_t len); +static ase_size_t find_global ( + ase_awk_t* awk, const ase_char_t* name, ase_size_t len); static int add_global ( ase_awk_t* awk, const ase_char_t* name, ase_size_t len, ase_size_t line, int force); @@ -876,16 +880,12 @@ static ase_awk_nde_t* parse_function (ase_awk_t* awk) if (awk->option & ASE_AWK_UNIQUEFN) { /* check if it coincides to be a global variable name */ - ase_size_t g; - -// TODO: setword - g = ase_awk_tab_find (&awk->parse.globals, 0, name, name_len); + ase_size_t g = find_global (awk, name, name_len); if (g != (ase_size_t)-1) { SETERRARG ( awk, ASE_AWK_EGBLRED, awk->token.line, name, name_len); - return ASE_NULL; } } @@ -1395,7 +1395,8 @@ static void adjust_static_globals (ase_awk_t* awk) for (id = ASE_AWK_MIN_GLOBAL_ID; id <= ASE_AWK_MAX_GLOBAL_ID; id++) { - if (gtab[id].valid != 0 && (awk->option & gtab[id].valid) == 0) + if (gtab[id].valid != 0 && + (awk->option & gtab[id].valid) != gtab[id].valid) { awk->parse.globals.buf[id].name.len = 0; } @@ -1406,6 +1407,45 @@ static void adjust_static_globals (ase_awk_t* awk) } } +static void trans_global ( + ase_size_t index, ase_cstr_t* word, void* arg) +{ + ase_awk_tab_t* tab = (ase_awk_tab_t*)arg; + ase_awk_t* awk = tab->awk; + + /* + if (index >= ASE_AWK_MIN_GLOBAL_ID && + index <= ASE_AWK_MAX_GLOBAL_ID) + */ + if (index < awk->tree.nbglobals) + { + ase_awk_pair_t* pair; + + pair = ase_awk_map_get (awk->wtab, word->ptr, word->len); + if (pair != ASE_NULL) + { + word->ptr = ((ase_cstr_t*)(pair->val))->ptr; + word->len = ((ase_cstr_t*)(pair->val))->len; + } + } +} + +static ase_size_t get_global ( + ase_awk_t* awk, const ase_char_t* name, ase_size_t len) +{ + return ase_awk_tab_rrfindx ( + &awk->parse.globals, 0, name, len, + trans_global, &awk->parse.globals); +} + +static ase_size_t find_global ( + ase_awk_t* awk, const ase_char_t* name, ase_size_t len) +{ + return ase_awk_tab_findx ( + &awk->parse.globals, 0, name, len, + trans_global, &awk->parse.globals); +} + static int add_global ( ase_awk_t* awk, const ase_char_t* name, ase_size_t len, ase_size_t line, int disabled) @@ -1435,8 +1475,7 @@ static int add_global ( } /* check if it conflicts with other global variable names */ - if (ase_awk_tab_find ( - &awk->parse.globals, 0, name, len) != (ase_size_t)-1) + if (find_global (awk, name, len) != (ase_size_t)-1) { SETERRARG (awk, ASE_AWK_EDUPGBL, line, name, len); return -1; @@ -1483,7 +1522,6 @@ int ase_awk_addglobal ( SETERR (awk, ASE_AWK_ENOPER); return -1; } - n = add_global (awk, name, len, 0, 0); /* update the count of the static globals. @@ -1628,7 +1666,7 @@ static ase_awk_t* collect_locals (ase_awk_t* awk, ase_size_t nlocals) } /* check if it conflicts with global variable names */ - n = ase_awk_tab_find (&awk->parse.globals, 0, local, local_len); + n = find_global (awk, local, local_len); if (n != (ase_size_t)-1) { if (n < awk->tree.nbglobals) @@ -2984,7 +3022,6 @@ static ase_awk_nde_t* parse_primary (ase_awk_t* awk, ase_size_t line) return ASE_NULL; } -#include static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) { ase_char_t* name_dup; @@ -3026,8 +3063,8 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) return ASE_NULL; } - ASE_AWK_FREE (awk, name_dup); - nde = parse_fncall (awk, ASE_NULL, 0, bfn, line); + nde = parse_fncall (awk, name_dup, name_len, bfn, line); + if (nde == ASE_NULL) ASE_AWK_FREE (awk, name_dup); return (ase_awk_nde_t*)nde; } @@ -3052,9 +3089,6 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) /* normal variable */ ase_awk_nde_var_t* nde; ase_size_t idxa; - ase_awk_pair_t* pair; - const ase_char_t* k; - ase_size_t l; nde = (ase_awk_nde_var_t*) ASE_AWK_MALLOC ( awk, ASE_SIZEOF(ase_awk_nde_var_t)); @@ -3099,33 +3133,8 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) return (ase_awk_nde_t*)nde; } - /* check if the word given should be replaced */ - pair = ase_awk_map_get (awk->rwtab, name_dup, name_len); - if (pair != ASE_NULL) - { - /* found in the customized word table */ - k = ((ase_cstr_t*)(pair->val))->ptr; - l = ((ase_cstr_t*)(pair->val))->len; - } - else - { - pair = ase_awk_map_get (awk->wtab, name_dup, name_len); - if (pair != ASE_NULL) - { - /* found in the customized word table */ - k = ((ase_cstr_t*)(pair->val))->ptr; - l = ((ase_cstr_t*)(pair->val))->len; - } - else - { - k = name_dup; - l = name_len; - } - } - - - /* search the global variable list */ - idxa = ase_awk_tab_rrfind (&awk->parse.globals, 0, k, l); + /* gets the global variable index */ + idxa = get_global (awk, name_dup, name_len); if (idxa != (ase_size_t)-1) { nde->type = ASE_AWK_NDE_GLOBAL; @@ -3142,6 +3151,25 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) if (awk->option & ASE_AWK_IMPLICIT) { + if (awk->option & ASE_AWK_UNIQUEFN) + { + /* the name should not conflict with a function name */ + /* check if it is a builtin function */ + if (ase_awk_getbfn (awk, name_dup, name_len) != ASE_NULL) + { + SETERRARG (awk, ASE_AWK_EBFNRED, line, name_dup, name_len); + goto exit_func; + } + + /* check if it is an AWK function */ + if (ase_awk_map_get(awk->tree.afns, name_dup, name_len) != ASE_NULL) + { + /* the function is defined previously */ + SETERRARG (awk, ASE_AWK_EAFNRED, line, name_dup, name_len); + goto exit_func; + } + } + nde->type = ASE_AWK_NDE_NAMED; nde->line = line; nde->next = ASE_NULL; @@ -3153,9 +3181,10 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) return (ase_awk_nde_t*)nde; } + /* undefined variable */ SETERRARG (awk, ASE_AWK_EUNDEF, line, name_dup, name_len); - /* undefined variable */ + exit_func: ASE_AWK_FREE (awk, name_dup); ASE_AWK_FREE (awk, nde); @@ -3169,9 +3198,6 @@ static ase_awk_nde_t* parse_hashidx ( ase_awk_nde_t* idx, * tmp, * last; ase_awk_nde_var_t* nde; ase_size_t idxa; - ase_awk_pair_t* pair; - const ase_char_t* k; - ase_size_t l; idx = ASE_NULL; last = ASE_NULL; @@ -3261,22 +3287,8 @@ static ase_awk_nde_t* parse_hashidx ( return (ase_awk_nde_t*)nde; } - /* check if the word given should be replaced */ - pair = ase_awk_map_get (awk->rwtab, name, name_len); - if (pair != ASE_NULL) - { - /* found in the customized word table */ - k = ((ase_cstr_t*)(pair->val))->ptr; - l = ((ase_cstr_t*)(pair->val))->len; - } - else - { - k = name; - l = name_len; - } - - /* search the global variable list */ - idxa = ase_awk_tab_rrfind(&awk->parse.globals, 0, k, l); + /* gets the global variable index */ + idxa = get_global (awk, name, name_len); if (idxa != (ase_size_t)-1) { nde->type = ASE_AWK_NDE_GLOBALIDX; @@ -3293,6 +3305,24 @@ static ase_awk_nde_t* parse_hashidx ( if (awk->option & ASE_AWK_IMPLICIT) { + if (awk->option & ASE_AWK_UNIQUEFN) + { + /* check if it is a builtin function */ + if (ase_awk_getbfn (awk, name, name_len) != ASE_NULL) + { + SETERRARG (awk, ASE_AWK_EBFNRED, line, name, name_len); + goto exit_func; + } + + /* check if it is an AWK function */ + if (ase_awk_map_get(awk->tree.afns, name, name_len) != ASE_NULL) + { + /* the function is defined previously */ + SETERRARG (awk, ASE_AWK_EAFNRED, line, name, name_len); + goto exit_func; + } + } + nde->type = ASE_AWK_NDE_NAMEDIDX; nde->line = line; nde->next = ASE_NULL; @@ -3305,10 +3335,13 @@ static ase_awk_nde_t* parse_hashidx ( } /* undefined variable */ + SETERRARG (awk, ASE_AWK_EUNDEF, line, name, name_len); + + +exit_func: ase_awk_clrpt (awk, idx); ASE_AWK_FREE (awk, nde); - SETERRARG (awk, ASE_AWK_EUNDEF, line, name, name_len); return ASE_NULL; } @@ -3394,8 +3427,13 @@ static ase_awk_nde_t* parse_fncall ( call->next = ASE_NULL; /*call->what.bfn = bfn; */ + /* call->what.bfn.name.ptr = bfn->name.ptr; call->what.bfn.name.len = bfn->name.len; + */ + call->what.bfn.name.ptr = name; + call->what.bfn.name.len = name_len; + call->what.bfn.arg.min = bfn->arg.min; call->what.bfn.arg.max = bfn->arg.max; call->what.bfn.arg.spec = bfn->arg.spec; diff --git a/ase/awk/tab.c b/ase/awk/tab.c index b24f197b..b5bf2b19 100644 --- a/ase/awk/tab.c +++ b/ase/awk/tab.c @@ -1,5 +1,5 @@ /* - * $Id: tab.c,v 1.4 2007/09/23 16:48:55 bacon Exp $ + * $Id: tab.c,v 1.5 2007/11/06 09:47:12 bacon Exp $ * * {License} */ @@ -237,3 +237,70 @@ ase_size_t ase_awk_tab_rrfind ( return (ase_size_t)-1; } + +ase_size_t ase_awk_tab_findx ( + ase_awk_tab_t* tab, ase_size_t index, + const ase_char_t* str, ase_size_t len, + void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg) +{ + ase_size_t i; + + for (i = index; i < tab->size; i++) + { + ase_cstr_t x; + + x.ptr = tab->buf[i].name.ptr; + x.len = tab->buf[i].name.len; + + transform (i, &x, arg); + if (ase_strxncmp (x.ptr, x.len, str, len) == 0) return i; + } + + return (ase_size_t)-1; +} + +ase_size_t ase_awk_tab_rfindx ( + ase_awk_tab_t* tab, ase_size_t index, + const ase_char_t* str, ase_size_t len, + void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg) +{ + ase_size_t i; + + if (index >= tab->size) return (ase_size_t)-1; + + for (i = index + 1; i-- > 0; ) + { + ase_cstr_t x; + + x.ptr = tab->buf[i].name.ptr; + x.len = tab->buf[i].name.len; + + transform (i, &x, arg); + if (ase_strxncmp (x.ptr, x.len, str, len) == 0) return i; + } + + return (ase_size_t)-1; +} + +ase_size_t ase_awk_tab_rrfindx ( + ase_awk_tab_t* tab, ase_size_t index, + const ase_char_t* str, ase_size_t len, + void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg) +{ + ase_size_t i; + + if (index >= tab->size) return (ase_size_t)-1; + + for (i = tab->size - index; i-- > 0; ) + { + ase_cstr_t x; + + x.ptr = tab->buf[i].name.ptr; + x.len = tab->buf[i].name.len; + + transform (i, &x, arg); + if (ase_strxncmp (x.ptr, x.len, str, len) == 0) return i; + } + + return (ase_size_t)-1; +} diff --git a/ase/awk/tab.h b/ase/awk/tab.h index bf4cbe92..a2a071fa 100644 --- a/ase/awk/tab.h +++ b/ase/awk/tab.h @@ -1,5 +1,5 @@ /* - * $Id: tab.h,v 1.4 2007/09/23 16:48:55 bacon Exp $ + * $Id: tab.h,v 1.5 2007/11/06 09:47:12 bacon Exp $ * * {License} */ @@ -65,6 +65,19 @@ ase_size_t ase_awk_tab_rrfind ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len); +ase_size_t ase_awk_tab_findx ( + ase_awk_tab_t* tab, ase_size_t index, + const ase_char_t* str, ase_size_t len, + void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg); +ase_size_t ase_awk_tab_rfindx ( + ase_awk_tab_t* tab, ase_size_t index, + const ase_char_t* str, ase_size_t len, + void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg); +ase_size_t ase_awk_tab_rrfindx ( + ase_awk_tab_t* tab, ase_size_t index, + const ase_char_t* str, ase_size_t len, + void(*transform)(ase_size_t, ase_cstr_t*,void*), void* arg); + #ifdef __cplusplus } #endif diff --git a/ase/awk/tree.c b/ase/awk/tree.c index 01880acf..7ff0b2e2 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.5 2007/09/25 15:27:54 bacon Exp $ + * $Id: tree.c,v 1.6 2007/11/06 09:47:12 bacon Exp $ * * {License} */ @@ -1155,6 +1155,7 @@ void ase_awk_clrpt (ase_awk_t* awk, ase_awk_nde_t* tree) { ase_awk_nde_call_t* px = (ase_awk_nde_call_t*)p; /* ASE_AWK_FREE (awk, px->what.bfn); */ + ASE_AWK_FREE (awk, px->what.bfn.name.ptr); ase_awk_clrpt (awk, px->args); ASE_AWK_FREE (awk, p); break; diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 362e6dc7..2acbbbac 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.5 2007/09/25 15:27:54 bacon Exp $ + * $Id: tree.h,v 1.6 2007/11/06 09:47:12 bacon Exp $ * * {License} */ @@ -271,7 +271,7 @@ struct ase_awk_nde_call_t { struct { - const ase_char_t* ptr; + ase_char_t* ptr; ase_size_t len; } name; diff --git a/ase/test/awk/AseAwkPanel.java b/ase/test/awk/AseAwkPanel.java index 0ef9cb7c..0d2975c6 100644 --- a/ase/test/awk/AseAwkPanel.java +++ b/ase/test/awk/AseAwkPanel.java @@ -1,5 +1,5 @@ /* - * $Id: AseAwkPanel.java,v 1.23 2007/11/05 14:59:23 bacon Exp $ + * $Id: AseAwkPanel.java,v 1.24 2007/11/06 09:47:12 bacon Exp $ */ import java.awt.*; @@ -107,6 +107,7 @@ public class AseAwkPanel extends Panel implements DropTargetListener setWord ("sin", "cain"); setWord ("length", "len"); setWord ("OFMT", "ofmt"); + setWord ("END", "end"); } public void sleep (Context ctx, String name, Return ret, Argument[] args) throws ase.awk.Exception diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 57baee25..8c2c318e 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.21 2007/10/28 06:12:37 bacon Exp $ + * $Id: awk.c,v 1.22 2007/11/06 09:47:12 bacon Exp $ */ #include @@ -262,8 +262,16 @@ static ase_ssize_t awk_srcio_out ( } else if (cmd == ASE_AWK_IO_WRITE) { - int n = ase_fprintf (stdout, ASE_T("%.*s"), size, data); - if (n < 0) return -1; + while (size > 0) + { + int n, chunk; + + chunk = (size > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): size; + n = ase_fprintf (stdout, ASE_T("%.*s"), (int)chunk, data); + if (n < 0) return -1; + + data += n; size -= n; + } return size; } @@ -340,21 +348,23 @@ static ase_ssize_t awk_extio_pipe ( * pointer opened by popen, as of this writing. * anyway, hopefully the following replacement * will work all the way. */ - int n = fprintf (fp, "%.*ls", left, data); + int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): left; + int n = fprintf (fp, "%.*ls", chunk, data); if (n >= 0) { size_t x; - for (x = 0; x < left; x++) + for (x = 0; x < chunk; x++) { if (data[x] == ASE_T('\0')) break; } n = x; } #else - int n = ase_fprintf (fp, ASE_T("%.*s"), left, data); + int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): left; + int n = ase_fprintf (fp, ASE_T("%.*s"), chunk, data); #endif - if (n < 0 || n > left) return -1; + if (n < 0 || n > chunk) return -1; left -= n; data += n; } } @@ -447,7 +457,8 @@ static ase_ssize_t awk_extio_file ( } else { - int n = ase_fprintf (fp, ASE_T("%.*s"), left, data); + int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): left; + int n = ase_fprintf (fp, ASE_T("%.*s"), chunk, data); if (n < 0) return -1; left -= n; data += n; } @@ -522,7 +533,7 @@ static ase_ssize_t awk_extio_console ( { ase_cstr_t errarg; - errarg.ptr = ASE_T("consolXXXe"); + errarg.ptr = ASE_T("console"); errarg.len = 7; ase_awk_setrunerror (epa->run, ASE_AWK_ECLOSE, 0, &errarg, 1); @@ -593,10 +604,32 @@ static ase_ssize_t awk_extio_console ( } else if (cmd == ASE_AWK_IO_WRITE) { + /* int n = ase_fprintf ( (FILE*)epa->handle, ASE_T("%.*s"), size, data); if (n < 0) return -1; + return size; + */ + FILE* fp = (FILE*)epa->handle; + ase_ssize_t left = size; + + while (left > 0) + { + if (*data == ASE_T('\0')) + { + if (ase_fputc (*data, fp) == ASE_CHAR_EOF) return -1; + left -= 1; data += 1; + } + else + { + int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): left; + int n = ase_fprintf (fp, ASE_T("%.*s"), chunk, data); + if (n < 0) return -1; + left -= n; data += n; + } + } + return size; } else if (cmd == ASE_AWK_IO_FLUSH)