*** empty log message ***
This commit is contained in:
parent
aaad83e199
commit
40c5fef59c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.h,v 1.86 2006-08-03 09:53:42 bacon Exp $
|
* $Id: awk.h,v 1.87 2006-08-03 15:49:37 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _XP_AWK_AWK_H_
|
#ifndef _XP_AWK_AWK_H_
|
||||||
@ -146,6 +146,8 @@ enum
|
|||||||
XP_AWK_EWHILE, /* keyword 'while' is expected */
|
XP_AWK_EWHILE, /* keyword 'while' is expected */
|
||||||
XP_AWK_EASSIGNMENT, /* assignment statement expected */
|
XP_AWK_EASSIGNMENT, /* assignment statement expected */
|
||||||
XP_AWK_EIDENT, /* identifier expected */
|
XP_AWK_EIDENT, /* identifier expected */
|
||||||
|
XP_AWK_EBEGINBLOCK, /* BEGIN requires an action block */
|
||||||
|
XP_AWK_EENDBLOCK, /* END requires an action block */
|
||||||
XP_AWK_EDUPBEGIN, /* duplicate BEGIN */
|
XP_AWK_EDUPBEGIN, /* duplicate BEGIN */
|
||||||
XP_AWK_EDUPEND, /* duplicate END */
|
XP_AWK_EDUPEND, /* duplicate END */
|
||||||
XP_AWK_EDUPFUNC, /* duplicate function name */
|
XP_AWK_EDUPFUNC, /* duplicate function name */
|
||||||
@ -175,6 +177,8 @@ enum
|
|||||||
XP_AWK_ENOTSCALARIZABLE, /* not scalarizable variable */
|
XP_AWK_ENOTSCALARIZABLE, /* not scalarizable variable */
|
||||||
XP_AWK_EVALTYPE, /* wrong value type */
|
XP_AWK_EVALTYPE, /* wrong value type */
|
||||||
XP_AWK_EPIPE, /* pipe operation error */
|
XP_AWK_EPIPE, /* pipe operation error */
|
||||||
|
XP_AWK_ENEXTCALL, /* next called from BEGIN or END */
|
||||||
|
XP_AWK_ENEXTFILECALL, /* nextfile called from BEGIN or END */
|
||||||
XP_AWK_EIOIMPL, /* wrong implementation of user io handler */
|
XP_AWK_EIOIMPL, /* wrong implementation of user io handler */
|
||||||
XP_AWK_EINTERNAL /* internal error */
|
XP_AWK_EINTERNAL /* internal error */
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk_i.h,v 1.37 2006-08-02 14:36:22 bacon Exp $
|
* $Id: awk_i.h,v 1.38 2006-08-03 15:49:37 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _XP_AWK_AWKI_H_
|
#ifndef _XP_AWK_AWKI_H_
|
||||||
@ -177,6 +177,8 @@ struct xp_awk_run_t
|
|||||||
xp_size_t icache_count;
|
xp_size_t icache_count;
|
||||||
xp_size_t rcache_count;
|
xp_size_t rcache_count;
|
||||||
|
|
||||||
|
xp_awk_nde_blk_t* active_block;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
xp_char_t buf[1024];
|
xp_char_t buf[1024];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: err.c,v 1.30 2006-08-03 09:53:42 bacon Exp $
|
* $Id: err.c,v 1.31 2006-08-03 15:49:37 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk_i.h>
|
#include <xp/awk/awk_i.h>
|
||||||
@ -64,6 +64,8 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
|
|||||||
XP_T("keyword 'while' expected"),
|
XP_T("keyword 'while' expected"),
|
||||||
XP_T("assignment statement expected"),
|
XP_T("assignment statement expected"),
|
||||||
XP_T("identifier expected"),
|
XP_T("identifier expected"),
|
||||||
|
XP_T("BEGIN requires an action block"),
|
||||||
|
XP_T("END requires an action block"),
|
||||||
XP_T("duplicate BEGIN"),
|
XP_T("duplicate BEGIN"),
|
||||||
XP_T("duplicate END"),
|
XP_T("duplicate END"),
|
||||||
XP_T("duplicate function name"),
|
XP_T("duplicate function name"),
|
||||||
@ -92,8 +94,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
|
|||||||
XP_T("variable not scalarizable"),
|
XP_T("variable not scalarizable"),
|
||||||
XP_T("wrong value type"),
|
XP_T("wrong value type"),
|
||||||
XP_T("pipe operation error"),
|
XP_T("pipe operation error"),
|
||||||
|
XP_T("next cannot be called from the BEGIN or END block"),
|
||||||
|
XP_T("nextfile cannot be called from the BEGIN or END block"),
|
||||||
XP_T("wrong implementation of user-defined io handler"),
|
XP_T("wrong implementation of user-defined io handler"),
|
||||||
|
|
||||||
XP_T("internal error that should never have happened")
|
XP_T("internal error that should never have happened")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: parse.c,v 1.154 2006-08-03 09:58:15 bacon Exp $
|
* $Id: parse.c,v 1.155 2006-08-03 15:49:37 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk_i.h>
|
#include <xp/awk/awk_i.h>
|
||||||
@ -102,12 +102,14 @@ enum
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PARSE_BLOCK_GLOBAL,
|
PARSE_GLOBAL,
|
||||||
PARSE_BLOCK_FUNCTION,
|
PARSE_FUNCTION,
|
||||||
PARSE_BLOCK_BEGIN,
|
PARSE_BEGIN,
|
||||||
PARSE_BLOCK_END,
|
PARSE_END,
|
||||||
PARSE_BLOCK_PATTERN,
|
PARSE_BEGIN_BLOCK,
|
||||||
PARSE_BLOCK_ACTION
|
PARSE_END_BLOCK,
|
||||||
|
PARSE_PATTERN,
|
||||||
|
PARSE_ACTION_BLOCK
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -139,7 +141,6 @@ static xp_awk_nde_t* __parse_end (xp_awk_t* awk);
|
|||||||
static xp_awk_chain_t* __parse_pattern_block (
|
static xp_awk_chain_t* __parse_pattern_block (
|
||||||
xp_awk_t* awk, xp_awk_nde_t* ptn, xp_bool_t blockless);
|
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);
|
static xp_awk_nde_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top);
|
||||||
static xp_awk_nde_t* __parse_statement (xp_awk_t* awk);
|
static xp_awk_nde_t* __parse_statement (xp_awk_t* awk);
|
||||||
static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk);
|
static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk);
|
||||||
@ -456,7 +457,7 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
|
|||||||
{
|
{
|
||||||
xp_size_t nglobals;
|
xp_size_t nglobals;
|
||||||
|
|
||||||
awk->parse.id.block = PARSE_BLOCK_GLOBAL;
|
awk->parse.id.block = PARSE_GLOBAL;
|
||||||
|
|
||||||
if (__get_token(awk) == -1) return XP_NULL;
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
|
||||||
@ -471,23 +472,49 @@ 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_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_BEGIN;
|
||||||
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
|
||||||
|
if ((awk->opt.parse & XP_AWK_BLOCKLESS) &&
|
||||||
|
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
|
||||||
|
{
|
||||||
|
/* when the blockless pattern is supported
|
||||||
|
* BEGIN and { should be located on the same line */
|
||||||
|
PANIC (awk, XP_AWK_EBEGINBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
|
||||||
|
|
||||||
|
awk->parse.id.block = PARSE_BEGIN_BLOCK;
|
||||||
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_END;
|
||||||
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
|
||||||
|
if ((awk->opt.parse & XP_AWK_BLOCKLESS) &&
|
||||||
|
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
|
||||||
|
{
|
||||||
|
/* when the blockless pattern is supported
|
||||||
|
* END and { should be located on the same line */
|
||||||
|
PANIC (awk, XP_AWK_EENDBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
|
||||||
|
|
||||||
|
awk->parse.id.block = PARSE_END_BLOCK;
|
||||||
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))
|
||||||
{
|
{
|
||||||
/* patternless block */
|
/* patternless block */
|
||||||
awk->parse.id.block = PARSE_BLOCK_ACTION;
|
awk->parse.id.block = PARSE_ACTION_BLOCK;
|
||||||
if (__parse_pattern_block (
|
if (__parse_pattern_block (
|
||||||
awk, XP_NULL, xp_false) == XP_NULL) return XP_NULL;
|
awk, XP_NULL, xp_false) == XP_NULL) return XP_NULL;
|
||||||
}
|
}
|
||||||
@ -504,7 +531,7 @@ 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;
|
awk->parse.id.block = PARSE_PATTERN;
|
||||||
|
|
||||||
ptn = __parse_expression (awk);
|
ptn = __parse_expression (awk);
|
||||||
if (ptn == XP_NULL) return XP_NULL;
|
if (ptn == XP_NULL) return XP_NULL;
|
||||||
@ -531,10 +558,9 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
|
|||||||
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
|
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
|
||||||
{
|
{
|
||||||
/* blockless pattern */
|
/* blockless pattern */
|
||||||
|
|
||||||
xp_bool_t newline = MATCH(awk,TOKEN_NEWLINE);
|
xp_bool_t newline = MATCH(awk,TOKEN_NEWLINE);
|
||||||
|
|
||||||
awk->parse.id.block = PARSE_BLOCK_ACTION;
|
awk->parse.id.block = PARSE_ACTION_BLOCK;
|
||||||
if (__parse_pattern_block (
|
if (__parse_pattern_block (
|
||||||
awk, ptn, xp_true) == XP_NULL)
|
awk, ptn, xp_true) == XP_NULL)
|
||||||
{
|
{
|
||||||
@ -554,14 +580,13 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* parse the action block */
|
/* parse the action block */
|
||||||
|
|
||||||
if (!MATCH(awk,TOKEN_LBRACE))
|
if (!MATCH(awk,TOKEN_LBRACE))
|
||||||
{
|
{
|
||||||
xp_awk_clrpt (ptn);
|
xp_awk_clrpt (ptn);
|
||||||
PANIC (awk, XP_AWK_ELBRACE);
|
PANIC (awk, XP_AWK_ELBRACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
awk->parse.id.block = PARSE_BLOCK_ACTION;
|
awk->parse.id.block = PARSE_ACTION_BLOCK;
|
||||||
if (__parse_pattern_block (
|
if (__parse_pattern_block (
|
||||||
awk, ptn, xp_false) == XP_NULL)
|
awk, ptn, xp_false) == XP_NULL)
|
||||||
{
|
{
|
||||||
@ -586,6 +611,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* eat up the keyword 'function' and get the next token */
|
/* eat up the keyword 'function' and get the next token */
|
||||||
|
xp_assert (MATCH(awk,TOKEN_FUNCTION));
|
||||||
if (__get_token(awk) == -1) return XP_NULL;
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
|
||||||
/* match a function name */
|
/* match a function name */
|
||||||
@ -802,10 +828,10 @@ static xp_awk_nde_t* __parse_begin (xp_awk_t* awk)
|
|||||||
{
|
{
|
||||||
xp_awk_nde_t* nde;
|
xp_awk_nde_t* nde;
|
||||||
|
|
||||||
if (awk->tree.begin != XP_NULL) PANIC (awk, XP_AWK_EDUPBEGIN);
|
xp_assert (MATCH(awk,TOKEN_LBRACE));
|
||||||
if (__get_token(awk) == -1) return XP_NULL;
|
|
||||||
|
|
||||||
nde = __parse_action (awk);
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
nde = __parse_block(awk, xp_true);
|
||||||
if (nde == XP_NULL) return XP_NULL;
|
if (nde == XP_NULL) return XP_NULL;
|
||||||
|
|
||||||
awk->tree.begin = nde;
|
awk->tree.begin = nde;
|
||||||
@ -816,10 +842,10 @@ static xp_awk_nde_t* __parse_end (xp_awk_t* awk)
|
|||||||
{
|
{
|
||||||
xp_awk_nde_t* nde;
|
xp_awk_nde_t* nde;
|
||||||
|
|
||||||
if (awk->tree.end != XP_NULL) PANIC (awk, XP_AWK_EDUPEND);
|
xp_assert (MATCH(awk,TOKEN_LBRACE));
|
||||||
if (__get_token(awk) == -1) return XP_NULL;
|
|
||||||
|
|
||||||
nde = __parse_action (awk);
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
nde = __parse_block(awk, xp_true);
|
||||||
if (nde == XP_NULL) return XP_NULL;
|
if (nde == XP_NULL) return XP_NULL;
|
||||||
|
|
||||||
awk->tree.end = nde;
|
awk->tree.end = nde;
|
||||||
@ -835,7 +861,9 @@ static xp_awk_chain_t* __parse_pattern_block (
|
|||||||
if (blockless) nde = XP_NULL;
|
if (blockless) nde = XP_NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nde = __parse_action (awk);
|
xp_assert (MATCH(awk,TOKEN_LBRACE));
|
||||||
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
nde = __parse_block(awk, xp_true);
|
||||||
if (nde == XP_NULL) return XP_NULL;
|
if (nde == XP_NULL) return XP_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,13 +893,6 @@ static xp_awk_chain_t* __parse_pattern_block (
|
|||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xp_awk_nde_t* __parse_action (xp_awk_t* awk)
|
|
||||||
{
|
|
||||||
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
|
|
||||||
if (__get_token(awk) == -1) return XP_NULL;
|
|
||||||
return __parse_block(awk, xp_true);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
xp_awk_nde_t* head, * curr, * nde;
|
xp_awk_nde_t* head, * curr, * nde;
|
||||||
@ -3160,8 +3181,8 @@ 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 ||
|
if (awk->parse.id.block == PARSE_BEGIN_BLOCK ||
|
||||||
awk->parse.id.block == PARSE_BLOCK_END)
|
awk->parse.id.block == PARSE_END_BLOCK)
|
||||||
{
|
{
|
||||||
PANIC (awk, XP_AWK_ENEXT);
|
PANIC (awk, XP_AWK_ENEXT);
|
||||||
}
|
}
|
||||||
@ -3178,8 +3199,8 @@ 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 ||
|
if (awk->parse.id.block == PARSE_BEGIN_BLOCK ||
|
||||||
awk->parse.id.block == PARSE_BLOCK_END)
|
awk->parse.id.block == PARSE_END_BLOCK)
|
||||||
{
|
{
|
||||||
PANIC (awk, XP_AWK_ENEXTFILE);
|
PANIC (awk, XP_AWK_ENEXTFILE);
|
||||||
}
|
}
|
||||||
@ -3207,13 +3228,14 @@ 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) &&
|
if (line != 0 && (awk->opt.parse & XP_AWK_BLOCKLESS) &&
|
||||||
awk->parse.id.block == PARSE_BLOCK_PATTERN)
|
(awk->parse.id.block == PARSE_PATTERN ||
|
||||||
|
awk->parse.id.block == PARSE_BEGIN ||
|
||||||
|
awk->parse.id.block == PARSE_END))
|
||||||
{
|
{
|
||||||
if (awk->token.line != line)
|
if (awk->token.line != line)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: run.c,v 1.158 2006-08-03 09:53:45 bacon Exp $
|
* $Id: run.c,v 1.159 2006-08-03 15:49:37 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk_i.h>
|
#include <xp/awk/awk_i.h>
|
||||||
@ -458,6 +458,7 @@ static int __run_main (xp_awk_run_t* run)
|
|||||||
blk = (xp_awk_nde_blk_t*)run->awk->tree.begin;
|
blk = (xp_awk_nde_blk_t*)run->awk->tree.begin;
|
||||||
xp_assert (blk->type == XP_AWK_NDE_BLK);
|
xp_assert (blk->type == XP_AWK_NDE_BLK);
|
||||||
|
|
||||||
|
run->active_block = blk;
|
||||||
run->exit_level = EXIT_NONE;
|
run->exit_level = EXIT_NONE;
|
||||||
if (__run_block (run, blk) == -1) n = -1;
|
if (__run_block (run, blk) == -1) n = -1;
|
||||||
}
|
}
|
||||||
@ -474,6 +475,7 @@ static int __run_main (xp_awk_run_t* run)
|
|||||||
blk = (xp_awk_nde_blk_t*)run->awk->tree.end;
|
blk = (xp_awk_nde_blk_t*)run->awk->tree.end;
|
||||||
xp_assert (blk->type == XP_AWK_NDE_BLK);
|
xp_assert (blk->type == XP_AWK_NDE_BLK);
|
||||||
|
|
||||||
|
run->active_block = blk;
|
||||||
run->exit_level = EXIT_NONE;
|
run->exit_level = EXIT_NONE;
|
||||||
if (__run_block (run, blk) == -1) n = -1;
|
if (__run_block (run, blk) == -1) n = -1;
|
||||||
}
|
}
|
||||||
@ -619,6 +621,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
|
|||||||
if (ptn == XP_NULL)
|
if (ptn == XP_NULL)
|
||||||
{
|
{
|
||||||
/* just execute the block */
|
/* just execute the block */
|
||||||
|
run->active_block = blk;
|
||||||
if (__run_block (run, blk) == -1) return -1;
|
if (__run_block (run, blk) == -1) return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -635,6 +638,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
|
|||||||
|
|
||||||
if (xp_awk_valtobool(v1))
|
if (xp_awk_valtobool(v1))
|
||||||
{
|
{
|
||||||
|
run->active_block = blk;
|
||||||
if (__run_block (run, blk) == -1)
|
if (__run_block (run, blk) == -1)
|
||||||
{
|
{
|
||||||
xp_awk_refdownval (run, v1);
|
xp_awk_refdownval (run, v1);
|
||||||
@ -659,6 +663,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
|
|||||||
|
|
||||||
if (xp_awk_valtobool(v1))
|
if (xp_awk_valtobool(v1))
|
||||||
{
|
{
|
||||||
|
run->active_block = blk;
|
||||||
if (__run_block (run, blk) == -1)
|
if (__run_block (run, blk) == -1)
|
||||||
{
|
{
|
||||||
xp_awk_refdownval (run, v1);
|
xp_awk_refdownval (run, v1);
|
||||||
@ -678,6 +683,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
|
|||||||
if (v2 == XP_NULL) return -1;
|
if (v2 == XP_NULL) return -1;
|
||||||
xp_awk_refupval (v2);
|
xp_awk_refupval (v2);
|
||||||
|
|
||||||
|
run->active_block = blk;
|
||||||
if (__run_block (run, blk) == -1)
|
if (__run_block (run, blk) == -1)
|
||||||
{
|
{
|
||||||
xp_awk_refdownval (run, v2);
|
xp_awk_refdownval (run, v2);
|
||||||
@ -1164,7 +1170,6 @@ static int __run_continue (xp_awk_run_t* run, xp_awk_nde_continue_t* nde)
|
|||||||
|
|
||||||
static int __run_return (xp_awk_run_t* run, xp_awk_nde_return_t* nde)
|
static int __run_return (xp_awk_run_t* run, xp_awk_nde_return_t* nde)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (nde->val != XP_NULL)
|
if (nde->val != XP_NULL)
|
||||||
{
|
{
|
||||||
xp_awk_val_t* val;
|
xp_awk_val_t* val;
|
||||||
@ -1212,19 +1217,33 @@ static int __run_exit (xp_awk_run_t* run, xp_awk_nde_exit_t* nde)
|
|||||||
|
|
||||||
static int __run_next (xp_awk_run_t* run, xp_awk_nde_next_t* nde)
|
static int __run_next (xp_awk_run_t* run, xp_awk_nde_next_t* nde)
|
||||||
{
|
{
|
||||||
/* TODO: trigger an error if "next" is called from BEGIN or END */
|
/* the parser checks if next has been called in the begin/end
|
||||||
|
* block or whereever inappropriate. so the runtime doesn't
|
||||||
|
* check that explicitly */
|
||||||
|
|
||||||
|
if (run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.begin ||
|
||||||
|
run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.end)
|
||||||
|
{
|
||||||
|
PANIC_I (run, XP_AWK_ENEXTCALL);
|
||||||
|
}
|
||||||
|
|
||||||
run->exit_level = EXIT_NEXT;
|
run->exit_level = EXIT_NEXT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __run_nextfile (xp_awk_run_t* run, xp_awk_nde_nextfile_t* nde)
|
static int __run_nextfile (xp_awk_run_t* run, xp_awk_nde_nextfile_t* nde)
|
||||||
{
|
{
|
||||||
/* TODO: trigger an error if "nextfile" is called from BEGIN or END */
|
|
||||||
/* TODO: some extentions such as nextfile "in/out";
|
/* TODO: some extentions such as nextfile "in/out";
|
||||||
* what about awk -i in1,in2,in3 -o out1,out2,out3 ?
|
* what about awk -i in1,in2,in3 -o out1,out2,out3 ?
|
||||||
*/
|
*/
|
||||||
int n, errnum;
|
int n, errnum;
|
||||||
|
|
||||||
|
if (run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.begin ||
|
||||||
|
run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.end)
|
||||||
|
{
|
||||||
|
PANIC_I (run, XP_AWK_ENEXTFILECALL);
|
||||||
|
}
|
||||||
|
|
||||||
n = xp_awk_nextextio_read (
|
n = xp_awk_nextextio_read (
|
||||||
run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
|
run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
|
13
ase/test/awk/t26.awk
Normal file
13
ase/test/awk/t26.awk
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function call_next ()
|
||||||
|
{
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
//call_next ();
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
call_next ();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user