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:
parent
fa850168ee
commit
b903f8ebb5
@ -518,7 +518,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
||||
}
|
||||
|
||||
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)
|
||||
@ -947,7 +947,8 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CALLBACK
|
||||
rcb.stm = on_statement;
|
||||
qse_memset (&rcb, 0, QSE_SIZEOF(rcb));
|
||||
rcb.stmt = on_statement;
|
||||
rcb.ctx = &arg;
|
||||
#endif
|
||||
|
||||
@ -968,7 +969,7 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
|
||||
app_rtx = rtx;
|
||||
#ifdef ENABLE_CALLBACK
|
||||
qse_awk_rtx_setrcb (rtx, &rcb);
|
||||
qse_awk_rtx_pushrcb (rtx, &rcb);
|
||||
#endif
|
||||
|
||||
set_intr_run ();
|
||||
|
@ -1026,10 +1026,11 @@ public:
|
||||
/// function.
|
||||
///
|
||||
int addFunction (
|
||||
const char_t* name, ///< function name
|
||||
size_t minArgs, ///< minimum numbers of arguments
|
||||
size_t maxArgs, ///< maximum numbers of arguments
|
||||
FunctionHandler handler ///< function handler
|
||||
const char_t* name, ///< function name
|
||||
size_t minArgs, ///< minimum numbers of arguments
|
||||
size_t maxArgs, ///< maximum numbers of arguments
|
||||
FunctionHandler handler, ///< function handler
|
||||
int validOpts = 0 ///< valid if these options are set
|
||||
);
|
||||
|
||||
///
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
|
||||
int open ();
|
||||
void close ();
|
||||
Run* parse (Source& in, Source& out);
|
||||
|
||||
int addConsoleOutput (const char_t* arg, size_t len);
|
||||
int addConsoleOutput (const char_t* arg);
|
||||
@ -112,6 +113,14 @@ protected:
|
||||
int system (Run& run, Value& ret, const Value* args, size_t nargs,
|
||||
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
|
||||
int openPipe (Pipe& io);
|
||||
int closePipe (Pipe& io);
|
||||
@ -140,8 +149,8 @@ protected:
|
||||
void freeMem (void* ptr);
|
||||
|
||||
|
||||
int vsprintf (char_t* buf, size_t size,
|
||||
const char_t* fmt, va_list arg);
|
||||
int vsprintf (char_t* buf, size_t size,
|
||||
const char_t* fmt, va_list arg);
|
||||
|
||||
flt_t pow (flt_t x, flt_t y);
|
||||
flt_t mod (flt_t x, flt_t y);
|
||||
@ -156,6 +165,8 @@ protected:
|
||||
|
||||
protected:
|
||||
unsigned int seed;
|
||||
qse_htb_t cmgrtab;
|
||||
bool cmgrtab_inited;
|
||||
|
||||
/* standard input console - reuse runarg */
|
||||
size_t runarg_index;
|
||||
|
@ -672,35 +672,54 @@ struct 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.
|
||||
*/
|
||||
typedef void (*qse_awk_rcb_stm_t) (
|
||||
typedef void (*qse_awk_rcb_stmt_t) (
|
||||
qse_awk_rtx_t* rtx, /**< runtime context */
|
||||
qse_awk_nde_t* nde, /**< node */
|
||||
void* ctx /**< user-defined data */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_rcb_t type defines runtime callbacks. You can specify callback
|
||||
* functions with qse_awk_rtx_setrcb() to be informed of important events
|
||||
* during runtime.
|
||||
* The qse_awk_rcb_t type defines a runtime callback set. You can
|
||||
* register a callback function set with qse_awk_rtx_pushrcb().
|
||||
* 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
|
||||
{
|
||||
/**
|
||||
* called by qse_awk_rtx_close().
|
||||
*/
|
||||
qse_awk_rcb_close_t close;
|
||||
|
||||
/**
|
||||
* called by qse_awk_rtx_loop() and qse_awk_rtx_call() for
|
||||
* 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
|
||||
* 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
|
||||
@ -1655,18 +1674,18 @@ void qse_awk_rtx_stop (
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_rtx_setrcb() function gets runtime callbacks.
|
||||
* @return #QSE_NULL if no callback is set. Otherwise, the pointer to a
|
||||
* callback set.
|
||||
* The qse_awk_rtx_poprcb() function pops a runtime callback set
|
||||
* and returns the pointer to it. If no callback set can be popped,
|
||||
* 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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* 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_rcb_t* rcb /**< callback set */
|
||||
);
|
||||
|
@ -49,7 +49,7 @@
|
||||
* int i;
|
||||
*
|
||||
* 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++)
|
||||
* {
|
||||
@ -302,10 +302,10 @@ extern "C" {
|
||||
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.
|
||||
*/
|
||||
const qse_htb_mancbs_t* qse_htb_mancbs (
|
||||
const qse_htb_mancbs_t* qse_gethtbmancbs (
|
||||
qse_htb_mancbs_kind_t kind
|
||||
);
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
# 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_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_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)
|
||||
@ -91,7 +91,7 @@
|
||||
# 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_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_close(map) qse_rbt_close(map)
|
||||
# define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_rbt_init(map,mmgr,ks,vs)
|
||||
|
@ -21,6 +21,10 @@
|
||||
#ifndef _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/macros.h>
|
||||
|
||||
@ -28,9 +32,25 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
/* BUILTIN CMGR */
|
||||
/* --------------------------------------------------- */
|
||||
extern qse_cmgr_t* qse_utf8cmgr;
|
||||
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 (
|
||||
void
|
||||
);
|
||||
@ -39,7 +59,6 @@ void qse_setdflcmgr (
|
||||
qse_cmgr_t* cmgr
|
||||
);
|
||||
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
/* STRING CONVERSION USING CMGR */
|
||||
/* --------------------------------------------------- */
|
||||
@ -142,7 +161,7 @@ qse_mchar_t* qse_wcsatombsdupwithcmgr (
|
||||
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
/* STRING CONVERSION */
|
||||
/* STRING CONVERSION WITH DEFAULT GLOBAL CMGR */
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
/**
|
||||
|
@ -49,7 +49,7 @@
|
||||
* int i;
|
||||
*
|
||||
* 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++)
|
||||
* {
|
||||
@ -273,10 +273,10 @@ extern "C" {
|
||||
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.
|
||||
*/
|
||||
const qse_rbt_mancbs_t* qse_rbt_mancbs (
|
||||
const qse_rbt_mancbs_t* qse_getrbtmancbs (
|
||||
qse_rbt_mancbs_kind_t kind
|
||||
);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 &&
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "fs.h"
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/cmn/path.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
|
@ -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];
|
||||
};
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/cmn/slmb.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.
|
||||
* 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]);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
int qse_mbstowcs (
|
||||
|
@ -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];
|
||||
};
|
||||
|
@ -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;
|
||||
qse_map_setmancbs (
|
||||
&sed->tmp.labs,
|
||||
qse_map_mancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER)
|
||||
qse_getmapmancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER)
|
||||
);
|
||||
|
||||
/* init_append (sed); */
|
||||
|
@ -115,7 +115,7 @@ static int test1 ()
|
||||
qse_printf (QSE_T("cannot open a hash table\n"));
|
||||
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)
|
||||
{
|
||||
@ -167,7 +167,7 @@ static int test2 ()
|
||||
qse_printf (QSE_T("cannot open a hash table\n"));
|
||||
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++)
|
||||
{
|
||||
@ -384,7 +384,7 @@ static int test5 ()
|
||||
qse_printf (QSE_T("cannot open a hash table\n"));
|
||||
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++)
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ static int test1 ()
|
||||
qse_printf (QSE_T("cannot open a table\n"));
|
||||
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++)
|
||||
{
|
||||
@ -100,7 +100,7 @@ static int test2 ()
|
||||
qse_printf (QSE_T("cannot open a table\n"));
|
||||
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("world"), 5, QSE_T("ms. panda"), 9);
|
||||
@ -192,7 +192,7 @@ static int test5 ()
|
||||
qse_printf (QSE_T("cannot open a hash table\n"));
|
||||
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++)
|
||||
{
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include <locale.h>
|
||||
#if defined(_WIN32)
|
||||
# include <stdio.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <locale.h>
|
||||
#if defined(_WIN32)
|
||||
# include <stdio.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user