From 3bfaaa2bc9e08099ad4d5d30864d3fb533dabda6 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 12 May 2019 17:03:30 +0000 Subject: [PATCH] added the unique_id field to qse_awk_sio_arg_t to implement the single time inclusion feature. added primitive logic to check and remember inclusion --- qse/include/qse/awk/awk.h | 5 ++ qse/lib/awk/awk-prv.h | 7 ++ qse/lib/awk/awk.c | 11 ++- qse/lib/awk/mod-sys.c | 160 +++++++++++++++++++++++++++++--------- qse/lib/awk/parse.c | 98 ++++++++++++++++------- qse/lib/awk/parse.h | 1 + qse/lib/awk/std.c | 35 +++------ 7 files changed, 226 insertions(+), 91 deletions(-) diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 387498de..0af0cc52 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -577,6 +577,11 @@ struct qse_awk_sio_arg_t */ void* handle; + /** + * [OUT] unique id set by an input handler. it is used for a single time inclusion check. + */ + qse_uint8_t unique_id[16]; + /** * [IN] points to the includer. #QSE_NULL for the toplevel. * diff --git a/qse/lib/awk/awk-prv.h b/qse/lib/awk/awk-prv.h index d6ed9e63..d4e40a31 100644 --- a/qse/lib/awk/awk-prv.h +++ b/qse/lib/awk/awk-prv.h @@ -243,6 +243,13 @@ struct qse_awk_t */ qse_size_t lparen_seq; qse_size_t lparen_last_closed; + + struct + { + qse_uint8_t* ptr; + qse_size_t count; + qse_size_t capa; + } incl_hist; } parse; /* source code management */ diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index 4842788f..69f565fd 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -293,6 +293,7 @@ void qse_awk_fini (qse_awk_t* awk) fini_token (&awk->tok); fini_token (&awk->ptok); + if (awk->parse.incl_hist.ptr) qse_awk_freemem (awk, awk->parse.incl_hist.ptr); qse_awk_clearsionames (awk); /* destroy dynamically allocated options */ @@ -349,6 +350,8 @@ void qse_awk_clear (qse_awk_t* awk) awk->parse.depth.incl = 0; awk->parse.pragmas = (awk->opt.trait & QSE_AWK_IMPLICIT); + awk->parse.incl_hist.count =0; + /* clear parse trees */ /*awk->tree.ngbls_base = 0; awk->tree.ngbls = 0; */ @@ -358,7 +361,7 @@ void qse_awk_clear (qse_awk_t* awk) awk->tree.cur_fun.len = 0; qse_htb_clear (awk->tree.funs); - if (awk->tree.begin != QSE_NULL) + if (awk->tree.begin) { /*QSE_ASSERT (awk->tree.begin->next == QSE_NULL);*/ qse_awk_clrpt (awk, awk->tree.begin); @@ -366,7 +369,7 @@ void qse_awk_clear (qse_awk_t* awk) awk->tree.begin_tail = QSE_NULL; } - if (awk->tree.end != QSE_NULL) + if (awk->tree.end) { /*QSE_ASSERT (awk->tree.end->next == QSE_NULL);*/ qse_awk_clrpt (awk, awk->tree.end); @@ -374,7 +377,7 @@ void qse_awk_clear (qse_awk_t* awk) awk->tree.end_tail = QSE_NULL; } - while (awk->tree.chain != QSE_NULL) + while (awk->tree.chain) { qse_awk_chain_t* next = awk->tree.chain->next; @@ -398,7 +401,7 @@ void qse_awk_clear (qse_awk_t* awk) void* qse_awk_getxtn (qse_awk_t* awk) { - return QSE_XTN (awk); + return QSE_XTN(awk); } void qse_awk_getprm (qse_awk_t* awk, qse_awk_prm_t* prm) diff --git a/qse/lib/awk/mod-sys.c b/qse/lib/awk/mod-sys.c index 3da4e5f2..87c9a170 100644 --- a/qse/lib/awk/mod-sys.c +++ b/qse/lib/awk/mod-sys.c @@ -105,7 +105,7 @@ static int fnc_fork (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) pid = fork (); #endif - retv = qse_awk_rtx_makeintval (rtx, pid); + retv = qse_awk_rtx_makeintval(rtx, pid); if (retv == QSE_NULL) return -1; qse_awk_rtx_setretval (rtx, retv); @@ -117,29 +117,112 @@ static int fnc_wait (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) qse_awk_int_t pid; qse_awk_val_t* retv; int rx; + qse_size_t nargs; + qse_awk_int_t opts = 0; + int status; -/* TODO: handle more parameters */ + nargs = qse_awk_rtx_getnargs(rtx); + if (nargs >= 3) + { + if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 2), &opts) <= -1) return -1; + } - rx = qse_awk_rtx_valtoint (rtx, qse_awk_rtx_getarg (rtx, 0), &pid); + rx = qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &pid); if (rx >= 0) { #if defined(_WIN32) /* TOOD: implement this*/ rx = -1; + status = 0; #elif defined(__OS2__) /* TOOD: implement this*/ rx = -1; + status = 0; #elif defined(__DOS__) /* TOOD: implement this*/ rx = -1; + status = 0; #else - rx = waitpid (pid, QSE_NULL, 0); + rx = waitpid(pid, &status, opts); #endif } - retv = qse_awk_rtx_makeintval (rtx, rx); - if (retv == QSE_NULL) return -1; + retv = qse_awk_rtx_makeintval(rtx, rx); + if (!retv) return -1; + if (nargs >= 2) + { + qse_awk_val_t* sv; + int x; + + sv = qse_awk_rtx_makeintval(rtx, status); + if (!sv) return -1; + + qse_awk_rtx_refupval (rtx, sv); + x = qse_awk_rtx_setrefval(rtx, (qse_awk_val_ref_t*)qse_awk_rtx_getarg(rtx, 1), sv); + qse_awk_rtx_refdownval (rtx, sv); + if (x <= -1) + { + qse_awk_rtx_freemem (rtx, retv); + return -1; + } + } + + qse_awk_rtx_setretval (rtx, retv); + return 0; +} + +static int fnc_wifexited (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + qse_awk_int_t wstatus; + qse_awk_val_t* retv; + if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; + retv = qse_awk_rtx_makeintval(rtx, WIFEXITED(wstatus)); + if (!retv) return -1; + qse_awk_rtx_setretval (rtx, retv); + return 0; +} + +static int fnc_wexitstatus (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + qse_awk_int_t wstatus; + qse_awk_val_t* retv; + if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; + retv = qse_awk_rtx_makeintval(rtx, WEXITSTATUS(wstatus)); + if (!retv) return -1; + qse_awk_rtx_setretval (rtx, retv); + return 0; +} + +static int fnc_wifsignaled (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + qse_awk_int_t wstatus; + qse_awk_val_t* retv; + if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; + retv = qse_awk_rtx_makeintval(rtx, WIFSIGNALED(wstatus)); + if (!retv) return -1; + qse_awk_rtx_setretval (rtx, retv); + return 0; +} + +static int fnc_wtermsig (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + qse_awk_int_t wstatus; + qse_awk_val_t* retv; + if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; + retv = qse_awk_rtx_makeintval(rtx, WTERMSIG(wstatus)); + if (!retv) return -1; + qse_awk_rtx_setretval (rtx, retv); + return 0; +} + +static int fnc_wcoredump (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + qse_awk_int_t wstatus; + qse_awk_val_t* retv; + if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; + retv = qse_awk_rtx_makeintval(rtx, WCOREDUMP(wstatus)); + if (!retv) return -1; qse_awk_rtx_setretval (rtx, retv); return 0; } @@ -150,8 +233,8 @@ static int fnc_kill (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) qse_awk_val_t* retv; int rx; - if (qse_awk_rtx_valtoint (rtx, qse_awk_rtx_getarg (rtx, 0), &pid) <= -1 || - qse_awk_rtx_valtoint (rtx, qse_awk_rtx_getarg (rtx, 1), &sig) <= -1) + if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg (rtx, 0), &pid) <= -1 || + qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg (rtx, 1), &sig) <= -1) { rx = -1; } @@ -426,7 +509,7 @@ static int fnc_sleep (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) qse_awk_val_t* retv; int rx; - rx = qse_awk_rtx_valtonum (rtx, qse_awk_rtx_getarg (rtx, 0), &lv, &fv); + rx = qse_awk_rtx_valtonum(rtx, qse_awk_rtx_getarg (rtx, 0), &lv, &fv); if (rx == 0) { #if defined(_WIN32) @@ -534,7 +617,7 @@ static int fnc_mktime (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) qse_size_t nargs; qse_awk_val_t* retv; - nargs = qse_awk_rtx_getnargs (rtx); + nargs = qse_awk_rtx_getnargs(rtx); if (nargs >= 1) { int sign; @@ -1240,29 +1323,34 @@ static fnctab_t fnctab[] = { /* keep this table sorted for binary search in query(). */ - { QSE_T("closelog"), { { 0, 0, QSE_NULL }, fnc_closelog, 0 } }, - { QSE_T("fork"), { { 0, 0, QSE_NULL }, fnc_fork, 0 } }, - { QSE_T("getegid"), { { 0, 0, QSE_NULL }, fnc_getegid, 0 } }, - { QSE_T("getenv"), { { 1, 1, QSE_NULL }, fnc_getenv, 0 } }, - { QSE_T("geteuid"), { { 0, 0, QSE_NULL }, fnc_geteuid, 0 } }, - { QSE_T("getgid"), { { 0, 0, QSE_NULL }, fnc_getgid, 0 } }, - { QSE_T("getnwifcfg"), { { 3, 3, QSE_T("vvr") }, fnc_getnwifcfg, 0 } }, - { QSE_T("getpgid"), { { 0, 0, QSE_NULL }, fnc_getpgid, 0 } }, - { QSE_T("getpid"), { { 0, 0, QSE_NULL }, fnc_getpid, 0 } }, - { QSE_T("getppid"), { { 0, 0, QSE_NULL }, fnc_getppid, 0 } }, - { QSE_T("gettid"), { { 0, 0, QSE_NULL }, fnc_gettid, 0 } }, - { QSE_T("gettime"), { { 0, 0, QSE_NULL }, fnc_gettime, 0 } }, - { QSE_T("getuid"), { { 0, 0, QSE_NULL }, fnc_getuid, 0 } }, - { QSE_T("kill"), { { 2, 2, QSE_NULL }, fnc_kill, 0 } }, - { QSE_T("mktime"), { { 0, 1, QSE_NULL }, fnc_mktime, 0 } }, - { QSE_T("openlog"), { { 3, 3, QSE_NULL }, fnc_openlog, 0 } }, - { QSE_T("settime"), { { 1, 1, QSE_NULL }, fnc_settime, 0 } }, - { QSE_T("sleep"), { { 1, 1, QSE_NULL }, fnc_sleep, 0 } }, - { QSE_T("strftime"), { { 2, 2, QSE_NULL }, fnc_strftime, 0 } }, - { QSE_T("system"), { { 1, 1, QSE_NULL }, fnc_system, 0 } }, - { QSE_T("systime"), { { 0, 0, QSE_NULL }, fnc_gettime, 0 } }, /* alias to gettime() */ - { QSE_T("wait"), { { 1, 1, QSE_NULL }, fnc_wait, 0 } }, - { QSE_T("writelog"), { { 2, 2, QSE_NULL }, fnc_writelog, 0 } } + { QSE_T("WCOREDUMP"), { { 1, 1, QSE_NULL }, fnc_wcoredump, 0 } }, + { QSE_T("WEXITSTATUS"), { { 1, 1, QSE_NULL }, fnc_wexitstatus, 0 } }, + { QSE_T("WIFEXITED"), { { 1, 1, QSE_NULL }, fnc_wifexited, 0 } }, + { QSE_T("WIFSIGNALED"), { { 1, 1, QSE_NULL }, fnc_wifsignaled, 0 } }, + { QSE_T("WTERMSIG"), { { 1, 1, QSE_NULL }, fnc_wtermsig, 0 } }, + { QSE_T("closelog"), { { 0, 0, QSE_NULL }, fnc_closelog, 0 } }, + { QSE_T("fork"), { { 0, 0, QSE_NULL }, fnc_fork, 0 } }, + { QSE_T("getegid"), { { 0, 0, QSE_NULL }, fnc_getegid, 0 } }, + { QSE_T("getenv"), { { 1, 1, QSE_NULL }, fnc_getenv, 0 } }, + { QSE_T("geteuid"), { { 0, 0, QSE_NULL }, fnc_geteuid, 0 } }, + { QSE_T("getgid"), { { 0, 0, QSE_NULL }, fnc_getgid, 0 } }, + { QSE_T("getnwifcfg"), { { 3, 3, QSE_T("vvr") }, fnc_getnwifcfg, 0 } }, + { QSE_T("getpgid"), { { 0, 0, QSE_NULL }, fnc_getpgid, 0 } }, + { QSE_T("getpid"), { { 0, 0, QSE_NULL }, fnc_getpid, 0 } }, + { QSE_T("getppid"), { { 0, 0, QSE_NULL }, fnc_getppid, 0 } }, + { QSE_T("gettid"), { { 0, 0, QSE_NULL }, fnc_gettid, 0 } }, + { QSE_T("gettime"), { { 0, 0, QSE_NULL }, fnc_gettime, 0 } }, + { QSE_T("getuid"), { { 0, 0, QSE_NULL }, fnc_getuid, 0 } }, + { QSE_T("kill"), { { 2, 2, QSE_NULL }, fnc_kill, 0 } }, + { QSE_T("mktime"), { { 0, 1, QSE_NULL }, fnc_mktime, 0 } }, + { QSE_T("openlog"), { { 3, 3, QSE_NULL }, fnc_openlog, 0 } }, + { QSE_T("settime"), { { 1, 1, QSE_NULL }, fnc_settime, 0 } }, + { QSE_T("sleep"), { { 1, 1, QSE_NULL }, fnc_sleep, 0 } }, + { QSE_T("strftime"), { { 2, 2, QSE_NULL }, fnc_strftime, 0 } }, + { QSE_T("system"), { { 1, 1, QSE_NULL }, fnc_system, 0 } }, + { QSE_T("systime"), { { 0, 0, QSE_NULL }, fnc_gettime, 0 } }, /* alias to gettime() */ + { QSE_T("wait"), { { 1, 3, QSE_T("vrv") }, fnc_wait, 0 } }, + { QSE_T("writelog"), { { 2, 2, QSE_NULL }, fnc_writelog, 0 } } }; #if !defined(SIGHUP) @@ -1341,11 +1429,9 @@ static inttab_t inttab[] = { QSE_T("SIGKILL"), { SIGKILL } }, { QSE_T("SIGQUIT"), { SIGQUIT } }, { QSE_T("SIGSEGV"), { SIGSEGV } }, - { QSE_T("SIGTERM"), { SIGTERM } } + { QSE_T("SIGTERM"), { SIGTERM } }, -/* - { QSE_T("WNOHANG"), { WNOHANG } }, -*/ + { QSE_T("WNOHANG"), { WNOHANG } } }; static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym) diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index dc04ab8c..5dd74e43 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -117,6 +117,7 @@ enum tok_t /* === extended reserved words === */ TOK_XGLOBAL, TOK_XLOCAL, + TOK_XINCLONE, TOK_XINCLUDE, TOK_XPRAGMA, TOK_XABORT, @@ -261,6 +262,7 @@ static kwent_t kwtab[] = * also keep it sorted by the first field for binary search */ { { QSE_T("@abort"), 6 }, TOK_XABORT, 0 }, { { QSE_T("@global"), 7 }, TOK_XGLOBAL, 0 }, + { { QSE_T("@inclone"), 8 }, TOK_XINCLONE, 0 }, { { QSE_T("@include"), 8 }, TOK_XINCLUDE, 0 }, { { QSE_T("@local"), 6 }, TOK_XLOCAL, 0 }, { { QSE_T("@pragma"), 7 }, TOK_XPRAGMA, 0 }, @@ -742,7 +744,37 @@ static int end_include (qse_awk_t* awk) return 1; /* ended the included file successfully */ } -static int begin_include (qse_awk_t* awk) +static int ever_included (qse_awk_t* awk, qse_awk_sio_arg_t* arg) +{ + qse_size_t i; + for (i = 0; i < awk->parse.incl_hist.count; i++) + { + if (QSE_MEMCMP(&awk->parse.incl_hist.ptr[i * QSE_SIZEOF(arg->unique_id)], arg->unique_id, QSE_SIZEOF(arg->unique_id)) == 0) return 1; + } + return 0; +} + +static int record_ever_included (qse_awk_t* awk, qse_awk_sio_arg_t* arg) +{ + if (awk->parse.incl_hist.count >= awk->parse.incl_hist.capa) + { + qse_uint8_t* tmp; + qse_size_t newcapa; + + newcapa = awk->parse.incl_hist.capa + 128; + tmp = (qse_uint8_t*)qse_awk_reallocmem(awk, awk->parse.incl_hist.ptr, newcapa * QSE_SIZEOF(arg->unique_id)); + if (!tmp) return -1; + + awk->parse.incl_hist.ptr = tmp; + awk->parse.incl_hist.capa = newcapa; + } + + QSE_MEMCPY (&awk->parse.incl_hist.ptr[awk->parse.incl_hist.count * QSE_SIZEOF(arg->unique_id)], arg->unique_id, QSE_SIZEOF(arg->unique_id)); + awk->parse.incl_hist.count++; + return 0; +} + +static int begin_include (qse_awk_t* awk, int once) { qse_awk_sio_arg_t* arg = QSE_NULL; qse_link_t* link; @@ -769,7 +801,7 @@ static int begin_include (qse_awk_t* awk) /* store the include-file name into a list * and this list is not deleted after qse_awk_parse. - * the errinfo.loc.file can point to a string here. */ + * the errinfo.loc.file can point to a include_oncestring here. */ link = (qse_link_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*link) + QSE_SIZEOF(*arg) + QSE_SIZEOF(qse_char_t) * (QSE_STR_LEN(awk->tok.name) + 1)); if (link == QSE_NULL) @@ -791,7 +823,6 @@ static int begin_include (qse_awk_t* awk) arg->name = (const qse_char_t*)(link + 1); arg->line = 1; arg->colm = 1; - /* let the argument's prev field point to the current */ arg->prev = awk->sio.inp; @@ -815,15 +846,23 @@ static int begin_include (qse_awk_t* awk) awk->sio.inp = arg; awk->parse.depth.incl++; - /* read in the first character in the included file. - * so the next call to get_token() sees the character read - * from this file. */ - if (get_char(awk) <= -1 || get_token(awk) <= -1) + if (once && ever_included(awk, arg)) { end_include (awk); - /* i don't jump to oops since i've called - * end_include() where awk->sio.inp/arg is freed. */ - return -1; + /* it has been included previously. don't include this file again. */ + } + else + { + /* read in the first character in the included file. + * so the next call to get_token() sees the character read + * from this file. */ + if (record_ever_included(awk, arg) <= -1 || get_char(awk) <= -1 || get_token(awk) <= -1) + { + end_include (awk); + /* i don't jump to oops since i've called + * end_include() where awk->sio.inp/arg is freed. */ + return -1; + } } return 0; @@ -865,15 +904,18 @@ static int parse_progunit (qse_awk_t* awk) return -1; } } - else if (MATCH(awk, TOK_XINCLUDE)) + else if (MATCH(awk, TOK_XINCLUDE) || MATCH(awk, TOK_XINCLONE)) { + int once; + if (awk->opt.depth.s.incl > 0 && awk->parse.depth.incl >= awk->opt.depth.s.incl) { SETERR_LOC (awk, QSE_AWK_EINCLTD, &awk->ptok.loc); return -1; } - + + once = MATCH(awk, TOK_XINCLONE); if (get_token(awk) <= -1) return -1; if (!MATCH(awk, TOK_STR)) @@ -882,7 +924,7 @@ static int parse_progunit (qse_awk_t* awk) return -1; } - if (begin_include(awk) <= -1) return -1; + if (begin_include(awk, once) <= -1) return -1; /* i just return without doing anything special * after having setting up the environment for file @@ -1515,16 +1557,19 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in if (get_token(awk) <= -1) return QSE_NULL; } - if (MATCH(awk,TOK_XINCLUDE)) + if (MATCH(awk,TOK_XINCLUDE) || MATCH(awk, TOK_XINCLONE)) { /* @include ... */ + int once; + if (awk->opt.depth.s.incl > 0 && awk->parse.depth.incl >= awk->opt.depth.s.incl) { SETERR_LOC (awk, QSE_AWK_EINCLTD, &awk->ptok.loc); return QSE_NULL; } - + + once = MATCH(awk, TOK_XINCLONE); if (get_token(awk) <= -1) return QSE_NULL; if (!MATCH(awk,TOK_STR)) @@ -1532,25 +1577,21 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in SETERR_LOC (awk, QSE_AWK_EINCLSTR, &awk->ptok.loc); return QSE_NULL; } - - if (begin_include (awk) <= -1) return QSE_NULL; + + if (begin_include(awk, once) <= -1) return QSE_NULL; } else if (MATCH(awk,TOK_XLOCAL)) { /* @local ... */ if (get_token(awk) <= -1) { - qse_arr_delete ( - awk->parse.lcls, nlcls, - QSE_ARR_SIZE(awk->parse.lcls)-nlcls); + qse_arr_delete (awk->parse.lcls, nlcls, QSE_ARR_SIZE(awk->parse.lcls)-nlcls); return QSE_NULL; } if (collect_locals (awk, nlcls, istop) == QSE_NULL) { - qse_arr_delete ( - awk->parse.lcls, nlcls, - QSE_ARR_SIZE(awk->parse.lcls)-nlcls); + qse_arr_delete (awk->parse.lcls, nlcls, QSE_ARR_SIZE(awk->parse.lcls)-nlcls); return QSE_NULL; } } @@ -1594,15 +1635,18 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in break; } - if (MATCH(awk,TOK_XINCLUDE)) + else if (MATCH(awk, TOK_XINCLUDE) || MATCH(awk, TOK_XINCLONE)) { + int once; + if (awk->opt.depth.s.incl > 0 && awk->parse.depth.incl >= awk->opt.depth.s.incl) { SETERR_LOC (awk, QSE_AWK_EINCLTD, &awk->ptok.loc); return QSE_NULL; } - + + once = MATCH(awk, TOK_XINCLONE); if (get_token(awk) <= -1) return QSE_NULL; if (!MATCH(awk,TOK_STR)) @@ -1610,8 +1654,8 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in SETERR_LOC (awk, QSE_AWK_EINCLSTR, &awk->ptok.loc); return QSE_NULL; } - - if (begin_include (awk) <= -1) return QSE_NULL; + + if (begin_include(awk, once) <= -1) return QSE_NULL; } else { diff --git a/qse/lib/awk/parse.h b/qse/lib/awk/parse.h index fca5bf1a..b3b24458 100644 --- a/qse/lib/awk/parse.h +++ b/qse/lib/awk/parse.h @@ -32,6 +32,7 @@ enum qse_awk_kwid_t { QSE_AWK_KWID_XABORT, QSE_AWK_KWID_XGLOBAL, + QSE_AWK_KWID_XINCLONE, QSE_AWK_KWID_XINCLUDE, QSE_AWK_KWID_XLOCAL, QSE_AWK_KWID_XPRAGMA, diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index e4634172..c7e9ae28 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -666,8 +666,7 @@ static int open_parsestd (qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn, qs } } -static qse_ssize_t sf_in_open ( - qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn) +static qse_ssize_t sf_in_open (qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn) { if (arg->prev == QSE_NULL) { @@ -707,12 +706,12 @@ static qse_ssize_t sf_in_open ( { const qse_char_t* outer; - outer = qse_sio_getpath (arg->prev->handle); + outer = qse_sio_getpath(arg->prev->handle); if (outer) { const qse_char_t* base; - base = qse_basename (outer); + base = qse_basename(outer); if (base != outer && arg->name[0] != QSE_T('/')) { qse_size_t tmplen, totlen, dirlen; @@ -721,11 +720,8 @@ static qse_ssize_t sf_in_open ( totlen = qse_strlen(arg->name) + dirlen; if (totlen >= QSE_COUNTOF(fbuf)) { - dbuf = qse_awk_allocmem ( - awk, QSE_SIZEOF(qse_char_t) * (totlen + 1) - ); - if (dbuf == QSE_NULL) return -1; - + dbuf = qse_awk_allocmem(awk, QSE_SIZEOF(qse_char_t) * (totlen + 1)); + if (!dbuf) return -1; path = dbuf; } else path = fbuf; @@ -740,8 +736,8 @@ static qse_ssize_t sf_in_open ( awk->mmgr, 0, path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH ); - if (dbuf) QSE_MMGR_FREE (awk->mmgr, dbuf); - if (arg->handle == QSE_NULL) + if (dbuf) qse_awk_freemem (awk, dbuf); + if (!arg->handle) { qse_cstr_t ea; ea.ptr = (qse_char_t*)arg->name; @@ -750,12 +746,12 @@ static qse_ssize_t sf_in_open ( return -1; } +/* TODO: set arg->unique_id.... to support @inclone */ return 0; } } -static qse_ssize_t sf_in_close ( - qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn) +static qse_ssize_t sf_in_close (qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn) { if (arg->prev == QSE_NULL) { @@ -785,9 +781,7 @@ static qse_ssize_t sf_in_close ( return 0; } -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) +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->prev == QSE_NULL) { @@ -876,9 +870,7 @@ static qse_ssize_t sf_in_read ( } } -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) +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); @@ -899,9 +891,7 @@ static qse_ssize_t sf_in ( } } -static qse_ssize_t sf_out ( - qse_awk_t* awk, qse_awk_sio_cmd_t cmd, - qse_awk_sio_arg_t* arg, qse_char_t* data, qse_size_t size) +static qse_ssize_t sf_out (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); @@ -915,7 +905,6 @@ static qse_ssize_t sf_out ( if (xtn->s.out.x->u.file.path == QSE_NULL || (xtn->s.out.x->u.file.path[0] == QSE_T('-') && xtn->s.out.x->u.file.path[1] == QSE_T('\0'))) - { /* no path name or - -> stdout */ xtn->s.out.u.file.sio = open_sio_std (