*** empty log message ***

This commit is contained in:
hyung-hwan 2006-08-01 15:57:43 +00:00
parent 47b8fc75d6
commit 389dcc0e88
10 changed files with 126 additions and 17 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.62 2006-07-30 15:53:42 bacon Exp $ * $Id: awk.c,v 1.63 2006-08-01 15:57:42 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -123,6 +123,7 @@ void xp_awk_clear (xp_awk_t* awk)
xp_awk_tab_clear (&awk->parse.params); xp_awk_tab_clear (&awk->parse.params);
awk->parse.nlocals_max = 0; awk->parse.nlocals_max = 0;
awk->parse.depth.loop = 0;
/* clear parse trees */ /* clear parse trees */
awk->tree.nglobals = 0; awk->tree.nglobals = 0;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.84 2006-07-30 15:53:42 bacon Exp $ * $Id: awk.h,v 1.85 2006-08-01 15:57:42 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -148,6 +148,10 @@ enum
XP_AWK_ELVALUE, /* l-value required */ XP_AWK_ELVALUE, /* l-value required */
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_EBREAK, /* break outside a loop */
XP_AWK_ECONTINUE, /* continue outside a loop */
XP_AWK_ENEXT, /* next illegal in BEGIN or END block */
XP_AWK_ENEXTFILE, /* nextfile illegal in BEGIN or END block */
XP_AWK_EGETLINE, /* getline expected */ XP_AWK_EGETLINE, /* getline expected */
XP_AWK_EREXBUILD, /* cannot build regexp */ XP_AWK_EREXBUILD, /* cannot build regexp */
XP_AWK_EREXMATCH, /* an error occurred in matching regexp */ XP_AWK_EREXMATCH, /* an error occurred in matching regexp */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk_i.h,v 1.35 2006-07-27 16:50:28 bacon Exp $ * $Id: awk_i.h,v 1.36 2006-08-01 15:57:42 bacon Exp $
*/ */
#ifndef _XP_AWK_AWKI_H_ #ifndef _XP_AWK_AWKI_H_
@ -93,10 +93,22 @@ struct xp_awk_t
/* parse tree */ /* parse tree */
xp_awk_tree_t tree; xp_awk_tree_t tree;
int state;
/* temporary information that the parser needs */ /* temporary information that the parser needs */
struct struct
{ {
struct
{
int block;
int loop;
} id;
struct
{
xp_size_t loop;
} depth;
xp_awk_tab_t globals; xp_awk_tab_t globals;
xp_awk_tab_t locals; xp_awk_tab_t locals;
xp_awk_tab_t params; xp_awk_tab_t params;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: err.c,v 1.28 2006-07-26 16:43:35 bacon Exp $ * $Id: err.c,v 1.29 2006-08-01 15:57:42 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -69,6 +69,10 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_T("l-value required"), XP_T("l-value required"),
XP_T("too few arguments"), XP_T("too few arguments"),
XP_T("too many arguments"), XP_T("too many arguments"),
XP_T("break outside a loop"),
XP_T("continue outside a loop"),
XP_T("next illegal in BEGIN or END block"),
XP_T("nextfile illegal in BEGIN or END block"),
XP_T("getline expected"), XP_T("getline expected"),
XP_T("cannot build the regular expression"), XP_T("cannot build the regular expression"),
XP_T("an error occurred in the regular expression match"), XP_T("an error occurred in the regular expression match"),

View File

@ -1,5 +1,5 @@
/* /*
* $Id: extio.c,v 1.22 2006-07-30 15:53:42 bacon Exp $ * $Id: extio.c,v 1.23 2006-08-01 15:57:42 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -415,7 +415,8 @@ int xp_awk_nextextio_read (
return n; return n;
} }
int xp_awk_closeextio (xp_awk_run_t* run, const xp_char_t* name, int* errnum) int xp_awk_closeextio (
xp_awk_run_t* run, const xp_char_t* name, int* errnum)
{ {
xp_awk_extio_t* p = run->extio, * px = XP_NULL; xp_awk_extio_t* p = run->extio, * px = XP_NULL;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.147 2006-08-01 04:40:14 bacon Exp $ * $Id: parse.c,v 1.148 2006-08-01 15:57:42 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -97,6 +97,23 @@ enum
__TOKEN_COUNT__ __TOKEN_COUNT__
}; };
enum
{
PARSE_BLOCK_GLOBAL,
PARSE_BLOCK_FUNCTION,
PARSE_BLOCK_BEGIN,
PARSE_BLOCK_END,
PARSE_BLOCK_PATTERN
};
enum
{
PARSE_LOOP_NONE,
PARSE_LOOP_WHILE,
PARSE_LOOP_FOR,
PARSE_LOOP_DOWHILE
};
typedef struct __binmap_t __binmap_t; typedef struct __binmap_t __binmap_t;
struct __binmap_t struct __binmap_t
@ -415,10 +432,14 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
function name (parameter-list) { statement } function name (parameter-list) { statement }
*/ */
xp_assert (awk->parse.depth.loop == 0);
if ((awk->opt.parse & XP_AWK_EXPLICIT) && MATCH(awk,TOKEN_GLOBAL)) if ((awk->opt.parse & XP_AWK_EXPLICIT) && MATCH(awk,TOKEN_GLOBAL))
{ {
xp_size_t nglobals; xp_size_t nglobals;
awk->parse.id.block = PARSE_BLOCK_GLOBAL;
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);
@ -432,19 +453,23 @@ 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;
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;
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;
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 */ /* pattern less block */
awk->parse.id.block = PARSE_BLOCK_PATTERN;
if (__parse_ptnblock(awk,XP_NULL) == XP_NULL) return XP_NULL; if (__parse_ptnblock(awk,XP_NULL) == XP_NULL) return XP_NULL;
} }
else else
@ -460,6 +485,8 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
*/ */
xp_awk_nde_t* ptn; xp_awk_nde_t* ptn;
awk->parse.id.block = PARSE_BLOCK_PATTERN;
ptn = __parse_expression (awk); ptn = __parse_expression (awk);
if (ptn == XP_NULL) return XP_NULL; if (ptn == XP_NULL) return XP_NULL;
@ -1083,12 +1110,22 @@ static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk)
else if (MATCH(awk,TOKEN_WHILE)) else if (MATCH(awk,TOKEN_WHILE))
{ {
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
return __parse_while (awk);
awk->parse.depth.loop++;
nde = __parse_while (awk);
awk->parse.depth.loop--;
return nde;
} }
else if (MATCH(awk,TOKEN_FOR)) else if (MATCH(awk,TOKEN_FOR))
{ {
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
return __parse_for (awk);
awk->parse.depth.loop++;
nde = __parse_for (awk);
awk->parse.depth.loop--;
return nde;
} }
/* /*
@ -1097,7 +1134,12 @@ static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk)
if (MATCH(awk,TOKEN_DO)) if (MATCH(awk,TOKEN_DO))
{ {
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
awk->parse.depth.loop++;
nde = __parse_dowhile (awk); nde = __parse_dowhile (awk);
awk->parse.depth.loop--;
return nde;
} }
else if (MATCH(awk,TOKEN_BREAK)) else if (MATCH(awk,TOKEN_BREAK))
{ {
@ -2815,6 +2857,8 @@ static xp_awk_nde_t* __parse_break (xp_awk_t* awk)
{ {
xp_awk_nde_break_t* nde; xp_awk_nde_break_t* nde;
if (awk->parse.depth.loop <= 0) PANIC (awk, XP_AWK_EBREAK);
nde = (xp_awk_nde_break_t*) xp_malloc (xp_sizeof(xp_awk_nde_break_t)); nde = (xp_awk_nde_break_t*) xp_malloc (xp_sizeof(xp_awk_nde_break_t));
if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
nde->type = XP_AWK_NDE_BREAK; nde->type = XP_AWK_NDE_BREAK;
@ -2827,6 +2871,8 @@ static xp_awk_nde_t* __parse_continue (xp_awk_t* awk)
{ {
xp_awk_nde_continue_t* nde; xp_awk_nde_continue_t* nde;
if (awk->parse.depth.loop <= 0) PANIC (awk, XP_AWK_ECONTINUE);
nde = (xp_awk_nde_continue_t*)xp_malloc(xp_sizeof(xp_awk_nde_continue_t)); nde = (xp_awk_nde_continue_t*)xp_malloc(xp_sizeof(xp_awk_nde_continue_t));
if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
nde->type = XP_AWK_NDE_CONTINUE; nde->type = XP_AWK_NDE_CONTINUE;
@ -3047,6 +3093,12 @@ static xp_awk_nde_t* __parse_next (xp_awk_t* awk)
{ {
xp_awk_nde_next_t* nde; xp_awk_nde_next_t* nde;
if (awk->parse.id.block == PARSE_BLOCK_BEGIN ||
awk->parse.id.block == PARSE_BLOCK_END)
{
PANIC (awk, XP_AWK_ENEXT);
}
nde = (xp_awk_nde_next_t*) xp_malloc (xp_sizeof(xp_awk_nde_next_t)); nde = (xp_awk_nde_next_t*) xp_malloc (xp_sizeof(xp_awk_nde_next_t));
if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
nde->type = XP_AWK_NDE_NEXT; nde->type = XP_AWK_NDE_NEXT;
@ -3059,6 +3111,12 @@ static xp_awk_nde_t* __parse_nextfile (xp_awk_t* awk)
{ {
xp_awk_nde_nextfile_t* nde; xp_awk_nde_nextfile_t* nde;
if (awk->parse.id.block == PARSE_BLOCK_BEGIN ||
awk->parse.id.block == PARSE_BLOCK_END)
{
PANIC (awk, XP_AWK_ENEXTFILE);
}
nde = (xp_awk_nde_nextfile_t*) nde = (xp_awk_nde_nextfile_t*)
xp_malloc (xp_sizeof(xp_awk_nde_nextfile_t)); xp_malloc (xp_sizeof(xp_awk_nde_nextfile_t));
if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: run.c,v 1.148 2006-08-01 04:40:14 bacon Exp $ * $Id: run.c,v 1.149 2006-08-01 15:57:43 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -528,6 +528,7 @@ xp_printf (XP_T("-[END VARIABLES]--------------------------\n"));
static int __run_pattern_blocks (xp_awk_run_t* run) static int __run_pattern_blocks (xp_awk_run_t* run)
{ {
xp_ssize_t n; xp_ssize_t n;
xp_bool_t need_to_close = xp_false;
int errnum; int errnum;
run->inrec.buf_pos = 0; run->inrec.buf_pos = 0;
@ -549,6 +550,7 @@ static int __run_pattern_blocks (xp_awk_run_t* run)
return -1; return -1;
} }
need_to_close = xp_true;
if (x == 0) break; /* end of input */ if (x == 0) break; /* end of input */
if (__run_pattern_block_chain (run, run->awk->tree.chain) == -1) if (__run_pattern_block_chain (run, run->awk->tree.chain) == -1)
@ -565,13 +567,16 @@ static int __run_pattern_blocks (xp_awk_run_t* run)
* pattern-block loop, which is totally different from getline. * pattern-block loop, which is totally different from getline.
* So it just returns -1 as long as closeextio returns -1 regardless * So it just returns -1 as long as closeextio returns -1 regardless
* of the value of errnum */ * of the value of errnum */
n = xp_awk_closeextio (run, XP_T(""), &errnum); if (need_to_close)
if (n == -1)
{ {
if (errnum == XP_AWK_ENOERR) n = xp_awk_closeextio (run, XP_T(""), &errnum);
PANIC_I (run, XP_AWK_ETXTINCLOSE); if (n == -1)
else {
PANIC_I (run, errnum); if (errnum == XP_AWK_ENOERR)
PANIC_I (run, XP_AWK_ETXTINCLOSE);
else
PANIC_I (run, errnum);
}
} }
return 0; return 0;
@ -2824,6 +2829,7 @@ static xp_awk_val_t* __eval_binop_ma (
if (lv == XP_NULL) return XP_NULL; if (lv == XP_NULL) return XP_NULL;
xp_awk_refupval (lv); xp_awk_refupval (lv);
rv = __eval_expression0 (run, right); rv = __eval_expression0 (run, right);
if (rv == XP_NULL) if (rv == XP_NULL)
{ {
@ -2853,6 +2859,7 @@ static xp_awk_val_t* __eval_binop_nm (
if (lv == XP_NULL) return XP_NULL; if (lv == XP_NULL) return XP_NULL;
xp_awk_refupval (lv); xp_awk_refupval (lv);
rv = __eval_expression0 (run, right); rv = __eval_expression0 (run, right);
if (rv == XP_NULL) if (rv == XP_NULL)
{ {

View File

@ -2,7 +2,7 @@
/a\/b/ { /a\/b/ {
print $0 ~ /abc/; print $0 ~ /abc/;
print $0 !~ /abc/; print $0 !~ /abc/;
print $0 ~ "abc[[:space]]"; print $0 ~ "abc[[:space:]]";
print $0 !~ "abc"; print $0 !~ "abc";
print /abc/; print /abc/;
} }

7
ase/test/awk/t21.awk Normal file
View File

@ -0,0 +1,7 @@
BEGIN { exit 10; }
{
print $0;
}
END { print "== END OF PROGRAM =="; }

15
ase/test/awk/t22.awk Normal file
View File

@ -0,0 +1,15 @@
//BEGIN { exit 10; }
//{ while (1) {if (x == 20) continue; if (a) break; while (10) break; }}
//END { while (1) {if (x == 20) continue; if (a) break; while (10) break; }}
{
//return 20;
print getline abc < "";
print "[[" abc "]]";
print close("");
//exit 20;
}
END { print "end";