*** 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> #include <xp/awk/awk_i.h>
@ -77,8 +77,8 @@ xp_awk_t* xp_awk_open (void)
awk->token.prev = 0; awk->token.prev = 0;
awk->token.type = 0; awk->token.type = 0;
awk->token.line = 1; awk->token.line = 0;
awk->token.column = 1; awk->token.column = 0;
awk->lex.curc = XP_CHAR_EOF; awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0; awk->lex.ungotc_count = 0;
@ -153,6 +153,7 @@ void xp_awk_clear (xp_awk_t* awk)
xp_free (awk->tree.chain); xp_free (awk->tree.chain);
awk->tree.chain = next; awk->tree.chain = next;
} }
awk->tree.chain_tail = XP_NULL; 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_ #ifndef _XP_AWK_AWK_H_
@ -91,7 +91,10 @@ enum
XP_AWK_STRCONCAT = (1 << 7), XP_AWK_STRCONCAT = (1 << 7),
/* support getline and print */ /* support getline and print */
XP_AWK_EXTIO = (1 << 8) XP_AWK_EXTIO = (1 << 8),
/* support blockless patterns */
XP_AWK_BLOCKLESS = (1 << 9),
}; };
/* run options */ /* run options */
@ -113,10 +116,15 @@ enum
XP_AWK_ESRCINNEXT, XP_AWK_ESRCINNEXT,
XP_AWK_ESRCINDATA, /* error in reading source */ XP_AWK_ESRCINDATA, /* error in reading source */
XP_AWK_ETXTINOPEN, XP_AWK_ECONINOPEN,
XP_AWK_ETXTINCLOSE, XP_AWK_ECONINCLOSE,
XP_AWK_ETXTINNEXT, XP_AWK_ECONINNEXT,
XP_AWK_ETXTINDATA, /* error in reading text */ 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_ELXCHR, /* lexer came accross an wrong character */
XP_AWK_ELXUNG, /* lexer failed to unget a 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> #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 switch to next source input"),
XP_T("cannot read source input"), XP_T("cannot read source input"),
XP_T("cannot open text input"), XP_T("cannot open console for read"),
XP_T("cannot close text input"), XP_T("cannot close console for read"),
XP_T("cannot switch to next text input"), XP_T("cannot switch to next console for read"),
XP_T("cannot read text input"), 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("invalid character"),
XP_T("cannot unget 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> #include <xp/awk/awk_i.h>
@ -78,6 +78,10 @@ static int __out_mask_map[] =
__MASK_WRITE __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 ( int xp_awk_readextio (
xp_awk_run_t* run, int in_type, xp_awk_run_t* run, int in_type,
const xp_char_t* name, xp_str_t* buf, int* errnum) const xp_char_t* name, xp_str_t* buf, int* errnum)
@ -221,10 +225,26 @@ int xp_awk_readextio (
int xp_awk_writeextio ( int xp_awk_writeextio (
xp_awk_run_t* run, int out_type, xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum) 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_extio_t* p = run->extio;
xp_awk_io_t handler; xp_awk_io_t handler;
xp_str_t buf; xp_str_t buf;
xp_char_t* str;
xp_size_t len;
int extio_type, extio_mode, extio_mask, n; int extio_type, extio_mode, extio_mask, n;
xp_assert (out_type >= 0 && out_type <= xp_countof(__out_type_map)); xp_assert (out_type >= 0 && out_type <= xp_countof(__out_type_map));
@ -336,33 +356,55 @@ int xp_awk_writeextio (
/* TODO: */ /* TODO: */
if (v->type != XP_AWK_VAL_STR) if (v->type != XP_AWK_VAL_STR)
{ {
n = handler (XP_AWK_IO_WRITE, p, str = XP_STR_BUF(&buf);
XP_STR_BUF(&buf), XP_STR_LEN(&buf)); len = XP_STR_LEN(&buf);
} }
else else
{ {
n = handler (XP_AWK_IO_WRITE, p, str = ((xp_awk_val_str_t*)v)->buf;
((xp_awk_val_str_t*)v)->buf, len = ((xp_awk_val_str_t*)v)->len;
((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;
} }
if (n == 0) if (len > 0)
{ {
if (v->type != XP_AWK_VAL_STR) xp_str_close (&buf); n = handler (XP_AWK_IO_WRITE, p, str, len);
return 0;
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 (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; 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_ #ifndef _XP_AWK_EXTIO_H_
@ -21,6 +21,10 @@ int xp_awk_writeextio (
xp_awk_run_t* run, int out_type, xp_awk_run_t* run, int out_type,
const xp_char_t* name, xp_awk_val_t* v, int* errnum); 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 ( int xp_awk_nextextio_read (
xp_awk_run_t* run, int in_type, const xp_char_t* name, int* errnum); 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) OBJS = $(SRCS:.c=.obj)
OUT = xpawk OUT = xpawk
JAVA_INC = \
/I"C:\Program Files\IBM\Java141\Include" \
/I"C:\Program Files\IBM\Java141\Include\Win32"
CC = cl CC = cl
#CFLAGS = /nologo /MT /W3 /GR- /D_WIN32_WINNT=0x0400 -I../.. #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 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> #include <xp/awk/awk_i.h>
@ -15,7 +15,10 @@
enum enum
{ {
TOKEN_EOF, TOKEN_EOF,
TOKEN_NEWLINE,
/* TOKEN_XXX_ASSIGNs should in sync
* with __assop in __assign_to_opcode */
TOKEN_ASSIGN, TOKEN_ASSIGN,
TOKEN_PLUS_ASSIGN, TOKEN_PLUS_ASSIGN,
TOKEN_MINUS_ASSIGN, TOKEN_MINUS_ASSIGN,
@ -103,7 +106,8 @@ enum
PARSE_BLOCK_FUNCTION, PARSE_BLOCK_FUNCTION,
PARSE_BLOCK_BEGIN, PARSE_BLOCK_BEGIN,
PARSE_BLOCK_END, PARSE_BLOCK_END,
PARSE_BLOCK_PATTERN PARSE_BLOCK_PATTERN,
PARSE_BLOCK_ACTION
}; };
enum 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_function (xp_awk_t* awk);
static xp_awk_nde_t* __parse_begin (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_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_action (xp_awk_t* awk);
static xp_awk_nde_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top); 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 __unget_char (xp_awk_t* awk, xp_cint_t c);
static int __skip_spaces (xp_awk_t* awk); static int __skip_spaces (xp_awk_t* awk);
static int __skip_comment (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 __assign_to_opcode (xp_awk_t* awk);
static int __is_plain_var (xp_awk_nde_t* nde); static int __is_plain_var (xp_awk_nde_t* nde);
static int __is_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 struct __kwent
{ {
const xp_char_t* name; const xp_char_t* name;
xp_size_t name_len;
int type; int type;
int valid; /* the entry is valid when this option is set */ int valid; /* the entry is valid when this option is set */
}; };
@ -210,36 +217,36 @@ struct __kwent
static struct __kwent __kwtab[] = static struct __kwent __kwtab[] =
{ {
/* operators */ /* operators */
{ XP_T("in"), TOKEN_IN, 0 }, { XP_T("in"), 2, TOKEN_IN, 0 },
/* top-level block starters */ /* top-level block starters */
{ XP_T("BEGIN"), TOKEN_BEGIN, 0 }, { XP_T("BEGIN"), 5, TOKEN_BEGIN, 0 },
{ XP_T("END"), TOKEN_END, 0 }, { XP_T("END"), 3, TOKEN_END, 0 },
{ XP_T("function"), TOKEN_FUNCTION, 0 }, { XP_T("function"), 8, TOKEN_FUNCTION, 0 },
{ XP_T("func"), TOKEN_FUNCTION, 0 }, { XP_T("func"), 4, TOKEN_FUNCTION, 0 },
/* keywords for variable declaration */ /* keywords for variable declaration */
{ XP_T("local"), TOKEN_LOCAL, XP_AWK_EXPLICIT }, { XP_T("local"), 5, TOKEN_LOCAL, XP_AWK_EXPLICIT },
{ XP_T("global"), TOKEN_GLOBAL, XP_AWK_EXPLICIT }, { XP_T("global"), 6, TOKEN_GLOBAL, XP_AWK_EXPLICIT },
/* keywords that start statements excluding expression statements */ /* keywords that start statements excluding expression statements */
{ XP_T("if"), TOKEN_IF, 0 }, { XP_T("if"), 2, TOKEN_IF, 0 },
{ XP_T("else"), TOKEN_ELSE, 0 }, { XP_T("else"), 4, TOKEN_ELSE, 0 },
{ XP_T("while"), TOKEN_WHILE, 0 }, { XP_T("while"), 5, TOKEN_WHILE, 0 },
{ XP_T("for"), TOKEN_FOR, 0 }, { XP_T("for"), 3, TOKEN_FOR, 0 },
{ XP_T("do"), TOKEN_DO, 0 }, { XP_T("do"), 2, TOKEN_DO, 0 },
{ XP_T("break"), TOKEN_BREAK, 0 }, { XP_T("break"), 5, TOKEN_BREAK, 0 },
{ XP_T("continue"), TOKEN_CONTINUE, 0 }, { XP_T("continue"), 8, TOKEN_CONTINUE, 0 },
{ XP_T("return"), TOKEN_RETURN, 0 }, { XP_T("return"), 6, TOKEN_RETURN, 0 },
{ XP_T("exit"), TOKEN_EXIT, 0 }, { XP_T("exit"), 4, TOKEN_EXIT, 0 },
{ XP_T("next"), TOKEN_NEXT, 0 }, { XP_T("next"), 4, TOKEN_NEXT, 0 },
{ XP_T("nextfile"), TOKEN_NEXTFILE, 0 }, { XP_T("nextfile"), 8, TOKEN_NEXTFILE, 0 },
{ XP_T("delete"), TOKEN_DELETE, 0 }, { XP_T("delete"), 6, TOKEN_DELETE, 0 },
{ XP_T("print"), TOKEN_PRINT, XP_AWK_EXTIO }, { XP_T("print"), 5, TOKEN_PRINT, XP_AWK_EXTIO },
{ XP_T("printf"), TOKEN_PRINTF, XP_AWK_EXTIO }, { XP_T("printf"), 6, TOKEN_PRINTF, XP_AWK_EXTIO },
/* keywords that can start an expression */ /* 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 } { XP_NULL, 0, 0 }
}; };
@ -403,6 +410,8 @@ int xp_awk_parse (xp_awk_t* awk)
return -1; 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); xp_awk_clear (awk);
if (__add_builtin_globals (awk) == XP_NULL) return -1; if (__add_builtin_globals (awk) == XP_NULL) return -1;
@ -413,8 +422,9 @@ int xp_awk_parse (xp_awk_t* awk)
while (1) while (1)
{ {
if (MATCH(awk,TOKEN_EOF)) break; 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); xp_awk_clear (awk);
return -1; return -1;
@ -446,7 +456,7 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
nglobals = xp_awk_tab_getsize(&awk->parse.globals); nglobals = xp_awk_tab_getsize(&awk->parse.globals);
if (__collect_globals(awk) == XP_NULL) if (__collect_globals (awk) == XP_NULL)
{ {
xp_awk_tab_remove ( xp_awk_tab_remove (
&awk->parse.globals, nglobals, &awk->parse.globals, nglobals,
@ -457,24 +467,24 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
else if (MATCH(awk,TOKEN_FUNCTION)) else if (MATCH(awk,TOKEN_FUNCTION))
{ {
awk->parse.id.block = PARSE_BLOCK_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)) else if (MATCH(awk,TOKEN_BEGIN))
{ {
awk->parse.id.block = PARSE_BLOCK_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)) else if (MATCH(awk,TOKEN_END))
{ {
awk->parse.id.block = PARSE_BLOCK_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)) else if (MATCH(awk,TOKEN_LBRACE))
{ {
/* pattern less block */ /* patternless block */
awk->parse.id.block = PARSE_BLOCK_PATTERN; awk->parse.id.block = PARSE_BLOCK_ACTION;
if (__parse_pattern_block ( if (__parse_pattern_block (
awk, XP_NULL) == XP_NULL) return XP_NULL; awk, XP_NULL, xp_false) == XP_NULL) return XP_NULL;
} }
else else
{ {
@ -498,7 +508,7 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
if (MATCH(awk,TOKEN_COMMA)) if (MATCH(awk,TOKEN_COMMA))
{ {
if (__get_token(awk) == -1) if (__get_token (awk) == -1)
{ {
xp_awk_clrpt (ptn); xp_awk_clrpt (ptn);
return XP_NULL; 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); xp_awk_clrpt (ptn);
return XP_NULL; 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; 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 */ /* 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_free (name_dup);
xp_awk_tab_clear (&awk->parse.params); 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 */ /* 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_free (name_dup);
xp_awk_tab_clear (&awk->parse.params); xp_awk_tab_clear (&awk->parse.params);
@ -781,13 +821,18 @@ static xp_awk_nde_t* __parse_end (xp_awk_t* awk)
return nde; 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_nde_t* nde;
xp_awk_chain_t* chain; xp_awk_chain_t* chain;
nde = __parse_action (awk); if (blockless) nde = XP_NULL;
if (nde == XP_NULL) return 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)); chain = (xp_awk_chain_t*) xp_malloc (xp_sizeof(xp_awk_chain_t));
if (chain == XP_NULL) 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; awk->tree.chain_tail = chain;
} }
return nde; return chain;
} }
static xp_awk_nde_t* __parse_action (xp_awk_t* awk) 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 /* the regular expression is tokenized here because
* of the context-sensitivity of the slash symbol */ * of the context-sensitivity of the slash symbol */
SET_TOKEN_TYPE (awk, TOKEN_REX); SET_TOKEN_TYPE (awk, TOKEN_REX);
xp_str_clear (&awk->token.name);
if (__get_rexstr (awk) == -1) return XP_NULL; if (__get_rexstr (awk) == -1) return XP_NULL;
xp_assert (MATCH(awk,TOKEN_REX)); 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->len = XP_STR_LEN(&awk->token.name);
nde->buf = xp_strxdup ( nde->buf = xp_strxdup (
XP_STR_BUF(&awk->token.name), XP_STR_BUF(&awk->token.name),
XP_STR_LEN(&awk->token.name)); XP_STR_LEN(&awk->token.name));
if (nde->buf == XP_NULL) 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) static int __get_token (xp_awk_t* awk)
{ {
xp_cint_t c; xp_cint_t c;
xp_size_t line;
int n; int n;
line = awk->token.line;
do do
{ {
if (__skip_spaces(awk) == -1) return -1; if (__skip_spaces(awk) == -1) return -1;
@ -3154,10 +3202,21 @@ static int __get_token (xp_awk_t* awk)
} }
while (n == 1); while (n == 1);
xp_str_clear (&awk->token.name); xp_str_clear (&awk->token.name);
awk->token.line = awk->lex.line; awk->token.line = awk->lex.line;
awk->token.column = awk->lex.column; 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; c = awk->lex.curc;
if (c == XP_CHAR_EOF) 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)); 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); SET_TOKEN_TYPE (awk, type);
} }
else if (c == XP_T('\"')) else if (c == XP_T('\"'))
@ -3207,116 +3268,117 @@ static int __get_token (xp_awk_t* awk)
} }
else if (c == XP_T('=')) else if (c == XP_T('='))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('=')) if (c == XP_T('='))
{ {
SET_TOKEN_TYPE (awk, TOKEN_EQ); SET_TOKEN_TYPE (awk, TOKEN_EQ);
ADD_TOKEN_STR (awk, XP_T("==")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_ASSIGN); SET_TOKEN_TYPE (awk, TOKEN_ASSIGN);
ADD_TOKEN_STR (awk, XP_T("="));
} }
} }
else if (c == XP_T('!')) else if (c == XP_T('!'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('=')) if (c == XP_T('='))
{ {
SET_TOKEN_TYPE (awk, TOKEN_NE); SET_TOKEN_TYPE (awk, TOKEN_NE);
ADD_TOKEN_STR (awk, XP_T("!=")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (c == XP_T('~')) else if (c == XP_T('~'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_NM); SET_TOKEN_TYPE (awk, TOKEN_NM);
ADD_TOKEN_STR (awk, XP_T("!~")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_NOT); SET_TOKEN_TYPE (awk, TOKEN_NOT);
ADD_TOKEN_STR (awk, XP_T("!"));
} }
} }
else if (c == XP_T('>')) else if (c == XP_T('>'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if ((awk->opt.parse & XP_AWK_SHIFT) && c == XP_T('>')) if ((awk->opt.parse & XP_AWK_SHIFT) && c == XP_T('>'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_RSHIFT); SET_TOKEN_TYPE (awk, TOKEN_RSHIFT);
ADD_TOKEN_STR (awk, XP_T(">>")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (c == XP_T('=')) else if (c == XP_T('='))
{ {
SET_TOKEN_TYPE (awk, TOKEN_GE); SET_TOKEN_TYPE (awk, TOKEN_GE);
ADD_TOKEN_STR (awk, XP_T(">=")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_GT); SET_TOKEN_TYPE (awk, TOKEN_GT);
ADD_TOKEN_STR (awk, XP_T(">"));
} }
} }
else if (c == XP_T('<')) else if (c == XP_T('<'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if ((awk->opt.parse & XP_AWK_SHIFT) && c == XP_T('<')) if ((awk->opt.parse & XP_AWK_SHIFT) && c == XP_T('<'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_LSHIFT); SET_TOKEN_TYPE (awk, TOKEN_LSHIFT);
ADD_TOKEN_STR (awk, XP_T("<<")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (c == XP_T('=')) else if (c == XP_T('='))
{ {
SET_TOKEN_TYPE (awk, TOKEN_LE); SET_TOKEN_TYPE (awk, TOKEN_LE);
ADD_TOKEN_STR (awk, XP_T("<=")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_LT); SET_TOKEN_TYPE (awk, TOKEN_LT);
ADD_TOKEN_STR (awk, XP_T("<"));
} }
} }
else if (c == XP_T('|')) else if (c == XP_T('|'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('|')) if (c == XP_T('|'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_LOR); SET_TOKEN_TYPE (awk, TOKEN_LOR);
ADD_TOKEN_STR (awk, XP_T("||")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (c == XP_T('&')) else if (c == XP_T('&'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_BORAND); SET_TOKEN_TYPE (awk, TOKEN_BORAND);
ADD_TOKEN_STR (awk, XP_T("|&")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_BOR); SET_TOKEN_TYPE (awk, TOKEN_BOR);
ADD_TOKEN_STR (awk, XP_T("|"));
} }
} }
else if (c == XP_T('&')) else if (c == XP_T('&'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('&')) if (c == XP_T('&'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_LAND); SET_TOKEN_TYPE (awk, TOKEN_LAND);
ADD_TOKEN_STR (awk, XP_T("&&")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_BAND); SET_TOKEN_TYPE (awk, TOKEN_BAND);
ADD_TOKEN_STR (awk, XP_T("&"));
} }
} }
else if (c == XP_T('~')) else if (c == XP_T('~'))
@ -3333,48 +3395,49 @@ static int __get_token (xp_awk_t* awk)
} }
else if (c == XP_T('+')) else if (c == XP_T('+'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('+')) if (c == XP_T('+'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_PLUSPLUS); SET_TOKEN_TYPE (awk, TOKEN_PLUSPLUS);
ADD_TOKEN_STR (awk, XP_T("++")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (c == XP_T('=')) else if (c == XP_T('='))
{ {
SET_TOKEN_TYPE (awk, TOKEN_PLUS_ASSIGN); SET_TOKEN_TYPE (awk, TOKEN_PLUS_ASSIGN);
ADD_TOKEN_STR (awk, XP_T("+=")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_PLUS); SET_TOKEN_TYPE (awk, TOKEN_PLUS);
ADD_TOKEN_STR (awk, XP_T("+"));
} }
} }
else if (c == XP_T('-')) else if (c == XP_T('-'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('-')) if (c == XP_T('-'))
{ {
SET_TOKEN_TYPE (awk, TOKEN_MINUSMINUS); SET_TOKEN_TYPE (awk, TOKEN_MINUSMINUS);
ADD_TOKEN_STR (awk, XP_T("--")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (c == XP_T('=')) else if (c == XP_T('='))
{ {
SET_TOKEN_TYPE (awk, TOKEN_MINUS_ASSIGN); SET_TOKEN_TYPE (awk, TOKEN_MINUS_ASSIGN);
ADD_TOKEN_STR (awk, XP_T("-=")); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_MINUS); SET_TOKEN_TYPE (awk, TOKEN_MINUS);
ADD_TOKEN_STR (awk, XP_T("-"));
} }
} }
else if (c == XP_T('*')) else if (c == XP_T('*'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('=')) if (c == XP_T('='))
@ -3385,6 +3448,7 @@ static int __get_token (xp_awk_t* awk)
} }
else if (c == XP_T('*')) else if (c == XP_T('*'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('=')) if (c == XP_T('='))
{ {
@ -3395,17 +3459,16 @@ static int __get_token (xp_awk_t* awk)
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_EXP); SET_TOKEN_TYPE (awk, TOKEN_EXP);
ADD_TOKEN_CHAR (awk, c);
} }
} }
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_MUL); SET_TOKEN_TYPE (awk, TOKEN_MUL);
ADD_TOKEN_CHAR (awk, c);
} }
} }
else if (c == XP_T('/')) else if (c == XP_T('/'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('=')) if (c == XP_T('='))
@ -3417,11 +3480,11 @@ static int __get_token (xp_awk_t* awk)
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_DIV); SET_TOKEN_TYPE (awk, TOKEN_DIV);
ADD_TOKEN_CHAR (awk, c);
} }
} }
else if (c == XP_T('%')) else if (c == XP_T('%'))
{ {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_T('=')) if (c == XP_T('='))
@ -3433,7 +3496,6 @@ static int __get_token (xp_awk_t* awk)
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_MOD); SET_TOKEN_TYPE (awk, TOKEN_MOD);
ADD_TOKEN_CHAR (awk, c);
} }
} }
else if (c == XP_T('(')) 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) 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); return __get_string (awk, XP_T('\"'), XP_T('\\'), xp_false);
} }
static int __get_rexstr (xp_awk_t* awk) 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); return __get_string (awk, XP_T('/'), XP_T('\\'), xp_true);
} }
@ -3772,7 +3846,7 @@ static int __get_string (
ADD_TOKEN_CHAR (awk, c); ADD_TOKEN_CHAR (awk, c);
} }
return 0; 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) static int __skip_spaces (xp_awk_t* awk)
{ {
xp_cint_t c = awk->lex.curc; xp_cint_t c = awk->lex.curc;
while (xp_isspace(c)) GET_CHAR_TO (awk, c); while (xp_isspace(c)) GET_CHAR_TO (awk, c);
return 0; return 0;
} }
@ -3904,7 +3979,8 @@ static int __skip_comment (xp_awk_t* awk)
return 0; 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; struct __kwent* kwp;
@ -3912,7 +3988,11 @@ static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident)
{ {
if (kwp->valid != 0 && if (kwp->valid != 0 &&
(awk->opt.parse & kwp->valid) == 0) continue; (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; 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) static int __assign_to_opcode (xp_awk_t* awk)
{ {
if (MATCH(awk,TOKEN_ASSIGN)) return XP_AWK_ASSOP_NONE; static int __assop[] =
if (MATCH(awk,TOKEN_PLUS_ASSIGN)) return XP_AWK_ASSOP_PLUS; {
if (MATCH(awk,TOKEN_MINUS_ASSIGN)) return XP_AWK_ASSOP_MINUS; XP_AWK_ASSOP_NONE,
if (MATCH(awk,TOKEN_MUL_ASSIGN)) return XP_AWK_ASSOP_MUL; XP_AWK_ASSOP_PLUS,
if (MATCH(awk,TOKEN_DIV_ASSIGN)) return XP_AWK_ASSOP_DIV; XP_AWK_ASSOP_MINUS,
if (MATCH(awk,TOKEN_MOD_ASSIGN)) return XP_AWK_ASSOP_MOD; XP_AWK_ASSOP_MUL,
if (MATCH(awk,TOKEN_EXP_ASSIGN)) return XP_AWK_ASSOP_EXP; 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; 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> #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 */ /* don't care about the result of input close */
xp_awk_closeextio_read ( xp_awk_closeextio_read (
run, XP_AWK_EXTIO_CONSOLE, XP_T(""), &errnum); run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
return -1; 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) if (__run_pattern_block_chain (run, run->awk->tree.chain) == -1)
{ {
xp_awk_closeextio_read ( xp_awk_closeextio_read (
run, XP_AWK_EXTIO_CONSOLE, XP_T(""), &errnum); run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
return -1; return -1;
} }
} }
@ -577,11 +577,11 @@ static int __run_pattern_blocks (xp_awk_run_t* run)
if (need_to_close) if (need_to_close)
{ {
n = xp_awk_closeextio_read ( 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 (n == -1)
{ {
if (errnum == XP_AWK_ENOERR) if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ETXTINCLOSE); PANIC_I (run, XP_AWK_ECONINCLOSE);
else else
PANIC_I (run, errnum); 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; xp_size_t saved_stack_top;
int n = 0; 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); xp_assert (nde->type == XP_AWK_NDE_BLK);
p = nde->body; 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 (n == -1)
{ {
if (errnum == XP_AWK_ENOERR) if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ETXTINNEXT); PANIC_I (run, XP_AWK_ECONINNEXT);
else else
PANIC_I (run, errnum); 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_PIPE && p->out != XP_NULL) ||
(p->out_type == XP_AWK_OUT_COPROC && 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 && 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)); (p->out_type == XP_AWK_OUT_CONSOLE && p->out == XP_NULL));
if (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 /* TODO: change xp_awk_val_nil to
* for performance improvement*/ * xp_awk_val_empty_string or something */
v = xp_awk_makestrval (XP_T("\n"), 1); n = xp_awk_writeextio_nl (
if (v == XP_NULL) run, p->out_type, dst, xp_awk_val_nil, &errnum);
{
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);
if (n < 0 && errnum != XP_AWK_ENOERR) if (n < 0 && errnum != XP_AWK_ENOERR)
{ {
if (out != XP_NULL) xp_free (out); if (out != XP_NULL) xp_free (out);
xp_awk_refdownval (run, v);
PANIC_I (run, errnum); 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... */ /* 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); xp_assert (right->next == XP_NULL);
lv = __eval_expression (run, left); lv = __eval_expression (run, left);
if (lv == XP_NULL) return XP_NULL; if (lv == XP_NULL)
{
return XP_NULL;
}
xp_awk_refupval (lv); xp_awk_refupval (lv);
@ -3006,7 +3024,7 @@ static xp_awk_val_t* __eval_binop_match0 (
} }
else 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 (str == XP_NULL)
{ {
if (right->type != XP_AWK_VAL_REX) xp_free (rex_code); 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 */ /*TODO: use RS */
n = xp_awk_readextio ( n = xp_awk_readextio (
run, XP_AWK_EXTIO_CONSOLE, run, XP_AWK_IN_CONSOLE,
XP_T(""), &run->inrec.line, &errnum); XP_T(""), &run->inrec.line, &errnum);
if (n < 0) if (n < 0)
{ {
if (errnum == XP_AWK_ENOERR) if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ETXTINDATA); PANIC_I (run, XP_AWK_ECONINDATA);
else else
PANIC_I (run, errnum); 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> #include <xp/awk/awk.h>
@ -522,7 +522,8 @@ static int __main (int argc, xp_char_t* argv[])
xp_awk_setparseopt (awk, xp_awk_setparseopt (awk,
XP_AWK_EXPLICIT | XP_AWK_UNIQUE | XP_AWK_DBLSLASHES | 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) 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/