*** empty log message ***

This commit is contained in:
hyung-hwan 2006-07-26 16:43:35 +00:00
parent fceb523c6f
commit b33e583071
10 changed files with 96 additions and 54 deletions

View File

@ -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_ #ifndef _XP_AWK_AWK_H_
@ -127,7 +127,8 @@ enum
XP_AWK_ETOOFEWARGS, /* too few arguments */ XP_AWK_ETOOFEWARGS, /* too few arguments */
XP_AWK_ETOOMANYARGS, /* too many arguments */ XP_AWK_ETOOMANYARGS, /* too many arguments */
XP_AWK_EGETLINE, /* getline expected */ 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 */ /* run time error */
XP_AWK_EDIVBYZERO, /* divide by zero */ 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); int xp_awk_geterrnum (xp_awk_t* awk);
const xp_char_t* xp_awk_geterrstr (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_clear (xp_awk_t* awk);
void xp_awk_setparseopt (xp_awk_t* awk, int opt); void xp_awk_setparseopt (xp_awk_t* awk, int opt);

View File

@ -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_ #ifndef _XP_AWK_AWKI_H_
@ -138,7 +138,8 @@ struct xp_awk_t
} bfn; } bfn;
/* housekeeping */ /* housekeeping */
int errnum; short errnum;
short suberrnum;
}; };
struct xp_awk_chain_t struct xp_awk_chain_t
@ -190,7 +191,8 @@ struct xp_awk_run_t
xp_awk_extio_t* extio; xp_awk_extio_t* extio;
int opt; int opt;
int errnum; short errnum;
short suberrnum;
/*xp_awk_tree_t* tree; /*xp_awk_tree_t* tree;
xp_size_t nglobals;*/ xp_size_t nglobals;*/

View File

@ -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 <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -9,6 +9,17 @@ int xp_awk_geterrnum (xp_awk_t* awk)
return awk->errnum; 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) const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
{ {
static const xp_char_t* __errstr[] = 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 few arguments"),
XP_T("too many arguments"), XP_T("too many arguments"),
XP_T("getline expected"), 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("divide by zero"),
XP_T("invalid operand"), XP_T("invalid operand"),
@ -83,3 +95,14 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
return XP_T("unknown error"); 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");
}

View File

@ -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 <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -294,6 +294,9 @@ static struct __bvent __bvtab[] =
#define PANIC(awk,code) \ #define PANIC(awk,code) \
do { (awk)->errnum = (code); return XP_NULL; } while (0) 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 */ /* TODO: remove stdio.h */
#ifndef XP_AWK_STAND_ALONE #ifndef XP_AWK_STAND_ALONE
#include <xp/bas/stdio.h> #include <xp/bas/stdio.h>
@ -1902,6 +1905,7 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk)
else if (MATCH(awk,TOKEN_DIV)) else if (MATCH(awk,TOKEN_DIV))
{ {
xp_awk_nde_rex_t* nde; xp_awk_nde_rex_t* nde;
int errnum;
/* the regular expression is tokenized here because /* the regular expression is tokenized here because
* of the context-sensitivity of the slash symbol */ * 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 ( nde->code = xp_awk_buildrex (
XP_STR_BUF(&awk->token.name), XP_STR_BUF(&awk->token.name),
XP_STR_LEN(&awk->token.name)); XP_STR_LEN(&awk->token.name),
&errnum);
if (nde->code == XP_NULL) if (nde->code == XP_NULL)
{ {
/* TODO: get the proper errnum */
xp_free (nde->buf); xp_free (nde->buf);
xp_free (nde); xp_free (nde);
PANIC (awk, XP_AWK_ENOMEM); PANIC2 (awk, XP_AWK_EREXBUILD, errnum);
} }
if (__get_token(awk) == -1) if (__get_token(awk) == -1)
{ {
xp_free (nde->buf);
xp_free (nde->code);
xp_free (nde); xp_free (nde);
return XP_NULL; return XP_NULL;
} }

View File

@ -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 <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -225,7 +225,6 @@ const xp_char_t* xp_awk_getrexerrstr (int errnum)
{ {
XP_T("no error"), XP_T("no error"),
XP_T("out of memory"), XP_T("out of memory"),
XP_T("no pattern built"),
XP_T("a right parenthesis is expected"), XP_T("a right parenthesis is expected"),
XP_T("a right bracket is expected"), XP_T("a right bracket is expected"),
XP_T("a right brace 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 range"),
XP_T("invalid character class"), XP_T("invalid character class"),
XP_T("invalid boundary range"), XP_T("invalid boundary range"),
XP_T("unexpected end of the pattern"), XP_T("unexpected end of the regular expression"),
XP_T("garbage after the pattern") XP_T("garbage after the regular expression")
}; };
if (errnum >= 0 && errnum < xp_countof(__errstr)) 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"); 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_t builder;
builder.code.capa = 512; builder.code.capa = 512;
builder.code.size = 0; builder.code.size = 0;
builder.code.buf = (xp_byte_t*) xp_malloc (builder.code.capa); 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.ptr = ptn;
builder.ptn.end = builder.ptn.ptr + len; 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); //NEXT_CHAR (&builder, LEVEL_TOP);
if (__next_char (&builder, LEVEL_TOP) == -1) if (__next_char (&builder, LEVEL_TOP) == -1)
{ {
if (errnum != XP_NULL) *errnum = builder.errnum;
xp_free (builder.code.buf); xp_free (builder.code.buf);
return XP_NULL; return XP_NULL;
} }
if (__build_pattern (&builder) == -1) if (__build_pattern (&builder) == -1)
{ {
if (errnum != XP_NULL) *errnum = builder.errnum;
xp_free (builder.code.buf); xp_free (builder.code.buf);
return XP_NULL; return XP_NULL;
} }
if (builder.ptn.curc.type != CT_EOF) 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); xp_free (builder.code.buf);
return XP_NULL; 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, int xp_awk_matchrex (void* code,
const xp_char_t* str, xp_size_t len, 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; __matcher_t matcher;
__match_t mat; __match_t mat;
@ -303,8 +308,11 @@ int xp_awk_matchrex (void* code,
while (mat.match_ptr < matcher.match.str.end) while (mat.match_ptr < matcher.match.str.end)
{ {
if (__match_pattern ( if (__match_pattern (&matcher, code, &mat) == XP_NULL)
&matcher, code, &mat) == XP_NULL) return -1; {
if (errnum != XP_NULL) *errnum = matcher.errnum;
return -1;
}
if (mat.matched) if (mat.matched)
{ {

View File

@ -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_ #ifndef _XP_AWK_REX_H_
#define _XP_AWK_REX_H_ #define _XP_AWK_REX_H_
/*
#ifndef _XP_AWK_AWK_H_
#error Never include this file directly. Include <xp/awk/awk.h> instead
#endif
*/
#include <xp/types.h> #include <xp/types.h>
#include <xp/macros.h> #include <xp/macros.h>
@ -27,9 +22,9 @@
* | nb | el | na | bl | cmd | arg | cmd | arg | na | bl | cmd | arg | na | bl | cmd | * | nb | el | na | bl | cmd | arg | cmd | arg | na | bl | cmd | arg | na | bl | cmd |
* *
* nb: the number of branches * 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 * 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. * cmd: The command and repetition info encoded together.
* Some commands require an argument to follow them but some other don't. * Some commands require an argument to follow them but some other don't.
* It is encoded as follows: * It is encoded as follows:
@ -46,7 +41,6 @@ enum
{ {
XP_AWK_REX_ENOERR, /* no error */ XP_AWK_REX_ENOERR, /* no error */
XP_AWK_REX_ENOMEM, /* ran out of memory */ 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_ERPAREN, /* a right parenthesis is expected */
XP_AWK_REX_ERBRACKET, /* a right bracket is expected */ XP_AWK_REX_ERBRACKET, /* a right bracket is expected */
XP_AWK_REX_ERBRACE, /* a right brace is expected */ XP_AWK_REX_ERBRACE, /* a right brace is expected */
@ -58,22 +52,22 @@ enum
XP_AWK_REX_EGARBAGE /* garbage after the pattern */ 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))) (*(xp_size_t*)((xp_byte_t*)(code)+xp_sizeof(xp_size_t)))
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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, int xp_awk_matchrex (void* code,
const xp_char_t* str, xp_size_t len, 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); void xp_awk_printrex (void* code);

View File

@ -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 <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -39,8 +39,13 @@ enum
#define PANIC(run,code) \ #define PANIC(run,code) \
do { (run)->errnum = (code); return XP_NULL; } while (0) 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) \ #define PANIC_I(run,code) \
do { (run)->errnum = (code); return -1; } while (0) 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 ( static int __open_run (
xp_awk_run_t* run, xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg); 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) 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) if (val->type == XP_AWK_VAL_REX)
{ {
xp_assert (run->inrec.d0->type == XP_AWK_VAL_STR); 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 ( n = xp_awk_matchrex (
((xp_awk_val_rex_t*)val)->code, ((xp_awk_val_rex_t*)val)->code,
((xp_awk_val_str_t*)run->inrec.d0)->buf, ((xp_awk_val_str_t*)run->inrec.d0)->buf,
((xp_awk_val_str_t*)run->inrec.d0)->len, ((xp_awk_val_str_t*)run->inrec.d0)->len,
XP_NULL, XP_NULL); XP_NULL, XP_NULL, &errnum);
if (n == -1) if (n == -1) PANIC2_I (run, XP_AWK_EREXMATCH, errnum);
{
// TODO: convert rex_matcher->errnum to run->errnum.
PANIC_I (run, XP_AWK_ENOMEM);
};
} }
else n = xp_awk_valtobool(val)? 1: 0; else n = xp_awk_valtobool(val)? 1: 0;
return n; return n;
} }
static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde) static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde)
{ {
xp_awk_nde_t* p; xp_awk_nde_t* p;

View File

@ -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 <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -153,7 +153,7 @@ xp_awk_val_t* xp_awk_makerexval (
return XP_NULL; 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) if (val->code == XP_NULL)
{ {
xp_free (val->buf); xp_free (val->buf);
@ -161,7 +161,7 @@ xp_awk_val_t* xp_awk_makerexval (
return XP_NULL; 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; return (xp_awk_val_t*)val;
} }

View File

@ -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 <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -504,15 +504,24 @@ static int __main (int argc, xp_char_t* argv[])
{ {
#if defined(__STAND_ALONE) && !defined(_WIN32) && defined(XP_CHAR_IS_WCHAR) #if defined(__STAND_ALONE) && !defined(_WIN32) && defined(XP_CHAR_IS_WCHAR)
xp_printf ( 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), (unsigned int)xp_awk_getsrcline(awk),
xp_awk_geterrnum(awk), xp_awk_geterrstr(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 #else
xp_printf ( 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), (unsigned int)xp_awk_getsrcline(awk),
xp_awk_geterrnum(awk), xp_awk_geterrstr(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 #endif
xp_printf (XP_T("\n"));
xp_awk_close (awk); xp_awk_close (awk);
return -1; return -1;
} }

View File

@ -1 +1 @@
/hello/ { print $0; } /hello[[:space:]]/ { print $0; }