From 65c324d373f4d5d2586077f9567b259947ffd5f5 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 31 Oct 2012 09:43:56 +0000 Subject: [PATCH] added QSE_AWK_MODERN --- qse/cmd/awk/awk.c | 56 ++++++++++++++++++++++++++------------- qse/include/qse/awk/awk.h | 13 +++++---- qse/lib/awk/awk.c | 2 +- qse/lib/awk/parse.c | 14 +++++++++- qse/lib/awk/run.c | 10 ++++++- 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 366c7a86..16c6cc56 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -94,6 +94,8 @@ struct arg_t qse_cmgr_t* script_cmgr; qse_cmgr_t* console_cmgr; + unsigned int modern: 1; + unsigned int classic: 1; int opton; int optoff; qse_ulong_t memlimit; @@ -380,7 +382,7 @@ struct opttab_t } opttab[] = { { QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") }, - { QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("allow declared variables(local,global)") }, + { QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("enable local,global for variable declaration") }, { QSE_T("extrakws"), QSE_AWK_EXTRAKWS, QSE_T("enable abort,reset,nextofile,OFILENAME,@include") }, { QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") }, { QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") }, @@ -426,6 +428,8 @@ static void print_usage (QSE_FILE* out, const qse_char_t* argv0) qse_fprintf (out, QSE_T(" --script-encoding string specify script file encoding name\n")); qse_fprintf (out, QSE_T(" --console-encoding string specify console encoding name\n")); #endif + qse_fprintf (out, QSE_T(" --modern run in the modern mode(default)\n")); + qse_fprintf (out, QSE_T(" --classic run in the classic mode\n")); for (j = 0; opttab[j].name; j++) { @@ -519,6 +523,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) { static qse_opt_lng_t lng[] = { + { QSE_T(":implicit"), QSE_T('\0') }, { QSE_T(":explicit"), QSE_T('\0') }, { QSE_T(":extrakws"), QSE_T('\0') }, @@ -546,6 +551,9 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) { QSE_T(":script-encoding"), QSE_T('\0') }, { QSE_T(":console-encoding"), QSE_T('\0') }, + { QSE_T("modern"), QSE_T('\0') }, + { QSE_T("classic"), QSE_T('\0') }, + { QSE_T("version"), QSE_T('\0') }, { QSE_T("help"), QSE_T('h') }, { QSE_NULL, QSE_T('\0') } @@ -727,25 +735,35 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) goto oops; } } - - for (i = 0; opttab[i].name; i++) + else if (qse_strcmp(opt.lngopt, QSE_T("modern")) == 0) { - if (qse_strcmp (opt.lngopt, opttab[i].name) == 0) - { - if (qse_strcmp (opt.arg, QSE_T("off")) == 0) - arg->optoff |= opttab[i].opt; - else if (qse_strcmp (opt.arg, QSE_T("on")) == 0) - arg->opton |= opttab[i].opt; - else - { - print_error (QSE_T("invalid value '%s' for '%s' - use 'on' or 'off'\n"), opt.arg, opt.lngopt); - oops_ret = 3; - goto oops; - } - break; - } + arg->modern = 1; } + else if (qse_strcmp(opt.lngopt, QSE_T("classic")) == 0) + { + arg->classic = 1; + } + else + { + for (i = 0; opttab[i].name; i++) + { + if (qse_strcmp (opt.lngopt, opttab[i].name) == 0) + { + if (qse_strcmp (opt.arg, QSE_T("off")) == 0) + arg->optoff |= opttab[i].opt; + else if (qse_strcmp (opt.arg, QSE_T("on")) == 0) + arg->opton |= opttab[i].opt; + else + { + print_error (QSE_T("invalid value '%s' for '%s' - use 'on' or 'off'\n"), opt.arg, opt.lngopt); + oops_ret = 3; + goto oops; + } + break; + } + } + } break; } @@ -1010,7 +1028,9 @@ static int awk_main (int argc, qse_char_t* argv[]) goto oops; } - qse_awk_getopt (awk, QSE_AWK_TRAIT, &i); + if (arg.modern) i = QSE_AWK_MODERN; + else if (arg.classic) i = QSE_AWK_CLASSIC; + else qse_awk_getopt (awk, QSE_AWK_TRAIT, &i); if (arg.opton) i |= arg.opton; if (arg.optoff) i &= ~arg.optoff; qse_awk_setopt (awk, QSE_AWK_TRAIT, &i); diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index dc6366c7..216e338a 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1021,11 +1021,6 @@ enum qse_awk_trait_t */ QSE_AWK_STRICTNAMING = (1 << 15), - /** - * supports file inclusion by enabling a keyword 'include' - */ - QSE_AWK_INCLUDE = (1 << 16), - /** * makes AWK more fault-tolerant. * - prevents termination due to print and printf failure. @@ -1043,10 +1038,14 @@ enum qse_awk_trait_t * makes #qse_awk_t to behave compatibly with classical AWK * implementations */ - QSE_AWK_CLASSIC = + QSE_AWK_CLASSIC = QSE_AWK_IMPLICIT | QSE_AWK_RIO | QSE_AWK_NEWLINE | QSE_AWK_BLANKCONCAT | QSE_AWK_PABLOCK | - QSE_AWK_STRIPSTRSPC | QSE_AWK_STRICTNAMING + QSE_AWK_STRIPSTRSPC | QSE_AWK_STRICTNAMING, + + QSE_AWK_MODERN = + QSE_AWK_CLASSIC | QSE_AWK_EXTRAKWS | QSE_AWK_MAPTOVAR | + QSE_AWK_RWPIPE | QSE_AWK_REXBOUND | QSE_AWK_TOLERANT }; /* ------------------------------------------------------------------------ */ diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index 274499f7..bac15f05 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -209,7 +209,7 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_awk_prm_t* pr qse_lda_setscale (awk->parse.params, QSE_SIZEOF(qse_char_t)); qse_lda_setcopier (awk->parse.params, QSE_LDA_COPIER_INLINE); - awk->opt.trait = QSE_AWK_CLASSIC; + awk->opt.trait = QSE_AWK_MODERN; #if defined(__OS2__) || defined(_WIN32) || defined(__DOS__) awk->opt.trait |= QSE_AWK_CRLF; #endif diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 6d9e0eb2..784a3b9e 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -5206,6 +5206,7 @@ static qse_awk_nde_t* parse_fncall ( qse_awk_loc_t eloc; head = curr = QSE_NULL; + call = QSE_NULL; nargs = 0; if (noarg) goto make_node; @@ -5277,6 +5278,17 @@ make_node: call->args = head; call->nargs = nargs; + + if (nargs > call->u.fnc.arg.max) + { + SETERR_LOC (awk, QSE_AWK_EARGTM, xloc); + goto oops; + } + else if (nargs < call->u.fnc.arg.min) + { + SETERR_LOC (awk, QSE_AWK_EARGTF, xloc); + goto oops; + } } else { @@ -5293,7 +5305,6 @@ make_node: awk->parse.funs, name->ptr, name->len, call, 0) == QSE_NULL) { SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); - QSE_AWK_FREE (awk, call); goto oops; } } @@ -5301,6 +5312,7 @@ make_node: return (qse_awk_nde_t*)call; oops: + if (call) QSE_AWK_FREE (awk, call); if (head) qse_awk_clrpt (awk, head); return QSE_NULL; } diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index fb27f55c..918fc88d 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -5512,9 +5512,16 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde) { + /* intrinsic function */ + qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde; - /* intrinsic function */ + /* the parser must make sure taht the number of arguments + * is proper */ + QSE_ASSERT (call->nargs >= call->u.fnc.arg.min && + call->nargs <= call->u.fnc.arg.max); + +#if 0 if (call->nargs < call->u.fnc.arg.min) { SETERR_LOC (run, QSE_AWK_EARGTF, &nde->loc); @@ -5526,6 +5533,7 @@ static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde) SETERR_LOC (run, QSE_AWK_EARGTM, &nde->loc); return QSE_NULL; } +#endif return eval_call (run, nde, call->u.fnc.arg.spec, QSE_NULL, QSE_NULL, QSE_NULL); }