implemented @include partially

This commit is contained in:
hyung-hwan 2009-07-27 20:31:58 +00:00
parent 90955d1b0a
commit 0da1c65cf5
10 changed files with 420 additions and 230 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c 239 2009-07-18 12:02:24Z hyunghwan.chung $ * $Id: awk.c 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -729,6 +729,7 @@ static int awk_main (int argc, qse_char_t* argv[])
awk, QSE_AWK_DEPTH_BLOCK_PARSE | QSE_AWK_DEPTH_EXPR_PARSE, 50); awk, QSE_AWK_DEPTH_BLOCK_PARSE | QSE_AWK_DEPTH_EXPR_PARSE, 50);
qse_awk_setmaxdepth ( qse_awk_setmaxdepth (
awk, QSE_AWK_DEPTH_BLOCK_RUN | QSE_AWK_DEPTH_EXPR_RUN, 500); awk, QSE_AWK_DEPTH_BLOCK_RUN | QSE_AWK_DEPTH_EXPR_RUN, 500);
qse_awk_setmaxdepth (awk, QSE_AWK_DEPTH_INCLUDE, 32);
if (qse_awk_addfnc (awk, if (qse_awk_addfnc (awk,
QSE_T("sleep"), 5, 0, QSE_T("sleep"), 5, 0,

View File

@ -1,5 +1,5 @@
/* /*
* $Id: Awk.hpp 245 2009-07-25 05:18:42Z hyunghwan.chung $ * $Id: Awk.hpp 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -56,6 +56,10 @@ public:
typedef qse_awk_rio_cmd_t rio_cmd_t; typedef qse_awk_rio_cmd_t rio_cmd_t;
typedef qse_awk_sio_arg_t sio_arg_t;
typedef qse_awk_sio_cmd_t sio_cmd_t;
class Run; class Run;
friend class Run; friend class Run;
@ -111,8 +115,6 @@ public:
ERR_FUNNAME = QSE_AWK_EFUNNAME, ERR_FUNNAME = QSE_AWK_EFUNNAME,
ERR_BLKBEG = QSE_AWK_EBLKBEG, ERR_BLKBEG = QSE_AWK_EBLKBEG,
ERR_BLKEND = QSE_AWK_EBLKEND, ERR_BLKEND = QSE_AWK_EBLKEND,
ERR_DUPBEG = QSE_AWK_EDUPBEG,
ERR_DUPEND = QSE_AWK_EDUPEND,
ERR_KWRED = QSE_AWK_EKWRED, ERR_KWRED = QSE_AWK_EKWRED,
ERR_FNCRED = QSE_AWK_EFNCRED, ERR_FNCRED = QSE_AWK_EFNCRED,
ERR_FUNRED = QSE_AWK_EFUNRED, ERR_FUNRED = QSE_AWK_EFUNRED,
@ -140,6 +142,8 @@ public:
ERR_PREPST = QSE_AWK_EPREPST, ERR_PREPST = QSE_AWK_EPREPST,
ERR_INCDECOPR = QSE_AWK_EINCDECOPR, ERR_INCDECOPR = QSE_AWK_EINCDECOPR,
ERR_INCLSTR = QSE_AWK_EINCLSTR, ERR_INCLSTR = QSE_AWK_EINCLSTR,
ERR_INCLTD = QSE_AWK_EINCLTD,
ERR_DIRECNR = QSE_AWK_EDIRECNR,
ERR_DIVBY0 = QSE_AWK_EDIVBY0, ERR_DIVBY0 = QSE_AWK_EDIVBY0,
ERR_OPERAND = QSE_AWK_EOPERAND, ERR_OPERAND = QSE_AWK_EOPERAND,
ERR_POSIDX = QSE_AWK_EPOSIDX, ERR_POSIDX = QSE_AWK_EPOSIDX,
@ -1049,9 +1053,11 @@ protected:
// static glue members for various handlers // static glue members for various handlers
static ssize_t readSource ( static ssize_t readSource (
awk_t* awk, qse_awk_sio_cmd_t cmd, char_t* data, size_t count); awk_t* awk, sio_cmd_t cmd, sio_arg_t* arg,
char_t* data, size_t count);
static ssize_t writeSource ( static ssize_t writeSource (
awk_t* awk, qse_awk_sio_cmd_t cmd, char_t* data, size_t count); awk_t* awk, sio_cmd_t cmd, sio_arg_t* arg,
char_t* data, size_t count);
static ssize_t pipeHandler ( static ssize_t pipeHandler (
rtx_t* rtx, rio_cmd_t cmd, rio_arg_t* riod, rtx_t* rtx, rio_cmd_t cmd, rio_arg_t* riod,

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h 245 2009-07-25 05:18:42Z hyunghwan.chung $ * $Id: awk.h 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -276,6 +276,14 @@ struct qse_awk_sio_arg_t
qse_char_t* name; /**< [IN] name of I/O object */ qse_char_t* name; /**< [IN] name of I/O object */
void* handle; /**< [OUT] I/O handle set by a handler */ void* handle; /**< [OUT] I/O handle set by a handler */
/*-- from here down, internal use only --*/
struct
{
qse_char_t buf[1024];
qse_size_t pos;
qse_size_t len;
} b;
struct qse_awk_sio_arg_t* next; struct qse_awk_sio_arg_t* next;
}; };
typedef struct qse_awk_sio_arg_t qse_awk_sio_arg_t; typedef struct qse_awk_sio_arg_t qse_awk_sio_arg_t;
@ -653,8 +661,6 @@ enum qse_awk_errnum_t
QSE_AWK_EFUNNAME, /**< '${0}' not a valid function name */ QSE_AWK_EFUNNAME, /**< '${0}' not a valid function name */
QSE_AWK_EBLKBEG, /**< BEGIN not followed by left bracket on the same line */ QSE_AWK_EBLKBEG, /**< BEGIN not followed by left bracket on the same line */
QSE_AWK_EBLKEND, /**< END not followed by left bracket on the same line */ QSE_AWK_EBLKEND, /**< END not followed by left bracket on the same line */
QSE_AWK_EDUPBEG, /**< duplicate BEGIN */
QSE_AWK_EDUPEND, /**< duplicate END */
QSE_AWK_EKWRED, /**< keyword '${0}' redefined */ QSE_AWK_EKWRED, /**< keyword '${0}' redefined */
QSE_AWK_EFNCRED, /**< intrinsic function '${0}' redefined */ QSE_AWK_EFNCRED, /**< intrinsic function '${0}' redefined */
QSE_AWK_EFUNRED, /**< function '${0}' redefined */ QSE_AWK_EFUNRED, /**< function '${0}' redefined */
@ -684,6 +690,8 @@ enum qse_awk_errnum_t
QSE_AWK_EPREPST, /**< both prefix and postfix incr/decr operator present */ QSE_AWK_EPREPST, /**< both prefix and postfix incr/decr operator present */
QSE_AWK_EINCDECOPR,/**< illegal operand for incr/decr operator */ QSE_AWK_EINCDECOPR,/**< illegal operand for incr/decr operator */
QSE_AWK_EINCLSTR, /**< 'include' not followed by a string */ QSE_AWK_EINCLSTR, /**< 'include' not followed by a string */
QSE_AWK_EINCLTD, /**< include level too deep */
QSE_AWK_EDIRECNR, /**< directive '${0}' not recognized */
/* run time error */ /* run time error */
QSE_AWK_EDIVBY0, /**< divide by zero */ QSE_AWK_EDIVBY0, /**< divide by zero */
@ -773,7 +781,8 @@ enum qse_awk_depth_t
QSE_AWK_DEPTH_EXPR_PARSE = (1 << 2), QSE_AWK_DEPTH_EXPR_PARSE = (1 << 2),
QSE_AWK_DEPTH_EXPR_RUN = (1 << 3), QSE_AWK_DEPTH_EXPR_RUN = (1 << 3),
QSE_AWK_DEPTH_REX_BUILD = (1 << 4), QSE_AWK_DEPTH_REX_BUILD = (1 << 4),
QSE_AWK_DEPTH_REX_MATCH = (1 << 5) QSE_AWK_DEPTH_REX_MATCH = (1 << 5),
QSE_AWK_DEPTH_INCLUDE = (1 << 6)
}; };
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* $Id: Awk.cpp 239 2009-07-18 12:02:24Z hyunghwan.chung $ * $Id: Awk.cpp 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -1604,7 +1604,8 @@ void Awk::unsetAllWords ()
} }
Awk::ssize_t Awk::readSource ( Awk::ssize_t Awk::readSource (
awk_t* awk, qse_awk_sio_cmd_t cmd, char_t* data, size_t count) awk_t* awk, sio_cmd_t cmd, sio_arg_t* arg,
char_t* data, size_t count)
{ {
xtn_t* xtn = (xtn_t*) QSE_XTN (awk); xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
@ -1622,7 +1623,8 @@ Awk::ssize_t Awk::readSource (
} }
Awk::ssize_t Awk::writeSource ( Awk::ssize_t Awk::writeSource (
awk_t* awk, qse_awk_sio_cmd_t cmd, char_t* data, size_t count) awk_t* awk, qse_awk_sio_cmd_t cmd, sio_arg_t* arg,
char_t* data, size_t count)
{ {
xtn_t* xtn = (xtn_t*) QSE_XTN (awk); xtn_t* xtn = (xtn_t*) QSE_XTN (awk);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c 239 2009-07-18 12:02:24Z hyunghwan.chung $ * $Id: awk.c 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -67,6 +67,14 @@ static void fini_token (qse_awk_token_t* token)
} }
} }
static void clear_token (qse_awk_token_t* token)
{
if (token->name != QSE_NULL) qse_str_clear (token->name);
token->type = 0;
token->line = 0;
token->column = 0;
}
qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
{ {
qse_awk_t* awk; qse_awk_t* awk;
@ -105,7 +113,7 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
awk->prm = *prm; awk->prm = *prm;
if (init_token (mmgr, &awk->token) == -1) goto oops; if (init_token (mmgr, &awk->token) == -1) goto oops;
if (init_token (mmgr, &awk->atoken) == -1) goto oops; if (init_token (mmgr, &awk->ntoken) == -1) goto oops;
awk->wtab = qse_map_open (mmgr, QSE_SIZEOF(awk), 512, 70); awk->wtab = qse_map_open (mmgr, QSE_SIZEOF(awk), 512, 70);
if (awk->wtab == QSE_NULL) goto oops; if (awk->wtab == QSE_NULL) goto oops;
@ -165,14 +173,15 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
qse_lda_setcopier (awk->parse.params, QSE_LDA_COPIER_INLINE); qse_lda_setcopier (awk->parse.params, QSE_LDA_COPIER_INLINE);
qse_lda_setscale (awk->parse.params, QSE_SIZEOF(qse_char_t)); qse_lda_setscale (awk->parse.params, QSE_SIZEOF(qse_char_t));
awk->parse.nlcls_max = 0;
awk->sio.inp = &awk->sio.arg;
awk->option = QSE_AWK_CLASSIC; awk->option = QSE_AWK_CLASSIC;
awk->errinf.num = QSE_AWK_ENOERR; awk->errinf.num = QSE_AWK_ENOERR;
awk->errinf.lin = 0; awk->errinf.lin = 0;
awk->errstr = qse_awk_dflerrstr; awk->errstr = qse_awk_dflerrstr;
awk->stopall = QSE_FALSE; awk->stopall = QSE_FALSE;
awk->parse.nlcls_max = 0;
awk->tree.ngbls = 0; awk->tree.ngbls = 0;
awk->tree.ngbls_base = 0; awk->tree.ngbls_base = 0;
awk->tree.begin = QSE_NULL; awk->tree.begin = QSE_NULL;
@ -183,17 +192,6 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
awk->tree.chain_tail = QSE_NULL; awk->tree.chain_tail = QSE_NULL;
awk->tree.chain_size = 0; awk->tree.chain_size = 0;
awk->ptoken.type = 0;
awk->ptoken.line = 0;
awk->ptoken.column = 0;
awk->src.lex.curc = QSE_CHAR_EOF;
awk->src.lex.ungotc_count = 0;
awk->src.lex.line = 1;
awk->src.lex.column = 1;
awk->src.shared.buf_pos = 0;
awk->src.shared.buf_len = 0;
awk->fnc.sys = QSE_NULL; awk->fnc.sys = QSE_NULL;
awk->fnc.user = qse_map_open (mmgr, QSE_SIZEOF(awk), 512, 70); awk->fnc.user = qse_map_open (mmgr, QSE_SIZEOF(awk), 512, 70);
if (awk->fnc.user == QSE_NULL) goto oops; if (awk->fnc.user == QSE_NULL) goto oops;
@ -202,22 +200,10 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
qse_map_setfreeer (awk->fnc.user, QSE_MAP_VAL, free_fnc); qse_map_setfreeer (awk->fnc.user, QSE_MAP_VAL, free_fnc);
qse_map_setscale (awk->fnc.user, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t)); qse_map_setscale (awk->fnc.user, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
awk->parse.depth.cur.block = 0;
awk->parse.depth.cur.loop = 0;
awk->parse.depth.cur.expr = 0;
qse_awk_setmaxdepth (awk, QSE_AWK_DEPTH_BLOCK_PARSE, 0);
qse_awk_setmaxdepth (awk, QSE_AWK_DEPTH_BLOCK_RUN, 0);
qse_awk_setmaxdepth (awk, QSE_AWK_DEPTH_EXPR_PARSE, 0);
qse_awk_setmaxdepth (awk, QSE_AWK_DEPTH_EXPR_RUN, 0);
qse_awk_setmaxdepth (awk, QSE_AWK_DEPTH_REX_BUILD, 0);
qse_awk_setmaxdepth (awk, QSE_AWK_DEPTH_REX_MATCH, 0);
if (qse_awk_initgbls (awk) <= -1) goto oops; if (qse_awk_initgbls (awk) <= -1) goto oops;
return awk; return awk;
oops: oops:
if (awk->fnc.user) qse_map_close (awk->fnc.user); if (awk->fnc.user) qse_map_close (awk->fnc.user);
if (awk->parse.params) qse_lda_close (awk->parse.params); if (awk->parse.params) qse_lda_close (awk->parse.params);
@ -228,7 +214,7 @@ oops:
if (awk->tree.funs) qse_map_close (awk->tree.funs); if (awk->tree.funs) qse_map_close (awk->tree.funs);
if (awk->rwtab) qse_map_close (awk->rwtab); if (awk->rwtab) qse_map_close (awk->rwtab);
if (awk->wtab) qse_map_close (awk->wtab); if (awk->wtab) qse_map_close (awk->wtab);
fini_token (&awk->atoken); fini_token (&awk->ntoken);
fini_token (&awk->token); fini_token (&awk->token);
QSE_AWK_FREE (awk, awk); QSE_AWK_FREE (awk, awk);
@ -251,7 +237,7 @@ int qse_awk_close (qse_awk_t* awk)
qse_map_close (awk->rwtab); qse_map_close (awk->rwtab);
qse_map_close (awk->wtab); qse_map_close (awk->wtab);
fini_token (&awk->atoken); fini_token (&awk->ntoken);
fini_token (&awk->token); fini_token (&awk->token);
/* QSE_AWK_ALLOC, QSE_AWK_FREE, etc can not be used /* QSE_AWK_ALLOC, QSE_AWK_FREE, etc can not be used
@ -264,13 +250,21 @@ int qse_awk_clear (qse_awk_t* awk)
{ {
awk->stopall = QSE_FALSE; awk->stopall = QSE_FALSE;
QSE_MEMSET (&awk->src.ios, 0, QSE_SIZEOF(awk->src.ios)); awk->sio.lex.curc = QSE_CHAR_EOF;
awk->src.lex.curc = QSE_CHAR_EOF; awk->sio.lex.ungotc_count = 0;
awk->src.lex.ungotc_count = 0; awk->sio.lex.line = 1;
awk->src.lex.line = 1; awk->sio.lex.column = 1;
awk->src.lex.column = 1; awk->sio.arg.b.pos = 0;
awk->src.shared.buf_pos = 0; awk->sio.arg.b.len = 0;
awk->src.shared.buf_len = 0;
QSE_ASSERT (awk->sio.inp == &awk->sio.arg);
awk->ptoken.type = 0;
awk->ptoken.line = 0;
awk->ptoken.column = 0;
clear_token (&awk->token);
clear_token (&awk->ntoken);
QSE_ASSERT (QSE_LDA_SIZE(awk->parse.gbls) == awk->tree.ngbls); QSE_ASSERT (QSE_LDA_SIZE(awk->parse.gbls) == awk->tree.ngbls);
/* delete all non-builtin global variables */ /* delete all non-builtin global variables */
@ -287,9 +281,9 @@ int qse_awk_clear (qse_awk_t* awk)
awk->parse.depth.cur.block = 0; awk->parse.depth.cur.block = 0;
awk->parse.depth.cur.loop = 0; awk->parse.depth.cur.loop = 0;
awk->parse.depth.cur.expr = 0; awk->parse.depth.cur.expr = 0;
awk->parse.depth.cur.incl = 0;
/* clear parse trees */ /* clear parse trees */
awk->tree.ok = 0;
/*awk->tree.ngbls_base = 0; /*awk->tree.ngbls_base = 0;
awk->tree.ngbls = 0; */ awk->tree.ngbls = 0; */
awk->tree.ngbls = awk->tree.ngbls_base; awk->tree.ngbls = awk->tree.ngbls_base;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h 232 2009-07-14 08:06:14Z hyunghwan.chung $ * $Id: awk.h 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -140,12 +140,14 @@ struct qse_awk_t
qse_size_t block; qse_size_t block;
qse_size_t loop; qse_size_t loop;
qse_size_t expr; /* expression */ qse_size_t expr; /* expression */
qse_size_t incl;
} cur; } cur;
struct struct
{ {
qse_size_t block; qse_size_t block;
qse_size_t expr; qse_size_t expr;
qse_size_t incl;
} max; } max;
} depth; } depth;
@ -175,7 +177,8 @@ struct qse_awk_t
/* source code management */ /* source code management */
struct struct
{ {
qse_awk_sio_t ios; qse_awk_sio_fun_t inf;
qse_awk_sio_fun_t outf;
struct struct
{ {
@ -189,13 +192,9 @@ struct qse_awk_t
qse_size_t column; qse_size_t column;
} lex; } lex;
struct qse_awk_sio_arg_t arg;
{ qse_awk_sio_arg_t* inp; /* current input */
qse_char_t buf[512]; } sio;
qse_size_t buf_pos;
qse_size_t buf_len;
} shared;
} src;
/* previous token info excluding name */ /* previous token info excluding name */
struct struct
@ -207,7 +206,7 @@ struct qse_awk_t
/* current token */ /* current token */
qse_awk_token_t token; qse_awk_token_t token;
qse_awk_token_t atoken; qse_awk_token_t ntoken;
/* intrinsic functions */ /* intrinsic functions */
struct struct

View File

@ -1,5 +1,5 @@
/* /*
* $Id: err.c 245 2009-07-25 05:18:42Z hyunghwan.chung $ * $Id: err.c 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -70,8 +70,6 @@ const qse_char_t* qse_awk_dflerrstr (qse_awk_t* awk, qse_awk_errnum_t errnum)
QSE_T("'${0}' not a valid function name"), QSE_T("'${0}' not a valid function name"),
QSE_T("BEGIN not followed by left bracket on the same line"), QSE_T("BEGIN not followed by left bracket on the same line"),
QSE_T("END not followed by left bracket on the same line"), QSE_T("END not followed by left bracket on the same line"),
QSE_T("duplicate BEGIN"),
QSE_T("duplicate END"),
QSE_T("keyword '${0}' redefined"), QSE_T("keyword '${0}' redefined"),
QSE_T("intrinsic function '${0}' redefined"), QSE_T("intrinsic function '${0}' redefined"),
QSE_T("function '${0}' redefined"), QSE_T("function '${0}' redefined"),
@ -101,6 +99,8 @@ const qse_char_t* qse_awk_dflerrstr (qse_awk_t* awk, qse_awk_errnum_t errnum)
QSE_T("both prefix and postfix increment/decrement operator present"), QSE_T("both prefix and postfix increment/decrement operator present"),
QSE_T("illegal operand for increment/decrement operator"), QSE_T("illegal operand for increment/decrement operator"),
QSE_T("'include' not followed by a string"), QSE_T("'include' not followed by a string"),
QSE_T("include level too deep"),
QSE_T("directive '${0}' not recognized"),
QSE_T("divide by zero"), QSE_T("divide by zero"),
QSE_T("invalid operand"), QSE_T("invalid operand"),

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c 245 2009-07-25 05:18:42Z hyunghwan.chung $ * $Id: parse.c 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -82,6 +82,7 @@ enum token_t
TOKEN_SEMICOLON, TOKEN_SEMICOLON,
TOKEN_COLON, TOKEN_COLON,
TOKEN_QUEST, TOKEN_QUEST,
TOKEN_ATSIGN,
TOKEN_BEGIN, TOKEN_BEGIN,
TOKEN_END, TOKEN_END,
@ -334,7 +335,7 @@ static global_t gtab[] =
#define GET_CHAR_TO(awk,c) \ #define GET_CHAR_TO(awk,c) \
do { \ do { \
if (get_char(awk) <= -1) return -1; \ if (get_char(awk) <= -1) return -1; \
c = (awk)->src.lex.curc; \ c = (awk)->sio.lex.curc; \
} while(0) } while(0)
#define UNGET_CHAR(awk,c) \ #define UNGET_CHAR(awk,c) \
@ -402,7 +403,8 @@ qse_size_t qse_awk_getmaxdepth (qse_awk_t* awk, int type)
(type == QSE_AWK_DEPTH_EXPR_PARSE)? awk->parse.depth.max.expr: (type == QSE_AWK_DEPTH_EXPR_PARSE)? awk->parse.depth.max.expr:
(type == QSE_AWK_DEPTH_EXPR_RUN)? awk->run.depth.max.expr: (type == QSE_AWK_DEPTH_EXPR_RUN)? awk->run.depth.max.expr:
(type == QSE_AWK_DEPTH_REX_BUILD)? awk->rex.depth.max.build: (type == QSE_AWK_DEPTH_REX_BUILD)? awk->rex.depth.max.build:
(type == QSE_AWK_DEPTH_REX_MATCH)? awk->rex.depth.max.match: 0; (type == QSE_AWK_DEPTH_REX_MATCH)? awk->rex.depth.max.match:
(type == QSE_AWK_DEPTH_INCLUDE)? awk->parse.depth.max.incl: 0;
} }
void qse_awk_setmaxdepth (qse_awk_t* awk, int types, qse_size_t depth) void qse_awk_setmaxdepth (qse_awk_t* awk, int types, qse_size_t depth)
@ -440,6 +442,11 @@ void qse_awk_setmaxdepth (qse_awk_t* awk, int types, qse_size_t depth)
{ {
awk->rex.depth.max.match = depth; awk->rex.depth.max.match = depth;
} }
if (types & QSE_AWK_DEPTH_INCLUDE)
{
awk->parse.depth.max.incl = depth;
}
} }
const qse_char_t* qse_awk_getgblname ( const qse_char_t* qse_awk_getgblname (
@ -486,9 +493,11 @@ int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio)
QSE_ASSERT (awk->parse.depth.cur.expr == 0); QSE_ASSERT (awk->parse.depth.cur.expr == 0);
qse_awk_clear (awk); qse_awk_clear (awk);
awk->src.ios = *sio; awk->sio.inf = sio->in;
awk->sio.outf = sio->out;
n = parse (awk); n = parse (awk);
if (n == 0 && awk->sio.outf != QSE_NULL) n = deparse (awk);
QSE_ASSERT (awk->parse.depth.cur.loop == 0); QSE_ASSERT (awk->parse.depth.cur.loop == 0);
QSE_ASSERT (awk->parse.depth.cur.expr == 0); QSE_ASSERT (awk->parse.depth.cur.expr == 0);
@ -498,13 +507,13 @@ int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio)
static int parse (qse_awk_t* awk) static int parse (qse_awk_t* awk)
{ {
int n = 0; int ret = -1;
qse_ssize_t op; qse_ssize_t op;
QSE_ASSERT (awk->src.ios.in != QSE_NULL); QSE_ASSERT (awk->sio.inf != QSE_NULL);
CLRERR (awk); CLRERR (awk);
op = awk->src.ios.in (awk, QSE_AWK_SIO_OPEN, QSE_NULL, 0); op = awk->sio.inf (awk, QSE_AWK_SIO_OPEN, awk->sio.inp, QSE_NULL, 0);
if (op <= -1) if (op <= -1)
{ {
/* cannot open the source file. /* cannot open the source file.
@ -516,8 +525,6 @@ static int parse (qse_awk_t* awk)
adjust_static_globals (awk); adjust_static_globals (awk);
#define EXIT_PARSE(v) do { n = (v); goto exit_parse; } while(0)
/* the user io handler for the source code input returns 0 when /* the user io handler for the source code input returns 0 when
* it doesn't have any files to open. this is the same condition * it doesn't have any files to open. this is the same condition
* as the source code file is empty. so it will perform the parsing * as the source code file is empty. so it will perform the parsing
@ -525,19 +532,19 @@ static int parse (qse_awk_t* awk)
if (op > 0) if (op > 0)
{ {
/* get the first character */ /* get the first character */
if (get_char(awk) <= -1) EXIT_PARSE(-1); if (get_char(awk) <= -1) goto oops;
/* get the first token */ /* get the first token */
if (get_token(awk) <= -1) EXIT_PARSE(-1); if (get_token(awk) <= -1) goto oops;
while (1) while (1)
{ {
while (MATCH(awk,TOKEN_NEWLINE)) while (MATCH(awk,TOKEN_NEWLINE))
{ {
if (get_token(awk) <= -1) EXIT_PARSE(-1); if (get_token(awk) <= -1) goto oops;
} }
if (MATCH(awk,TOKEN_EOF)) break; if (MATCH(awk,TOKEN_EOF)) break;
if (parse_progunit(awk) == QSE_NULL) EXIT_PARSE(-1); if (parse_progunit(awk) == QSE_NULL) goto oops;
} }
if ((awk->option & QSE_AWK_EXPLICIT) && if ((awk->option & QSE_AWK_EXPLICIT) &&
@ -553,11 +560,13 @@ static int parse (qse_awk_t* awk)
QSE_MAP_KPTR(p), QSE_MAP_KLEN(p)) == QSE_NULL) QSE_MAP_KPTR(p), QSE_MAP_KLEN(p)) == QSE_NULL)
{ {
/* TODO: set better error no & line */ /* TODO: set better error no & line */
SETERRARG (awk, QSE_AWK_EFUNNF, SETERRARG (
awk, QSE_AWK_EFUNNF,
*(qse_size_t*)QSE_MAP_VPTR(p), *(qse_size_t*)QSE_MAP_VPTR(p),
QSE_MAP_KPTR(p), QSE_MAP_KPTR(p),
QSE_MAP_KLEN(p)); QSE_MAP_KLEN(p)
EXIT_PARSE(-1); );
goto oops;
} }
p = qse_map_getnextpair (awk->parse.funs, p, &buckno); p = qse_map_getnextpair (awk->parse.funs, p, &buckno);
@ -567,57 +576,126 @@ static int parse (qse_awk_t* awk)
} }
QSE_ASSERT (awk->tree.ngbls == QSE_LDA_SIZE(awk->parse.gbls)); QSE_ASSERT (awk->tree.ngbls == QSE_LDA_SIZE(awk->parse.gbls));
ret = 0;
if (awk->src.ios.out != QSE_NULL) oops:
if (ret <= -1)
{ {
if (deparse (awk) <= -1) EXIT_PARSE(-1); /* an error occurred and control has reached here
* probably, some included files might not have beed
* closed. close them */
while (awk->sio.inp != &awk->sio.arg)
{
qse_awk_sio_arg_t* next;
/* nothing much to do about a close error */
awk->sio.inf (
awk, QSE_AWK_SIO_CLOSE,
awk->sio.inp, QSE_NULL, 0);
next = awk->sio.inp->next;
QSE_ASSERT (awk->sio.inp->name != QSE_NULL);
QSE_MMGR_FREE (awk->mmgr, awk->sio.inp->name);
QSE_MMGR_FREE (awk->mmgr, awk->sio.inp);
awk->sio.inp = next;
}
}
else if (ret == 0)
{
/* no error occurred so far */
QSE_ASSERT (awk->sio.inp == &awk->sio.arg);
CLRERR (awk);
} }
#undef EXIT_PARSE if (awk->sio.inf (
exit_parse: awk, QSE_AWK_SIO_CLOSE, awk->sio.inp, QSE_NULL, 0) != 0)
if (n == 0) CLRERR (awk);
if (awk->src.ios.in (awk, QSE_AWK_SIO_CLOSE, QSE_NULL, 0) != 0)
{ {
if (n == 0) if (ret == 0)
{ {
/* this is to keep the earlier error above /* this is to keep the earlier error above
* that might be more critical than this */ * that might be more critical than this */
if (ISNOERR(awk)) if (ISNOERR(awk))
SETERRARG (awk, QSE_AWK_ECLOSE, 0, QSE_T("<SIN>"), 5); SETERRARG (awk, QSE_AWK_ECLOSE, 0, QSE_T("<SIN>"), 5);
n = -1; ret = -1;
} }
} }
if (n <= -1) qse_awk_clear (awk); if (ret <= -1)
else awk->tree.ok = 1; {
/* clear the parse tree partially constructed on error */
qse_awk_clear (awk);
}
return n; return ret;
} }
static int begin_include (qse_awk_t* awk) static int begin_include (qse_awk_t* awk)
{ {
int level;
qse_ssize_t op;
qse_char_t* file = QSE_NULL;
qse_awk_sio_arg_t* arg = QSE_NULL;
if (qse_strlen(awk->token.name->ptr) != awk->token.name->len) if (qse_strlen(awk->token.name->ptr) != awk->token.name->len)
{ {
SETERRARG ( SETERRARG (
awk, awk,
QSE_AWK_EIONMNL, QSE_AWK_EIONMNL,
awk->token.line, awk->token.line,
awk->token.name->ptr, QSE_STR_PTR(awk->token.name),
qse_strlen(awk->token.name->ptr) qse_strlen(QSE_STR_PTR(awk->token.name))
); );
return -1; return -1;
} }
file = qse_strdup (QSE_STR_PTR(awk->token.name), awk->mmgr);
if (file == QSE_NULL)
{
SETERRLIN (awk, QSE_AWK_ENOMEM, awk->ptoken.line);
goto oops;
}
arg = (qse_awk_sio_arg_t*) QSE_MMGR_ALLOC (awk->mmgr, QSE_SIZEOF(*arg));
if (arg == QSE_NULL)
{
SETERRLIN (awk, QSE_AWK_ENOMEM, awk->ptoken.line);
goto oops;
}
QSE_MEMSET (arg, 0, QSE_SIZEOF(*arg));
arg->name = file;
CLRERR (awk); CLRERR (awk);
op = awk->src.ios.in (awk, QSE_AWK_SIO_OPEN, QSE_NULL, 0); op = awk->sio.inf (awk, QSE_AWK_SIO_OPEN, arg, QSE_NULL, 0);
if (op <= -1) if (op <= -1)
{ {
if (ISNOERR(awk)) SETERRTOK (awk, QSE_AWK_EOPEN); if (ISNOERR(awk)) SETERRTOK (awk, QSE_AWK_EOPEN);
return -1; goto oops;
} }
/* TODO: implement this */ if (op == 0)
SETERRLIN (awk, QSE_AWK_ENOSUP, awk->ptoken.line); {
CLRERR (awk);
op = awk->sio.inf (awk, QSE_AWK_SIO_CLOSE, arg, QSE_NULL, 0);
if (op != 0)
{
if (ISNOERR(awk)) SETERRTOK (awk, QSE_AWK_ECLOSE);
goto oops;
}
}
arg->next = awk->sio.inp;
awk->sio.inp = arg;
awk->parse.depth.cur.incl++;
return 0;
oops:
if (file != QSE_NULL) QSE_MMGR_FREE (awk->mmgr, file);
if (arg != QSE_NULL) QSE_MMGR_FREE (awk->mmgr, arg);
return -1; return -1;
} }
@ -654,7 +732,11 @@ retry:
return QSE_NULL; return QSE_NULL;
} }
} }
else if (MATCH(awk,TOKEN_INCLUDE)) else if (MATCH(awk,TOKEN_ATSIGN))
{
if (get_token(awk) <= -1) return QSE_NULL;
if (MATCH(awk,TOKEN_INCLUDE))
{ {
if (get_token(awk) <= -1) return QSE_NULL; if (get_token(awk) <= -1) return QSE_NULL;
@ -664,9 +746,31 @@ retry:
return QSE_NULL; return QSE_NULL;
} }
if (awk->parse.depth.max.incl > 0 &&
awk->parse.depth.cur.incl >= awk->parse.depth.max.incl)
{
SETERRLIN (awk, QSE_AWK_EINCLTD, awk->ptoken.line);
return QSE_NULL;
}
if (begin_include (awk) <= -1) return QSE_NULL; if (begin_include (awk) <= -1) return QSE_NULL;
/* read the first meaningful token from the included file
* and rematch it by jumping to retry */
do
{
if (get_token(awk) <= -1) return QSE_NULL;
}
while (MATCH(awk,TOKEN_NEWLINE));
goto retry; goto retry;
} }
else
{
SETERRTOK (awk, QSE_AWK_EDIRECNR);
return QSE_NULL;
}
}
else if (MATCH(awk,TOKEN_FUNCTION)) else if (MATCH(awk,TOKEN_FUNCTION))
{ {
awk->parse.id.block = PARSE_FUNCTION; awk->parse.id.block = PARSE_FUNCTION;
@ -680,14 +784,6 @@ retry:
return QSE_NULL; return QSE_NULL;
} }
/*
if (awk->tree.begin != QSE_NULL)
{
SETERRLIN (awk, QSE_AWK_EDUPBEG, awk->ptoken.line);
return QSE_NULL;
}
*/
awk->parse.id.block = PARSE_BEGIN; awk->parse.id.block = PARSE_BEGIN;
if (get_token(awk) <= -1) return QSE_NULL; if (get_token(awk) <= -1) return QSE_NULL;
@ -716,14 +812,6 @@ retry:
return QSE_NULL; return QSE_NULL;
} }
/*
if (awk->tree.end != QSE_NULL)
{
SETERRLIN (awk, QSE_AWK_EDUPEND, awk->ptoken.line);
return QSE_NULL;
}
*/
awk->parse.id.block = PARSE_END; awk->parse.id.block = PARSE_END;
if (get_token(awk) <= -1) return QSE_NULL; if (get_token(awk) <= -1) return QSE_NULL;
@ -3175,11 +3263,11 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, qse_size_t line)
return QSE_NULL; return QSE_NULL;
} }
if (awk->atoken.type != TOKEN_GETLINE) break; if (awk->ntoken.type != TOKEN_GETLINE) break;
var = QSE_NULL; var = QSE_NULL;
/* consume atoken */ /* consume ntoken */
get_token (awk); get_token (awk);
/* get the next token */ /* get the next token */
@ -4667,7 +4755,7 @@ static int get_number (qse_awk_t* awk, qse_awk_token_t* token)
QSE_ASSERT (QSE_STR_LEN(token->name) == 0); QSE_ASSERT (QSE_STR_LEN(token->name) == 0);
SET_TOKEN_TYPE (awk, token, TOKEN_INT); SET_TOKEN_TYPE (awk, token, TOKEN_INT);
c = awk->src.lex.curc; c = awk->sio.lex.curc;
if (c == QSE_T('0')) if (c == QSE_T('0'))
{ {
@ -4920,18 +5008,18 @@ static int get_string (
static int get_charstr (qse_awk_t* awk, qse_awk_token_t* token) static int get_charstr (qse_awk_t* awk, qse_awk_token_t* token)
{ {
if (awk->src.lex.curc != QSE_T('\"')) if (awk->sio.lex.curc != QSE_T('\"'))
{ {
/* the starting quote has been consumed before this function /* the starting quote has been consumed before this function
* has been called */ * has been called */
ADD_TOKEN_CHAR (awk, token, awk->src.lex.curc); ADD_TOKEN_CHAR (awk, token, awk->sio.lex.curc);
} }
return get_string (awk, QSE_T('\"'), QSE_T('\\'), QSE_FALSE, 0, token); return get_string (awk, QSE_T('\"'), QSE_T('\\'), QSE_FALSE, 0, token);
} }
static int get_rexstr (qse_awk_t* awk, qse_awk_token_t* token) static int get_rexstr (qse_awk_t* awk, qse_awk_token_t* token)
{ {
if (awk->src.lex.curc == QSE_T('/')) if (awk->sio.lex.curc == QSE_T('/'))
{ {
/* this part of the function is different from get_charstr /* this part of the function is different from get_charstr
* because of the way this function is called. * because of the way this function is called.
@ -4947,7 +5035,7 @@ static int get_rexstr (qse_awk_t* awk, qse_awk_token_t* token)
else else
{ {
int escaped = 0; int escaped = 0;
if (awk->src.lex.curc == QSE_T('\\')) if (awk->sio.lex.curc == QSE_T('\\'))
{ {
/* for input like /\//, this condition is met. /* for input like /\//, this condition is met.
* the initial escape character is added when the * the initial escape character is added when the
@ -4958,7 +5046,7 @@ static int get_rexstr (qse_awk_t* awk, qse_awk_token_t* token)
{ {
/* add other initial characters here as get_string() /* add other initial characters here as get_string()
* begins with reading the next character */ * begins with reading the next character */
ADD_TOKEN_CHAR (awk, token, awk->src.lex.curc); ADD_TOKEN_CHAR (awk, token, awk->sio.lex.curc);
} }
return get_string ( return get_string (
awk, QSE_T('/'), QSE_T('\\'), QSE_TRUE, escaped, token); awk, QSE_T('/'), QSE_T('\\'), QSE_TRUE, escaped, token);
@ -4968,22 +5056,22 @@ static int get_rexstr (qse_awk_t* awk, qse_awk_token_t* token)
static int get_char (qse_awk_t* awk) static int get_char (qse_awk_t* awk)
{ {
qse_ssize_t n; qse_ssize_t n;
/*qse_char_t c;*/
if (awk->src.lex.ungotc_count > 0) if (awk->sio.lex.ungotc_count > 0)
{ {
awk->src.lex.curc = awk->src.lex.ungotc[--awk->src.lex.ungotc_count]; awk->sio.lex.curc = awk->sio.lex.ungotc[--awk->sio.lex.ungotc_count];
awk->src.lex.line = awk->src.lex.ungotc_line[awk->src.lex.ungotc_count]; awk->sio.lex.line = awk->sio.lex.ungotc_line[awk->sio.lex.ungotc_count];
awk->src.lex.column = awk->src.lex.ungotc_column[awk->src.lex.ungotc_count]; awk->sio.lex.column = awk->sio.lex.ungotc_column[awk->sio.lex.ungotc_count];
return 0; return 0;
} }
if (awk->src.shared.buf_pos >= awk->src.shared.buf_len) retry:
if (awk->sio.inp->b.pos >= awk->sio.inp->b.len)
{ {
CLRERR (awk); CLRERR (awk);
n = awk->src.ios.in ( n = awk->sio.inf (
awk, QSE_AWK_SIO_READ, awk, QSE_AWK_SIO_READ, awk->sio.inp,
awk->src.shared.buf, QSE_COUNTOF(awk->src.shared.buf) awk->sio.inp->b.buf, QSE_COUNTOF(awk->sio.inp->b.buf)
); );
if (n <= -1) if (n <= -1)
{ {
@ -4994,43 +5082,68 @@ static int get_char (qse_awk_t* awk)
if (n == 0) if (n == 0)
{ {
awk->src.lex.curc = QSE_CHAR_EOF; if (awk->sio.inp != &awk->sio.arg)
{
qse_awk_sio_arg_t* next;
CLRERR (awk);
if (awk->sio.inf (
awk, QSE_AWK_SIO_CLOSE,
awk->sio.inp, QSE_NULL, 0) != 0)
{
if (ISNOERR(awk))
SETERRARG (awk, QSE_AWK_ECLOSE, 0, QSE_T("<SIN>"), 5);
return -1;
}
next = awk->sio.inp->next;
QSE_ASSERT (awk->sio.inp->name != QSE_NULL);
QSE_MMGR_FREE (awk->mmgr, awk->sio.inp->name);
QSE_MMGR_FREE (awk->mmgr, awk->sio.inp);
awk->parse.depth.cur.incl--;
awk->sio.inp = next;
goto retry;
}
awk->sio.lex.curc = QSE_CHAR_EOF;
return 0; return 0;
} }
awk->src.shared.buf_pos = 0; awk->sio.inp->b.pos = 0;
awk->src.shared.buf_len = n; awk->sio.inp->b.len = n;
} }
awk->src.lex.curc = awk->src.shared.buf[awk->src.shared.buf_pos++]; awk->sio.lex.curc = awk->sio.inp->b.buf[awk->sio.inp->b.pos++];
if (awk->src.lex.curc == QSE_T('\n')) if (awk->sio.lex.curc == QSE_T('\n'))
{ {
awk->src.lex.line++; awk->sio.lex.line++;
awk->src.lex.column = 1; awk->sio.lex.column = 1;
} }
else awk->src.lex.column++; else awk->sio.lex.column++;
return 0; return 0;
} }
static int unget_char (qse_awk_t* awk, qse_cint_t c) static int unget_char (qse_awk_t* awk, qse_cint_t c)
{ {
if (awk->src.lex.ungotc_count >= QSE_COUNTOF(awk->src.lex.ungotc)) if (awk->sio.lex.ungotc_count >= QSE_COUNTOF(awk->sio.lex.ungotc))
{ {
SETERRLIN (awk, QSE_AWK_ELXUNG, awk->src.lex.line); SETERRLIN (awk, QSE_AWK_ELXUNG, awk->sio.lex.line);
return -1; return -1;
} }
awk->src.lex.ungotc_line[awk->src.lex.ungotc_count] = awk->src.lex.line; awk->sio.lex.ungotc_line[awk->sio.lex.ungotc_count] = awk->sio.lex.line;
awk->src.lex.ungotc_column[awk->src.lex.ungotc_count] = awk->src.lex.column; awk->sio.lex.ungotc_column[awk->sio.lex.ungotc_count] = awk->sio.lex.column;
awk->src.lex.ungotc[awk->src.lex.ungotc_count++] = c; awk->sio.lex.ungotc[awk->sio.lex.ungotc_count++] = c;
return 0; return 0;
} }
static int skip_spaces (qse_awk_t* awk) static int skip_spaces (qse_awk_t* awk)
{ {
qse_cint_t c = awk->src.lex.curc; qse_cint_t c = awk->sio.lex.curc;
if (awk->option & QSE_AWK_NEWLINE) if (awk->option & QSE_AWK_NEWLINE)
{ {
@ -5074,7 +5187,7 @@ static int skip_spaces (qse_awk_t* awk)
static int skip_comment (qse_awk_t* awk) static int skip_comment (qse_awk_t* awk)
{ {
qse_cint_t c = awk->src.lex.curc; qse_cint_t c = awk->sio.lex.curc;
qse_size_t line, column; qse_size_t line, column;
if (c == QSE_T('#')) if (c == QSE_T('#'))
@ -5088,8 +5201,8 @@ static int skip_comment (qse_awk_t* awk)
if (c != QSE_T('/')) return 0; /* not a comment */ if (c != QSE_T('/')) return 0; /* not a comment */
line = awk->src.lex.line; line = awk->sio.lex.line;
column = awk->src.lex.column; column = awk->sio.lex.column;
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == QSE_T('*')) if (c == QSE_T('*'))
@ -5099,7 +5212,7 @@ static int skip_comment (qse_awk_t* awk)
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == QSE_CHAR_EOF) if (c == QSE_CHAR_EOF)
{ {
SETERRLIN (awk, QSE_AWK_EENDCMT, awk->src.lex.line); SETERRLIN (awk, QSE_AWK_EENDCMT, awk->sio.lex.line);
return -1; return -1;
} }
@ -5108,7 +5221,7 @@ static int skip_comment (qse_awk_t* awk)
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == QSE_CHAR_EOF) if (c == QSE_CHAR_EOF)
{ {
SETERRLIN (awk, QSE_AWK_EENDCMT, awk->src.lex.line); SETERRLIN (awk, QSE_AWK_EENDCMT, awk->sio.lex.line);
return -1; return -1;
} }
@ -5126,9 +5239,9 @@ static int skip_comment (qse_awk_t* awk)
} }
UNGET_CHAR (awk, c); UNGET_CHAR (awk, c);
awk->src.lex.curc = QSE_T('/'); awk->sio.lex.curc = QSE_T('/');
awk->src.lex.line = line; awk->sio.lex.line = line;
awk->src.lex.column = column; awk->sio.lex.column = column;
return 0; return 0;
} }
@ -5196,6 +5309,7 @@ static int get_symbols (qse_awk_t* awk, qse_cint_t c, qse_awk_token_t* token)
{ QSE_T(";"), 1, TOKEN_SEMICOLON, 0 }, { QSE_T(";"), 1, TOKEN_SEMICOLON, 0 },
{ QSE_T(":"), 1, TOKEN_COLON, 0 }, { QSE_T(":"), 1, TOKEN_COLON, 0 },
{ QSE_T("?"), 1, TOKEN_QUEST, 0 }, { QSE_T("?"), 1, TOKEN_QUEST, 0 },
{ QSE_T("@"), 1, TOKEN_ATSIGN, 0 },
{ QSE_NULL, 0, 0, 0 } { QSE_NULL, 0, 0, 0 }
}; };
@ -5243,10 +5357,10 @@ static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token)
while (n >= 1); while (n >= 1);
qse_str_clear (token->name); qse_str_clear (token->name);
token->line = awk->src.lex.line; token->line = awk->sio.lex.line;
token->column = awk->src.lex.column; token->column = awk->sio.lex.column;
c = awk->src.lex.curc; c = awk->sio.lex.curc;
if (c == QSE_CHAR_EOF) if (c == QSE_CHAR_EOF)
{ {
@ -5271,7 +5385,7 @@ static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token)
if ((awk->option & QSE_AWK_EXPLICIT) == 0 && if ((awk->option & QSE_AWK_EXPLICIT) == 0 &&
QSE_AWK_ISDIGIT (awk, c)) QSE_AWK_ISDIGIT (awk, c))
{ {
awk->src.lex.curc = QSE_T('.'); awk->sio.lex.curc = QSE_T('.');
UNGET_CHAR (awk, c); UNGET_CHAR (awk, c);
if (get_number (awk, token) <= -1) return -1; if (get_number (awk, token) <= -1) return -1;
@ -5350,14 +5464,14 @@ static int get_token (qse_awk_t* awk)
awk->ptoken.line = awk->token.line; awk->ptoken.line = awk->token.line;
awk->ptoken.column = awk->token.column; awk->ptoken.column = awk->token.column;
if (QSE_STR_LEN(awk->atoken.name) > 0) if (QSE_STR_LEN(awk->ntoken.name) > 0)
{ {
awk->token.type = awk->atoken.type; awk->token.type = awk->ntoken.type;
awk->token.line = awk->atoken.line; awk->token.line = awk->ntoken.line;
awk->token.column = awk->token.column; awk->token.column = awk->token.column;
qse_str_swap (awk->token.name, awk->atoken.name); qse_str_swap (awk->token.name, awk->ntoken.name);
qse_str_clear (awk->atoken.name); qse_str_clear (awk->ntoken.name);
return 0; return 0;
} }
@ -5367,7 +5481,7 @@ static int get_token (qse_awk_t* awk)
static int preget_token (qse_awk_t* awk) static int preget_token (qse_awk_t* awk)
{ {
return get_token_into (awk, &awk->atoken); return get_token_into (awk, &awk->ntoken);
} }
static int classify_ident ( static int classify_ident (
@ -5484,13 +5598,16 @@ static int deparse (qse_awk_t* awk)
qse_ssize_t op; qse_ssize_t op;
qse_cstr_t kw; qse_cstr_t kw;
QSE_ASSERT (awk->src.ios.out != QSE_NULL); QSE_ASSERT (awk->sio.outf != QSE_NULL);
awk->src.shared.buf_len = 0; awk->sio.arg.name = QSE_NULL;
awk->src.shared.buf_pos = 0; awk->sio.arg.handle = QSE_NULL;
awk->sio.arg.b.len = 0;
awk->sio.arg.b.pos = 0;
CLRERR (awk); CLRERR (awk);
op = awk->src.ios.out (awk, QSE_AWK_SIO_OPEN, QSE_NULL, 0); op = awk->sio.outf (
awk, QSE_AWK_SIO_OPEN, &awk->sio.arg, QSE_NULL, 0);
if (op <= -1) if (op <= -1)
{ {
if (ISNOERR(awk)) if (ISNOERR(awk))
@ -5507,8 +5624,8 @@ static int deparse (qse_awk_t* awk)
* that this is not really an error for the parse and deparser. * that this is not really an error for the parse and deparser.
* *
* in fact, there are two ways to skip deparsing. * in fact, there are two ways to skip deparsing.
* 1. set awk->src.ios.out to NULL. * 1. set awk->sio.inf to NULL.
* 2. set awk->src.ios.out to a normal handler but * 2. set awk->sio.inf to a normal handler but
* make it return 0 on the OPEN request. * make it return 0 on the OPEN request.
*/ */
n = 0; n = 0;
@ -5698,7 +5815,8 @@ static int deparse (qse_awk_t* awk)
exit_deparse: exit_deparse:
if (n == 0) CLRERR (awk); if (n == 0) CLRERR (awk);
if (awk->src.ios.out (awk, QSE_AWK_SIO_CLOSE, QSE_NULL, 0) != 0) if (awk->sio.outf (
awk, QSE_AWK_SIO_CLOSE, &awk->sio.arg, QSE_NULL, 0) != 0)
{ {
if (n == 0) if (n == 0)
{ {
@ -5777,8 +5895,8 @@ static qse_map_walk_t deparse_func (
static int put_char (qse_awk_t* awk, qse_char_t c) static int put_char (qse_awk_t* awk, qse_char_t c)
{ {
awk->src.shared.buf[awk->src.shared.buf_len++] = c; awk->sio.arg.b.buf[awk->sio.arg.b.len++] = c;
if (awk->src.shared.buf_len >= QSE_COUNTOF(awk->src.shared.buf)) if (awk->sio.arg.b.len >= QSE_COUNTOF(awk->sio.arg.b.buf))
{ {
if (flush_out (awk) <= -1) return -1; if (flush_out (awk) <= -1) return -1;
} }
@ -5789,15 +5907,13 @@ static int flush_out (qse_awk_t* awk)
{ {
qse_ssize_t n; qse_ssize_t n;
QSE_ASSERT (awk->src.ios.out != QSE_NULL); while (awk->sio.arg.b.pos < awk->sio.arg.b.len)
while (awk->src.shared.buf_pos < awk->src.shared.buf_len)
{ {
CLRERR (awk); CLRERR (awk);
n = awk->src.ios.out ( n = awk->sio.outf (
awk, QSE_AWK_SIO_WRITE, awk, QSE_AWK_SIO_WRITE, &awk->sio.arg,
&awk->src.shared.buf[awk->src.shared.buf_pos], &awk->sio.arg.b.buf[awk->sio.arg.b.pos],
awk->src.shared.buf_len - awk->src.shared.buf_pos awk->sio.arg.b.len - awk->sio.arg.b.pos
); );
if (n <= 0) if (n <= 0)
{ {
@ -5806,11 +5922,11 @@ static int flush_out (qse_awk_t* awk)
return -1; return -1;
} }
awk->src.shared.buf_pos += n; awk->sio.arg.b.pos += n;
} }
awk->src.shared.buf_pos = 0; awk->sio.arg.b.pos = 0;
awk->src.shared.buf_len = 0; awk->sio.arg.b.len = 0;
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: std.c 245 2009-07-25 05:18:42Z hyunghwan.chung $ * $Id: std.c 246 2009-07-27 02:31:58Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -155,13 +155,10 @@ void* qse_awk_getxtnstd (qse_awk_t* awk)
/*** PARSESTD ***/ /*** PARSESTD ***/
static qse_ssize_t sf_in ( static qse_ssize_t sf_in_open (
qse_awk_t* awk, qse_awk_sio_cmd_t cmd, qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
qse_awk_sio_arg_t* arg, qse_char_t* data, qse_size_t size)
{ {
xtn_t* xtn = QSE_XTN (awk); if (arg == QSE_NULL || arg->name == QSE_NULL)
if (cmd == QSE_AWK_SIO_OPEN)
{ {
switch (xtn->s.in.type) switch (xtn->s.in.type)
{ {
@ -184,12 +181,12 @@ static qse_ssize_t sf_in (
); );
if (xtn->s.in.handle == QSE_NULL) if (xtn->s.in.handle == QSE_NULL)
{ {
qse_cstr_t arg; qse_cstr_t ea;
arg.ptr = xtn->s.in.u.file; ea.ptr = xtn->s.in.u.file;
arg.len = qse_strlen(arg.ptr); ea.len = qse_strlen(ea.ptr);
qse_awk_seterror ( qse_awk_seterror (
awk, QSE_AWK_EOPEN, awk, QSE_AWK_EOPEN,
0, &arg 0, &ea
); );
return -1; return -1;
} }
@ -206,7 +203,29 @@ static qse_ssize_t sf_in (
return 1; return 1;
} }
} }
else if (cmd == QSE_AWK_SIO_CLOSE) else
{
/* TODO: standard include path */
arg->handle = qse_sio_open (
awk->mmgr, 0, arg->name, QSE_SIO_READ
);
if (arg->handle == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = arg->name;
ea.len = qse_strlen(ea.ptr);
qse_awk_seterror (awk, QSE_AWK_EOPEN, 0, &ea);
return -1;
}
return 1;
}
}
static qse_ssize_t sf_in_close (
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
{
if (arg == QSE_NULL || arg->name == QSE_NULL)
{ {
if (xtn->s.in.handle != QSE_NULL && if (xtn->s.in.handle != QSE_NULL &&
xtn->s.in.handle != qse_sio_in && xtn->s.in.handle != qse_sio_in &&
@ -215,10 +234,20 @@ static qse_ssize_t sf_in (
{ {
qse_sio_close (xtn->s.in.handle); qse_sio_close (xtn->s.in.handle);
} }
}
else
{
qse_sio_close (arg->handle);
}
return 0; return 0;
} }
else if (cmd == QSE_AWK_SIO_READ)
static qse_ssize_t sf_in_read (
qse_awk_t* awk, qse_awk_sio_arg_t* arg,
qse_char_t* data, qse_size_t size, xtn_t* xtn)
{
if (arg == QSE_NULL || arg->name == QSE_NULL)
{ {
switch (xtn->s.in.type) switch (xtn->s.in.type)
{ {
@ -231,11 +260,11 @@ static qse_ssize_t sf_in (
n = qse_sio_getsn (xtn->s.in.handle, data, size); n = qse_sio_getsn (xtn->s.in.handle, data, size);
if (n == -1) if (n == -1)
{ {
qse_cstr_t arg; qse_cstr_t ea;
arg.ptr = xtn->s.in.u.file; ea.ptr = xtn->s.in.u.file;
arg.len = qse_strlen(arg.ptr); ea.len = qse_strlen(ea.ptr);
qse_awk_seterror ( qse_awk_seterror (
awk, QSE_AWK_EREAD, 0, &arg); awk, QSE_AWK_EREAD, 0, &ea);
} }
return n; return n;
} }
@ -259,12 +288,46 @@ static qse_ssize_t sf_in (
} }
return n; return n;
} }
}
}
else
{
qse_ssize_t n;
QSE_ASSERT (arg->handle != QSE_NULL);
n = qse_sio_getsn (arg->handle, data, size);
if (n == -1)
{
qse_cstr_t ea;
ea.ptr = arg->name;
ea.len = qse_strlen(ea.ptr);
qse_awk_seterror (awk, QSE_AWK_EREAD, 0, &ea);
}
return n;
} }
} }
static qse_ssize_t sf_in (
qse_awk_t* awk, qse_awk_sio_cmd_t cmd,
qse_awk_sio_arg_t* arg, qse_char_t* data, qse_size_t size)
{
xtn_t* xtn = QSE_XTN (awk);
switch (cmd)
{
case QSE_AWK_SIO_OPEN:
return sf_in_open (awk, arg, xtn);
case QSE_AWK_SIO_CLOSE:
return sf_in_close (awk, arg, xtn);
case QSE_AWK_SIO_READ:
return sf_in_read (awk, arg, data, size, xtn);
default:
return -1; return -1;
} }
}
static qse_ssize_t sf_out ( static qse_ssize_t sf_out (
qse_awk_t* awk, qse_awk_sio_cmd_t cmd, qse_awk_t* awk, qse_awk_sio_cmd_t cmd,
@ -297,12 +360,12 @@ static qse_ssize_t sf_out (
); );
if (xtn->s.out.handle == QSE_NULL) if (xtn->s.out.handle == QSE_NULL)
{ {
qse_cstr_t arg; qse_cstr_t ea;
arg.ptr = xtn->s.out.u.file; ea.ptr = xtn->s.out.u.file;
arg.len = qse_strlen(arg.ptr); ea.len = qse_strlen(ea.ptr);
qse_awk_seterror ( qse_awk_seterror (
awk, QSE_AWK_EOPEN, awk, QSE_AWK_EOPEN,
0, &arg 0, &ea
); );
return -1; return -1;
} }
@ -358,11 +421,11 @@ static qse_ssize_t sf_out (
n = qse_sio_putsn (xtn->s.out.handle, data, size); n = qse_sio_putsn (xtn->s.out.handle, data, size);
if (n == -1) if (n == -1)
{ {
qse_cstr_t arg; qse_cstr_t ea;
arg.ptr = xtn->s.in.u.file; ea.ptr = xtn->s.in.u.file;
arg.len = qse_strlen(arg.ptr); ea.len = qse_strlen(ea.ptr);
qse_awk_seterror ( qse_awk_seterror (
awk, QSE_AWK_EWRITE, 0, &arg); awk, QSE_AWK_EWRITE, 0, &ea);
} }
return n; return n;

View File

@ -956,7 +956,7 @@ BEGIN {
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --newline=on -o- -f lang-004.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --newline=on -o- -f lang-004.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [52] LINE [3] function 'a' redefined ERROR: CODE [44] LINE [3] function 'a' redefined
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --implicit=off --explicit=on --newline=on -o- -f lang-005.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --implicit=off --explicit=on --newline=on -o- -f lang-005.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -984,7 +984,7 @@ BEGIN {
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --implicit=off --explicit=on --newline=on -o- -f lang-006.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --implicit=off --explicit=on --newline=on -o- -f lang-006.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [53] LINE [5] global variable 'a' redefined ERROR: CODE [45] LINE [5] global variable 'a' redefined
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --implicit=on --explicit=on --newline=on -o- -f lang-007.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --implicit=on --explicit=on --newline=on -o- -f lang-007.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -1352,7 +1352,7 @@ BEGIN {
printf ("%s\n",10.34); printf ("%s\n",10.34);
} }
ERROR: CODE [110] LINE [3] recursion detected in format conversion ERROR: CODE [105] LINE [3] recursion detected in format conversion
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --newline=on -o- -f lang-014.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --newline=on -o- -f lang-014.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -1481,27 +1481,27 @@ END {
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-018.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-018.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [57] LINE [1] duplicate global variable 'ARGV' ERROR: CODE [49] LINE [1] duplicate global variable 'ARGV'
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-019.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-019.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [59] LINE [1] '+' not a valid parameter name ERROR: CODE [51] LINE [1] '+' not a valid parameter name
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-020.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-020.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [60] LINE [1] '+' not a valid variable name ERROR: CODE [52] LINE [1] '+' not a valid variable name
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-021.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-021.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [60] LINE [3] '+' not a valid variable name ERROR: CODE [52] LINE [3] '+' not a valid variable name
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --newline=on -o- -f lang-022.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --newline=on -o- -f lang-022.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [31] LINE [2] left parenthesis expected in place of '=' ERROR: CODE [25] LINE [2] left parenthesis expected in place of '='
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-023.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-023.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [36] LINE [5] colon expected in place of ';' ERROR: CODE [30] LINE [5] colon expected in place of ';'
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-024.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-024.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -1520,7 +1520,7 @@ BEGIN {
delete iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix; delete iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix;
} }
ERROR: CODE [85] LINE [3] variable 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix' not deletable ERROR: CODE [80] LINE [3] variable 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix' not deletable
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --newline=on -o- -f lang-026.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --newline=on -o- -f lang-026.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -1532,19 +1532,19 @@ BEGIN {
} }
abc abc
ERROR: CODE [93] LINE [4] map 'abc' not assignable with a scalar ERROR: CODE [88] LINE [4] map 'abc' not assignable with a scalar
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --newline=on -o- -f lang-027.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --newline=on -o- -f lang-027.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [23] LINE [2] invalid character '<NUL>' ERROR: CODE [17] LINE [2] invalid character '<NUL>'
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --newline=on -o- -f lang-028.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --newline=on -o- -f lang-028.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [51] LINE [2] intrinsic function 'substr' redefined ERROR: CODE [43] LINE [2] intrinsic function 'substr' redefined
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-029.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --explicit=on --newline=on -o- -f lang-029.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ERROR: CODE [52] LINE [9] function 'abc' redefined ERROR: CODE [44] LINE [9] function 'abc' redefined
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
../../cmd/awk/qseawk --newline=on -o- -f lang-030.awk </dev/stdin 2>&1 ../../cmd/awk/qseawk --newline=on -o- -f lang-030.awk </dev/stdin 2>&1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------