From b33e58307155a0050b332e82e7e210dada98dbe8 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 26 Jul 2006 16:43:35 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.h | 7 +++++-- ase/awk/awk_i.h | 8 +++++--- ase/awk/err.c | 27 +++++++++++++++++++++++++-- ase/awk/parse.c | 14 ++++++++++---- ase/awk/rex.c | 28 ++++++++++++++++++---------- ase/awk/rex.h | 22 ++++++++-------------- ase/awk/run.c | 21 +++++++++------------ ase/awk/val.c | 6 +++--- ase/test/awk/awk.c | 15 ++++++++++++--- ase/test/awk/t17.awk | 2 +- 10 files changed, 96 insertions(+), 54 deletions(-) diff --git a/ase/awk/awk.h b/ase/awk/awk.h index e7fde3d7..0e1fa07c 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.80 2006-07-25 16:41:40 bacon Exp $ + * $Id: awk.h,v 1.81 2006-07-26 16:43:35 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -127,7 +127,8 @@ enum XP_AWK_ETOOFEWARGS, /* too few arguments */ XP_AWK_ETOOMANYARGS, /* too many arguments */ XP_AWK_EGETLINE, /* getline expected */ - XP_AWK_EREXCMPL, /* cannot compile the regular expressio n*/ + XP_AWK_EREXBUILD, /* cannot build regexp */ + XP_AWK_EREXMATCH, /* an error occurred in matching regexp */ /* run time error */ XP_AWK_EDIVBYZERO, /* divide by zero */ @@ -166,6 +167,8 @@ int xp_awk_close (xp_awk_t* awk); int xp_awk_geterrnum (xp_awk_t* awk); const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk); +int xp_awk_getsuberrnum (xp_awk_t* awk); +const xp_char_t* xp_awk_getsuberrstr (xp_awk_t* awk); void xp_awk_clear (xp_awk_t* awk); void xp_awk_setparseopt (xp_awk_t* awk, int opt); diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index 62686c79..338ee7ee 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -1,5 +1,5 @@ /* - * $Id: awk_i.h,v 1.33 2006-07-26 05:19:45 bacon Exp $ + * $Id: awk_i.h,v 1.34 2006-07-26 16:43:35 bacon Exp $ */ #ifndef _XP_AWK_AWKI_H_ @@ -138,7 +138,8 @@ struct xp_awk_t } bfn; /* housekeeping */ - int errnum; + short errnum; + short suberrnum; }; struct xp_awk_chain_t @@ -190,7 +191,8 @@ struct xp_awk_run_t xp_awk_extio_t* extio; int opt; - int errnum; + short errnum; + short suberrnum; /*xp_awk_tree_t* tree; xp_size_t nglobals;*/ diff --git a/ase/awk/err.c b/ase/awk/err.c index f6c7c353..bc361271 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.27 2006-07-25 16:41:40 bacon Exp $ + * $Id: err.c,v 1.28 2006-07-26 16:43:35 bacon Exp $ */ #include @@ -9,6 +9,17 @@ int xp_awk_geterrnum (xp_awk_t* awk) return awk->errnum; } +int xp_awk_getsuberrnum (xp_awk_t* awk) +{ + if (awk->errnum == XP_AWK_EREXBUILD || + awk->errnum == XP_AWK_EREXMATCH) + { + return awk->suberrnum; + } + + return XP_AWK_ENOERR; +} + const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) { static const xp_char_t* __errstr[] = @@ -59,7 +70,8 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) XP_T("too few arguments"), XP_T("too many arguments"), XP_T("getline expected"), - XP_T("cannot compile the regular expression"), + XP_T("cannot build the regular expression"), + XP_T("an error occurred in the regular expression match"), XP_T("divide by zero"), XP_T("invalid operand"), @@ -83,3 +95,14 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) return XP_T("unknown error"); } + +const xp_char_t* xp_awk_getsuberrstr (xp_awk_t* awk) +{ + if (awk->errnum == XP_AWK_EREXBUILD || + awk->errnum == XP_AWK_EREXMATCH) + { + return xp_awk_getrexerrstr (awk->suberrnum); + } + + return XP_T("no error"); +} diff --git a/ase/awk/parse.c b/ase/awk/parse.c index a53d7b1e..03cdae41 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.141 2006-07-26 14:59:59 bacon Exp $ + * $Id: parse.c,v 1.142 2006-07-26 16:43:35 bacon Exp $ */ #include @@ -294,6 +294,9 @@ static struct __bvent __bvtab[] = #define PANIC(awk,code) \ do { (awk)->errnum = (code); return XP_NULL; } while (0) +#define PANIC2(awk,code,subcode) \ + do { (awk)->errnum = (code); (awk)->suberrnum = (subcode); return XP_NULL; } while (0) + /* TODO: remove stdio.h */ #ifndef XP_AWK_STAND_ALONE #include @@ -1902,6 +1905,7 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) else if (MATCH(awk,TOKEN_DIV)) { xp_awk_nde_rex_t* nde; + int errnum; /* the regular expression is tokenized here because * of the context-sensitivity of the slash symbol */ @@ -1928,17 +1932,19 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) nde->code = xp_awk_buildrex ( XP_STR_BUF(&awk->token.name), - XP_STR_LEN(&awk->token.name)); + XP_STR_LEN(&awk->token.name), + &errnum); if (nde->code == XP_NULL) { - /* TODO: get the proper errnum */ xp_free (nde->buf); xp_free (nde); - PANIC (awk, XP_AWK_ENOMEM); + PANIC2 (awk, XP_AWK_EREXBUILD, errnum); } if (__get_token(awk) == -1) { + xp_free (nde->buf); + xp_free (nde->code); xp_free (nde); return XP_NULL; } diff --git a/ase/awk/rex.c b/ase/awk/rex.c index eb9fde64..e51e0def 100644 --- a/ase/awk/rex.c +++ b/ase/awk/rex.c @@ -1,5 +1,5 @@ /* - * $Id: rex.c,v 1.16 2006-07-26 15:00:00 bacon Exp $ + * $Id: rex.c,v 1.17 2006-07-26 16:43:35 bacon Exp $ */ #include @@ -225,7 +225,6 @@ const xp_char_t* xp_awk_getrexerrstr (int errnum) { XP_T("no error"), XP_T("out of memory"), - XP_T("no pattern built"), XP_T("a right parenthesis is expected"), XP_T("a right bracket is expected"), XP_T("a right brace is expected"), @@ -233,8 +232,8 @@ const xp_char_t* xp_awk_getrexerrstr (int errnum) XP_T("invalid character range"), XP_T("invalid character class"), XP_T("invalid boundary range"), - XP_T("unexpected end of the pattern"), - XP_T("garbage after the pattern") + XP_T("unexpected end of the regular expression"), + XP_T("garbage after the regular expression") }; if (errnum >= 0 && errnum < xp_countof(__errstr)) @@ -245,14 +244,18 @@ const xp_char_t* xp_awk_getrexerrstr (int errnum) return XP_T("unknown error"); } -void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len) +void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len, int* errnum) { __builder_t builder; builder.code.capa = 512; builder.code.size = 0; builder.code.buf = (xp_byte_t*) xp_malloc (builder.code.capa); - if (builder.code.buf == XP_NULL) return XP_NULL; + if (builder.code.buf == XP_NULL) + { + *errnum = XP_AWK_REX_ENOMEM; + return XP_NULL; + } builder.ptn.ptr = ptn; builder.ptn.end = builder.ptn.ptr + len; @@ -264,19 +267,21 @@ void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len) //NEXT_CHAR (&builder, LEVEL_TOP); if (__next_char (&builder, LEVEL_TOP) == -1) { + if (errnum != XP_NULL) *errnum = builder.errnum; xp_free (builder.code.buf); return XP_NULL; } if (__build_pattern (&builder) == -1) { + if (errnum != XP_NULL) *errnum = builder.errnum; xp_free (builder.code.buf); return XP_NULL; } if (builder.ptn.curc.type != CT_EOF) { - /* garbage after the pattern */ + if (errnum != XP_NULL) *errnum = XP_AWK_REX_EGARBAGE; xp_free (builder.code.buf); return XP_NULL; } @@ -286,7 +291,7 @@ void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len) int xp_awk_matchrex (void* code, const xp_char_t* str, xp_size_t len, - const xp_char_t** match_ptr, xp_size_t* match_len) + const xp_char_t** match_ptr, xp_size_t* match_len, int* errnum) { __matcher_t matcher; __match_t mat; @@ -303,8 +308,11 @@ int xp_awk_matchrex (void* code, while (mat.match_ptr < matcher.match.str.end) { - if (__match_pattern ( - &matcher, code, &mat) == XP_NULL) return -1; + if (__match_pattern (&matcher, code, &mat) == XP_NULL) + { + if (errnum != XP_NULL) *errnum = matcher.errnum; + return -1; + } if (mat.matched) { diff --git a/ase/awk/rex.h b/ase/awk/rex.h index b8576ae9..6d75bcf7 100644 --- a/ase/awk/rex.h +++ b/ase/awk/rex.h @@ -1,15 +1,10 @@ /* - * $Id: rex.h,v 1.9 2006-07-26 05:19:45 bacon Exp $ + * $Id: rex.h,v 1.10 2006-07-26 16:43:35 bacon Exp $ **/ #ifndef _XP_AWK_REX_H_ #define _XP_AWK_REX_H_ -/* -#ifndef _XP_AWK_AWK_H_ -#error Never include this file directly. Include instead -#endif -*/ #include #include @@ -27,9 +22,9 @@ * | nb | el | na | bl | cmd | arg | cmd | arg | na | bl | cmd | arg | na | bl | cmd | * * nb: the number of branches - * el: the length of a expression excluding the length of nb and el + * el: the length of a expression including the length of nb and el * na: the number of atoms - * bl: the length of a branch excluding the length of bl + * bl: the length of a branch including the length of na and bl * cmd: The command and repetition info encoded together. * Some commands require an argument to follow them but some other don't. * It is encoded as follows: @@ -46,7 +41,6 @@ enum { XP_AWK_REX_ENOERR, /* no error */ XP_AWK_REX_ENOMEM, /* ran out of memory */ - XP_AWK_REX_ENOPTN, /* no pattern compiled */ XP_AWK_REX_ERPAREN, /* a right parenthesis is expected */ XP_AWK_REX_ERBRACKET, /* a right bracket is expected */ XP_AWK_REX_ERBRACE, /* a right brace is expected */ @@ -58,22 +52,22 @@ enum XP_AWK_REX_EGARBAGE /* garbage after the pattern */ }; -#define XP_AWK_REXNA(code) (*(xp_size_t*)(code)) +#define XP_AWK_REX_NA(code) (*(xp_size_t*)(code)) -#define XP_AWK_REXLEN(code) \ +#define XP_AWK_REX_LEN(code) \ (*(xp_size_t*)((xp_byte_t*)(code)+xp_sizeof(xp_size_t))) #ifdef __cplusplus extern "C" { #endif -const xp_char_t* xp_awk_rex_geterrstr (int errnum); +const xp_char_t* xp_awk_getrexerrstr (int errnum); -void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len); +void* xp_awk_buildrex (const xp_char_t* ptn, xp_size_t len, int* errnum); int xp_awk_matchrex (void* code, const xp_char_t* str, xp_size_t len, - const xp_char_t** match_ptr, xp_size_t* match_len); + const xp_char_t** match_ptr, xp_size_t* match_len, int* errnum); void xp_awk_printrex (void* code); diff --git a/ase/awk/run.c b/ase/awk/run.c index b2e34773..7a52edf3 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.139 2006-07-26 15:00:00 bacon Exp $ + * $Id: run.c,v 1.140 2006-07-26 16:43:35 bacon Exp $ */ #include @@ -39,8 +39,13 @@ enum #define PANIC(run,code) \ do { (run)->errnum = (code); return XP_NULL; } while (0) +#define PANIC2(awk,code,subcode) \ + do { (awk)->errnum = (code); (awk)->suberrnum = (subcode); return XP_NULL; } while (0) + #define PANIC_I(run,code) \ do { (run)->errnum = (code); return -1; } while (0) +#define PANIC2_I(awk,code,subcode) \ + do { (awk)->errnum = (code); (awk)->suberrnum = (subcode); return -1; } while (0) static int __open_run ( xp_awk_run_t* run, xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg); @@ -634,33 +639,25 @@ static int __run_pattern_block_chain (xp_awk_run_t* run, xp_awk_chain_t* chain) static int __handle_pattern (xp_awk_run_t* run, xp_awk_val_t* val) { - int n; + int n, errnum; if (val->type == XP_AWK_VAL_REX) { xp_assert (run->inrec.d0->type == XP_AWK_VAL_STR); -/* TODO: do it properly match value...*/ - //xp_awk_rex_setpattern (v->buf, v->len); - n = xp_awk_matchrex ( ((xp_awk_val_rex_t*)val)->code, ((xp_awk_val_str_t*)run->inrec.d0)->buf, ((xp_awk_val_str_t*)run->inrec.d0)->len, - XP_NULL, XP_NULL); + XP_NULL, XP_NULL, &errnum); - if (n == -1) - { -// TODO: convert rex_matcher->errnum to run->errnum. - PANIC_I (run, XP_AWK_ENOMEM); - }; + if (n == -1) PANIC2_I (run, XP_AWK_EREXMATCH, errnum); } else n = xp_awk_valtobool(val)? 1: 0; return n; } - static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde) { xp_awk_nde_t* p; diff --git a/ase/awk/val.c b/ase/awk/val.c index ef697dc1..22594d70 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.47 2006-07-26 15:00:00 bacon Exp $ + * $Id: val.c,v 1.48 2006-07-26 16:43:35 bacon Exp $ */ #include @@ -153,7 +153,7 @@ xp_awk_val_t* xp_awk_makerexval ( return XP_NULL; } - val->code = xp_malloc (XP_AWK_REXLEN(code)); + val->code = xp_malloc (XP_AWK_REX_LEN(code)); if (val->code == XP_NULL) { xp_free (val->buf); @@ -161,7 +161,7 @@ xp_awk_val_t* xp_awk_makerexval ( return XP_NULL; } - xp_memcpy (val->code, code, XP_AWK_REXLEN(code)); + xp_memcpy (val->code, code, XP_AWK_REX_LEN(code)); return (xp_awk_val_t*)val; } diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index ed1c56cd..c958eb97 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.52 2006-07-06 13:57:31 bacon Exp $ + * $Id: awk.c,v 1.53 2006-07-26 16:43:35 bacon Exp $ */ #include @@ -504,15 +504,24 @@ static int __main (int argc, xp_char_t* argv[]) { #if defined(__STAND_ALONE) && !defined(_WIN32) && defined(XP_CHAR_IS_WCHAR) xp_printf ( - XP_T("error: cannot parse program - line %u [%d] %ls\n"), + XP_T("ERROR: cannot parse program - line %u [%d] %ls"), (unsigned int)xp_awk_getsrcline(awk), xp_awk_geterrnum(awk), xp_awk_geterrstr(awk)); + if (xp_awk_getsuberrnum(awk) != XP_AWK_ENOERR) + { + xp_printf (XP_T(" - %ls\n"), xp_awk_getsuberrstr(awk)); + } #else xp_printf ( - XP_T("error: cannot parse program - line %u [%d] %s\n"), + XP_T("ERROR: cannot parse program - line %u [%d] %s"), (unsigned int)xp_awk_getsrcline(awk), xp_awk_geterrnum(awk), xp_awk_geterrstr(awk)); + if (xp_awk_getsuberrnum(awk) != XP_AWK_ENOERR) + { + xp_printf (XP_T(" - %s\n"), xp_awk_getsuberrstr(awk)); + } #endif + xp_printf (XP_T("\n")); xp_awk_close (awk); return -1; } diff --git a/ase/test/awk/t17.awk b/ase/test/awk/t17.awk index a69679d3..4acfb3de 100644 --- a/ase/test/awk/t17.awk +++ b/ase/test/awk/t17.awk @@ -1 +1 @@ -/hello/ { print $0; } +/hello[[:space:]]/ { print $0; }