added qse_awk_rtx_pushrcb() and qse_awk_rtx_poprcb().

deleted qse_awk_rtx_setrcb() and qse_awk_rtx_getrcb().
added 'close' to qse_awk_rcb_t
added builtin functions 'setenc' and 'unsetenc' to awk/std.c
added qse_getcmgrbyname()
added builtin functions 'setenc' and 'unsetenc' to awk/StdAwk.cpp
This commit is contained in:
2012-01-17 16:45:01 +00:00
parent fa850168ee
commit b903f8ebb5
25 changed files with 527 additions and 153 deletions

View File

@ -1510,7 +1510,7 @@ int Awk::getGlobal (int id, Value& v)
int Awk::addFunction (
const char_t* name, size_t minArgs, size_t maxArgs,
FunctionHandler handler)
FunctionHandler handler, int validOpts)
{
QSE_ASSERT (awk != QSE_NULL);
@ -1529,7 +1529,7 @@ int Awk::addFunction (
void* p = qse_awk_addfnc (
awk, name, nameLen,
0, minArgs, maxArgs,
validOpts, minArgs, maxArgs,
#ifdef PASS_BY_REFERENCE
QSE_T("R"), // pass all arguments by reference
#else

View File

@ -22,7 +22,6 @@
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/time.h>
#include <qse/cmn/fio.h>
#include <qse/cmn/pio.h>
#include <qse/cmn/sio.h>
#include <qse/cmn/path.h>
@ -42,10 +41,10 @@
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
#define ADDFNC(name,min,max,impl) \
#define ADDFNC(name,min,max,impl,vopts) \
do { \
if (addFunction (name, min, max, \
(FunctionHandler)impl) == -1) \
(FunctionHandler)impl, vopts) == -1) \
{ \
Awk::close (); \
return -1; \
@ -97,9 +96,14 @@ int StdAwk::open ()
int n = Awk::open ();
if (n == -1) return n;
ADDFNC (QSE_T("rand"), 0, 0, &StdAwk::rand);
ADDFNC (QSE_T("srand"), 0, 1, &StdAwk::srand);
ADDFNC (QSE_T("system"), 1, 1, &StdAwk::system);
ADDFNC (QSE_T("rand"), 0, 0, &StdAwk::rand, 0);
ADDFNC (QSE_T("srand"), 0, 1, &StdAwk::srand, 0);
ADDFNC (QSE_T("system"), 1, 1, &StdAwk::system, 0);
#if defined(QSE_CHAR_IS_WCHAR)
ADDFNC (QSE_T("setenc"), 2, 2, &StdAwk::setenc, QSE_AWK_RIO);
ADDFNC (QSE_T("unsetenc"), 1, 1, &StdAwk::unsetenc, QSE_AWK_RIO);
#endif
qse_ntime_t now;
@ -107,15 +111,58 @@ int StdAwk::open ()
else this->seed = (unsigned int)now;
::srand (this->seed);
this->cmgrtab_inited = false;
return 0;
}
void StdAwk::close ()
{
#if defined(QSE_CHAR_IS_WCHAR)
if (this->cmgrtab_inited)
{
qse_htb_fini (&this->cmgrtab);
this->cmgrtab_inited = false;
}
#endif
clearConsoleOutputs ();
Awk::close ();
}
StdAwk::Run* StdAwk::parse (Source& in, Source& out)
{
Run* run = Awk::parse (in, out);
#if defined(QSE_CHAR_IS_WCHAR)
if (this->cmgrtab_inited)
{
// if cmgrtab has already been initialized,
// just clear the contents regardless of
// parse() result.
qse_htb_clear (&this->cmgrtab);
}
else if (run && (this->getOption() & QSE_AWK_RIO))
{
// it initialized cmgrtab only if QSE_AWK_RIO is set.
// but if you call parse() multiple times while
// setting and unsetting QSE_AWK_RIO in-between,
// cmgrtab can still be initialized when QSE_AWK_RIO is not set.
if (qse_htb_init (
&this->cmgrtab, this->getMmgr(), 256, 70,
QSE_SIZEOF(qse_char_t), 1) <= -1)
{
this->setError (QSE_AWK_ENOMEM);
return QSE_NULL;
}
qse_htb_setmancbs (&this->cmgrtab,
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER));
this->cmgrtab_inited = true;
}
#endif
return run;
}
int StdAwk::rand (Run& run, Value& ret, const Value* args, size_t nargs,
const char_t* name, size_t len)
{
@ -165,6 +212,53 @@ int StdAwk::system (Run& run, Value& ret, const Value* args, size_t nargs,
#endif
}
#if defined(QSE_CHAR_IS_WCHAR)
qse_cmgr_t* StdAwk::getcmgr (const char_t* ioname)
{
QSE_ASSERT (this->cmgrtab_inited == true);
qse_htb_pair_t* pair = qse_htb_search (&this->cmgrtab, ioname, qse_strlen(ioname));
if (pair) return (qse_cmgr_t*)QSE_HTB_VPTR(pair);
return QSE_NULL;
}
int StdAwk::setenc (Run& run, Value& ret, const Value* args, size_t nargs,
const char_t* name, size_t len)
{
QSE_ASSERT (this->cmgrtab_inited == true);
size_t l[2];
const char_t* ptr[2];
ptr[0] = args[0].toStr(&l[0]);
ptr[1] = args[1].toStr(&l[1]);
if (qse_strxchr (ptr[0], l[0], QSE_T('\0')) ||
qse_strxchr (ptr[1], l[1], QSE_T('\0')))
{
return ret.setInt ((long_t)-1);
}
qse_cmgr_t* cmgr = qse_getcmgrbyname (ptr[1]);
if (cmgr == QSE_NULL)
{
return ret.setInt ((long_t)-1);
}
qse_htb_pair_t* pair = qse_htb_upsert (&this->cmgrtab, (char_t*)ptr[0], l[0], cmgr, 0);
return ret.setInt ((long_t)(pair? 0: -1));
}
int StdAwk::unsetenc (Run& run, Value& ret, const Value* args, size_t nargs,
const char_t* name, size_t len)
{
QSE_ASSERT (this->cmgrtab_inited == true);
size_t l;
const char_t* ptr = args[0].toStr(&l);
return ret.setInt ((long_t)qse_htb_delete (&this->cmgrtab, ptr, l));
}
#endif
int StdAwk::openPipe (Pipe& io)
{
Awk::Pipe::Mode mode = io.getMode();
@ -197,6 +291,15 @@ int StdAwk::openPipe (Pipe& io)
);
if (pio == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_WCHAR)
qse_cmgr_t* cmgr = this->getcmgr (io.getName());
if (cmgr)
{
qse_pio_setcmgr (pio, QSE_PIO_IN, cmgr);
qse_pio_setcmgr (pio, QSE_PIO_OUT, cmgr);
qse_pio_setcmgr (pio, QSE_PIO_ERR, cmgr);
}
#endif
io.setHandle (pio);
return 1;
}
@ -241,58 +344,55 @@ int StdAwk::flushPipe (Pipe& io)
int StdAwk::openFile (File& io)
{
Awk::File::Mode mode = io.getMode();
qse_fio_t* fio = QSE_NULL;
int flags = QSE_FIO_TEXT;
qse_sio_t* sio = QSE_NULL;
int flags = QSE_SIO_IGNOREMBWCERR;
switch (mode)
{
case Awk::File::READ:
flags |= QSE_FIO_READ;
flags |= QSE_SIO_READ;
break;
case Awk::File::WRITE:
flags |= QSE_FIO_WRITE |
QSE_FIO_CREATE |
QSE_FIO_TRUNCATE;
flags |= QSE_SIO_WRITE |
QSE_SIO_CREATE |
QSE_SIO_TRUNCATE;
break;
case Awk::File::APPEND:
flags |= QSE_FIO_APPEND |
QSE_FIO_CREATE;
flags |= QSE_SIO_APPEND |
QSE_SIO_CREATE;
break;
}
fio = qse_fio_open (
this->getMmgr(),
0,
io.getName(),
flags,
QSE_FIO_RUSR | QSE_FIO_WUSR |
QSE_FIO_RGRP | QSE_FIO_ROTH
);
if (fio == NULL) return -1;
sio = qse_sio_open (this->getMmgr(), 0, io.getName(), flags);
if (sio == NULL) return -1;
#if defined(QSE_CHAR_IS_WCHAR)
qse_cmgr_t* cmgr = this->getcmgr (io.getName());
if (cmgr) qse_sio_setcmgr (sio, cmgr);
#endif
io.setHandle (fio);
io.setHandle (sio);
return 1;
}
int StdAwk::closeFile (File& io)
{
qse_fio_close ((qse_fio_t*)io.getHandle());
qse_sio_close ((qse_sio_t*)io.getHandle());
return 0;
}
StdAwk::ssize_t StdAwk::readFile (File& io, char_t* buf, size_t len)
{
return qse_fio_read ((qse_fio_t*)io.getHandle(), buf, len);
return qse_sio_getstrn ((qse_sio_t*)io.getHandle(), buf, len);
}
StdAwk::ssize_t StdAwk::writeFile (File& io, const char_t* buf, size_t len)
{
return qse_fio_write ((qse_fio_t*)io.getHandle(), buf, len);
return qse_sio_putstrn ((qse_sio_t*)io.getHandle(), buf, len);
}
int StdAwk::flushFile (File& io)
{
return qse_fio_flush ((qse_fio_t*)io.getHandle());
return qse_sio_flush ((qse_sio_t*)io.getHandle());
}
int StdAwk::addConsoleOutput (const char_t* arg, size_t len)
@ -782,9 +882,14 @@ int StdAwk::SourceFile::open (Data& io)
if (this->name[0] == QSE_T('-') && this->name[1] == QSE_T('\0'))
{
if (io.getMode() == READ)
sio = open_sio_std (io, QSE_NULL, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
sio = open_sio_std (
io, QSE_NULL, QSE_SIO_STDIN,
QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
else
sio = open_sio_std (io, QSE_NULL, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR);
sio = open_sio_std (
io, QSE_NULL, QSE_SIO_STDOUT,
QSE_SIO_WRITE | QSE_SIO_CREATE |
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1;
}
else
@ -794,8 +899,9 @@ int StdAwk::SourceFile::open (Data& io)
sio = open_sio (
io, QSE_NULL, this->name,
(io.getMode() == READ?
QSE_SIO_READ:
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE|QSE_SIO_IGNOREMBWCERR))
(QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
(QSE_SIO_WRITE | QSE_SIO_CREATE |
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR))
);
if (sio == QSE_NULL) return -1;
@ -811,7 +917,6 @@ int StdAwk::SourceFile::open (Data& io)
else
{
// open an included file
const char_t* file = ioname;
char_t fbuf[64];
char_t* dbuf = QSE_NULL;
@ -844,8 +949,9 @@ int StdAwk::SourceFile::open (Data& io)
sio = open_sio (
io, QSE_NULL, file,
(io.getMode() == READ?
QSE_SIO_READ:
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE|QSE_SIO_IGNOREMBWCERR))
(QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
(QSE_SIO_WRITE | QSE_SIO_CREATE |
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR))
);
if (dbuf) QSE_MMGR_FREE (((Awk*)io)->getMmgr(), dbuf);
if (sio == QSE_NULL) return -1;

View File

@ -157,7 +157,7 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
if (awk->sio.names == QSE_NULL) goto oops;
*(qse_awk_t**)QSE_XTN(awk->sio.names) = awk;
qse_htb_setmancbs (awk->sio.names,
qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
);
awk->sio.inp = &awk->sio.arg;
@ -175,7 +175,7 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
if (awk->parse.funs == QSE_NULL) goto oops;
*(qse_awk_t**)QSE_XTN(awk->parse.funs) = awk;
qse_htb_setmancbs (awk->parse.funs,
qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
);
awk->parse.named = qse_htb_open (
@ -184,7 +184,7 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
if (awk->parse.named == QSE_NULL) goto oops;
*(qse_awk_t**)QSE_XTN(awk->parse.named) = awk;
qse_htb_setmancbs (awk->parse.named,
qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
);
awk->parse.gbls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 128);

View File

@ -295,7 +295,6 @@ struct qse_awk_rtx_t
qse_size_t len;
qse_awk_val_t* val; /* $1 .. $NF */
}* flds;
} inrec;
struct
@ -372,7 +371,7 @@ struct qse_awk_rtx_t
qse_awk_errinf_t errinf;
qse_awk_t* awk;
qse_awk_rcb_t rcb;
qse_awk_rcb_t* rcb;
};

View File

@ -100,6 +100,7 @@ void* qse_awk_addfnc (
qse_awk_fnc_fun_t handler)
{
qse_awk_fnc_t* fnc;
qse_size_t fnc_size;
qse_size_t spec_len;
if (name_len <= 0)
@ -121,16 +122,19 @@ void* qse_awk_addfnc (
spec_len = (arg_spec == QSE_NULL)? 0: qse_strlen(arg_spec);
fnc = (qse_awk_fnc_t*) QSE_AWK_ALLOC (awk,
fnc_size =
QSE_SIZEOF(qse_awk_fnc_t) +
(name_len+1) * QSE_SIZEOF(qse_char_t) +
(spec_len+1) * QSE_SIZEOF(qse_char_t));
(spec_len+1) * QSE_SIZEOF(qse_char_t);
fnc = (qse_awk_fnc_t*) QSE_AWK_ALLOC (awk, fnc_size);
if (fnc == QSE_NULL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return QSE_NULL;
}
QSE_MEMSET (fnc, 0, fnc_size);
fnc->name.ptr = (qse_char_t*)(fnc + 1);
fnc->name.len = name_len;
qse_strxncpy (fnc->name.ptr, name_len+1, name, name_len);
@ -187,8 +191,12 @@ qse_awk_fnc_t* qse_awk_getfnc (
qse_awk_fnc_t* fnc;
qse_htb_pair_t* pair;
/* search the system function table */
/* TODO: some speed up? binary search by ordering the table? */
/* search the system function table
* though some optimization like binary search can
* speed up the search, i don't do that since this
* function is called durting parse-time only.
* TODO: binary search.
*/
for (fnc = sys_fnc; fnc->name.ptr != QSE_NULL; fnc++)
{
if (fnc->valid != 0 &&

View File

@ -4832,7 +4832,7 @@ static qse_awk_nde_t* parse_primary_ident (
/* check if namedup is an intrinsic function name */
fnc = qse_awk_getfnc (awk, namedup, namelen);
if (fnc != QSE_NULL)
if (fnc)
{
if (MATCH(awk,TOK_LPAREN))
{

View File

@ -739,7 +739,19 @@ qse_awk_rtx_t* qse_awk_rtx_open (
void qse_awk_rtx_close (qse_awk_rtx_t* rtx)
{
qse_awk_rcb_t* rcb;
for (rcb = rtx->rcb; rcb; rcb = rcb->next)
if (rcb->close) rcb->close (rtx, rcb->ctx);
/* NOTE:
* the close callbacks are called before data in rtx
* is destroyed. if the destruction count on any data
* destroyed by the close callback, something bad
* will happen.
*/
fini_rtx (rtx, 1);
QSE_AWK_FREE (rtx->awk, rtx);
}
@ -753,14 +765,17 @@ qse_bool_t qse_awk_rtx_isstop (qse_awk_rtx_t* rtx)
return (rtx->exit_level == EXIT_ABORT || rtx->awk->stopall);
}
qse_awk_rcb_t* qse_awk_rtx_getrcb (qse_awk_rtx_t* rtx)
qse_awk_rcb_t* qse_awk_rtx_poprcb (qse_awk_rtx_t* rtx)
{
return &rtx->rcb;
qse_awk_rcb_t* top = rtx->rcb;
if (top) rtx->rcb = top->next;
return top;
}
void qse_awk_rtx_setrcb (qse_awk_rtx_t* rtx, qse_awk_rcb_t* rcb)
void qse_awk_rtx_pushrcb (qse_awk_rtx_t* rtx, qse_awk_rcb_t* rcb)
{
rtx->rcb = *rcb;
rcb->next = rtx->rcb;
rtx->rcb = rcb;
}
static void free_namedval (qse_htb_t* map, void* dptr, qse_size_t dlen)
@ -1891,9 +1906,12 @@ static int run_block0 (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde)
return n;
}
#define ON_STATEMENT(rtx,nde) \
#define ON_STATEMENT(rtx,nde) QSE_BLOCK ( \
qse_awk_rcb_t* rcb; \
if ((rtx)->awk->stopall) (rtx)->exit_level = EXIT_ABORT; \
if ((rtx)->rcb.stm) (rtx)->rcb.stm (rtx, nde, (rtx)->rcb.ctx);
for (rcb = (rtx)->rcb; rcb; rcb = rcb->next) \
if (rcb->stmt) rcb->stmt (rtx, nde, rcb->ctx); \
)
static int run_statement (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{

View File

@ -26,6 +26,7 @@
#include <qse/cmn/mbwc.h>
#include <qse/cmn/time.h>
#include <qse/cmn/path.h>
#include <qse/cmn/htb.h>
#include <qse/cmn/stdio.h> /* TODO: remove dependency on qse_vsprintf */
#include "../cmn/mem.h"
@ -116,8 +117,16 @@ typedef struct rxtn_t
qse_cmgr_t* cmgr;
} c; /* console */
#if defined(QSE_CHAR_IS_WCHAR)
int cmgrtab_inited;
qse_htb_t cmgrtab;
#endif
} rxtn_t;
#if defined(QSE_CHAR_IS_WCHAR)
static qse_cmgr_t* getcmgr_from_cmgrtab (qse_awk_rtx_t* rtx, const qse_char_t* ioname);
#endif
static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y)
{
#if defined(HAVE_POWL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
@ -466,7 +475,7 @@ static qse_ssize_t sf_in_open (
}
arg->handle = qse_sio_open (
awk->mmgr, 0, file, QSE_SIO_READ
awk->mmgr, 0, file, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR
);
if (dbuf != QSE_NULL) QSE_MMGR_FREE (awk->mmgr, dbuf);
@ -800,8 +809,20 @@ static qse_ssize_t awk_rio_pipe (
QSE_NULL,
flags|QSE_PIO_SHELL|QSE_PIO_TEXT|QSE_PIO_IGNOREMBWCERR
);
if (handle == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = getcmgr_from_cmgrtab (rtx, riod->name);
if (cmgr)
{
qse_pio_setcmgr (handle, QSE_PIO_IN, cmgr);
qse_pio_setcmgr (handle, QSE_PIO_OUT, cmgr);
qse_pio_setcmgr (handle, QSE_PIO_ERR, cmgr);
}
}
#endif
riod->handle = (void*)handle;
return 1;
}
@ -870,60 +891,61 @@ static qse_ssize_t awk_rio_file (
{
case QSE_AWK_RIO_OPEN:
{
qse_fio_t* handle;
int flags;
qse_sio_t* handle;
int flags = QSE_SIO_IGNOREMBWCERR;
if (riod->mode == QSE_AWK_RIO_FILE_READ)
switch (riod->mode)
{
flags = QSE_FIO_READ;
case QSE_AWK_RIO_FILE_READ:
flags |= QSE_SIO_READ;
break;
case QSE_AWK_RIO_FILE_WRITE:
flags |= QSE_SIO_WRITE |
QSE_SIO_CREATE |
QSE_SIO_TRUNCATE;
break;
case QSE_AWK_RIO_FILE_APPEND:
flags |= QSE_SIO_APPEND |
QSE_SIO_CREATE;
break;
default:
/* this must not happen */
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
else if (riod->mode == QSE_AWK_RIO_FILE_WRITE)
{
flags = QSE_FIO_WRITE |
QSE_FIO_CREATE |
QSE_FIO_TRUNCATE;
}
else if (riod->mode == QSE_AWK_RIO_FILE_APPEND)
{
flags = QSE_FIO_APPEND |
QSE_FIO_CREATE;
}
else return -1; /* TODO: any way to set the error number? */
handle = qse_fio_open (
rtx->awk->mmgr,
0,
riod->name,
flags | QSE_FIO_TEXT,
QSE_FIO_RUSR | QSE_FIO_WUSR |
QSE_FIO_RGRP | QSE_FIO_ROTH
);
handle = qse_sio_open (rtx->awk->mmgr, 0, riod->name, flags);
if (handle == QSE_NULL)
{
qse_cstr_t errarg;
errarg.ptr = riod->name;
errarg.len = qse_strlen(riod->name);
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &errarg);
return -1;
}
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = getcmgr_from_cmgrtab (rtx, riod->name);
if (cmgr) qse_sio_setcmgr (handle, cmgr);
}
#endif
riod->handle = (void*)handle;
return 1;
}
case QSE_AWK_RIO_CLOSE:
{
qse_fio_close ((qse_fio_t*)riod->handle);
qse_sio_close ((qse_sio_t*)riod->handle);
riod->handle = QSE_NULL;
return 0;
}
case QSE_AWK_RIO_READ:
{
return qse_fio_read (
(qse_fio_t*)riod->handle,
return qse_sio_getstrn (
(qse_sio_t*)riod->handle,
data,
size
);
@ -931,8 +953,8 @@ static qse_ssize_t awk_rio_file (
case QSE_AWK_RIO_WRITE:
{
return qse_fio_write (
(qse_fio_t*)riod->handle,
return qse_sio_putstrn (
(qse_sio_t*)riod->handle,
data,
size
);
@ -940,7 +962,7 @@ static qse_ssize_t awk_rio_file (
case QSE_AWK_RIO_FLUSH:
{
return qse_fio_flush ((qse_fio_t*)riod->handle);
return qse_sio_flush ((qse_sio_t*)riod->handle);
}
case QSE_AWK_RIO_NEXT:
@ -1245,13 +1267,19 @@ static qse_ssize_t awk_rio_console (
return -1;
}
/* TODO: provide a way to set cmgr for console files icf and ocf...
* should i accept something similar to qse_awk_parsestd_t?
*
* what is the best way to change cmgr for pipes and files?
* currently there is no way to change cmgr for each pipe and file.
* you can change the global cmgr only with qse_setdflcmgr().
*/
static void fini_rxtn (qse_awk_rtx_t* rtx, void* ctx)
{
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
#if defined(QSE_CHAR_IS_WCHAR)
if (rxtn->cmgrtab_inited)
{
qse_htb_fini (&rxtn->cmgrtab);
rxtn->cmgrtab_inited = 0;
}
#endif
}
qse_awk_rtx_t* qse_awk_rtx_openstd (
qse_awk_t* awk,
qse_size_t xtnsize,
@ -1260,6 +1288,13 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
const qse_char_t*const ocf[],
qse_cmgr_t* cmgr)
{
static qse_awk_rcb_t rcb =
{
fini_rxtn,
QSE_NULL,
QSE_NULL
};
qse_awk_rtx_t* rtx;
qse_awk_rio_t rio;
rxtn_t* rxtn;
@ -1325,6 +1360,25 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
rxtn = (rxtn_t*) QSE_XTN (rtx);
QSE_MEMSET (rxtn, 0, QSE_SIZEOF(rxtn_t));
#if defined(QSE_CHAR_IS_WCHAR)
if (rtx->awk->option & QSE_AWK_RIO)
{
if (qse_htb_init (
&rxtn->cmgrtab, awk->mmgr, 256, 70,
QSE_SIZEOF(qse_char_t), 1) <= -1)
{
qse_awk_rtx_close (rtx);
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return QSE_NULL;
}
qse_htb_setmancbs (&rxtn->cmgrtab,
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER));
rxtn->cmgrtab_inited = 1;
}
#endif
qse_awk_rtx_pushrcb (rtx, &rcb);
if (qse_gettime (&now) <= -1) rxtn->seed = 0;
else rxtn->seed = (unsigned int) now;
srand (rxtn->seed);
@ -1336,7 +1390,6 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
rxtn->c.out.index = 0;
rxtn->c.out.count = 0;
rxtn->c.cmgr = cmgr;
/* FILENAME can be set when the input console is opened.
* so we skip setting it here even if an explicit console file
@ -1430,7 +1483,7 @@ static int fnc_system (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
{
qse_size_t nargs;
qse_awk_val_t* v;
qse_char_t* str, * ptr, * end;
qse_char_t* str;
qse_size_t len;
int n = 0;
@ -1451,16 +1504,10 @@ static int fnc_system (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
/* the target name contains a null character.
* make system return -1 */
ptr = str; end = str + len;
while (ptr < end)
if (qse_strxchr (str, len, QSE_T('\0')))
{
if (*ptr == QSE_T('\0'))
{
n = -1;
goto skip_system;
}
ptr++;
n = -1;
goto skip_system;
}
#if defined(_WIN32)
@ -1493,15 +1540,143 @@ skip_system:
return 0;
}
#define ADDFNC(awk,name,min,max,fnc) \
#if defined(QSE_CHAR_IS_WCHAR)
static qse_cmgr_t* getcmgr_from_cmgrtab (qse_awk_rtx_t* rtx, const qse_char_t* ioname)
{
rxtn_t* rxtn;
qse_htb_pair_t* pair;
rxtn = (rxtn_t*) QSE_XTN (rtx);
QSE_ASSERT (rxtn->cmgrtab_inited == 1);
pair = qse_htb_search (&rxtn->cmgrtab, ioname, qse_strlen(ioname));
if (pair) return QSE_HTB_VPTR(pair);
return QSE_NULL;
}
static int fnc_setenc (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
{
rxtn_t* rxtn;
qse_size_t nargs;
qse_awk_val_t* v[2];
qse_char_t* ptr[2];
qse_size_t len[2];
int i, ret = 0, fret = 0;
qse_cmgr_t* cmgr;
rxtn = (rxtn_t*) QSE_XTN (rtx);
QSE_ASSERT (rxtn->cmgrtab_inited == 1);
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 2);
for (i = 0; i < 2; i++)
{
v[i] = qse_awk_rtx_getarg (rtx, i);
if (v[i]->type == QSE_AWK_VAL_STR)
{
ptr[i] = ((qse_awk_val_str_t*)v[i])->val.ptr;
len[i] = ((qse_awk_val_str_t*)v[i])->val.len;
}
else
{
ptr[i] = qse_awk_rtx_valtocpldup (rtx, v[i], &len[i]);
if (ptr[i] == QSE_NULL)
{
ret = -1;
goto done;
}
}
if (qse_strxchr (ptr[i], len[i], QSE_T('\0')))
{
fret = -1;
goto done;
}
}
cmgr = qse_getcmgrbyname (ptr[1]);
if (cmgr == QSE_NULL) fret = -1;
else
{
if (qse_htb_upsert (
&rxtn->cmgrtab, ptr[0], len[0], cmgr, 0) == QSE_NULL)
{
ret = -1;
}
}
done:
while (i > 0)
{
i--;
if (v[i]->type != QSE_AWK_VAL_STR)
QSE_AWK_FREE (rtx->awk, ptr[i]);
}
if (ret >= 0)
{
v[0] = qse_awk_rtx_makeintval (rtx, (qse_long_t)fret);
if (v[0] == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, v[0]);
}
return ret;
}
static int fnc_unsetenc (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
{
rxtn_t* rxtn;
qse_size_t nargs;
qse_awk_val_t* v;
qse_char_t* ptr;
qse_size_t len;
int fret = 0;
rxtn = (rxtn_t*) QSE_XTN (rtx);
QSE_ASSERT (rxtn->cmgrtab_inited == 1);
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 1);
v = qse_awk_rtx_getarg (rtx, 0);
if (v->type == QSE_AWK_VAL_STR)
{
ptr = ((qse_awk_val_str_t*)v)->val.ptr;
len = ((qse_awk_val_str_t*)v)->val.len;
}
else
{
ptr = qse_awk_rtx_valtocpldup (rtx, v, &len);
if (ptr == QSE_NULL) return -1;
}
fret = qse_htb_delete (&rxtn->cmgrtab, ptr, len);
if (v->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, ptr);
v = qse_awk_rtx_makeintval (rtx, fret);
if (v == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, v);
return 0;
}
#endif
#define ADDFNC(awk,name,min,max,fnc,valid) \
if (qse_awk_addfnc (\
(awk), (name), qse_strlen(name), \
0, (min), (max), QSE_NULL, (fnc)) == QSE_NULL) return -1;
valid, (min), (max), QSE_NULL, (fnc)) == QSE_NULL) return -1;
static int add_functions (qse_awk_t* awk)
{
ADDFNC (awk, QSE_T("rand"), 0, 0, fnc_rand);
ADDFNC (awk, QSE_T("srand"), 0, 1, fnc_srand);
ADDFNC (awk, QSE_T("system"), 1, 1, fnc_system);
ADDFNC (awk, QSE_T("rand"), 0, 0, fnc_rand, 0);
ADDFNC (awk, QSE_T("srand"), 0, 1, fnc_srand, 0);
ADDFNC (awk, QSE_T("system"), 1, 1, fnc_system, 0);
#if defined(QSE_CHAR_IS_WCHAR)
ADDFNC (awk, QSE_T("setenc"), 2, 2, fnc_setenc, QSE_AWK_RIO);
ADDFNC (awk, QSE_T("unsetenc"), 1, 1, fnc_unsetenc, QSE_AWK_RIO);
#endif
return 0;
}