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
This commit is contained in:
hyung-hwan 2019-05-12 17:03:30 +00:00
parent eb9413907b
commit 3bfaaa2bc9
7 changed files with 226 additions and 91 deletions

View File

@ -577,6 +577,11 @@ struct qse_awk_sio_arg_t
*/ */
void* handle; 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. * [IN] points to the includer. #QSE_NULL for the toplevel.
* *

View File

@ -243,6 +243,13 @@ struct qse_awk_t
*/ */
qse_size_t lparen_seq; qse_size_t lparen_seq;
qse_size_t lparen_last_closed; qse_size_t lparen_last_closed;
struct
{
qse_uint8_t* ptr;
qse_size_t count;
qse_size_t capa;
} incl_hist;
} parse; } parse;
/* source code management */ /* source code management */

View File

@ -293,6 +293,7 @@ void qse_awk_fini (qse_awk_t* awk)
fini_token (&awk->tok); fini_token (&awk->tok);
fini_token (&awk->ptok); fini_token (&awk->ptok);
if (awk->parse.incl_hist.ptr) qse_awk_freemem (awk, awk->parse.incl_hist.ptr);
qse_awk_clearsionames (awk); qse_awk_clearsionames (awk);
/* destroy dynamically allocated options */ /* destroy dynamically allocated options */
@ -349,6 +350,8 @@ void qse_awk_clear (qse_awk_t* awk)
awk->parse.depth.incl = 0; awk->parse.depth.incl = 0;
awk->parse.pragmas = (awk->opt.trait & QSE_AWK_IMPLICIT); awk->parse.pragmas = (awk->opt.trait & QSE_AWK_IMPLICIT);
awk->parse.incl_hist.count =0;
/* clear parse trees */ /* clear parse trees */
/*awk->tree.ngbls_base = 0; /*awk->tree.ngbls_base = 0;
awk->tree.ngbls = 0; */ awk->tree.ngbls = 0; */
@ -358,7 +361,7 @@ void qse_awk_clear (qse_awk_t* awk)
awk->tree.cur_fun.len = 0; awk->tree.cur_fun.len = 0;
qse_htb_clear (awk->tree.funs); 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_ASSERT (awk->tree.begin->next == QSE_NULL);*/
qse_awk_clrpt (awk, awk->tree.begin); 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; 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_ASSERT (awk->tree.end->next == QSE_NULL);*/
qse_awk_clrpt (awk, awk->tree.end); 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; 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; 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) 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) void qse_awk_getprm (qse_awk_t* awk, qse_awk_prm_t* prm)

View File

@ -105,7 +105,7 @@ static int fnc_fork (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
pid = fork (); pid = fork ();
#endif #endif
retv = qse_awk_rtx_makeintval (rtx, pid); retv = qse_awk_rtx_makeintval(rtx, pid);
if (retv == QSE_NULL) return -1; if (retv == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, retv); 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_int_t pid;
qse_awk_val_t* retv; qse_awk_val_t* retv;
int rx; 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 (rx >= 0)
{ {
#if defined(_WIN32) #if defined(_WIN32)
/* TOOD: implement this*/ /* TOOD: implement this*/
rx = -1; rx = -1;
status = 0;
#elif defined(__OS2__) #elif defined(__OS2__)
/* TOOD: implement this*/ /* TOOD: implement this*/
rx = -1; rx = -1;
status = 0;
#elif defined(__DOS__) #elif defined(__DOS__)
/* TOOD: implement this*/ /* TOOD: implement this*/
rx = -1; rx = -1;
status = 0;
#else #else
rx = waitpid (pid, QSE_NULL, 0); rx = waitpid(pid, &status, opts);
#endif #endif
} }
retv = qse_awk_rtx_makeintval (rtx, rx); retv = qse_awk_rtx_makeintval(rtx, rx);
if (retv == QSE_NULL) return -1; 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); qse_awk_rtx_setretval (rtx, retv);
return 0; 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; qse_awk_val_t* retv;
int rx; int rx;
if (qse_awk_rtx_valtoint (rtx, qse_awk_rtx_getarg (rtx, 0), &pid) <= -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) qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg (rtx, 1), &sig) <= -1)
{ {
rx = -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; qse_awk_val_t* retv;
int rx; 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 (rx == 0)
{ {
#if defined(_WIN32) #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_size_t nargs;
qse_awk_val_t* retv; qse_awk_val_t* retv;
nargs = qse_awk_rtx_getnargs (rtx); nargs = qse_awk_rtx_getnargs(rtx);
if (nargs >= 1) if (nargs >= 1)
{ {
int sign; int sign;
@ -1240,29 +1323,34 @@ static fnctab_t fnctab[] =
{ {
/* keep this table sorted for binary search in query(). */ /* keep this table sorted for binary search in query(). */
{ QSE_T("closelog"), { { 0, 0, QSE_NULL }, fnc_closelog, 0 } }, { QSE_T("WCOREDUMP"), { { 1, 1, QSE_NULL }, fnc_wcoredump, 0 } },
{ QSE_T("fork"), { { 0, 0, QSE_NULL }, fnc_fork, 0 } }, { QSE_T("WEXITSTATUS"), { { 1, 1, QSE_NULL }, fnc_wexitstatus, 0 } },
{ QSE_T("getegid"), { { 0, 0, QSE_NULL }, fnc_getegid, 0 } }, { QSE_T("WIFEXITED"), { { 1, 1, QSE_NULL }, fnc_wifexited, 0 } },
{ QSE_T("getenv"), { { 1, 1, QSE_NULL }, fnc_getenv, 0 } }, { QSE_T("WIFSIGNALED"), { { 1, 1, QSE_NULL }, fnc_wifsignaled, 0 } },
{ QSE_T("geteuid"), { { 0, 0, QSE_NULL }, fnc_geteuid, 0 } }, { QSE_T("WTERMSIG"), { { 1, 1, QSE_NULL }, fnc_wtermsig, 0 } },
{ QSE_T("getgid"), { { 0, 0, QSE_NULL }, fnc_getgid, 0 } }, { QSE_T("closelog"), { { 0, 0, QSE_NULL }, fnc_closelog, 0 } },
{ QSE_T("getnwifcfg"), { { 3, 3, QSE_T("vvr") }, fnc_getnwifcfg, 0 } }, { QSE_T("fork"), { { 0, 0, QSE_NULL }, fnc_fork, 0 } },
{ QSE_T("getpgid"), { { 0, 0, QSE_NULL }, fnc_getpgid, 0 } }, { QSE_T("getegid"), { { 0, 0, QSE_NULL }, fnc_getegid, 0 } },
{ QSE_T("getpid"), { { 0, 0, QSE_NULL }, fnc_getpid, 0 } }, { QSE_T("getenv"), { { 1, 1, QSE_NULL }, fnc_getenv, 0 } },
{ QSE_T("getppid"), { { 0, 0, QSE_NULL }, fnc_getppid, 0 } }, { QSE_T("geteuid"), { { 0, 0, QSE_NULL }, fnc_geteuid, 0 } },
{ QSE_T("gettid"), { { 0, 0, QSE_NULL }, fnc_gettid, 0 } }, { QSE_T("getgid"), { { 0, 0, QSE_NULL }, fnc_getgid, 0 } },
{ QSE_T("gettime"), { { 0, 0, QSE_NULL }, fnc_gettime, 0 } }, { QSE_T("getnwifcfg"), { { 3, 3, QSE_T("vvr") }, fnc_getnwifcfg, 0 } },
{ QSE_T("getuid"), { { 0, 0, QSE_NULL }, fnc_getuid, 0 } }, { QSE_T("getpgid"), { { 0, 0, QSE_NULL }, fnc_getpgid, 0 } },
{ QSE_T("kill"), { { 2, 2, QSE_NULL }, fnc_kill, 0 } }, { QSE_T("getpid"), { { 0, 0, QSE_NULL }, fnc_getpid, 0 } },
{ QSE_T("mktime"), { { 0, 1, QSE_NULL }, fnc_mktime, 0 } }, { QSE_T("getppid"), { { 0, 0, QSE_NULL }, fnc_getppid, 0 } },
{ QSE_T("openlog"), { { 3, 3, QSE_NULL }, fnc_openlog, 0 } }, { QSE_T("gettid"), { { 0, 0, QSE_NULL }, fnc_gettid, 0 } },
{ QSE_T("settime"), { { 1, 1, QSE_NULL }, fnc_settime, 0 } }, { QSE_T("gettime"), { { 0, 0, QSE_NULL }, fnc_gettime, 0 } },
{ QSE_T("sleep"), { { 1, 1, QSE_NULL }, fnc_sleep, 0 } }, { QSE_T("getuid"), { { 0, 0, QSE_NULL }, fnc_getuid, 0 } },
{ QSE_T("strftime"), { { 2, 2, QSE_NULL }, fnc_strftime, 0 } }, { QSE_T("kill"), { { 2, 2, QSE_NULL }, fnc_kill, 0 } },
{ QSE_T("system"), { { 1, 1, QSE_NULL }, fnc_system, 0 } }, { QSE_T("mktime"), { { 0, 1, QSE_NULL }, fnc_mktime, 0 } },
{ QSE_T("systime"), { { 0, 0, QSE_NULL }, fnc_gettime, 0 } }, /* alias to gettime() */ { QSE_T("openlog"), { { 3, 3, QSE_NULL }, fnc_openlog, 0 } },
{ QSE_T("wait"), { { 1, 1, QSE_NULL }, fnc_wait, 0 } }, { QSE_T("settime"), { { 1, 1, QSE_NULL }, fnc_settime, 0 } },
{ QSE_T("writelog"), { { 2, 2, QSE_NULL }, fnc_writelog, 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) #if !defined(SIGHUP)
@ -1341,11 +1429,9 @@ static inttab_t inttab[] =
{ QSE_T("SIGKILL"), { SIGKILL } }, { QSE_T("SIGKILL"), { SIGKILL } },
{ QSE_T("SIGQUIT"), { SIGQUIT } }, { QSE_T("SIGQUIT"), { SIGQUIT } },
{ QSE_T("SIGSEGV"), { SIGSEGV } }, { 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) static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym)

View File

@ -117,6 +117,7 @@ enum tok_t
/* === extended reserved words === */ /* === extended reserved words === */
TOK_XGLOBAL, TOK_XGLOBAL,
TOK_XLOCAL, TOK_XLOCAL,
TOK_XINCLONE,
TOK_XINCLUDE, TOK_XINCLUDE,
TOK_XPRAGMA, TOK_XPRAGMA,
TOK_XABORT, TOK_XABORT,
@ -261,6 +262,7 @@ static kwent_t kwtab[] =
* also keep it sorted by the first field for binary search */ * also keep it sorted by the first field for binary search */
{ { QSE_T("@abort"), 6 }, TOK_XABORT, 0 }, { { QSE_T("@abort"), 6 }, TOK_XABORT, 0 },
{ { QSE_T("@global"), 7 }, TOK_XGLOBAL, 0 }, { { QSE_T("@global"), 7 }, TOK_XGLOBAL, 0 },
{ { QSE_T("@inclone"), 8 }, TOK_XINCLONE, 0 },
{ { QSE_T("@include"), 8 }, TOK_XINCLUDE, 0 }, { { QSE_T("@include"), 8 }, TOK_XINCLUDE, 0 },
{ { QSE_T("@local"), 6 }, TOK_XLOCAL, 0 }, { { QSE_T("@local"), 6 }, TOK_XLOCAL, 0 },
{ { QSE_T("@pragma"), 7 }, TOK_XPRAGMA, 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 */ 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_awk_sio_arg_t* arg = QSE_NULL;
qse_link_t* link; qse_link_t* link;
@ -769,7 +801,7 @@ static int begin_include (qse_awk_t* awk)
/* store the include-file name into a list /* store the include-file name into a list
* and this list is not deleted after qse_awk_parse. * 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) + 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)); QSE_SIZEOF(*arg) + QSE_SIZEOF(qse_char_t) * (QSE_STR_LEN(awk->tok.name) + 1));
if (link == QSE_NULL) if (link == QSE_NULL)
@ -792,7 +824,6 @@ static int begin_include (qse_awk_t* awk)
arg->line = 1; arg->line = 1;
arg->colm = 1; arg->colm = 1;
/* let the argument's prev field point to the current */ /* let the argument's prev field point to the current */
arg->prev = awk->sio.inp; arg->prev = awk->sio.inp;
@ -815,15 +846,23 @@ static int begin_include (qse_awk_t* awk)
awk->sio.inp = arg; awk->sio.inp = arg;
awk->parse.depth.incl++; awk->parse.depth.incl++;
/* read in the first character in the included file. if (once && ever_included(awk, arg))
* so the next call to get_token() sees the character read
* from this file. */
if (get_char(awk) <= -1 || get_token(awk) <= -1)
{ {
end_include (awk); end_include (awk);
/* i don't jump to oops since i've called /* it has been included previously. don't include this file again. */
* end_include() where awk->sio.inp/arg is freed. */ }
return -1; 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; return 0;
@ -865,8 +904,10 @@ static int parse_progunit (qse_awk_t* awk)
return -1; 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 && if (awk->opt.depth.s.incl > 0 &&
awk->parse.depth.incl >= awk->opt.depth.s.incl) awk->parse.depth.incl >= awk->opt.depth.s.incl)
{ {
@ -874,6 +915,7 @@ static int parse_progunit (qse_awk_t* awk)
return -1; return -1;
} }
once = MATCH(awk, TOK_XINCLONE);
if (get_token(awk) <= -1) return -1; if (get_token(awk) <= -1) return -1;
if (!MATCH(awk, TOK_STR)) if (!MATCH(awk, TOK_STR))
@ -882,7 +924,7 @@ static int parse_progunit (qse_awk_t* awk)
return -1; return -1;
} }
if (begin_include(awk) <= -1) return -1; if (begin_include(awk, once) <= -1) return -1;
/* i just return without doing anything special /* i just return without doing anything special
* after having setting up the environment for file * after having setting up the environment for file
@ -1515,9 +1557,11 @@ 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 (get_token(awk) <= -1) return QSE_NULL;
} }
if (MATCH(awk,TOK_XINCLUDE)) if (MATCH(awk,TOK_XINCLUDE) || MATCH(awk, TOK_XINCLONE))
{ {
/* @include ... */ /* @include ... */
int once;
if (awk->opt.depth.s.incl > 0 && if (awk->opt.depth.s.incl > 0 &&
awk->parse.depth.incl >= awk->opt.depth.s.incl) awk->parse.depth.incl >= awk->opt.depth.s.incl)
{ {
@ -1525,6 +1569,7 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in
return QSE_NULL; return QSE_NULL;
} }
once = MATCH(awk, TOK_XINCLONE);
if (get_token(awk) <= -1) return QSE_NULL; if (get_token(awk) <= -1) return QSE_NULL;
if (!MATCH(awk,TOK_STR)) if (!MATCH(awk,TOK_STR))
@ -1533,24 +1578,20 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in
return QSE_NULL; 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)) else if (MATCH(awk,TOK_XLOCAL))
{ {
/* @local ... */ /* @local ... */
if (get_token(awk) <= -1) if (get_token(awk) <= -1)
{ {
qse_arr_delete ( qse_arr_delete (awk->parse.lcls, nlcls, QSE_ARR_SIZE(awk->parse.lcls)-nlcls);
awk->parse.lcls, nlcls,
QSE_ARR_SIZE(awk->parse.lcls)-nlcls);
return QSE_NULL; return QSE_NULL;
} }
if (collect_locals (awk, nlcls, istop) == QSE_NULL) if (collect_locals (awk, nlcls, istop) == QSE_NULL)
{ {
qse_arr_delete ( qse_arr_delete (awk->parse.lcls, nlcls, QSE_ARR_SIZE(awk->parse.lcls)-nlcls);
awk->parse.lcls, nlcls,
QSE_ARR_SIZE(awk->parse.lcls)-nlcls);
return QSE_NULL; return QSE_NULL;
} }
} }
@ -1594,8 +1635,10 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in
break; 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 && if (awk->opt.depth.s.incl > 0 &&
awk->parse.depth.incl >= awk->opt.depth.s.incl) awk->parse.depth.incl >= awk->opt.depth.s.incl)
{ {
@ -1603,6 +1646,7 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in
return QSE_NULL; return QSE_NULL;
} }
once = MATCH(awk, TOK_XINCLONE);
if (get_token(awk) <= -1) return QSE_NULL; if (get_token(awk) <= -1) return QSE_NULL;
if (!MATCH(awk,TOK_STR)) if (!MATCH(awk,TOK_STR))
@ -1611,7 +1655,7 @@ static qse_awk_nde_t* parse_block (qse_awk_t* awk, const qse_awk_loc_t* xloc, in
return QSE_NULL; return QSE_NULL;
} }
if (begin_include (awk) <= -1) return QSE_NULL; if (begin_include(awk, once) <= -1) return QSE_NULL;
} }
else else
{ {

View File

@ -32,6 +32,7 @@ enum qse_awk_kwid_t
{ {
QSE_AWK_KWID_XABORT, QSE_AWK_KWID_XABORT,
QSE_AWK_KWID_XGLOBAL, QSE_AWK_KWID_XGLOBAL,
QSE_AWK_KWID_XINCLONE,
QSE_AWK_KWID_XINCLUDE, QSE_AWK_KWID_XINCLUDE,
QSE_AWK_KWID_XLOCAL, QSE_AWK_KWID_XLOCAL,
QSE_AWK_KWID_XPRAGMA, QSE_AWK_KWID_XPRAGMA,

View File

@ -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 ( static qse_ssize_t sf_in_open (qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
{ {
if (arg->prev == QSE_NULL) if (arg->prev == QSE_NULL)
{ {
@ -707,12 +706,12 @@ static qse_ssize_t sf_in_open (
{ {
const qse_char_t* outer; const qse_char_t* outer;
outer = qse_sio_getpath (arg->prev->handle); outer = qse_sio_getpath(arg->prev->handle);
if (outer) if (outer)
{ {
const qse_char_t* base; const qse_char_t* base;
base = qse_basename (outer); base = qse_basename(outer);
if (base != outer && arg->name[0] != QSE_T('/')) if (base != outer && arg->name[0] != QSE_T('/'))
{ {
qse_size_t tmplen, totlen, dirlen; qse_size_t tmplen, totlen, dirlen;
@ -721,11 +720,8 @@ static qse_ssize_t sf_in_open (
totlen = qse_strlen(arg->name) + dirlen; totlen = qse_strlen(arg->name) + dirlen;
if (totlen >= QSE_COUNTOF(fbuf)) if (totlen >= QSE_COUNTOF(fbuf))
{ {
dbuf = qse_awk_allocmem ( dbuf = qse_awk_allocmem(awk, QSE_SIZEOF(qse_char_t) * (totlen + 1));
awk, QSE_SIZEOF(qse_char_t) * (totlen + 1) if (!dbuf) return -1;
);
if (dbuf == QSE_NULL) return -1;
path = dbuf; path = dbuf;
} }
else path = fbuf; 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 awk->mmgr, 0, path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH
); );
if (dbuf) QSE_MMGR_FREE (awk->mmgr, dbuf); if (dbuf) qse_awk_freemem (awk, dbuf);
if (arg->handle == QSE_NULL) if (!arg->handle)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = (qse_char_t*)arg->name; ea.ptr = (qse_char_t*)arg->name;
@ -750,12 +746,12 @@ static qse_ssize_t sf_in_open (
return -1; return -1;
} }
/* TODO: set arg->unique_id.... to support @inclone */
return 0; return 0;
} }
} }
static qse_ssize_t sf_in_close ( static qse_ssize_t sf_in_close (qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
{ {
if (arg->prev == QSE_NULL) if (arg->prev == QSE_NULL)
{ {
@ -785,9 +781,7 @@ static qse_ssize_t sf_in_close (
return 0; return 0;
} }
static qse_ssize_t sf_in_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)
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) if (arg->prev == QSE_NULL)
{ {
@ -876,9 +870,7 @@ static qse_ssize_t sf_in_read (
} }
} }
static qse_ssize_t sf_in ( 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)
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); xtn_t* xtn = QSE_XTN (awk);
@ -899,9 +891,7 @@ static qse_ssize_t sf_in (
} }
} }
static qse_ssize_t sf_out ( 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)
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); 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 || 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[0] == QSE_T('-') &&
xtn->s.out.x->u.file.path[1] == QSE_T('\0'))) xtn->s.out.x->u.file.path[1] == QSE_T('\0')))
{ {
/* no path name or - -> stdout */ /* no path name or - -> stdout */
xtn->s.out.u.file.sio = open_sio_std ( xtn->s.out.u.file.sio = open_sio_std (