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:
hyung-hwan 2012-01-17 16:45:01 +00:00
parent fa850168ee
commit b903f8ebb5
25 changed files with 527 additions and 153 deletions

View File

@ -518,7 +518,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
} }
qse_htb_setmancbs (gvm, qse_htb_setmancbs (gvm,
qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_VALUE_COPIER) qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_VALUE_COPIER)
); );
while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF) while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF)
@ -947,7 +947,8 @@ static int awk_main (int argc, qse_char_t* argv[])
} }
#ifdef ENABLE_CALLBACK #ifdef ENABLE_CALLBACK
rcb.stm = on_statement; qse_memset (&rcb, 0, QSE_SIZEOF(rcb));
rcb.stmt = on_statement;
rcb.ctx = &arg; rcb.ctx = &arg;
#endif #endif
@ -968,7 +969,7 @@ static int awk_main (int argc, qse_char_t* argv[])
app_rtx = rtx; app_rtx = rtx;
#ifdef ENABLE_CALLBACK #ifdef ENABLE_CALLBACK
qse_awk_rtx_setrcb (rtx, &rcb); qse_awk_rtx_pushrcb (rtx, &rcb);
#endif #endif
set_intr_run (); set_intr_run ();

View File

@ -1026,10 +1026,11 @@ public:
/// function. /// function.
/// ///
int addFunction ( int addFunction (
const char_t* name, ///< function name const char_t* name, ///< function name
size_t minArgs, ///< minimum numbers of arguments size_t minArgs, ///< minimum numbers of arguments
size_t maxArgs, ///< maximum numbers of arguments size_t maxArgs, ///< maximum numbers of arguments
FunctionHandler handler ///< function handler FunctionHandler handler, ///< function handler
int validOpts = 0 ///< valid if these options are set
); );
/// ///

View File

@ -98,6 +98,7 @@ public:
int open (); int open ();
void close (); void close ();
Run* parse (Source& in, Source& out);
int addConsoleOutput (const char_t* arg, size_t len); int addConsoleOutput (const char_t* arg, size_t len);
int addConsoleOutput (const char_t* arg); int addConsoleOutput (const char_t* arg);
@ -112,6 +113,14 @@ protected:
int system (Run& run, Value& ret, const Value* args, size_t nargs, int system (Run& run, Value& ret, const Value* args, size_t nargs,
const char_t* name, size_t len); const char_t* name, size_t len);
#if defined(QSE_CHAR_IS_WCHAR)
qse_cmgr_t* getcmgr (const char_t* ioname);
int setenc (Run& run, Value& ret, const Value* args, size_t nargs,
const char_t* name, size_t len);
int unsetenc (Run& run, Value& ret, const Value* args, size_t nargs,
const char_t* name, size_t len);
#endif
// pipe io handlers // pipe io handlers
int openPipe (Pipe& io); int openPipe (Pipe& io);
int closePipe (Pipe& io); int closePipe (Pipe& io);
@ -140,8 +149,8 @@ protected:
void freeMem (void* ptr); void freeMem (void* ptr);
int vsprintf (char_t* buf, size_t size, int vsprintf (char_t* buf, size_t size,
const char_t* fmt, va_list arg); const char_t* fmt, va_list arg);
flt_t pow (flt_t x, flt_t y); flt_t pow (flt_t x, flt_t y);
flt_t mod (flt_t x, flt_t y); flt_t mod (flt_t x, flt_t y);
@ -156,6 +165,8 @@ protected:
protected: protected:
unsigned int seed; unsigned int seed;
qse_htb_t cmgrtab;
bool cmgrtab_inited;
/* standard input console - reuse runarg */ /* standard input console - reuse runarg */
size_t runarg_index; size_t runarg_index;

View File

@ -672,35 +672,54 @@ struct qse_awk_rio_t
typedef struct qse_awk_rio_t qse_awk_rio_t; typedef struct qse_awk_rio_t qse_awk_rio_t;
/** /**
* The qse_awk_rcb_stm_t type defines the callback function for each * The qse_awk_rcb_close_t type defines the callback function
* called when the runtime context is closed.
*/
typedef void (*qse_awk_rcb_close_t) (
qse_awk_rtx_t* rtx, /**< runtime context */
void* ctx /**< user-defined data */
);
/**
* The qse_awk_rcb_stmt_t type defines the callback function for each
* statement. * statement.
*/ */
typedef void (*qse_awk_rcb_stm_t) ( typedef void (*qse_awk_rcb_stmt_t) (
qse_awk_rtx_t* rtx, /**< runtime context */ qse_awk_rtx_t* rtx, /**< runtime context */
qse_awk_nde_t* nde, /**< node */ qse_awk_nde_t* nde, /**< node */
void* ctx /**< user-defined data */ void* ctx /**< user-defined data */
); );
/** /**
* The qse_awk_rcb_t type defines runtime callbacks. You can specify callback * The qse_awk_rcb_t type defines a runtime callback set. You can
* functions with qse_awk_rtx_setrcb() to be informed of important events * register a callback function set with qse_awk_rtx_pushrcb().
* during runtime. * The callback functions in the set registered are called in a
* proper context in the reverse order of registeration.
*/ */
typedef struct qse_awk_rcb_t qse_awk_rcb_t;
struct qse_awk_rcb_t struct qse_awk_rcb_t
{ {
/**
* called by qse_awk_rtx_close().
*/
qse_awk_rcb_close_t close;
/** /**
* called by qse_awk_rtx_loop() and qse_awk_rtx_call() for * called by qse_awk_rtx_loop() and qse_awk_rtx_call() for
* each statement executed. * each statement executed.
*/ */
qse_awk_rcb_stm_t stm; qse_awk_rcb_stmt_t stmt;
/** /**
* A caller may store a user-defined data pointer into this field. This * A caller may store a user-defined data pointer into this field. This
* is passed to the actual callback. * is passed to an actual callback.
*/ */
void* ctx; void* ctx;
/* internal use only. don't touch this field */
qse_awk_rcb_t* next;
}; };
typedef struct qse_awk_rcb_t qse_awk_rcb_t;
/** /**
* The qse_awk_option_t type defines various options to change the behavior * The qse_awk_option_t type defines various options to change the behavior
@ -1655,18 +1674,18 @@ void qse_awk_rtx_stop (
); );
/** /**
* The qse_awk_rtx_setrcb() function gets runtime callbacks. * The qse_awk_rtx_poprcb() function pops a runtime callback set
* @return #QSE_NULL if no callback is set. Otherwise, the pointer to a * and returns the pointer to it. If no callback set can be popped,
* callback set. * it returns #QSE_NULL.
*/ */
qse_awk_rcb_t* qse_awk_rtx_getrcb ( qse_awk_rcb_t* qse_awk_rtx_poprcb (
qse_awk_rtx_t* rtx /**< runtime context */ qse_awk_rtx_t* rtx /**< runtime context */
); );
/** /**
* The qse_awk_rtx_setrcb() function sets runtime callbacks. * The qse_awk_rtx_pushrcb() function register a runtime callback set.
*/ */
void qse_awk_rtx_setrcb ( void qse_awk_rtx_pushrcb (
qse_awk_rtx_t* rtx, /**< runtime context */ qse_awk_rtx_t* rtx, /**< runtime context */
qse_awk_rcb_t* rcb /**< callback set */ qse_awk_rcb_t* rcb /**< callback set */
); );

View File

@ -49,7 +49,7 @@
* int i; * int i;
* *
* s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 30, 75, 1, 1); // error handling skipped * s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 30, 75, 1, 1); // error handling skipped
* qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS)); * qse_htb_setmancbs (s1, qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_COPIERS));
* *
* for (i = 0; i < 20; i++) * for (i = 0; i < 20; i++)
* { * {
@ -302,10 +302,10 @@ extern "C" {
QSE_DEFINE_COMMON_FUNCTIONS (htb) QSE_DEFINE_COMMON_FUNCTIONS (htb)
/** /**
* The qse_htb_mancbs() functions returns a predefined callback set for * The qse_gethtbmancbs() functions returns a predefined callback set for
* pair manipulation. * pair manipulation.
*/ */
const qse_htb_mancbs_t* qse_htb_mancbs ( const qse_htb_mancbs_t* qse_gethtbmancbs (
qse_htb_mancbs_kind_t kind qse_htb_mancbs_kind_t kind
); );

View File

@ -33,7 +33,7 @@
# define QSE_MAP_MANCBS_INLINE_COPIERS QSE_HTB_MANCBS_INLINE_COPIERS # define QSE_MAP_MANCBS_INLINE_COPIERS QSE_HTB_MANCBS_INLINE_COPIERS
# define QSE_MAP_MANCBS_INLINE_KEY_COPIER QSE_HTB_MANCBS_INLINE_KEY_COPIER # define QSE_MAP_MANCBS_INLINE_KEY_COPIER QSE_HTB_MANCBS_INLINE_KEY_COPIER
# define QSE_MAP_MANCBS_INLINE_VALUE_COPIER QSE_HTB_MANCBS_INLINE_VALUE_COPIER # define QSE_MAP_MANCBS_INLINE_VALUE_COPIER QSE_HTB_MANCBS_INLINE_VALUE_COPIER
# define qse_map_mancbs(kind) qse_htb_mancbs(kind) # define qse_getmapmancbs(kind) qse_gethtbmancbs(kind)
# define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_htb_open(mmgr,ext,capa,factor,ks,vs) # define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_htb_open(mmgr,ext,capa,factor,ks,vs)
# define qse_map_close(map) qse_htb_close(map) # define qse_map_close(map) qse_htb_close(map)
# define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_htb_init(map,mmgr,capa,factor,ks,vs) # define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_htb_init(map,mmgr,capa,factor,ks,vs)
@ -91,7 +91,7 @@
# define QSE_MAP_MANCBS_INLINE_COPIERS QSE_RBT_MANCBS_INLINE_COPIERS # define QSE_MAP_MANCBS_INLINE_COPIERS QSE_RBT_MANCBS_INLINE_COPIERS
# define QSE_MAP_MANCBS_INLINE_KEY_COPIER QSE_RBT_MANCBS_INLINE_KEY_COPIER # define QSE_MAP_MANCBS_INLINE_KEY_COPIER QSE_RBT_MANCBS_INLINE_KEY_COPIER
# define QSE_MAP_MANCBS_INLINE_VALUE_COPIER QSE_RBT_MANCBS_INLINE_VALUE_COPIER # define QSE_MAP_MANCBS_INLINE_VALUE_COPIER QSE_RBT_MANCBS_INLINE_VALUE_COPIER
# define qse_map_mancbs(kind) qse_rbt_mancbs(kind) # define qse_getmapmancbs(kind) qse_getrbtmancbs(kind)
# define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_rbt_open(mmgr,ext,ks,vs) # define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_rbt_open(mmgr,ext,ks,vs)
# define qse_map_close(map) qse_rbt_close(map) # define qse_map_close(map) qse_rbt_close(map)
# define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_rbt_init(map,mmgr,ks,vs) # define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_rbt_init(map,mmgr,ks,vs)

View File

@ -21,6 +21,10 @@
#ifndef _QSE_CMN_MBWC_H_ #ifndef _QSE_CMN_MBWC_H_
#define _QSE_CMN_MBWC_H_ #define _QSE_CMN_MBWC_H_
/** @file
* This file provides functions and definitions needed for
* multibyte/wide-characer conversion.
*/
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
@ -28,9 +32,25 @@
extern "C" { extern "C" {
#endif #endif
/* --------------------------------------------------- */
/* BUILTIN CMGR */
/* --------------------------------------------------- */
extern qse_cmgr_t* qse_utf8cmgr; extern qse_cmgr_t* qse_utf8cmgr;
extern qse_cmgr_t* qse_slmbcmgr; extern qse_cmgr_t* qse_slmbcmgr;
/**
* The qse_getcmgrbyname() function find a builtin cmgr matching a given
* @a name and returns it. It returns #QSE_NULL if no match is found.
* The @a name can be one of "utf8", "slmb", and an empty string. Calling this
* function with an empty string is the same as calling qse_getdflcmgr().
*/
qse_cmgr_t* qse_getcmgrbyname (
const qse_char_t* name
);
/* --------------------------------------------------- */
/* DEFAULT GLOBAL CMGR */
/* --------------------------------------------------- */
qse_cmgr_t* qse_getdflcmgr ( qse_cmgr_t* qse_getdflcmgr (
void void
); );
@ -39,7 +59,6 @@ void qse_setdflcmgr (
qse_cmgr_t* cmgr qse_cmgr_t* cmgr
); );
/* --------------------------------------------------- */ /* --------------------------------------------------- */
/* STRING CONVERSION USING CMGR */ /* STRING CONVERSION USING CMGR */
/* --------------------------------------------------- */ /* --------------------------------------------------- */
@ -142,7 +161,7 @@ qse_mchar_t* qse_wcsatombsdupwithcmgr (
/* --------------------------------------------------- */ /* --------------------------------------------------- */
/* STRING CONVERSION */ /* STRING CONVERSION WITH DEFAULT GLOBAL CMGR */
/* --------------------------------------------------- */ /* --------------------------------------------------- */
/** /**

View File

@ -49,7 +49,7 @@
* int i; * int i;
* *
* s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0, 1, 1); // error handling skipped * s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0, 1, 1); // error handling skipped
* qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS)); * qse_rbt_setmancbs (s1, qse_getrbtmancbs(QSE_RBT_MANCBS_INLINE_COPIERS));
* *
* for (i = 0; i < 20; i++) * for (i = 0; i < 20; i++)
* { * {
@ -273,10 +273,10 @@ extern "C" {
QSE_DEFINE_COMMON_FUNCTIONS (rbt) QSE_DEFINE_COMMON_FUNCTIONS (rbt)
/** /**
* The qse_rbt_mancbs() functions returns a predefined callback set for * The qse_getrbtmancbs() functions returns a predefined callback set for
* pair manipulation. * pair manipulation.
*/ */
const qse_rbt_mancbs_t* qse_rbt_mancbs ( const qse_rbt_mancbs_t* qse_getrbtmancbs (
qse_rbt_mancbs_kind_t kind qse_rbt_mancbs_kind_t kind
); );

View File

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

View File

@ -22,7 +22,6 @@
#include <qse/cmn/str.h> #include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h> #include <qse/cmn/mbwc.h>
#include <qse/cmn/time.h> #include <qse/cmn/time.h>
#include <qse/cmn/fio.h>
#include <qse/cmn/pio.h> #include <qse/cmn/pio.h>
#include <qse/cmn/sio.h> #include <qse/cmn/sio.h>
#include <qse/cmn/path.h> #include <qse/cmn/path.h>
@ -42,10 +41,10 @@
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
///////////////////////////////// /////////////////////////////////
#define ADDFNC(name,min,max,impl) \ #define ADDFNC(name,min,max,impl,vopts) \
do { \ do { \
if (addFunction (name, min, max, \ if (addFunction (name, min, max, \
(FunctionHandler)impl) == -1) \ (FunctionHandler)impl, vopts) == -1) \
{ \ { \
Awk::close (); \ Awk::close (); \
return -1; \ return -1; \
@ -97,9 +96,14 @@ int StdAwk::open ()
int n = Awk::open (); int n = Awk::open ();
if (n == -1) return n; if (n == -1) return n;
ADDFNC (QSE_T("rand"), 0, 0, &StdAwk::rand); ADDFNC (QSE_T("rand"), 0, 0, &StdAwk::rand, 0);
ADDFNC (QSE_T("srand"), 0, 1, &StdAwk::srand); ADDFNC (QSE_T("srand"), 0, 1, &StdAwk::srand, 0);
ADDFNC (QSE_T("system"), 1, 1, &StdAwk::system); 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; qse_ntime_t now;
@ -107,15 +111,58 @@ int StdAwk::open ()
else this->seed = (unsigned int)now; else this->seed = (unsigned int)now;
::srand (this->seed); ::srand (this->seed);
this->cmgrtab_inited = false;
return 0; return 0;
} }
void StdAwk::close () void StdAwk::close ()
{ {
#if defined(QSE_CHAR_IS_WCHAR)
if (this->cmgrtab_inited)
{
qse_htb_fini (&this->cmgrtab);
this->cmgrtab_inited = false;
}
#endif
clearConsoleOutputs (); clearConsoleOutputs ();
Awk::close (); 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, int StdAwk::rand (Run& run, Value& ret, const Value* args, size_t nargs,
const char_t* name, size_t len) 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 #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) int StdAwk::openPipe (Pipe& io)
{ {
Awk::Pipe::Mode mode = io.getMode(); Awk::Pipe::Mode mode = io.getMode();
@ -197,6 +291,15 @@ int StdAwk::openPipe (Pipe& io)
); );
if (pio == QSE_NULL) return -1; 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); io.setHandle (pio);
return 1; return 1;
} }
@ -241,58 +344,55 @@ int StdAwk::flushPipe (Pipe& io)
int StdAwk::openFile (File& io) int StdAwk::openFile (File& io)
{ {
Awk::File::Mode mode = io.getMode(); Awk::File::Mode mode = io.getMode();
qse_fio_t* fio = QSE_NULL; qse_sio_t* sio = QSE_NULL;
int flags = QSE_FIO_TEXT; int flags = QSE_SIO_IGNOREMBWCERR;
switch (mode) switch (mode)
{ {
case Awk::File::READ: case Awk::File::READ:
flags |= QSE_FIO_READ; flags |= QSE_SIO_READ;
break; break;
case Awk::File::WRITE: case Awk::File::WRITE:
flags |= QSE_FIO_WRITE | flags |= QSE_SIO_WRITE |
QSE_FIO_CREATE | QSE_SIO_CREATE |
QSE_FIO_TRUNCATE; QSE_SIO_TRUNCATE;
break; break;
case Awk::File::APPEND: case Awk::File::APPEND:
flags |= QSE_FIO_APPEND | flags |= QSE_SIO_APPEND |
QSE_FIO_CREATE; QSE_SIO_CREATE;
break; break;
} }
fio = qse_fio_open ( sio = qse_sio_open (this->getMmgr(), 0, io.getName(), flags);
this->getMmgr(), if (sio == NULL) return -1;
0, #if defined(QSE_CHAR_IS_WCHAR)
io.getName(), qse_cmgr_t* cmgr = this->getcmgr (io.getName());
flags, if (cmgr) qse_sio_setcmgr (sio, cmgr);
QSE_FIO_RUSR | QSE_FIO_WUSR | #endif
QSE_FIO_RGRP | QSE_FIO_ROTH
);
if (fio == NULL) return -1;
io.setHandle (fio); io.setHandle (sio);
return 1; return 1;
} }
int StdAwk::closeFile (File& io) int StdAwk::closeFile (File& io)
{ {
qse_fio_close ((qse_fio_t*)io.getHandle()); qse_sio_close ((qse_sio_t*)io.getHandle());
return 0; return 0;
} }
StdAwk::ssize_t StdAwk::readFile (File& io, char_t* buf, size_t len) 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) 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) 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) 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 (this->name[0] == QSE_T('-') && this->name[1] == QSE_T('\0'))
{ {
if (io.getMode() == READ) 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 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; if (sio == QSE_NULL) return -1;
} }
else else
@ -794,8 +899,9 @@ int StdAwk::SourceFile::open (Data& io)
sio = open_sio ( sio = open_sio (
io, QSE_NULL, this->name, io, QSE_NULL, this->name,
(io.getMode() == READ? (io.getMode() == READ?
QSE_SIO_READ: (QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE|QSE_SIO_IGNOREMBWCERR)) (QSE_SIO_WRITE | QSE_SIO_CREATE |
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR))
); );
if (sio == QSE_NULL) return -1; if (sio == QSE_NULL) return -1;
@ -811,7 +917,6 @@ int StdAwk::SourceFile::open (Data& io)
else else
{ {
// open an included file // open an included file
const char_t* file = ioname; const char_t* file = ioname;
char_t fbuf[64]; char_t fbuf[64];
char_t* dbuf = QSE_NULL; char_t* dbuf = QSE_NULL;
@ -844,8 +949,9 @@ int StdAwk::SourceFile::open (Data& io)
sio = open_sio ( sio = open_sio (
io, QSE_NULL, file, io, QSE_NULL, file,
(io.getMode() == READ? (io.getMode() == READ?
QSE_SIO_READ: (QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE|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 (dbuf) QSE_MMGR_FREE (((Awk*)io)->getMmgr(), dbuf);
if (sio == QSE_NULL) return -1; 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; if (awk->sio.names == QSE_NULL) goto oops;
*(qse_awk_t**)QSE_XTN(awk->sio.names) = awk; *(qse_awk_t**)QSE_XTN(awk->sio.names) = awk;
qse_htb_setmancbs (awk->sio.names, 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; 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; if (awk->parse.funs == QSE_NULL) goto oops;
*(qse_awk_t**)QSE_XTN(awk->parse.funs) = awk; *(qse_awk_t**)QSE_XTN(awk->parse.funs) = awk;
qse_htb_setmancbs (awk->parse.funs, 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 ( 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; if (awk->parse.named == QSE_NULL) goto oops;
*(qse_awk_t**)QSE_XTN(awk->parse.named) = awk; *(qse_awk_t**)QSE_XTN(awk->parse.named) = awk;
qse_htb_setmancbs (awk->parse.named, 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); 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_size_t len;
qse_awk_val_t* val; /* $1 .. $NF */ qse_awk_val_t* val; /* $1 .. $NF */
}* flds; }* flds;
} inrec; } inrec;
struct struct
@ -372,7 +371,7 @@ struct qse_awk_rtx_t
qse_awk_errinf_t errinf; qse_awk_errinf_t errinf;
qse_awk_t* awk; 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_fun_t handler)
{ {
qse_awk_fnc_t* fnc; qse_awk_fnc_t* fnc;
qse_size_t fnc_size;
qse_size_t spec_len; qse_size_t spec_len;
if (name_len <= 0) if (name_len <= 0)
@ -121,16 +122,19 @@ void* qse_awk_addfnc (
spec_len = (arg_spec == QSE_NULL)? 0: qse_strlen(arg_spec); 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) + QSE_SIZEOF(qse_awk_fnc_t) +
(name_len+1) * QSE_SIZEOF(qse_char_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) if (fnc == QSE_NULL)
{ {
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return QSE_NULL; return QSE_NULL;
} }
QSE_MEMSET (fnc, 0, fnc_size);
fnc->name.ptr = (qse_char_t*)(fnc + 1); fnc->name.ptr = (qse_char_t*)(fnc + 1);
fnc->name.len = name_len; fnc->name.len = name_len;
qse_strxncpy (fnc->name.ptr, name_len+1, name, 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_awk_fnc_t* fnc;
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
/* search the system function table */ /* search the system function table
/* TODO: some speed up? binary search by ordering the 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++) for (fnc = sys_fnc; fnc->name.ptr != QSE_NULL; fnc++)
{ {
if (fnc->valid != 0 && 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 */ /* check if namedup is an intrinsic function name */
fnc = qse_awk_getfnc (awk, namedup, namelen); fnc = qse_awk_getfnc (awk, namedup, namelen);
if (fnc != QSE_NULL) if (fnc)
{ {
if (MATCH(awk,TOK_LPAREN)) 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) 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); fini_rtx (rtx, 1);
QSE_AWK_FREE (rtx->awk, rtx); 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); 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) 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; 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)->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) 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/mbwc.h>
#include <qse/cmn/time.h> #include <qse/cmn/time.h>
#include <qse/cmn/path.h> #include <qse/cmn/path.h>
#include <qse/cmn/htb.h>
#include <qse/cmn/stdio.h> /* TODO: remove dependency on qse_vsprintf */ #include <qse/cmn/stdio.h> /* TODO: remove dependency on qse_vsprintf */
#include "../cmn/mem.h" #include "../cmn/mem.h"
@ -116,8 +117,16 @@ typedef struct rxtn_t
qse_cmgr_t* cmgr; qse_cmgr_t* cmgr;
} c; /* console */ } c; /* console */
#if defined(QSE_CHAR_IS_WCHAR)
int cmgrtab_inited;
qse_htb_t cmgrtab;
#endif
} rxtn_t; } 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) 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) #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 ( 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); if (dbuf != QSE_NULL) QSE_MMGR_FREE (awk->mmgr, dbuf);
@ -800,8 +809,20 @@ static qse_ssize_t awk_rio_pipe (
QSE_NULL, QSE_NULL,
flags|QSE_PIO_SHELL|QSE_PIO_TEXT|QSE_PIO_IGNOREMBWCERR flags|QSE_PIO_SHELL|QSE_PIO_TEXT|QSE_PIO_IGNOREMBWCERR
); );
if (handle == QSE_NULL) return -1; 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; riod->handle = (void*)handle;
return 1; return 1;
} }
@ -870,60 +891,61 @@ static qse_ssize_t awk_rio_file (
{ {
case QSE_AWK_RIO_OPEN: case QSE_AWK_RIO_OPEN:
{ {
qse_fio_t* handle; qse_sio_t* handle;
int flags; 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 ( handle = qse_sio_open (rtx->awk->mmgr, 0, riod->name, flags);
rtx->awk->mmgr,
0,
riod->name,
flags | QSE_FIO_TEXT,
QSE_FIO_RUSR | QSE_FIO_WUSR |
QSE_FIO_RGRP | QSE_FIO_ROTH
);
if (handle == QSE_NULL) if (handle == QSE_NULL)
{ {
qse_cstr_t errarg; qse_cstr_t errarg;
errarg.ptr = riod->name; errarg.ptr = riod->name;
errarg.len = qse_strlen(riod->name); errarg.len = qse_strlen(riod->name);
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &errarg); qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &errarg);
return -1; 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; riod->handle = (void*)handle;
return 1; return 1;
} }
case QSE_AWK_RIO_CLOSE: 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; riod->handle = QSE_NULL;
return 0; return 0;
} }
case QSE_AWK_RIO_READ: case QSE_AWK_RIO_READ:
{ {
return qse_fio_read ( return qse_sio_getstrn (
(qse_fio_t*)riod->handle, (qse_sio_t*)riod->handle,
data, data,
size size
); );
@ -931,8 +953,8 @@ static qse_ssize_t awk_rio_file (
case QSE_AWK_RIO_WRITE: case QSE_AWK_RIO_WRITE:
{ {
return qse_fio_write ( return qse_sio_putstrn (
(qse_fio_t*)riod->handle, (qse_sio_t*)riod->handle,
data, data,
size size
); );
@ -940,7 +962,7 @@ static qse_ssize_t awk_rio_file (
case QSE_AWK_RIO_FLUSH: 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: case QSE_AWK_RIO_NEXT:
@ -1245,13 +1267,19 @@ static qse_ssize_t awk_rio_console (
return -1; return -1;
} }
/* TODO: provide a way to set cmgr for console files icf and ocf... static void fini_rxtn (qse_awk_rtx_t* rtx, void* ctx)
* should i accept something similar to qse_awk_parsestd_t? {
* rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
* 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. #if defined(QSE_CHAR_IS_WCHAR)
* you can change the global cmgr only with qse_setdflcmgr(). if (rxtn->cmgrtab_inited)
*/ {
qse_htb_fini (&rxtn->cmgrtab);
rxtn->cmgrtab_inited = 0;
}
#endif
}
qse_awk_rtx_t* qse_awk_rtx_openstd ( qse_awk_rtx_t* qse_awk_rtx_openstd (
qse_awk_t* awk, qse_awk_t* awk,
qse_size_t xtnsize, qse_size_t xtnsize,
@ -1260,6 +1288,13 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
const qse_char_t*const ocf[], const qse_char_t*const ocf[],
qse_cmgr_t* cmgr) qse_cmgr_t* cmgr)
{ {
static qse_awk_rcb_t rcb =
{
fini_rxtn,
QSE_NULL,
QSE_NULL
};
qse_awk_rtx_t* rtx; qse_awk_rtx_t* rtx;
qse_awk_rio_t rio; qse_awk_rio_t rio;
rxtn_t* rxtn; rxtn_t* rxtn;
@ -1325,6 +1360,25 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
rxtn = (rxtn_t*) QSE_XTN (rtx); rxtn = (rxtn_t*) QSE_XTN (rtx);
QSE_MEMSET (rxtn, 0, QSE_SIZEOF(rxtn_t)); 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; if (qse_gettime (&now) <= -1) rxtn->seed = 0;
else rxtn->seed = (unsigned int) now; else rxtn->seed = (unsigned int) now;
srand (rxtn->seed); srand (rxtn->seed);
@ -1337,7 +1391,6 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
rxtn->c.out.count = 0; rxtn->c.out.count = 0;
rxtn->c.cmgr = cmgr; rxtn->c.cmgr = cmgr;
/* FILENAME can be set when the input console is opened. /* FILENAME can be set when the input console is opened.
* so we skip setting it here even if an explicit console file * so we skip setting it here even if an explicit console file
* is specified. So the value of FILENAME is empty in the * is specified. So the value of FILENAME is empty in the
@ -1430,7 +1483,7 @@ static int fnc_system (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
{ {
qse_size_t nargs; qse_size_t nargs;
qse_awk_val_t* v; qse_awk_val_t* v;
qse_char_t* str, * ptr, * end; qse_char_t* str;
qse_size_t len; qse_size_t len;
int n = 0; 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. /* the target name contains a null character.
* make system return -1 */ * make system return -1 */
ptr = str; end = str + len; if (qse_strxchr (str, len, QSE_T('\0')))
while (ptr < end)
{ {
if (*ptr == QSE_T('\0')) n = -1;
{ goto skip_system;
n = -1;
goto skip_system;
}
ptr++;
} }
#if defined(_WIN32) #if defined(_WIN32)
@ -1493,15 +1540,143 @@ skip_system:
return 0; 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 (\ if (qse_awk_addfnc (\
(awk), (name), qse_strlen(name), \ (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) static int add_functions (qse_awk_t* awk)
{ {
ADDFNC (awk, QSE_T("rand"), 0, 0, fnc_rand); ADDFNC (awk, QSE_T("rand"), 0, 0, fnc_rand, 0);
ADDFNC (awk, QSE_T("srand"), 0, 1, fnc_srand); ADDFNC (awk, QSE_T("srand"), 0, 1, fnc_srand, 0);
ADDFNC (awk, QSE_T("system"), 1, 1, fnc_system); 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; return 0;
} }

View File

@ -21,6 +21,7 @@
#include "fs.h" #include "fs.h"
#include <qse/cmn/mbwc.h> #include <qse/cmn/mbwc.h>
#include <qse/cmn/path.h> #include <qse/cmn/path.h>
#include <qse/cmn/str.h>
#include "mem.h" #include "mem.h"

View File

@ -250,7 +250,7 @@ static mancbs_t mancbs[] =
} }
}; };
const mancbs_t* qse_htb_mancbs (mancbs_kind_t kind) const mancbs_t* qse_gethtbmancbs (mancbs_kind_t kind)
{ {
return &mancbs[kind]; return &mancbs[kind];
}; };

View File

@ -21,6 +21,7 @@
#include <qse/cmn/mbwc.h> #include <qse/cmn/mbwc.h>
#include <qse/cmn/slmb.h> #include <qse/cmn/slmb.h>
#include <qse/cmn/utf8.h> #include <qse/cmn/utf8.h>
#include <qse/cmn/str.h>
/* TODO: there is no guarantee that slwc is a unicode charater or vice versa. /* TODO: there is no guarantee that slwc is a unicode charater or vice versa.
* the ctype handling functions should be made wide-character * the ctype handling functions should be made wide-character
@ -57,6 +58,19 @@ void qse_setdflcmgr (qse_cmgr_t* cmgr)
dfl_cmgr = (cmgr? cmgr: &builtin_cmgr[0]); dfl_cmgr = (cmgr? cmgr: &builtin_cmgr[0]);
} }
qse_cmgr_t* qse_getcmgrbyname (const qse_char_t* name)
{
if (name)
{
/* TODO: binary search */
if (qse_strcmp(name, QSE_T("")) == 0) return dfl_cmgr;
if (qse_strcmp(name, QSE_T("utf8")) == 0) return qse_utf8cmgr;
if (qse_strcmp(name, QSE_T("slmb")) == 0) return qse_slmbcmgr;
/* TODO: add more */
}
return QSE_NULL;
}
/* string conversion function using default character conversion manager */ /* string conversion function using default character conversion manager */
int qse_mbstowcs ( int qse_mbstowcs (

View File

@ -192,7 +192,7 @@ static mancbs_t mancbs[] =
} }
}; };
const mancbs_t* qse_rbt_mancbs (mancbs_kind_t kind) const mancbs_t* qse_getrbtmancbs (mancbs_kind_t kind)
{ {
return &mancbs[kind]; return &mancbs[kind];
}; };

View File

@ -89,7 +89,7 @@ int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
128, 70, QSE_SIZEOF(qse_char_t), 1) <= -1) goto oops_3; 128, 70, QSE_SIZEOF(qse_char_t), 1) <= -1) goto oops_3;
qse_map_setmancbs ( qse_map_setmancbs (
&sed->tmp.labs, &sed->tmp.labs,
qse_map_mancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER) qse_getmapmancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER)
); );
/* init_append (sed); */ /* init_append (sed); */

View File

@ -115,7 +115,7 @@ static int test1 ()
qse_printf (QSE_T("cannot open a hash table\n")); qse_printf (QSE_T("cannot open a hash table\n"));
return -1; return -1;
} }
qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS)); qse_htb_setmancbs (s1, qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_COPIERS));
if (test1_build(s1) == -1) if (test1_build(s1) == -1)
{ {
@ -167,7 +167,7 @@ static int test2 ()
qse_printf (QSE_T("cannot open a hash table\n")); qse_printf (QSE_T("cannot open a hash table\n"));
return -1; return -1;
} }
qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS)); qse_htb_setmancbs (s1, qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_COPIERS));
for (i = 0; i < QSE_COUNTOF(keys); i++) for (i = 0; i < QSE_COUNTOF(keys); i++)
{ {
@ -384,7 +384,7 @@ static int test5 ()
qse_printf (QSE_T("cannot open a hash table\n")); qse_printf (QSE_T("cannot open a hash table\n"));
return -1; return -1;
} }
qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS)); qse_htb_setmancbs (s1, qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_COPIERS));
for (i = 0; i < QSE_COUNTOF(vals); i++) for (i = 0; i < QSE_COUNTOF(vals); i++)
{ {

View File

@ -40,7 +40,7 @@ static int test1 ()
qse_printf (QSE_T("cannot open a table\n")); qse_printf (QSE_T("cannot open a table\n"));
return -1; return -1;
} }
qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS)); qse_rbt_setmancbs (s1, qse_getrbtmancbs(QSE_RBT_MANCBS_INLINE_COPIERS));
for (i = 0; i < 20; i++) for (i = 0; i < 20; i++)
{ {
@ -100,7 +100,7 @@ static int test2 ()
qse_printf (QSE_T("cannot open a table\n")); qse_printf (QSE_T("cannot open a table\n"));
return -1; return -1;
} }
qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS)); qse_rbt_setmancbs (s1, qse_getrbtmancbs(QSE_RBT_MANCBS_INLINE_COPIERS));
qse_rbt_insert (s1, QSE_T("hello"), 5, QSE_T("mr. monkey"), 10); qse_rbt_insert (s1, QSE_T("hello"), 5, QSE_T("mr. monkey"), 10);
qse_rbt_insert (s1, QSE_T("world"), 5, QSE_T("ms. panda"), 9); qse_rbt_insert (s1, QSE_T("world"), 5, QSE_T("ms. panda"), 9);
@ -192,7 +192,7 @@ static int test5 ()
qse_printf (QSE_T("cannot open a hash table\n")); qse_printf (QSE_T("cannot open a hash table\n"));
return -1; return -1;
} }
qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS)); qse_rbt_setmancbs (s1, qse_getrbtmancbs(QSE_RBT_MANCBS_INLINE_COPIERS));
for (i = 0; i < QSE_COUNTOF(vals); i++) for (i = 0; i < QSE_COUNTOF(vals); i++)
{ {

View File

@ -25,6 +25,7 @@
#include <locale.h> #include <locale.h>
#if defined(_WIN32) #if defined(_WIN32)
# include <stdio.h>
# include <windows.h> # include <windows.h>
#endif #endif

View File

@ -26,6 +26,7 @@
#include <locale.h> #include <locale.h>
#if defined(_WIN32) #if defined(_WIN32)
# include <stdio.h>
# include <windows.h> # include <windows.h>
#endif #endif