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;
/**
* [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.
*

View File

@ -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 */

View File

@ -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;

View File

@ -117,8 +117,15 @@ 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);
if (rx >= 0)
@ -126,20 +133,96 @@ static int fnc_wait (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
#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;
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;
}
@ -1240,6 +1323,11 @@ static fnctab_t fnctab[] =
{
/* keep this table sorted for binary search in query(). */
{ 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 } },
@ -1261,7 +1349,7 @@ static fnctab_t fnctab[] =
{ 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("wait"), { { 1, 3, QSE_T("vrv") }, fnc_wait, 0 } },
{ QSE_T("writelog"), { { 2, 2, QSE_NULL }, fnc_writelog, 0 } }
};
@ -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)

View File

@ -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)
@ -792,7 +824,6 @@ static int begin_include (qse_awk_t* awk)
arg->line = 1;
arg->colm = 1;
/* let the argument's prev field point to the current */
arg->prev = awk->sio.inp;
@ -815,16 +846,24 @@ static int begin_include (qse_awk_t* awk)
awk->sio.inp = arg;
awk->parse.depth.incl++;
if (once && ever_included(awk, arg))
{
end_include (awk);
/* 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 (get_char(awk) <= -1 || get_token(awk) <= -1)
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,8 +904,10 @@ 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)
{
@ -874,6 +915,7 @@ static int parse_progunit (qse_awk_t* awk)
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,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 (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)
{
@ -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;
}
once = MATCH(awk, TOK_XINCLONE);
if (get_token(awk) <= -1) return QSE_NULL;
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;
}
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,8 +1635,10 @@ 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)
{
@ -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;
}
once = MATCH(awk, TOK_XINCLONE);
if (get_token(awk) <= -1) return QSE_NULL;
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;
}
if (begin_include (awk) <= -1) return QSE_NULL;
if (begin_include(awk, once) <= -1) return QSE_NULL;
}
else
{

View File

@ -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,

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 (
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)
{
@ -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 (