From b903f8ebb53d1f1f57218392c106292378c16c24 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 17 Jan 2012 16:45:01 +0000 Subject: [PATCH] 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 --- qse/cmd/awk/awk.c | 7 +- qse/include/qse/awk/Awk.hpp | 9 +- qse/include/qse/awk/StdAwk.hpp | 15 +- qse/include/qse/awk/awk.h | 49 ++++-- qse/include/qse/cmn/htb.h | 6 +- qse/include/qse/cmn/map.h | 4 +- qse/include/qse/cmn/mbwc.h | 23 ++- qse/include/qse/cmn/rbt.h | 6 +- qse/lib/awk/Awk.cpp | 4 +- qse/lib/awk/StdAwk.cpp | 176 ++++++++++++++++---- qse/lib/awk/awk.c | 6 +- qse/lib/awk/awk.h | 3 +- qse/lib/awk/fnc.c | 16 +- qse/lib/awk/parse.c | 2 +- qse/lib/awk/run.c | 30 +++- qse/lib/awk/std.c | 289 ++++++++++++++++++++++++++------- qse/lib/cmn/fs-move.c | 1 + qse/lib/cmn/htb.c | 2 +- qse/lib/cmn/mbwc.c | 14 ++ qse/lib/cmn/rbt.c | 2 +- qse/lib/sed/sed.c | 2 +- qse/samples/cmn/htb.c | 6 +- qse/samples/cmn/rbt.c | 6 +- qse/samples/sed/sed02.cpp | 1 + qse/samples/sed/sed03.cpp | 1 + 25 files changed, 527 insertions(+), 153 deletions(-) diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 9cd90abd..73288ee7 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -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 (); diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 60b39d74..d9cc8de9 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -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 ); /// diff --git a/qse/include/qse/awk/StdAwk.hpp b/qse/include/qse/awk/StdAwk.hpp index 682e2416..083020bf 100644 --- a/qse/include/qse/awk/StdAwk.hpp +++ b/qse/include/qse/awk/StdAwk.hpp @@ -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; diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index d7078dc2..042e0069 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -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 */ ); diff --git a/qse/include/qse/cmn/htb.h b/qse/include/qse/cmn/htb.h index 1fb8eb91..cdbf10b8 100644 --- a/qse/include/qse/cmn/htb.h +++ b/qse/include/qse/cmn/htb.h @@ -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 ); diff --git a/qse/include/qse/cmn/map.h b/qse/include/qse/cmn/map.h index 11159fb1..a03ec6ee 100644 --- a/qse/include/qse/cmn/map.h +++ b/qse/include/qse/cmn/map.h @@ -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) diff --git a/qse/include/qse/cmn/mbwc.h b/qse/include/qse/cmn/mbwc.h index 2bf9e7e7..f3ba9618 100644 --- a/qse/include/qse/cmn/mbwc.h +++ b/qse/include/qse/cmn/mbwc.h @@ -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 #include @@ -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 */ /* --------------------------------------------------- */ /** diff --git a/qse/include/qse/cmn/rbt.h b/qse/include/qse/cmn/rbt.h index 05ccc6fa..8be88ac1 100644 --- a/qse/include/qse/cmn/rbt.h +++ b/qse/include/qse/cmn/rbt.h @@ -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 ); diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 2ad51b84..92f6ba37 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -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 diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index 69269bf7..099f5225 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -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; diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index a407c4b2..f9916de3 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -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); diff --git a/qse/lib/awk/awk.h b/qse/lib/awk/awk.h index b56b8694..1bef86c3 100644 --- a/qse/lib/awk/awk.h +++ b/qse/lib/awk/awk.h @@ -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; }; diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 05f65a8e..e3c14b4d 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -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 && diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index a892e5d8..1945ed07 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -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)) { diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index c7550c97..65464c90 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -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) { diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 1486c1c9..afb75d45 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -26,6 +26,7 @@ #include #include #include +#include #include /* 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; } diff --git a/qse/lib/cmn/fs-move.c b/qse/lib/cmn/fs-move.c index 1817fc46..70fd6cb8 100644 --- a/qse/lib/cmn/fs-move.c +++ b/qse/lib/cmn/fs-move.c @@ -21,6 +21,7 @@ #include "fs.h" #include #include +#include #include "mem.h" diff --git a/qse/lib/cmn/htb.c b/qse/lib/cmn/htb.c index 5f1b129a..12a95981 100644 --- a/qse/lib/cmn/htb.c +++ b/qse/lib/cmn/htb.c @@ -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]; }; diff --git a/qse/lib/cmn/mbwc.c b/qse/lib/cmn/mbwc.c index 3a5adf68..320321d8 100644 --- a/qse/lib/cmn/mbwc.c +++ b/qse/lib/cmn/mbwc.c @@ -21,6 +21,7 @@ #include #include #include +#include /* 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 ( diff --git a/qse/lib/cmn/rbt.c b/qse/lib/cmn/rbt.c index 404b8e14..41db7de8 100644 --- a/qse/lib/cmn/rbt.c +++ b/qse/lib/cmn/rbt.c @@ -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]; }; diff --git a/qse/lib/sed/sed.c b/qse/lib/sed/sed.c index 65495594..5c907b1d 100644 --- a/qse/lib/sed/sed.c +++ b/qse/lib/sed/sed.c @@ -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); */ diff --git a/qse/samples/cmn/htb.c b/qse/samples/cmn/htb.c index 3671096a..b3e98f29 100644 --- a/qse/samples/cmn/htb.c +++ b/qse/samples/cmn/htb.c @@ -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++) { diff --git a/qse/samples/cmn/rbt.c b/qse/samples/cmn/rbt.c index 117fccd0..efbfe8df 100644 --- a/qse/samples/cmn/rbt.c +++ b/qse/samples/cmn/rbt.c @@ -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++) { diff --git a/qse/samples/sed/sed02.cpp b/qse/samples/sed/sed02.cpp index d616045c..5fa6a4eb 100644 --- a/qse/samples/sed/sed02.cpp +++ b/qse/samples/sed/sed02.cpp @@ -25,6 +25,7 @@ #include #if defined(_WIN32) +# include # include #endif diff --git a/qse/samples/sed/sed03.cpp b/qse/samples/sed/sed03.cpp index f0f3cf9f..c2a995d2 100644 --- a/qse/samples/sed/sed03.cpp +++ b/qse/samples/sed/sed03.cpp @@ -26,6 +26,7 @@ #include #if defined(_WIN32) +# include # include #endif