*** empty log message ***
This commit is contained in:
parent
47b8fc75d6
commit
389dcc0e88
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
@ -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"),
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
7
ase/test/awk/t21.awk
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
BEGIN { exit 10; }
|
||||||
|
|
||||||
|
{
|
||||||
|
print $0;
|
||||||
|
}
|
||||||
|
|
||||||
|
END { print "== END OF PROGRAM =="; }
|
15
ase/test/awk/t22.awk
Normal file
15
ase/test/awk/t22.awk
Normal 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";
|
Loading…
Reference in New Issue
Block a user