*** empty log message ***

This commit is contained in:
hyung-hwan 2006-08-03 09:54:16 +00:00
parent 56305c8842
commit 85d22e41a7
12 changed files with 363 additions and 151 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c,v 1.63 2006-08-01 15:57:42 bacon Exp $
* $Id: awk.c,v 1.64 2006-08-03 09:53:41 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -77,8 +77,8 @@ xp_awk_t* xp_awk_open (void)
awk->token.prev = 0;
awk->token.type = 0;
awk->token.line = 1;
awk->token.column = 1;
awk->token.line = 0;
awk->token.column = 0;
awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0;
@ -153,6 +153,7 @@ void xp_awk_clear (xp_awk_t* awk)
xp_free (awk->tree.chain);
awk->tree.chain = next;
}
awk->tree.chain_tail = XP_NULL;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h,v 1.85 2006-08-01 15:57:42 bacon Exp $
* $Id: awk.h,v 1.86 2006-08-03 09:53:42 bacon Exp $
*/
#ifndef _XP_AWK_AWK_H_
@ -91,7 +91,10 @@ enum
XP_AWK_STRCONCAT = (1 << 7),
/* support getline and print */
XP_AWK_EXTIO = (1 << 8)
XP_AWK_EXTIO = (1 << 8),
/* support blockless patterns */
XP_AWK_BLOCKLESS = (1 << 9),
};
/* run options */
@ -113,10 +116,15 @@ enum
XP_AWK_ESRCINNEXT,
XP_AWK_ESRCINDATA, /* error in reading source */
XP_AWK_ETXTINOPEN,
XP_AWK_ETXTINCLOSE,
XP_AWK_ETXTINNEXT,
XP_AWK_ETXTINDATA, /* error in reading text */
XP_AWK_ECONINOPEN,
XP_AWK_ECONINCLOSE,
XP_AWK_ECONINNEXT,
XP_AWK_ECONINDATA,
XP_AWK_ECONOUTOPEN,
XP_AWK_ECONOUTCLOSE,
XP_AWK_ECONOUTNEXT,
XP_AWK_ECONOUTDATA,
XP_AWK_ELXCHR, /* lexer came accross an wrong character */
XP_AWK_ELXUNG, /* lexer failed to unget a character */

View File

@ -1,5 +1,5 @@
/*
* $Id: err.c,v 1.29 2006-08-01 15:57:42 bacon Exp $
* $Id: err.c,v 1.30 2006-08-03 09:53:42 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -34,10 +34,15 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_T("cannot switch to next source input"),
XP_T("cannot read source input"),
XP_T("cannot open text input"),
XP_T("cannot close text input"),
XP_T("cannot switch to next text input"),
XP_T("cannot read text input"),
XP_T("cannot open console for read"),
XP_T("cannot close console for read"),
XP_T("cannot switch to next console for read"),
XP_T("cannot read from console"),
XP_T("cannot open console for write"),
XP_T("cannot close console for write"),
XP_T("cannot switch to next console for write"),
XP_T("cannot write to console"),
XP_T("invalid character"),
XP_T("cannot unget character"),

View File

@ -1,5 +1,5 @@
/*
* $Id: extio.c,v 1.25 2006-08-03 05:05:46 bacon Exp $
* $Id: extio.c,v 1.26 2006-08-03 09:53:42 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -78,6 +78,10 @@ static int __out_mask_map[] =
__MASK_WRITE
};
static int __writeextio (
xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum, xp_bool_t nl);
int xp_awk_readextio (
xp_awk_run_t* run, int in_type,
const xp_char_t* name, xp_str_t* buf, int* errnum)
@ -221,10 +225,26 @@ int xp_awk_readextio (
int xp_awk_writeextio (
xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum)
{
return __writeextio (run, out_type, name, v, errnum, xp_false);
}
int xp_awk_writeextio_nl (
xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum)
{
return __writeextio (run, out_type, name, v, errnum, xp_true);
}
static int __writeextio (
xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum, xp_bool_t nl)
{
xp_awk_extio_t* p = run->extio;
xp_awk_io_t handler;
xp_str_t buf;
xp_char_t* str;
xp_size_t len;
int extio_type, extio_mode, extio_mask, n;
xp_assert (out_type >= 0 && out_type <= xp_countof(__out_type_map));
@ -336,33 +356,55 @@ int xp_awk_writeextio (
/* TODO: */
if (v->type != XP_AWK_VAL_STR)
{
n = handler (XP_AWK_IO_WRITE, p,
XP_STR_BUF(&buf), XP_STR_LEN(&buf));
str = XP_STR_BUF(&buf);
len = XP_STR_LEN(&buf);
}
else
{
n = handler (XP_AWK_IO_WRITE, p,
((xp_awk_val_str_t*)v)->buf,
((xp_awk_val_str_t*)v)->len);
}
if (n == -1)
{
if (v->type != XP_AWK_VAL_STR) xp_str_close (&buf);
/* TODO: use meaningful error code */
xp_awk_setglobal (run,
XP_AWK_GLOBAL_ERRNO, xp_awk_val_one);
*errnum = XP_AWK_ENOERR;
return -1;
str = ((xp_awk_val_str_t*)v)->buf;
len = ((xp_awk_val_str_t*)v)->len;
}
if (n == 0)
if (len > 0)
{
if (v->type != XP_AWK_VAL_STR) xp_str_close (&buf);
return 0;
n = handler (XP_AWK_IO_WRITE, p, str, len);
if (n == -1)
{
if (v->type != XP_AWK_VAL_STR) xp_str_close (&buf);
/* TODO: use meaningful error code */
xp_awk_setglobal (run,
XP_AWK_GLOBAL_ERRNO, xp_awk_val_one);
*errnum = XP_AWK_ENOERR;
return -1;
}
if (n == 0)
{
if (v->type != XP_AWK_VAL_STR) xp_str_close (&buf);
return 0;
}
}
if (v->type != XP_AWK_VAL_STR) xp_str_close (&buf);
if (nl)
{
/* TODO: use proper NEWLINE separator */
n = handler (XP_AWK_IO_WRITE, p, XP_T("\n"), 1);
if (n == -1)
{
/* TODO: use meaningful error code */
xp_awk_setglobal (run,
XP_AWK_GLOBAL_ERRNO, xp_awk_val_one);
*errnum = XP_AWK_ENOERR;
return -1;
}
if (n == 0) return 0;
}
return 1;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: extio.h,v 1.8 2006-08-02 11:26:10 bacon Exp $
* $Id: extio.h,v 1.9 2006-08-03 09:53:43 bacon Exp $
*/
#ifndef _XP_AWK_EXTIO_H_
@ -21,6 +21,10 @@ int xp_awk_writeextio (
xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum);
int xp_awk_writeextio_nl (
xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum);
int xp_awk_nextextio_read (
xp_awk_run_t* run, int in_type, const xp_char_t* name, int* errnum);

View File

@ -1,10 +1,17 @@
SRCS = awk.c err.c tree.c tab.c map.c parse.c run.c sa.c val.c func.c misc.c extio.c rex.c
SRCS = \
awk.c err.c tree.c tab.c map.c parse.c \
run.c sa.c val.c func.c misc.c extio.c rex.c
OBJS = $(SRCS:.c=.obj)
OUT = xpawk
JAVA_INC = \
/I"C:\Program Files\IBM\Java141\Include" \
/I"C:\Program Files\IBM\Java141\Include\Win32"
CC = cl
#CFLAGS = /nologo /MT /W3 /GR- /D_WIN32_WINNT=0x0400 -I../..
CFLAGS = /nologo /O2 /MT /W3 /GR- /Za /D_WIN32_WINNT=0x0400 -I../.. -DXP_AWK_STAND_ALONE -DXP_CHAR_IS_WCHAR /I"C:\Program Files\IBM\Java141\Include" /I"C:\Program Files\IBM\Java141\Include\Win32"
CFLAGS = /nologo /O2 /MT /W3 /GR- /Za /D_WIN32_WINNT=0x0400 -I../.. -DXP_AWK_STAND_ALONE -DXP_CHAR_IS_WCHAR $(JAVA_INC)
all: lib

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c,v 1.152 2006-08-03 06:06:27 bacon Exp $
* $Id: parse.c,v 1.153 2006-08-03 09:53:45 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -15,7 +15,10 @@
enum
{
TOKEN_EOF,
TOKEN_NEWLINE,
/* TOKEN_XXX_ASSIGNs should in sync
* with __assop in __assign_to_opcode */
TOKEN_ASSIGN,
TOKEN_PLUS_ASSIGN,
TOKEN_MINUS_ASSIGN,
@ -103,7 +106,8 @@ enum
PARSE_BLOCK_FUNCTION,
PARSE_BLOCK_BEGIN,
PARSE_BLOCK_END,
PARSE_BLOCK_PATTERN
PARSE_BLOCK_PATTERN,
PARSE_BLOCK_ACTION
};
enum
@ -132,7 +136,8 @@ static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals);
static xp_awk_nde_t* __parse_function (xp_awk_t* awk);
static xp_awk_nde_t* __parse_begin (xp_awk_t* awk);
static xp_awk_nde_t* __parse_end (xp_awk_t* awk);
static xp_awk_nde_t* __parse_pattern_block (xp_awk_t* awk, xp_awk_nde_t* ptn);
static xp_awk_chain_t* __parse_pattern_block (
xp_awk_t* awk, xp_awk_nde_t* ptn, xp_bool_t blockless);
static xp_awk_nde_t* __parse_action (xp_awk_t* awk);
static xp_awk_nde_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top);
@ -195,7 +200,8 @@ static int __get_char (xp_awk_t* awk);
static int __unget_char (xp_awk_t* awk, xp_cint_t c);
static int __skip_spaces (xp_awk_t* awk);
static int __skip_comment (xp_awk_t* awk);
static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident);
static int __classify_ident (
xp_awk_t* awk, const xp_char_t* name, xp_size_t len);
static int __assign_to_opcode (xp_awk_t* awk);
static int __is_plain_var (xp_awk_nde_t* nde);
static int __is_var (xp_awk_nde_t* nde);
@ -203,6 +209,7 @@ static int __is_var (xp_awk_nde_t* nde);
struct __kwent
{
const xp_char_t* name;
xp_size_t name_len;
int type;
int valid; /* the entry is valid when this option is set */
};
@ -210,36 +217,36 @@ struct __kwent
static struct __kwent __kwtab[] =
{
/* operators */
{ XP_T("in"), TOKEN_IN, 0 },
{ XP_T("in"), 2, TOKEN_IN, 0 },
/* top-level block starters */
{ XP_T("BEGIN"), TOKEN_BEGIN, 0 },
{ XP_T("END"), TOKEN_END, 0 },
{ XP_T("function"), TOKEN_FUNCTION, 0 },
{ XP_T("func"), TOKEN_FUNCTION, 0 },
{ XP_T("BEGIN"), 5, TOKEN_BEGIN, 0 },
{ XP_T("END"), 3, TOKEN_END, 0 },
{ XP_T("function"), 8, TOKEN_FUNCTION, 0 },
{ XP_T("func"), 4, TOKEN_FUNCTION, 0 },
/* keywords for variable declaration */
{ XP_T("local"), TOKEN_LOCAL, XP_AWK_EXPLICIT },
{ XP_T("global"), TOKEN_GLOBAL, XP_AWK_EXPLICIT },
{ XP_T("local"), 5, TOKEN_LOCAL, XP_AWK_EXPLICIT },
{ XP_T("global"), 6, TOKEN_GLOBAL, XP_AWK_EXPLICIT },
/* keywords that start statements excluding expression statements */
{ XP_T("if"), TOKEN_IF, 0 },
{ XP_T("else"), TOKEN_ELSE, 0 },
{ XP_T("while"), TOKEN_WHILE, 0 },
{ XP_T("for"), TOKEN_FOR, 0 },
{ XP_T("do"), TOKEN_DO, 0 },
{ XP_T("break"), TOKEN_BREAK, 0 },
{ XP_T("continue"), TOKEN_CONTINUE, 0 },
{ XP_T("return"), TOKEN_RETURN, 0 },
{ XP_T("exit"), TOKEN_EXIT, 0 },
{ XP_T("next"), TOKEN_NEXT, 0 },
{ XP_T("nextfile"), TOKEN_NEXTFILE, 0 },
{ XP_T("delete"), TOKEN_DELETE, 0 },
{ XP_T("print"), TOKEN_PRINT, XP_AWK_EXTIO },
{ XP_T("printf"), TOKEN_PRINTF, XP_AWK_EXTIO },
{ XP_T("if"), 2, TOKEN_IF, 0 },
{ XP_T("else"), 4, TOKEN_ELSE, 0 },
{ XP_T("while"), 5, TOKEN_WHILE, 0 },
{ XP_T("for"), 3, TOKEN_FOR, 0 },
{ XP_T("do"), 2, TOKEN_DO, 0 },
{ XP_T("break"), 5, TOKEN_BREAK, 0 },
{ XP_T("continue"), 8, TOKEN_CONTINUE, 0 },
{ XP_T("return"), 6, TOKEN_RETURN, 0 },
{ XP_T("exit"), 4, TOKEN_EXIT, 0 },
{ XP_T("next"), 4, TOKEN_NEXT, 0 },
{ XP_T("nextfile"), 8, TOKEN_NEXTFILE, 0 },
{ XP_T("delete"), 6, TOKEN_DELETE, 0 },
{ XP_T("print"), 5, TOKEN_PRINT, XP_AWK_EXTIO },
{ XP_T("printf"), 6, TOKEN_PRINTF, XP_AWK_EXTIO },
/* keywords that can start an expression */
{ XP_T("getline"), TOKEN_GETLINE, XP_AWK_EXTIO },
{ XP_T("getline"), 7, TOKEN_GETLINE, XP_AWK_EXTIO },
{ XP_NULL, 0, 0 }
};
@ -403,6 +410,8 @@ int xp_awk_parse (xp_awk_t* awk)
return -1;
}
/* TODO: consider opening source here rather in attsrc. same for closing.
* if it does, this part should initialize some of the data like token.line */
xp_awk_clear (awk);
if (__add_builtin_globals (awk) == XP_NULL) return -1;
@ -413,8 +422,9 @@ int xp_awk_parse (xp_awk_t* awk)
while (1)
{
if (MATCH(awk,TOKEN_EOF)) break;
if (MATCH(awk,TOKEN_NEWLINE)) continue;
if (__parse_progunit(awk) == XP_NULL)
if (__parse_progunit (awk) == XP_NULL)
{
xp_awk_clear (awk);
return -1;
@ -446,7 +456,7 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
if (__get_token(awk) == -1) return XP_NULL;
nglobals = xp_awk_tab_getsize(&awk->parse.globals);
if (__collect_globals(awk) == XP_NULL)
if (__collect_globals (awk) == XP_NULL)
{
xp_awk_tab_remove (
&awk->parse.globals, nglobals,
@ -457,24 +467,24 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
else if (MATCH(awk,TOKEN_FUNCTION))
{
awk->parse.id.block = PARSE_BLOCK_FUNCTION;
if (__parse_function(awk) == XP_NULL) return XP_NULL;
if (__parse_function (awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_BEGIN))
{
awk->parse.id.block = PARSE_BLOCK_BEGIN;
if (__parse_begin(awk) == XP_NULL) return XP_NULL;
if (__parse_begin (awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_END))
{
awk->parse.id.block = PARSE_BLOCK_END;
if (__parse_end(awk) == XP_NULL) return XP_NULL;
if (__parse_end (awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_LBRACE))
{
/* pattern less block */
awk->parse.id.block = PARSE_BLOCK_PATTERN;
/* patternless block */
awk->parse.id.block = PARSE_BLOCK_ACTION;
if (__parse_pattern_block (
awk, XP_NULL) == XP_NULL) return XP_NULL;
awk, XP_NULL, xp_false) == XP_NULL) return XP_NULL;
}
else
{
@ -498,7 +508,7 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
if (MATCH(awk,TOKEN_COMMA))
{
if (__get_token(awk) == -1)
if (__get_token (awk) == -1)
{
xp_awk_clrpt (ptn);
return XP_NULL;
@ -512,22 +522,48 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
}
}
if (MATCH(awk,TOKEN_LBRACE))
if ((awk->opt.parse & XP_AWK_BLOCKLESS) &&
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
{
if (__parse_pattern_block (awk,ptn) == XP_NULL)
/* blockless pattern */
xp_bool_t newline = MATCH(awk,TOKEN_NEWLINE);
awk->parse.id.block = PARSE_BLOCK_ACTION;
if (__parse_pattern_block (
awk, ptn, xp_true) == XP_NULL)
{
xp_awk_clrpt (ptn);
return XP_NULL;
}
if (newline)
{
if (__get_token (awk) == -1)
{
xp_awk_clrpt (ptn);
return XP_NULL;
}
}
}
else
{
/* parse the action block */
if (!MATCH(awk,TOKEN_LBRACE))
{
xp_awk_clrpt (ptn);
PANIC (awk, XP_AWK_ELBRACE);
}
awk->parse.id.block = PARSE_BLOCK_ACTION;
if (__parse_pattern_block (
awk, ptn, xp_false) == XP_NULL)
{
xp_awk_clrpt (ptn);
return XP_NULL;
}
}
else
{
/* pattern without a block */
/* TODO: ... pattern { print $0; }*/
xp_awk_clrpt (ptn);
xp_printf (XP_T("BLOCKLESS NOT IMPLEMENTED\n"));
PANIC (awk, XP_AWK_EINTERNAL);
}
}
return awk;
@ -647,7 +683,9 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
}
/* check if a parameter conflicts with other parameters */
if (xp_awk_tab_find (&awk->parse.params, 0, param, param_len) != (xp_size_t)-1)
if (xp_awk_tab_find (
&awk->parse.params,
0, param, param_len) != (xp_size_t)-1)
{
xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
@ -655,7 +693,9 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
}
/* push the parameter to the parameter list */
if (xp_awk_tab_add (&awk->parse.params, param, param_len) == (xp_size_t)-1)
if (xp_awk_tab_add (
&awk->parse.params,
param, param_len) == (xp_size_t)-1)
{
xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
@ -781,13 +821,18 @@ static xp_awk_nde_t* __parse_end (xp_awk_t* awk)
return nde;
}
static xp_awk_nde_t* __parse_pattern_block (xp_awk_t* awk, xp_awk_nde_t* ptn)
static xp_awk_chain_t* __parse_pattern_block (
xp_awk_t* awk, xp_awk_nde_t* ptn, xp_bool_t blockless)
{
xp_awk_nde_t* nde;
xp_awk_chain_t* chain;
nde = __parse_action (awk);
if (nde == XP_NULL) return XP_NULL;
if (blockless) nde = XP_NULL;
else
{
nde = __parse_action (awk);
if (nde == XP_NULL) return XP_NULL;
}
chain = (xp_awk_chain_t*) xp_malloc (xp_sizeof(xp_awk_chain_t));
if (chain == XP_NULL)
@ -812,7 +857,7 @@ static xp_awk_nde_t* __parse_pattern_block (xp_awk_t* awk, xp_awk_nde_t* ptn)
awk->tree.chain_tail = chain;
}
return nde;
return chain;
}
static xp_awk_nde_t* __parse_action (xp_awk_t* awk)
@ -1969,6 +2014,7 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk)
/* the regular expression is tokenized here because
* of the context-sensitivity of the slash symbol */
SET_TOKEN_TYPE (awk, TOKEN_REX);
xp_str_clear (&awk->token.name);
if (__get_rexstr (awk) == -1) return XP_NULL;
xp_assert (MATCH(awk,TOKEN_REX));
@ -1981,7 +2027,7 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk)
nde->len = XP_STR_LEN(&awk->token.name);
nde->buf = xp_strxdup (
XP_STR_BUF(&awk->token.name),
XP_STR_BUF(&awk->token.name),
XP_STR_LEN(&awk->token.name));
if (nde->buf == XP_NULL)
{
@ -3145,8 +3191,10 @@ static xp_awk_nde_t* __parse_nextfile (xp_awk_t* awk)
static int __get_token (xp_awk_t* awk)
{
xp_cint_t c;
xp_size_t line;
int n;
line = awk->token.line;
do
{
if (__skip_spaces(awk) == -1) return -1;
@ -3154,10 +3202,21 @@ static int __get_token (xp_awk_t* awk)
}
while (n == 1);
xp_str_clear (&awk->token.name);
awk->token.line = awk->lex.line;
awk->token.column = awk->lex.column;
if (line != 0 && (awk->opt.parse & XP_AWK_BLOCKLESS) &&
awk->parse.id.block == PARSE_BLOCK_PATTERN)
{
if (awk->token.line != line)
{
SET_TOKEN_TYPE (awk, TOKEN_NEWLINE);
return 0;
}
}
c = awk->lex.curc;
if (c == XP_CHAR_EOF)
@ -3180,7 +3239,9 @@ static int __get_token (xp_awk_t* awk)
}
while (xp_isalpha(c) || c == XP_T('_') || xp_isdigit(c));
type = __classify_ident (awk,XP_STR_BUF(&awk->token.name));
type = __classify_ident (awk,
XP_STR_BUF(&awk->token.name),
XP_STR_LEN(&awk->token.name));
SET_TOKEN_TYPE (awk, type);
}
else if (c == XP_T('\"'))
@ -3207,116 +3268,117 @@ static int __get_token (xp_awk_t* awk)
}
else if (c == XP_T('='))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_EQ);
ADD_TOKEN_STR (awk, XP_T("=="));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_ASSIGN);
ADD_TOKEN_STR (awk, XP_T("="));
}
}
else if (c == XP_T('!'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_NE);
ADD_TOKEN_STR (awk, XP_T("!="));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_T('~'))
{
SET_TOKEN_TYPE (awk, TOKEN_NM);
ADD_TOKEN_STR (awk, XP_T("!~"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_NOT);
ADD_TOKEN_STR (awk, XP_T("!"));
}
}
else if (c == XP_T('>'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if ((awk->opt.parse & XP_AWK_SHIFT) && c == XP_T('>'))
{
SET_TOKEN_TYPE (awk, TOKEN_RSHIFT);
ADD_TOKEN_STR (awk, XP_T(">>"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_GE);
ADD_TOKEN_STR (awk, XP_T(">="));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_GT);
ADD_TOKEN_STR (awk, XP_T(">"));
}
}
else if (c == XP_T('<'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if ((awk->opt.parse & XP_AWK_SHIFT) && c == XP_T('<'))
{
SET_TOKEN_TYPE (awk, TOKEN_LSHIFT);
ADD_TOKEN_STR (awk, XP_T("<<"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_LE);
ADD_TOKEN_STR (awk, XP_T("<="));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_LT);
ADD_TOKEN_STR (awk, XP_T("<"));
}
}
else if (c == XP_T('|'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('|'))
{
SET_TOKEN_TYPE (awk, TOKEN_LOR);
ADD_TOKEN_STR (awk, XP_T("||"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_T('&'))
{
SET_TOKEN_TYPE (awk, TOKEN_BORAND);
ADD_TOKEN_STR (awk, XP_T("|&"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_BOR);
ADD_TOKEN_STR (awk, XP_T("|"));
}
}
else if (c == XP_T('&'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('&'))
{
SET_TOKEN_TYPE (awk, TOKEN_LAND);
ADD_TOKEN_STR (awk, XP_T("&&"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_BAND);
ADD_TOKEN_STR (awk, XP_T("&"));
}
}
else if (c == XP_T('~'))
@ -3333,48 +3395,49 @@ static int __get_token (xp_awk_t* awk)
}
else if (c == XP_T('+'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('+'))
{
SET_TOKEN_TYPE (awk, TOKEN_PLUSPLUS);
ADD_TOKEN_STR (awk, XP_T("++"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_PLUS_ASSIGN);
ADD_TOKEN_STR (awk, XP_T("+="));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_PLUS);
ADD_TOKEN_STR (awk, XP_T("+"));
}
}
else if (c == XP_T('-'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('-'))
{
SET_TOKEN_TYPE (awk, TOKEN_MINUSMINUS);
ADD_TOKEN_STR (awk, XP_T("--"));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_MINUS_ASSIGN);
ADD_TOKEN_STR (awk, XP_T("-="));
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_MINUS);
ADD_TOKEN_STR (awk, XP_T("-"));
}
}
else if (c == XP_T('*'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('='))
@ -3385,6 +3448,7 @@ static int __get_token (xp_awk_t* awk)
}
else if (c == XP_T('*'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('='))
{
@ -3395,17 +3459,16 @@ static int __get_token (xp_awk_t* awk)
else
{
SET_TOKEN_TYPE (awk, TOKEN_EXP);
ADD_TOKEN_CHAR (awk, c);
}
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_MUL);
ADD_TOKEN_CHAR (awk, c);
}
}
else if (c == XP_T('/'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('='))
@ -3417,11 +3480,11 @@ static int __get_token (xp_awk_t* awk)
else
{
SET_TOKEN_TYPE (awk, TOKEN_DIV);
ADD_TOKEN_CHAR (awk, c);
}
}
else if (c == XP_T('%'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == XP_T('='))
@ -3433,7 +3496,6 @@ static int __get_token (xp_awk_t* awk)
else
{
SET_TOKEN_TYPE (awk, TOKEN_MOD);
ADD_TOKEN_CHAR (awk, c);
}
}
else if (c == XP_T('('))
@ -3615,11 +3677,23 @@ static int __get_number (xp_awk_t* awk)
static int __get_charstr (xp_awk_t* awk)
{
if (awk->lex.curc != XP_T('\"'))
{
/* the starting quote has been comsumed before this function
* has been called */
ADD_TOKEN_CHAR (awk, awk->lex.curc);
}
return __get_string (awk, XP_T('\"'), XP_T('\\'), xp_false);
}
static int __get_rexstr (xp_awk_t* awk)
{
if (awk->lex.curc != XP_T('/'))
{
/* the starting slash has been comsumed before this function
* has been called */
ADD_TOKEN_CHAR (awk, awk->lex.curc);
}
return __get_string (awk, XP_T('/'), XP_T('\\'), xp_true);
}
@ -3772,7 +3846,7 @@ static int __get_string (
ADD_TOKEN_CHAR (awk, c);
}
return 0;
}
@ -3844,6 +3918,7 @@ static int __unget_char (xp_awk_t* awk, xp_cint_t c)
static int __skip_spaces (xp_awk_t* awk)
{
xp_cint_t c = awk->lex.curc;
while (xp_isspace(c)) GET_CHAR_TO (awk, c);
return 0;
}
@ -3904,7 +3979,8 @@ static int __skip_comment (xp_awk_t* awk)
return 0;
}
static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident)
static int __classify_ident (
xp_awk_t* awk, const xp_char_t* name, xp_size_t len)
{
struct __kwent* kwp;
@ -3912,7 +3988,11 @@ static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident)
{
if (kwp->valid != 0 &&
(awk->opt.parse & kwp->valid) == 0) continue;
if (xp_strcmp(kwp->name, ident) == 0) return kwp->type;
if (xp_strxncmp (kwp->name, kwp->name_len, name, len) == 0)
{
return kwp->type;
}
}
return TOKEN_IDENT;
@ -3920,13 +4000,22 @@ static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident)
static int __assign_to_opcode (xp_awk_t* awk)
{
if (MATCH(awk,TOKEN_ASSIGN)) return XP_AWK_ASSOP_NONE;
if (MATCH(awk,TOKEN_PLUS_ASSIGN)) return XP_AWK_ASSOP_PLUS;
if (MATCH(awk,TOKEN_MINUS_ASSIGN)) return XP_AWK_ASSOP_MINUS;
if (MATCH(awk,TOKEN_MUL_ASSIGN)) return XP_AWK_ASSOP_MUL;
if (MATCH(awk,TOKEN_DIV_ASSIGN)) return XP_AWK_ASSOP_DIV;
if (MATCH(awk,TOKEN_MOD_ASSIGN)) return XP_AWK_ASSOP_MOD;
if (MATCH(awk,TOKEN_EXP_ASSIGN)) return XP_AWK_ASSOP_EXP;
static int __assop[] =
{
XP_AWK_ASSOP_NONE,
XP_AWK_ASSOP_PLUS,
XP_AWK_ASSOP_MINUS,
XP_AWK_ASSOP_MUL,
XP_AWK_ASSOP_DIV,
XP_AWK_ASSOP_MOD,
XP_AWK_ASSOP_EXP
};
if (awk->token.type >= TOKEN_ASSIGN &&
awk->token.type <= TOKEN_EXP_ASSIGN)
{
return __assop[awk->token.type - TOKEN_ASSIGN];
}
return -1;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c,v 1.157 2006-08-03 05:05:47 bacon Exp $
* $Id: run.c,v 1.158 2006-08-03 09:53:45 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -552,7 +552,7 @@ static int __run_pattern_blocks (xp_awk_run_t* run)
{
/* don't care about the result of input close */
xp_awk_closeextio_read (
run, XP_AWK_EXTIO_CONSOLE, XP_T(""), &errnum);
run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
return -1;
}
@ -562,7 +562,7 @@ static int __run_pattern_blocks (xp_awk_run_t* run)
if (__run_pattern_block_chain (run, run->awk->tree.chain) == -1)
{
xp_awk_closeextio_read (
run, XP_AWK_EXTIO_CONSOLE, XP_T(""), &errnum);
run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
return -1;
}
}
@ -577,11 +577,11 @@ static int __run_pattern_blocks (xp_awk_run_t* run)
if (need_to_close)
{
n = xp_awk_closeextio_read (
run, XP_AWK_EXTIO_CONSOLE, XP_T(""), &errnum);
run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
if (n == -1)
{
if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ETXTINCLOSE);
PANIC_I (run, XP_AWK_ECONINCLOSE);
else
PANIC_I (run, errnum);
}
@ -702,6 +702,30 @@ static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde)
xp_size_t saved_stack_top;
int n = 0;
if (nde == XP_NULL)
{
/* blockless pattern - execute print $0*/
int errnum;
xp_awk_refupval (run->inrec.d0);
n = xp_awk_writeextio_nl (run,
XP_AWK_OUT_CONSOLE, XP_T(""), run->inrec.d0, &errnum);
if (n == -1)
{
xp_awk_refdownval (run, run->inrec.d0);
if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ECONOUTDATA);
else
PANIC_I (run, errnum);
}
xp_awk_refdownval (run, run->inrec.d0);
return 0;
}
xp_assert (nde->type == XP_AWK_NDE_BLK);
p = nde->body;
@ -1206,7 +1230,7 @@ static int __run_nextfile (xp_awk_run_t* run, xp_awk_nde_nextfile_t* nde)
if (n == -1)
{
if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ETXTINNEXT);
PANIC_I (run, XP_AWK_ECONINNEXT);
else
PANIC_I (run, errnum);
}
@ -1404,7 +1428,7 @@ static int __run_print (xp_awk_run_t* run, xp_awk_nde_print_t* nde)
(p->out_type == XP_AWK_OUT_PIPE && p->out != XP_NULL) ||
(p->out_type == XP_AWK_OUT_COPROC && p->out != XP_NULL) ||
(p->out_type == XP_AWK_OUT_FILE && p->out != XP_NULL) ||
(p->out_type == XP_AWK_OUT_FILE_APPEND && p->out != XP_NULL) ||
(p->out_type == XP_AWK_OUT_FILE_APPEND && p->out != XP_NULL) ||
(p->out_type == XP_AWK_OUT_CONSOLE && p->out == XP_NULL));
if (p->out != XP_NULL)
@ -1495,24 +1519,15 @@ static int __run_print (xp_awk_run_t* run, xp_awk_nde_print_t* nde)
}
}
/* TODO: predefine the new line string
* for performance improvement*/
v = xp_awk_makestrval (XP_T("\n"), 1);
if (v == XP_NULL)
{
if (out != XP_NULL) xp_free (out);
PANIC_I (run, XP_AWK_ENOMEM);
}
xp_awk_refupval (v);
n = xp_awk_writeextio (run, p->out_type, dst, v, &errnum);
/* TODO: change xp_awk_val_nil to
* xp_awk_val_empty_string or something */
n = xp_awk_writeextio_nl (
run, p->out_type, dst, xp_awk_val_nil, &errnum);
if (n < 0 && errnum != XP_AWK_ENOERR)
{
if (out != XP_NULL) xp_free (out);
xp_awk_refdownval (run, v);
PANIC_I (run, errnum);
}
xp_awk_refdownval (run, v);
/* TODO: how to handle n == -1 && errnum == XP_AWK_ENOERR. that is the user handler returned an error... */
@ -2897,7 +2912,10 @@ static xp_awk_val_t* __eval_binop_ma (
xp_assert (right->next == XP_NULL);
lv = __eval_expression (run, left);
if (lv == XP_NULL) return XP_NULL;
if (lv == XP_NULL)
{
return XP_NULL;
}
xp_awk_refupval (lv);
@ -3006,7 +3024,7 @@ static xp_awk_val_t* __eval_binop_match0 (
}
else
{
str = xp_awk_valtostr (right, &errnum, xp_true, XP_NULL, &len);
str = xp_awk_valtostr (left, &errnum, xp_true, XP_NULL, &len);
if (str == XP_NULL)
{
if (right->type != XP_AWK_VAL_REX) xp_free (rex_code);
@ -4093,12 +4111,12 @@ static int __read_record (xp_awk_run_t* run)
/*TODO: use RS */
n = xp_awk_readextio (
run, XP_AWK_EXTIO_CONSOLE,
run, XP_AWK_IN_CONSOLE,
XP_T(""), &run->inrec.line, &errnum);
if (n < 0)
{
if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ETXTINDATA);
PANIC_I (run, XP_AWK_ECONINDATA);
else
PANIC_I (run, errnum);
}

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c,v 1.61 2006-08-02 14:36:23 bacon Exp $
* $Id: awk.c,v 1.62 2006-08-03 09:53:46 bacon Exp $
*/
#include <xp/awk/awk.h>
@ -522,7 +522,8 @@ static int __main (int argc, xp_char_t* argv[])
xp_awk_setparseopt (awk,
XP_AWK_EXPLICIT | XP_AWK_UNIQUE | XP_AWK_DBLSLASHES |
XP_AWK_SHADING | XP_AWK_IMPLICIT | XP_AWK_SHIFT | XP_AWK_EXTIO);
XP_AWK_SHADING | XP_AWK_IMPLICIT | XP_AWK_SHIFT |
XP_AWK_EXTIO | XP_AWK_BLOCKLESS);
if (argc == 2)
{

18
ase/test/awk/t23.awk Normal file
View File

@ -0,0 +1,18 @@
/*
{
print "ALL ==> " $0;
}
/1/,/5/
{
print "/1/,/5/ ==> " $0;
}
*/
BEGIN { c["Europe"] = "XXX"; }
/Europe/, /Africa/ { print $0; }
//(a = "20") { }
/*"Europe" in c { print $0; }*/

6
ase/test/awk/t24.awk Normal file
View File

@ -0,0 +1,6 @@
BEGIN {
a["abc\0\0xxx"] = "abcdefg";
print a["abc"];
print a["abc\0\0xxx"];
}

13
ase/test/awk/t25.awk Normal file
View File

@ -0,0 +1,13 @@
/Europe/, /Africa/
1
2
3 % 23
/zab/ { print "XXXX"; }
{
print /ABC/ ~ /DEF/;
}
/zzz/