Added QSE_AWK_TOLERANT
This commit is contained in:
@ -311,7 +311,7 @@ static global_t gtab[] =
|
||||
{ QSE_T("OFILENAME"), 9, QSE_AWK_PABLOCK | QSE_AWK_NEXTOFILE },
|
||||
|
||||
/* output real-to-str conversion format for 'print' */
|
||||
{ QSE_T("OFMT"), 4, QSE_AWK_RIO},
|
||||
{ QSE_T("OFMT"), 4, QSE_AWK_RIO },
|
||||
|
||||
/* output field separator for 'print' */
|
||||
{ QSE_T("OFS"), 3, QSE_AWK_RIO },
|
||||
@ -2727,6 +2727,16 @@ static qse_awk_nde_t* parse_print (
|
||||
qse_awk_nde_t* args_tail;
|
||||
qse_awk_nde_t* tail_prev;
|
||||
|
||||
/* print and printf provide weird syntaxs.
|
||||
*
|
||||
* 1. print 10, 20;
|
||||
* 2. print (10, 20);
|
||||
* 3. print (10,20,30) in a;
|
||||
* 4. print ((10,20,30) in a);
|
||||
*
|
||||
* Due the case 3, i can't consume LPAREN
|
||||
* here and expect RPAREN later.
|
||||
*/
|
||||
{
|
||||
qse_awk_loc_t eloc = awk->tok.loc;
|
||||
args = parse_expr_dc (awk, &eloc);
|
||||
@ -2831,11 +2841,11 @@ static qse_awk_nde_t* parse_print (
|
||||
if (out == QSE_NULL)
|
||||
{
|
||||
out_type = MATCH(awk,TOK_GT)? QSE_AWK_OUT_FILE:
|
||||
MATCH(awk,TOK_RS)? QSE_AWK_OUT_APFILE:
|
||||
MATCH(awk,TOK_RS)? QSE_AWK_OUT_APFILE:
|
||||
MATCH(awk,TOK_BOR)? QSE_AWK_OUT_PIPE:
|
||||
((awk->option & QSE_AWK_RWPIPE) &&
|
||||
MATCH(awk,TOK_LOR))? QSE_AWK_OUT_RWPIPE:
|
||||
QSE_AWK_OUT_CONSOLE;
|
||||
MATCH(awk,TOK_LOR))? QSE_AWK_OUT_RWPIPE:
|
||||
QSE_AWK_OUT_CONSOLE;
|
||||
|
||||
if (out_type != QSE_AWK_OUT_CONSOLE)
|
||||
{
|
||||
@ -2977,15 +2987,21 @@ static qse_awk_nde_t* parse_statement_nb (
|
||||
if (get_token(awk) <= -1) return QSE_NULL;
|
||||
nde = parse_reset (awk, xloc);
|
||||
}
|
||||
else if (MATCH(awk,TOK_PRINT))
|
||||
else if (!(awk->option & QSE_AWK_TOLERANT))
|
||||
{
|
||||
if (get_token(awk) <= -1) return QSE_NULL;
|
||||
nde = parse_print (awk, xloc, QSE_AWK_NDE_PRINT);
|
||||
}
|
||||
else if (MATCH(awk,TOK_PRINTF))
|
||||
{
|
||||
if (get_token(awk) <= -1) return QSE_NULL;
|
||||
nde = parse_print (awk, xloc, QSE_AWK_NDE_PRINTF);
|
||||
/* in the non-tolerant mode, we treat print and printf
|
||||
* as a separate statement */
|
||||
if (MATCH(awk,TOK_PRINT))
|
||||
{
|
||||
if (get_token(awk) <= -1) return QSE_NULL;
|
||||
nde = parse_print (awk, xloc, QSE_AWK_NDE_PRINT);
|
||||
}
|
||||
else if (MATCH(awk,TOK_PRINTF))
|
||||
{
|
||||
if (get_token(awk) <= -1) return QSE_NULL;
|
||||
nde = parse_print (awk, xloc, QSE_AWK_NDE_PRINTF);
|
||||
}
|
||||
else nde = parse_expr_dc (awk, xloc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3860,6 +3876,8 @@ static qse_awk_nde_t* parse_concat (
|
||||
MATCH(awk,TOK_PLUSPLUS) ||
|
||||
MATCH(awk,TOK_MINUSMINUS) ||
|
||||
MATCH(awk,TOK_LNOT) ||
|
||||
((awk->option & QSE_AWK_TOLERANT) &&
|
||||
(awk->tok.type == TOK_PRINT || awk->tok.type == TOK_PRINTF)) ||
|
||||
awk->tok.type >= TOK_GETLINE)
|
||||
{
|
||||
/* TODO: is the check above sufficient? */
|
||||
@ -4514,9 +4532,9 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
||||
}
|
||||
|
||||
/* check if it is a chained node */
|
||||
if (nde->next != QSE_NULL)
|
||||
if (nde->next)
|
||||
{
|
||||
/* if so, it is a expression group */
|
||||
/* if so, it is an expression group */
|
||||
/* (expr1, expr2, expr2) */
|
||||
|
||||
qse_awk_nde_grp_t* tmp;
|
||||
@ -4525,7 +4543,8 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
||||
awk->parse.id.stmt != TOK_PRINTF) ||
|
||||
awk->parse.depth.cur.expr != 1)
|
||||
{
|
||||
if (!MATCH(awk,TOK_IN))
|
||||
if (!(awk->option & QSE_AWK_TOLERANT) &&
|
||||
!MATCH(awk,TOK_IN))
|
||||
{
|
||||
qse_awk_clrpt (awk, nde);
|
||||
SETERR_TOK (awk, QSE_AWK_EKWIN);
|
||||
@ -4611,6 +4630,21 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
||||
|
||||
return (qse_awk_nde_t*)nde;
|
||||
}
|
||||
else if (awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
/* in the tolerant mode, we treat print and printf
|
||||
* as a function like getline */
|
||||
if (MATCH(awk,TOK_PRINT))
|
||||
{
|
||||
if (get_token(awk) <= -1) return QSE_NULL;
|
||||
return parse_print (awk, xloc, QSE_AWK_NDE_PRINT);
|
||||
}
|
||||
else if (MATCH(awk,TOK_PRINTF))
|
||||
{
|
||||
if (get_token(awk) <= -1) return QSE_NULL;
|
||||
return parse_print (awk, xloc, QSE_AWK_NDE_PRINTF);
|
||||
}
|
||||
}
|
||||
|
||||
/* valid expression introducer is expected */
|
||||
if (MATCH(awk,TOK_NEWLINE))
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <qse/cmn/stdio.h>
|
||||
#endif
|
||||
|
||||
#define PRINT_IOERR -99
|
||||
|
||||
#define CMP_ERROR -99
|
||||
#define DEF_BUF_CAPA 256
|
||||
#define STACK_INCREMENT 512
|
||||
@ -242,6 +244,8 @@ static qse_awk_val_t* eval_lclidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||
static qse_awk_val_t* eval_argidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||
static qse_awk_val_t* eval_pos (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||
static qse_awk_val_t* eval_getline (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||
static qse_awk_val_t* eval_print (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||
static qse_awk_val_t* eval_printf (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||
|
||||
static int __raw_push (qse_awk_rtx_t* run, void* val);
|
||||
#define __raw_pop(run) \
|
||||
@ -1830,138 +1834,96 @@ static int run_block0 (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde)
|
||||
|
||||
static int run_statement (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||
{
|
||||
int xret;
|
||||
qse_awk_val_t* tmp;
|
||||
|
||||
ON_STATEMENT (rtx, nde);
|
||||
|
||||
switch (nde->type)
|
||||
{
|
||||
case QSE_AWK_NDE_NULL:
|
||||
{
|
||||
/* do nothing */
|
||||
xret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_BLK:
|
||||
{
|
||||
if (run_block (rtx,
|
||||
(qse_awk_nde_blk_t*)nde) == -1) return -1;
|
||||
xret = run_block (rtx, (qse_awk_nde_blk_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_IF:
|
||||
{
|
||||
if (run_if (rtx,
|
||||
(qse_awk_nde_if_t*)nde) == -1) return -1;
|
||||
xret = run_if (rtx, (qse_awk_nde_if_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_WHILE:
|
||||
case QSE_AWK_NDE_DOWHILE:
|
||||
{
|
||||
if (run_while (rtx,
|
||||
(qse_awk_nde_while_t*)nde) == -1) return -1;
|
||||
xret = run_while (rtx, (qse_awk_nde_while_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_FOR:
|
||||
{
|
||||
if (run_for (rtx,
|
||||
(qse_awk_nde_for_t*)nde) == -1) return -1;
|
||||
xret = run_for (rtx, (qse_awk_nde_for_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_FOREACH:
|
||||
{
|
||||
if (run_foreach (rtx,
|
||||
(qse_awk_nde_foreach_t*)nde) == -1) return -1;
|
||||
xret = run_foreach (rtx, (qse_awk_nde_foreach_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_BREAK:
|
||||
{
|
||||
if (run_break (rtx,
|
||||
(qse_awk_nde_break_t*)nde) == -1) return -1;
|
||||
xret = run_break (rtx, (qse_awk_nde_break_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_CONTINUE:
|
||||
{
|
||||
if (run_continue (rtx,
|
||||
(qse_awk_nde_continue_t*)nde) == -1) return -1;
|
||||
xret = run_continue (rtx, (qse_awk_nde_continue_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_RETURN:
|
||||
{
|
||||
if (run_return (rtx,
|
||||
(qse_awk_nde_return_t*)nde) == -1) return -1;
|
||||
xret = run_return (rtx, (qse_awk_nde_return_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_EXIT:
|
||||
{
|
||||
if (run_exit (rtx,
|
||||
(qse_awk_nde_exit_t*)nde) == -1) return -1;
|
||||
xret = run_exit (rtx, (qse_awk_nde_exit_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_NEXT:
|
||||
{
|
||||
if (run_next (rtx,
|
||||
(qse_awk_nde_next_t*)nde) == -1) return -1;
|
||||
xret = run_next (rtx, (qse_awk_nde_next_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_NEXTFILE:
|
||||
{
|
||||
if (run_nextfile (rtx,
|
||||
(qse_awk_nde_nextfile_t*)nde) == -1) return -1;
|
||||
xret = run_nextfile (rtx, (qse_awk_nde_nextfile_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_DELETE:
|
||||
{
|
||||
if (run_delete (rtx,
|
||||
(qse_awk_nde_delete_t*)nde) == -1) return -1;
|
||||
xret = run_delete (rtx, (qse_awk_nde_delete_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_RESET:
|
||||
{
|
||||
if (run_reset (rtx,
|
||||
(qse_awk_nde_reset_t*)nde) == -1) return -1;
|
||||
xret = run_reset (rtx, (qse_awk_nde_reset_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case QSE_AWK_NDE_PRINT:
|
||||
{
|
||||
if (run_print (rtx,
|
||||
(qse_awk_nde_print_t*)nde) == -1) return -1;
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT) goto __fallback__;
|
||||
xret = run_print (rtx, (qse_awk_nde_print_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_PRINTF:
|
||||
{
|
||||
if (run_printf (rtx,
|
||||
(qse_awk_nde_print_t*)nde) == -1) return -1;
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT) goto __fallback__;
|
||||
xret = run_printf (rtx, (qse_awk_nde_print_t*)nde);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
qse_awk_val_t* v;
|
||||
v = eval_expression (rtx, nde);
|
||||
if (v == QSE_NULL) return -1;
|
||||
|
||||
/* destroy the value if not referenced */
|
||||
qse_awk_rtx_refupval (rtx, v);
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
|
||||
__fallback__:
|
||||
tmp = eval_expression (rtx, nde);
|
||||
if (tmp == QSE_NULL) xret = -1;
|
||||
else
|
||||
{
|
||||
/* destroy the value if not referenced */
|
||||
qse_awk_rtx_refupval (rtx, tmp);
|
||||
qse_awk_rtx_refdownval (rtx, tmp);
|
||||
xret = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return xret;
|
||||
}
|
||||
|
||||
static int run_if (qse_awk_rtx_t* rtx, qse_awk_nde_if_t* nde)
|
||||
@ -2738,7 +2700,7 @@ static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
qse_char_t* out = QSE_NULL;
|
||||
const qse_char_t* dst;
|
||||
qse_awk_val_t* v;
|
||||
int n;
|
||||
int n, xret = 0;
|
||||
|
||||
QSE_ASSERT (
|
||||
(nde->out_type == QSE_AWK_OUT_PIPE && nde->out != QSE_NULL) ||
|
||||
@ -2813,9 +2775,16 @@ static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
QSE_STR_LEN(&rtx->inrec.line));
|
||||
if (n <= -1 /*&& rtx->errinf.num != QSE_AWK_EIOIMPL*/)
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
xret = PRINT_IOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2842,9 +2811,16 @@ static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
rtx->gbl.ofs.len);
|
||||
if (n <= -1 /*&& rtx->errinf.num != QSE_AWK_EIOIMPL*/)
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
xret = PRINT_IOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2860,10 +2836,17 @@ static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
rtx, nde->out_type, dst, v);
|
||||
if (n <= -1 /*&& rtx->errinf.num != QSE_AWK_EIOIMPL*/)
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
xret = PRINT_IOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
@ -2876,9 +2859,16 @@ static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
rtx->gbl.ors.ptr, rtx->gbl.ors.len);
|
||||
if (n <= -1 /*&& rtx->errinf.num != QSE_AWK_EIOIMPL*/)
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
xret = PRINT_IOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* unlike printf, flushio() is not needed here as print
|
||||
@ -2887,7 +2877,7 @@ static int run_print (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
if (out) QSE_AWK_FREE (rtx->awk, out);
|
||||
|
||||
/*skip_write:*/
|
||||
return 0;
|
||||
return xret;
|
||||
}
|
||||
|
||||
static int run_printf (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
@ -2896,7 +2886,7 @@ static int run_printf (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
const qse_char_t* dst;
|
||||
qse_awk_val_t* v;
|
||||
qse_awk_nde_t* head;
|
||||
int n;
|
||||
int n, xret = 0;
|
||||
|
||||
QSE_ASSERT (
|
||||
(nde->out_type == QSE_AWK_OUT_PIPE && nde->out != QSE_NULL) ||
|
||||
@ -2957,7 +2947,7 @@ static int run_printf (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
dst = (out == QSE_NULL)? QSE_T(""): out;
|
||||
|
||||
QSE_ASSERTX (nde->args != QSE_NULL,
|
||||
"a valid printf statement should have at least one argument. the parser must ensure this.");
|
||||
"valid printf statement should have at least one argument. the parser must ensure this.");
|
||||
|
||||
if (nde->args->type == QSE_AWK_NDE_GRP)
|
||||
{
|
||||
@ -2968,7 +2958,7 @@ static int run_printf (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
else head = nde->args;
|
||||
|
||||
QSE_ASSERTX (head != QSE_NULL,
|
||||
"a valid printf statement should have at least one argument. the parser must ensure this.");
|
||||
"valid printf statement should have at least one argument. the parser must ensure this.");
|
||||
|
||||
v = eval_expression (rtx, head);
|
||||
if (v == QSE_NULL)
|
||||
@ -2985,36 +2975,58 @@ static int run_printf (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde)
|
||||
n = qse_awk_rtx_writeio_val (rtx, nde->out_type, dst, v);
|
||||
if (n <= -1 /*&& rtx->errinf.num != QSE_AWK_EIOIMPL*/)
|
||||
{
|
||||
if (out != QSE_NULL) QSE_AWK_FREE (rtx->awk, out);
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
xret = PRINT_IOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out != QSE_NULL) QSE_AWK_FREE (rtx->awk, out);
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* perform the formatted output */
|
||||
if (output_formatted (
|
||||
n = output_formatted (
|
||||
rtx, nde->out_type, dst,
|
||||
((qse_awk_val_str_t*)v)->val.ptr,
|
||||
((qse_awk_val_str_t*)v)->val.len,
|
||||
head->next) == -1)
|
||||
head->next);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (out != QSE_NULL) QSE_AWK_FREE (rtx->awk, out);
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
if (n == PRINT_IOERR) xret = n;
|
||||
else
|
||||
{
|
||||
if (out != QSE_NULL) QSE_AWK_FREE (rtx->awk, out);
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
ADJERR_LOC (rtx, &nde->loc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
|
||||
|
||||
/*skip_write:*/
|
||||
n = qse_awk_rtx_flushio (rtx, nde->out_type, dst);
|
||||
if (qse_awk_rtx_flushio (rtx, nde->out_type, dst) <= -1)
|
||||
{
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
xret = PRINT_IOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out != QSE_NULL) QSE_AWK_FREE (rtx->awk, out);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (out != QSE_NULL) QSE_AWK_FREE (rtx->awk, out);
|
||||
|
||||
return n;
|
||||
return xret;
|
||||
}
|
||||
|
||||
static int output_formatted (
|
||||
@ -3030,7 +3042,17 @@ static int output_formatted (
|
||||
if (ptr == QSE_NULL) return -1;
|
||||
|
||||
n = qse_awk_rtx_writeio_str (rtx, out_type, dst, ptr, len);
|
||||
if (n <= -1 /*&& rtx->errinf.num != QSE_AWK_EIOIMPL*/) return -1;
|
||||
if (n <= -1 /*&& rtx->errinf.num != QSE_AWK_EIOIMPL*/)
|
||||
{
|
||||
if (rtx->awk->option & QSE_AWK_TOLERANT)
|
||||
{
|
||||
return PRINT_IOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3145,7 +3167,9 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||
eval_lclidx,
|
||||
eval_argidx,
|
||||
eval_pos,
|
||||
eval_getline
|
||||
eval_getline,
|
||||
eval_print,
|
||||
eval_printf
|
||||
};
|
||||
|
||||
qse_awk_val_t* v;
|
||||
@ -3173,11 +3197,44 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||
|
||||
static qse_awk_val_t* eval_group (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||
{
|
||||
#if 0
|
||||
/* eval_binop_in evaluates the QSE_AWK_NDE_GRP specially.
|
||||
* so this function should never be reached. */
|
||||
QSE_ASSERT (!"should never happen - NDE_GRP only for in");
|
||||
SETERR_LOC (rtx, QSE_AWK_EINTERN, &nde->loc);
|
||||
return QSE_NULL;
|
||||
#endif
|
||||
|
||||
/* a group can be evauluated in a normal context
|
||||
* if a program is parsed with QSE_AWK_TOLERANT on.
|
||||
* before the introduction of this option, the grouped
|
||||
* expression was valid only coerced with the 'in'
|
||||
* operator.
|
||||
* */
|
||||
|
||||
/* when a group is evaluated in a normal context,
|
||||
* we return the last expression as a value. */
|
||||
|
||||
qse_awk_val_t* val;
|
||||
qse_awk_nde_t* np;
|
||||
|
||||
np = ((qse_awk_nde_grp_t*)nde)->body;
|
||||
|
||||
QSE_ASSERT (np != QSE_NULL);
|
||||
|
||||
loop:
|
||||
val = eval_expression (rtx, np);
|
||||
if (val == QSE_NULL) return QSE_NULL;
|
||||
|
||||
np = np->next;
|
||||
if (np)
|
||||
{
|
||||
qse_awk_rtx_refupval (rtx, val);
|
||||
qse_awk_rtx_refdownval (rtx, val);
|
||||
goto loop;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static qse_awk_val_t* eval_assignment (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||
@ -6304,6 +6361,22 @@ skip_read:
|
||||
return res;
|
||||
}
|
||||
|
||||
static qse_awk_val_t* eval_print (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||
{
|
||||
int n = run_print (run, (qse_awk_nde_print_t*)nde);
|
||||
if (n == PRINT_IOERR) n = -1; /* let print return -1 */
|
||||
else if (n <= -1) return QSE_NULL;
|
||||
return qse_awk_rtx_makeintval (run, n);
|
||||
}
|
||||
|
||||
static qse_awk_val_t* eval_printf (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||
{
|
||||
int n = run_printf (run, (qse_awk_nde_print_t*)nde);
|
||||
if (n == PRINT_IOERR) n = -1; /* let print return -1 */
|
||||
else if (n <= -1) return QSE_NULL;
|
||||
return qse_awk_rtx_makeintval (run, n);
|
||||
}
|
||||
|
||||
static int __raw_push (qse_awk_rtx_t* run, void* val)
|
||||
{
|
||||
if (run->stack_top >= run->stack_limit)
|
||||
|
@ -149,6 +149,38 @@ static int print_tabs (qse_awk_t* awk, int depth)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_printx (qse_awk_t* awk, qse_awk_nde_print_t* px)
|
||||
{
|
||||
qse_cstr_t kw;
|
||||
|
||||
if (px->type == QSE_AWK_NDE_PRINT)
|
||||
{
|
||||
qse_awk_getkwname (awk, QSE_AWK_KWID_PRINT, &kw);
|
||||
PUT_SRCSTRN (awk, kw.ptr, kw.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_awk_getkwname (awk, QSE_AWK_KWID_PRINTF, &kw);
|
||||
PUT_SRCSTRN (awk, kw.ptr, kw.len);
|
||||
}
|
||||
|
||||
if (px->args != QSE_NULL)
|
||||
{
|
||||
PUT_SRCSTR (awk, QSE_T(" "));
|
||||
PRINT_EXPR_LIST (awk, px->args);
|
||||
}
|
||||
|
||||
if (px->out != QSE_NULL)
|
||||
{
|
||||
PUT_SRCSTR (awk, QSE_T(" "));
|
||||
PUT_SRCSTR (awk, print_outop_str[px->out_type]);
|
||||
PUT_SRCSTR (awk, QSE_T(" "));
|
||||
PRINT_EXPR (awk, px->out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
||||
{
|
||||
qse_cstr_t kw;
|
||||
@ -650,8 +682,18 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_PRINT:
|
||||
case QSE_AWK_NDE_PRINTF:
|
||||
{
|
||||
PUT_SRCSTR (awk, QSE_T("("));
|
||||
if (print_printx (awk, (qse_awk_nde_print_t*)nde) <= -1) return -1;
|
||||
PUT_SRCSTR (awk, QSE_T(")"));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
qse_awk_seterrnum (awk, QSE_AWK_EINTERN, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -998,35 +1040,8 @@ static int print_stmt (qse_awk_t* awk, qse_awk_nde_t* p, int depth)
|
||||
case QSE_AWK_NDE_PRINT:
|
||||
case QSE_AWK_NDE_PRINTF:
|
||||
{
|
||||
qse_awk_nde_print_t* px = (qse_awk_nde_print_t*)p;
|
||||
|
||||
PRINT_TABS (awk, depth);
|
||||
|
||||
if (p->type == QSE_AWK_NDE_PRINT)
|
||||
{
|
||||
qse_awk_getkwname (awk, QSE_AWK_KWID_PRINT, &kw);
|
||||
PUT_SRCSTRN (awk, kw.ptr, kw.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_awk_getkwname (awk, QSE_AWK_KWID_PRINTF, &kw);
|
||||
PUT_SRCSTRN (awk, kw.ptr, kw.len);
|
||||
}
|
||||
|
||||
if (px->args != QSE_NULL)
|
||||
{
|
||||
PUT_SRCSTR (awk, QSE_T(" "));
|
||||
PRINT_EXPR_LIST (awk, px->args);
|
||||
}
|
||||
|
||||
if (px->out != QSE_NULL)
|
||||
{
|
||||
PUT_SRCSTR (awk, QSE_T(" "));
|
||||
PUT_SRCSTR (awk, print_outop_str[px->out_type]);
|
||||
PUT_SRCSTR (awk, QSE_T(" "));
|
||||
PRINT_EXPR (awk, px->out);
|
||||
}
|
||||
|
||||
if (print_printx (awk, (qse_awk_nde_print_t*)p) <= -1) return -1;
|
||||
PUT_SRCSTR (awk, QSE_T(";"));
|
||||
PUT_NL (awk);
|
||||
break;
|
||||
@ -1038,6 +1053,7 @@ static int print_stmt (qse_awk_t* awk, qse_awk_nde_t* p, int depth)
|
||||
PRINT_EXPR (awk, p);
|
||||
PUT_SRCSTR (awk, QSE_T(";"));
|
||||
PUT_NL (awk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user