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_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 ();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

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];
};

View File

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

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];
};

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;
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); */

View File

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

View File

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

View File

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

View File

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