diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 5d81c76a..fcd002bb 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.102 2006-08-27 10:45:36 bacon Exp $ + * $Id: awk.h,v 1.103 2006-08-29 15:01:44 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -170,6 +170,7 @@ enum XP_AWK_ELXUNG, /* lexer failed to unget a character */ XP_AWK_EENDSRC, /* unexpected end of source */ + XP_AWK_EENDCOMMENT, /* unexpected end of a comment */ XP_AWK_EENDSTR, /* unexpected end of a string */ XP_AWK_EENDREX, /* unexpected end of a regular expression */ XP_AWK_ELBRACE, /* left brace expected */ diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index 483dad8c..5204f84d 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -1,5 +1,5 @@ /* - * $Id: awk_i.h,v 1.46 2006-08-21 02:53:42 bacon Exp $ + * $Id: awk_i.h,v 1.47 2006-08-29 15:01:44 bacon Exp $ */ #ifndef _XP_AWK_AWKI_H_ @@ -189,6 +189,7 @@ struct xp_awk_run_t { xp_awk_io_t handler[XP_AWK_EXTIO_NUM]; xp_awk_extio_t* chain; + void* rs_rex; } extio; int errnum; diff --git a/ase/awk/err.c b/ase/awk/err.c index 9ad93351..6a0a6f89 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.38 2006-08-23 15:41:46 bacon Exp $ + * $Id: err.c,v 1.39 2006-08-29 15:01:44 bacon Exp $ */ #include @@ -43,6 +43,7 @@ const xp_char_t* xp_awk_geterrstr (int errnum) XP_T("cannot unget character"), XP_T("unexpected end of source"), + XP_T("unexpected end of a comment"), XP_T("unexpected end of a string"), XP_T("unexpected end of a regular expression"), XP_T("left brace expected"), diff --git a/ase/awk/extio.c b/ase/awk/extio.c index 04f44b6f..9142be16 100644 --- a/ase/awk/extio.c +++ b/ase/awk/extio.c @@ -1,5 +1,5 @@ /* - * $Id: extio.c,v 1.36 2006-08-27 15:29:20 bacon Exp $ + * $Id: extio.c,v 1.37 2006-08-29 15:01:44 bacon Exp $ */ #include @@ -285,16 +285,15 @@ int xp_awk_readextio ( } else { -#if 0 xp_char_t* match_ptr; xp_size_t match_len; - /* TODO: */ - /* regular expression */ - /* TODO: safematchrex ?? */ - n = xp_awk_matchrex (rs_rex, + xp_assert (run->extio.rs_rex != NULL); + + /* TODO: safematchrex */ + n = xp_awk_matchrex (run->extio.rs_rex, XP_STR_BUF(buf), XP_STR_LEN(buf), - &match_ptr, &match_len, errnum); + &match_ptr, &match_len, &run->errnum); if (n == -1) { ret = -1; @@ -303,10 +302,15 @@ int xp_awk_readextio ( if (n == 1) { - /* matched... */ - /* DO SOMTHING */ + /* the match should be found at the end of + * the current buffer */ + xp_assert ( + XP_STR_BUF(buf) + XP_STR_LEN(buf) == + match_ptr + match_len); + + XP_STR_LEN(buf) -= match_len; + break; } -#endif } if (xp_str_ccat (buf, c) == (xp_size_t)-1) diff --git a/ase/awk/parse.c b/ase/awk/parse.c index cc573f8b..84a5322f 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.168 2006-08-23 15:46:29 bacon Exp $ + * $Id: parse.c,v 1.169 2006-08-29 15:01:44 bacon Exp $ */ #include @@ -3970,9 +3970,21 @@ static int __skip_comment (xp_awk_t* awk) do { GET_CHAR_TO (awk, c); + if (c == XP_CHAR_EOF) + { + awk->errnum = XP_AWK_EENDCOMMENT; + return -1; + } + if (c == XP_T('*')) { GET_CHAR_TO (awk, c); + if (c == XP_CHAR_EOF) + { + awk->errnum = XP_AWK_EENDCOMMENT; + return -1; + } + if (c == XP_T('/')) { GET_CHAR_TO (awk, c); diff --git a/ase/awk/run.c b/ase/awk/run.c index e001afb1..b1705d87 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.181 2006-08-27 15:29:21 bacon Exp $ + * $Id: run.c,v 1.182 2006-08-29 15:01:45 bacon Exp $ */ #include @@ -216,12 +216,14 @@ 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) { - xp_awk_val_t* old = STACK_GLOBAL((xp_awk_run_t*)run,idx); + xp_awk_run_t* r = (xp_awk_run_t*)run; + + xp_awk_val_t* old = STACK_GLOBAL(r,idx); if (old->type == XP_AWK_VAL_MAP) { /* once a variable becomes an array, * it cannot be changed to a scalar variable */ - PANIC_I ((xp_awk_run_t*)run, XP_AWK_EMAPTOSCALAR); + PANIC_I (r, XP_AWK_EMAPTOSCALAR); } /* TODO: is this correct?? */ @@ -230,12 +232,50 @@ 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 ((xp_awk_run_t*)run, XP_AWK_ESCALARTOMAP); + PANIC_I (r, XP_AWK_ESCALARTOMAP); } if (idx == XP_AWK_GLOBAL_RS) { -/* TODO: if idx == XP_AWK_GLOBAL_RS and it is multi-char sttring, compile it */ + xp_char_t* rs_ptr; + xp_size_t rs_len; + + if (val->type == XP_AWK_VAL_STR) + { + rs_ptr = ((xp_awk_val_str_t*)val)->buf; + rs_len = ((xp_awk_val_str_t*)val)->len; + } + else + { + /* due to the expression evaluation rule, the + * regular expression can not be an assigned value */ + xp_assert (val->type != XP_AWK_VAL_REX); + + rs_ptr = xp_awk_valtostr ( + val, &r->errnum, xp_true, XP_NULL, &rs_len); + if (rs_ptr == XP_NULL) return -1; + } + + if (rs_len > 1) + { + void* rex; + + /* compile the regular expression */ + /* TODO: use safebuild */ + rex = xp_awk_buildrex (rs_ptr, rs_len, &r->errnum); + if (rex == XP_NULL) + { + if (val->type != XP_AWK_VAL_STR) + xp_free (rs_ptr); + return -1; + } + + if (r->extio.rs_rex != XP_NULL) + xp_awk_freerex (r->extio.rs_rex); + r->extio.rs_rex = rex; + } + + if (val->type != XP_AWK_VAL_STR) xp_free (rs_ptr); } /* TODO: if idx == XP_AWK_GLOBAL_NF recompute $0, etc */ @@ -494,6 +534,7 @@ static int __init_run ( run->extio.handler[XP_AWK_EXTIO_FILE] = runios->file; run->extio.handler[XP_AWK_EXTIO_CONSOLE] = runios->console; run->extio.chain = XP_NULL; + run->extio.rs_rex = XP_NULL; return 0; } @@ -506,6 +547,11 @@ static void __deinit_run (xp_awk_run_t* run) /* TODO: what if this operation fails? */ xp_awk_clearextio (run); xp_assert (run->extio.chain == XP_NULL); + if (run->extio.rs_rex != XP_NULL) + { + xp_free (run->extio.rs_rex); + run->extio.rs_rex = XP_NULL; + } /* destroy input record. __clear_record should be called * before the run stack has been destroyed because it may try diff --git a/ase/test/awk/t32.awk b/ase/test/awk/t32.awk index f28a030a..973dd41e 100644 --- a/ase/test/awk/t32.awk +++ b/ase/test/awk/t32.awk @@ -1,2 +1,2 @@ -BEGIN { RS = ""; } +BEGIN { /*RS = "Asia";*/ /*RS=746;*/ RS=/USA/; } { print "RECORD: ", $0; } diff --git a/ase/test/awk/t34.awk b/ase/test/awk/t34.awk new file mode 100644 index 00000000..7e5e5b5c --- /dev/null +++ b/ase/test/awk/t34.awk @@ -0,0 +1 @@ +/* unterminated comment