changed Awk to use HashTable instead of htb.
added Cstr, Mcstr, Wcstr. changed Awk not to use in-class placement new in allocating a value
This commit is contained in:
		
							
								
								
									
										156
									
								
								qse/include/qse/Cstr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								qse/include/qse/Cstr.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | |||||||
|  | /* | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |     Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. | ||||||
|  |  | ||||||
|  |     Redistribution and use in source and binary forms, with or without | ||||||
|  |     modification, are permitted provided that the following conditions | ||||||
|  |     are met: | ||||||
|  |     1. Redistributions of source code must retain the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer. | ||||||
|  |     2. Redistributions in binary form must reproduce the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer in the | ||||||
|  |        documentation and/or other materials provided with the distribution. | ||||||
|  |  | ||||||
|  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||||
|  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||||
|  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||||
|  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||||
|  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||||
|  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef _QSE_CSTR_HPP_ | ||||||
|  | #define _QSE_CSTR_HPP_ | ||||||
|  |  | ||||||
|  | #include <qse/Types.hpp> | ||||||
|  | #include <qse/Hashable.hpp> | ||||||
|  | #include <qse/cmn/str.h> | ||||||
|  |  | ||||||
|  | ///////////////////////////////// | ||||||
|  | QSE_BEGIN_NAMESPACE(QSE) | ||||||
|  | ///////////////////////////////// | ||||||
|  |  | ||||||
|  | /// The Mcstr class encapsulates a multibyte string pointer and length. | ||||||
|  | class Mcstr: public Types::mcstr_t, public Hashable | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	Mcstr (qse_mchar_t* ptr, qse_size_t len) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = ptr; | ||||||
|  | 		this->len = len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Mcstr (const qse_mchar_t* ptr, qse_size_t len) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = (qse_mchar_t*)ptr; | ||||||
|  | 		this->len = len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Mcstr (Types::mcstr_t& str) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = (qse_mchar_t*)str.ptr; | ||||||
|  | 		this->len = str.len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	qse_size_t getHashCode () const  | ||||||
|  | 	{ | ||||||
|  | 		return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(*this->ptr)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool operator== (const Mcstr& str) const | ||||||
|  | 	{ | ||||||
|  | 		return qse_mbsxncmp (this->ptr, this->len, str.ptr, str.len) == 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool operator!= (const Mcstr& str) const | ||||||
|  | 	{ | ||||||
|  | 		return qse_mbsxncmp (this->ptr, this->len, str.ptr, str.len) != 0; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// The Mcstr class encapsulates a wide-character string pointer and length. | ||||||
|  | class Wcstr: public Types::wcstr_t, public Hashable | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	Wcstr (qse_wchar_t* ptr, qse_size_t len) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = ptr; | ||||||
|  | 		this->len = len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Wcstr (const qse_wchar_t* ptr, qse_size_t len) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = (qse_wchar_t*)ptr; | ||||||
|  | 		this->len = len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Wcstr (Types::wcstr_t& str) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = (qse_wchar_t*)str.ptr; | ||||||
|  | 		this->len = str.len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	qse_size_t getHashCode () const  | ||||||
|  | 	{ | ||||||
|  | 		return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(*this->ptr)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool operator== (const Wcstr& str) const | ||||||
|  | 	{ | ||||||
|  | 		return qse_wcsxncmp (this->ptr, this->len, str.ptr, str.len) == 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool operator!= (const Wcstr& str) const | ||||||
|  | 	{ | ||||||
|  | 		return qse_wcsxncmp (this->ptr, this->len, str.ptr, str.len) != 0; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// The Mcstr class encapsulates a character string pointer and length. | ||||||
|  | class Cstr: public Types::cstr_t, public Hashable | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	Cstr (qse_char_t* ptr, qse_size_t len) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = ptr; | ||||||
|  | 		this->len = len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Cstr (const qse_char_t* ptr, qse_size_t len) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = (qse_char_t*)ptr; | ||||||
|  | 		this->len = len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Cstr (Types::cstr_t& str) | ||||||
|  | 	{ | ||||||
|  | 		this->ptr = (qse_char_t*)str.ptr; | ||||||
|  | 		this->len = str.len; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	qse_size_t getHashCode () const  | ||||||
|  | 	{ | ||||||
|  | 		return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(*this->ptr)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool operator== (const Cstr& str) const | ||||||
|  | 	{ | ||||||
|  | 		return qse_strxncmp (this->ptr, this->len, str.ptr, str.len) == 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool operator!= (const Cstr& str) const | ||||||
|  | 	{ | ||||||
|  | 		return qse_strxncmp (this->ptr, this->len, str.ptr, str.len) != 0; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | ///////////////////////////////// | ||||||
|  | QSE_END_NAMESPACE(QSE) | ||||||
|  | ///////////////////////////////// | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @ -27,7 +27,8 @@ | |||||||
| #ifndef _QSE_HASHABLE_HPP_ | #ifndef _QSE_HASHABLE_HPP_ | ||||||
| #define _QSE_HASHABLE_HPP_ | #define _QSE_HASHABLE_HPP_ | ||||||
|  |  | ||||||
| #include <qse/Types.hpp> | #include <qse/types.h> | ||||||
|  | #include <qse/macros.h> | ||||||
|  |  | ||||||
| ///////////////////////////////// | ///////////////////////////////// | ||||||
| QSE_BEGIN_NAMESPACE(QSE) | QSE_BEGIN_NAMESPACE(QSE) | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ pkginclude_HEADERS = \ | |||||||
| if ENABLE_CXX | if ENABLE_CXX | ||||||
| pkginclude_HEADERS += \ | pkginclude_HEADERS += \ | ||||||
| 	Types.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \ | 	Types.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \ | ||||||
| 	Exception.hpp | 	Exception.hpp Cstr.hpp | ||||||
| endif | endif | ||||||
|  |  | ||||||
| install-data-hook: | install-data-hook: | ||||||
|  | |||||||
| @ -52,7 +52,7 @@ build_triplet = @build@ | |||||||
| host_triplet = @host@ | host_triplet = @host@ | ||||||
| @ENABLE_CXX_TRUE@am__append_1 = \ | @ENABLE_CXX_TRUE@am__append_1 = \ | ||||||
| @ENABLE_CXX_TRUE@	Types.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \ | @ENABLE_CXX_TRUE@	Types.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \ | ||||||
| @ENABLE_CXX_TRUE@	Exception.hpp | @ENABLE_CXX_TRUE@	Exception.hpp Cstr.hpp | ||||||
|  |  | ||||||
| subdir = include/qse | subdir = include/qse | ||||||
| DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \ | DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \ | ||||||
| @ -95,7 +95,7 @@ am__can_run_installinfo = \ | |||||||
| am__pkginclude_HEADERS_DIST = conf-msw.h conf-os2.h conf-dos.h \ | am__pkginclude_HEADERS_DIST = conf-msw.h conf-os2.h conf-dos.h \ | ||||||
| 	conf-vms.h conf-mac.h conf-inf.h types.h macros.h pack1.h \ | 	conf-vms.h conf-mac.h conf-inf.h types.h macros.h pack1.h \ | ||||||
| 	unpack.h Types.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \ | 	unpack.h Types.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \ | ||||||
| 	Exception.hpp | 	Exception.hpp Cstr.hpp | ||||||
| am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | ||||||
| am__vpath_adj = case $$p in \ | am__vpath_adj = case $$p in \ | ||||||
|     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ |     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ | ||||||
|  | |||||||
| @ -81,6 +81,12 @@ public: | |||||||
|  |  | ||||||
| 	/** redefines a structure of a character pointer and length */ | 	/** redefines a structure of a character pointer and length */ | ||||||
| 	typedef qse_cstr_t cstr_t; | 	typedef qse_cstr_t cstr_t; | ||||||
|  |  | ||||||
|  | 	/** redefines a structure of a character pointer and length */ | ||||||
|  | 	typedef qse_wcstr_t wcstr_t; | ||||||
|  |  | ||||||
|  | 	/** redefines a structure of a character pointer and length */ | ||||||
|  | 	typedef qse_mcstr_t mcstr_t; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| ///////////////////////////////// | ///////////////////////////////// | ||||||
|  | |||||||
| @ -28,13 +28,23 @@ | |||||||
| #define _QSE_AWK_AWK_HPP_ | #define _QSE_AWK_AWK_HPP_ | ||||||
|  |  | ||||||
| #include <qse/awk/awk.h> | #include <qse/awk/awk.h> | ||||||
| #include <qse/cmn/htb.h> |  | ||||||
| #include <qse/cmn/chr.h> | #include <qse/cmn/chr.h> | ||||||
| #include <qse/Uncopyable.hpp> | #include <qse/Uncopyable.hpp> | ||||||
| #include <qse/Types.hpp> | #include <qse/Types.hpp> | ||||||
| #include <qse/cmn/Mmged.hpp> | #include <qse/cmn/Mmged.hpp> | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
|  |  | ||||||
|  | //#define QSE_AWK_USE_HTB_FOR_FUNCTION_MAP 1 | ||||||
|  | //#define QSE_AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW 1 | ||||||
|  |  | ||||||
|  | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
|  | #	include <qse/cmn/htb.h> | ||||||
|  | #else | ||||||
|  | #	include <qse/cmn/HashTable.hpp> | ||||||
|  | #	include <qse/Cstr.hpp> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /// \file | /// \file | ||||||
| /// AWK Interpreter | /// AWK Interpreter | ||||||
|  |  | ||||||
| @ -49,8 +59,6 @@ QSE_BEGIN_NAMESPACE(QSE) | |||||||
| class QSE_EXPORT Awk: public Uncopyable, public Types, public Mmged | class QSE_EXPORT Awk: public Uncopyable, public Types, public Mmged | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	typedef qse_htb_t htb_t; |  | ||||||
| 	typedef qse_htb_pair_t pair_t; |  | ||||||
|  |  | ||||||
| 	// define a primitive handle  | 	// define a primitive handle  | ||||||
| 	typedef qse_awk_t awk_t; | 	typedef qse_awk_t awk_t; | ||||||
| @ -522,6 +530,7 @@ public: | |||||||
| 	public: | 	public: | ||||||
| 		friend class Awk; | 		friend class Awk; | ||||||
|  |  | ||||||
|  | 	#if defined(QSE_AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW) | ||||||
| 		// initialization | 		// initialization | ||||||
| 		void* operator new (size_t n, Run* run) throw (); | 		void* operator new (size_t n, Run* run) throw (); | ||||||
| 		void* operator new[] (size_t n, Run* run) throw (); | 		void* operator new[] (size_t n, Run* run) throw (); | ||||||
| @ -535,6 +544,7 @@ public: | |||||||
| 		// normal deletion | 		// normal deletion | ||||||
| 		void operator delete (void* p); | 		void operator delete (void* p); | ||||||
| 		void operator delete[] (void* p); | 		void operator delete[] (void* p); | ||||||
|  | 	#endif | ||||||
|  |  | ||||||
| 		/// | 		/// | ||||||
| 		/// The Index class encapsulates an index of an arrayed value. | 		/// The Index class encapsulates an index of an arrayed value. | ||||||
| @ -634,7 +644,7 @@ public: | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 		protected: | 		protected: | ||||||
| 			IndexIterator (pair_t* pair, size_t buckno) | 			IndexIterator (qse_htb_pair_t* pair, size_t buckno) | ||||||
| 			{ | 			{ | ||||||
| 				this->pair = pair; | 				this->pair = pair; | ||||||
| 				this->buckno = buckno; | 				this->buckno = buckno; | ||||||
| @ -939,7 +949,7 @@ public: | |||||||
| 	/// The Awk() function creates an interpreter without fully  | 	/// The Awk() function creates an interpreter without fully  | ||||||
| 	/// initializing it. You must call open() for full initialization | 	/// initializing it. You must call open() for full initialization | ||||||
| 	/// before calling other functions.  | 	/// before calling other functions.  | ||||||
| 	Awk (Mmgr* mmgr); | 	Awk (Mmgr* mmgr = QSE_NULL); | ||||||
|  |  | ||||||
| 	/// The ~Awk() function destroys an interpreter. Make sure to have | 	/// The ~Awk() function destroys an interpreter. Make sure to have | ||||||
| 	/// called close() for finalization before the destructor is executed. | 	/// called close() for finalization before the destructor is executed. | ||||||
| @ -1333,7 +1343,21 @@ protected: | |||||||
| 	errstr_t dflerrstr; | 	errstr_t dflerrstr; | ||||||
| 	errinf_t errinf; | 	errinf_t errinf; | ||||||
|  |  | ||||||
| 	htb_t* functionMap; | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
|  | 	qse_htb_t* functionMap; | ||||||
|  | #else | ||||||
|  | 	 | ||||||
|  | 	class FunctionMap: public HashTable<Cstr,FunctionHandler> | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		FunctionMap (Awk* awk): awk(awk) {} | ||||||
|  |  | ||||||
|  | 	protected: | ||||||
|  | 		Awk* awk; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	FunctionMap functionMap; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	Source* source_reader; | 	Source* source_reader; | ||||||
| 	Source* source_writer; | 	Source* source_writer; | ||||||
|  | |||||||
| @ -88,8 +88,7 @@ public: | |||||||
| 		const char_t* ptr; | 		const char_t* ptr; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	StdAwk (Mmgr* mmgr = StdMmgr::getDFL()): | 	StdAwk (Mmgr* mmgr = QSE_NULL): Awk(mmgr), console_cmgr(QSE_NULL)  | ||||||
| 		Awk (mmgr), console_cmgr (QSE_NULL)  |  | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -39,7 +39,7 @@ struct HashListHasher | |||||||
| { | { | ||||||
| 	qse_size_t operator() (const T& v) const | 	qse_size_t operator() (const T& v) const | ||||||
| 	{ | 	{ | ||||||
| 		return v.hashCode(); | 		return v.getHashCode(); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | |||||||
| @ -39,7 +39,7 @@ struct HashTableHasher | |||||||
| { | { | ||||||
| 	qse_size_t operator() (const T& v) const | 	qse_size_t operator() (const T& v) const | ||||||
| 	{ | 	{ | ||||||
| 		return v.hashCode(); | 		return v.getHashCode(); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | |||||||
| @ -49,6 +49,8 @@ QSE_BEGIN_NAMESPACE(QSE) | |||||||
| class QSE_EXPORT HeapMmgr: public Mmgr, public Mmged | class QSE_EXPORT HeapMmgr: public Mmgr, public Mmged | ||||||
| { | { | ||||||
| public: | public: | ||||||
|  | 	HeapMmgr (qse_size_t heap_size); | ||||||
|  |  | ||||||
| 	/// The constructor function accepts an memory manager \a mmgr that  | 	/// The constructor function accepts an memory manager \a mmgr that  | ||||||
| 	/// is used to create a heap of the size \a heap_size.  | 	/// is used to create a heap of the size \a heap_size.  | ||||||
| 	HeapMmgr (Mmgr* mmgr, qse_size_t heap_size); | 	HeapMmgr (Mmgr* mmgr, qse_size_t heap_size); | ||||||
|  | |||||||
| @ -246,6 +246,7 @@ Awk::Value::IntIndex::IntIndex (int_t x) | |||||||
| #undef NTOC | #undef NTOC | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if defined(QSE_AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW) | ||||||
| void* Awk::Value::operator new (size_t n, Run* run) throw () | void* Awk::Value::operator new (size_t n, Run* run) throw () | ||||||
| { | { | ||||||
| 	void* ptr = qse_awk_rtx_allocmem (run->rtx, QSE_SIZEOF(run) + n); | 	void* ptr = qse_awk_rtx_allocmem (run->rtx, QSE_SIZEOF(run) + n); | ||||||
| @ -293,6 +294,7 @@ void Awk::Value::operator delete[] (void* ptr) | |||||||
| 	void* p = (char*)ptr - QSE_SIZEOF(Run*); | 	void* p = (char*)ptr - QSE_SIZEOF(Run*); | ||||||
| 	qse_awk_rtx_freemem ((*(Run**)p)->rtx, p); | 	qse_awk_rtx_freemem ((*(Run**)p)->rtx, p); | ||||||
| } | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| Awk::Value::Value (): run (QSE_NULL), val (qse_getawknilval())  | Awk::Value::Value (): run (QSE_NULL), val (qse_getawknilval())  | ||||||
| { | { | ||||||
| @ -1011,7 +1013,12 @@ int Awk::Run::getGlobal (int id, Value& g) const | |||||||
| ////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
| Awk::Awk (Mmgr* mmgr):  | Awk::Awk (Mmgr* mmgr):  | ||||||
| 	Mmged (mmgr), awk (QSE_NULL), functionMap (QSE_NULL),  | 	Mmged (mmgr), awk (QSE_NULL),  | ||||||
|  | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
|  | 	functionMap (QSE_NULL),  | ||||||
|  | #else | ||||||
|  | 	functionMap (this),  | ||||||
|  | #endif | ||||||
| 	source_reader (QSE_NULL), source_writer (QSE_NULL), | 	source_reader (QSE_NULL), source_writer (QSE_NULL), | ||||||
| 	pipe_handler (QSE_NULL), file_handler (QSE_NULL),  | 	pipe_handler (QSE_NULL), file_handler (QSE_NULL),  | ||||||
| 	console_handler (QSE_NULL), runctx (this) | 	console_handler (QSE_NULL), runctx (this) | ||||||
| @ -1108,16 +1115,12 @@ void Awk::retrieveError (Run* run) | |||||||
| 	qse_awk_rtx_geterrinf (run->rtx, &errinf); | 	qse_awk_rtx_geterrinf (run->rtx, &errinf); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void free_function_map_value ( |  | ||||||
| 	Awk::htb_t* map, void* dptr, Awk::size_t dlen) |  | ||||||
| { |  | ||||||
| 	Awk* awk = *(Awk**) QSE_XTN (map); |  | ||||||
| 	qse_awk_freemem ((Awk::awk_t*)*awk, dptr); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int Awk::open ()  | int Awk::open ()  | ||||||
| { | { | ||||||
| 	QSE_ASSERT (awk == QSE_NULL && functionMap == QSE_NULL); | 	QSE_ASSERT (this->awk == QSE_NULL); | ||||||
|  | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
|  | 	QSE_ASSERT (this->functionMap == QSE_NULL); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	qse_awk_prm_t prm; | 	qse_awk_prm_t prm; | ||||||
|  |  | ||||||
| @ -1129,73 +1132,80 @@ int Awk::open () | |||||||
| 	prm.modsym  = modsym; | 	prm.modsym  = modsym; | ||||||
|  |  | ||||||
| 	qse_awk_errnum_t errnum; | 	qse_awk_errnum_t errnum; | ||||||
| 	awk = qse_awk_open (this->getMmgr(), QSE_SIZEOF(xtn_t), &prm, &errnum); | 	this->awk = qse_awk_open (this->getMmgr(), QSE_SIZEOF(xtn_t), &prm, &errnum); | ||||||
| 	if (awk == QSE_NULL) | 	if (this->awk == QSE_NULL) | ||||||
| 	{ | 	{ | ||||||
| 		this->setError (errnum); | 		this->setError (errnum); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// associate this Awk object with the underlying awk object | 	// associate this Awk object with the underlying awk object | ||||||
| 	xtn_t* xtn = (xtn_t*) QSE_XTN (awk); | 	xtn_t* xtn = (xtn_t*) QSE_XTN (this->awk); | ||||||
| 	xtn->awk = this; | 	xtn->awk = this; | ||||||
|  |  | ||||||
| 	dflerrstr = qse_awk_geterrstr (awk); | 	dflerrstr = qse_awk_geterrstr (this->awk); | ||||||
| 	qse_awk_seterrstr (awk, xerrstr); | 	qse_awk_seterrstr (this->awk, xerrstr); | ||||||
|  |  | ||||||
| 	functionMap = qse_htb_open ( | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
| 		qse_awk_getmmgr(awk), QSE_SIZEOF(this), 512, 70, | 	this->functionMap = qse_htb_open ( | ||||||
|  | 		qse_awk_getmmgr(this->awk), QSE_SIZEOF(this), 512, 70, | ||||||
| 		QSE_SIZEOF(qse_char_t), 1 | 		QSE_SIZEOF(qse_char_t), 1 | ||||||
| 	); | 	); | ||||||
| 	if (functionMap == QSE_NULL) | 	if (this->functionMap == QSE_NULL) | ||||||
| 	{ | 	{ | ||||||
| 		qse_awk_close (awk); | 		qse_awk_close (this->awk); | ||||||
| 		awk = QSE_NULL; | 		this->awk = QSE_NULL; | ||||||
|  |  | ||||||
| 		this->setError (QSE_AWK_ENOMEM); | 		this->setError (QSE_AWK_ENOMEM); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	*(Awk**)QSE_XTN(functionMap) = this; | 	*(Awk**)QSE_XTN(this->functionMap) = this; | ||||||
|  |  | ||||||
| 	static qse_htb_style_t style = | 	static qse_htb_style_t style = | ||||||
| 	{ | 	{ | ||||||
| 		{ | 		{ | ||||||
| 			QSE_HTB_COPIER_INLINE, | 			QSE_HTB_COPIER_DEFAULT, // keep the key pointer only | ||||||
| 			QSE_HTB_COPIER_DEFAULT  | 			QSE_HTB_COPIER_INLINE   // copy the value into the pair | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			QSE_HTB_FREEER_DEFAULT, | 			QSE_HTB_FREEER_DEFAULT, // free nothing  | ||||||
| 			free_function_map_value | 			QSE_HTB_FREEER_DEFAULT  // free nothing  | ||||||
| 		}, | 		}, | ||||||
| 		QSE_HTB_COMPER_DEFAULT, | 		QSE_HTB_COMPER_DEFAULT, | ||||||
| 		QSE_HTB_KEEPER_DEFAULT, | 		QSE_HTB_KEEPER_DEFAULT, | ||||||
| 		QSE_HTB_SIZER_DEFAULT, | 		QSE_HTB_SIZER_DEFAULT, | ||||||
| 		QSE_HTB_HASHER_DEFAULT | 		QSE_HTB_HASHER_DEFAULT | ||||||
| 	}; | 	}; | ||||||
| 	qse_htb_setstyle (functionMap, &style); | 	qse_htb_setstyle (this->functionMap, &style); | ||||||
|  | 	 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Awk::close ()  | void Awk::close ()  | ||||||
| { | { | ||||||
| 	fini_runctx (); | 	this->fini_runctx (); | ||||||
| 	clearArguments (); | 	this->clearArguments (); | ||||||
|  |  | ||||||
| 	if (functionMap != QSE_NULL) | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
|  | 	if (this->functionMap) | ||||||
| 	{ | 	{ | ||||||
| 		qse_htb_close (functionMap); | 		qse_htb_close (this->functionMap); | ||||||
| 		functionMap = QSE_NULL; | 		this->functionMap = QSE_NULL; | ||||||
|  | 	} | ||||||
|  | #else | ||||||
|  | 	this->functionMap.clear (); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	if (this->awk)  | ||||||
|  | 	{ | ||||||
|  | 		qse_awk_close (this->awk); | ||||||
|  | 		this->awk = QSE_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (awk != QSE_NULL)  | 	this->clearError (); | ||||||
| 	{ |  | ||||||
| 		qse_awk_close (awk); |  | ||||||
| 		awk = QSE_NULL; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	clearError (); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| Awk::Run* Awk::parse (Source& in, Source& out)  | Awk::Run* Awk::parse (Source& in, Source& out)  | ||||||
| @ -1372,10 +1382,11 @@ void Awk::setMaxDepth (depth_t id, size_t depth) | |||||||
|  |  | ||||||
| int Awk::dispatch_function (Run* run, const fnc_info_t* fi) | int Awk::dispatch_function (Run* run, const fnc_info_t* fi) | ||||||
| { | { | ||||||
| 	pair_t* pair; |  | ||||||
| 	bool has_ref_arg = false; | 	bool has_ref_arg = false; | ||||||
|  |  | ||||||
| 	pair = qse_htb_search (functionMap, fi->name.ptr, fi->name.len); | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
|  | 	qse_htb_pair_t* pair; | ||||||
|  | 	pair = qse_htb_search (this->functionMap, fi->name.ptr, fi->name.len); | ||||||
| 	if (pair == QSE_NULL)  | 	if (pair == QSE_NULL)  | ||||||
| 	{ | 	{ | ||||||
| 		run->setError (QSE_AWK_EFUNNF, &fi->name); | 		run->setError (QSE_AWK_EFUNNF, &fi->name); | ||||||
| @ -1384,6 +1395,17 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi) | |||||||
| 	 | 	 | ||||||
| 	FunctionHandler handler; | 	FunctionHandler handler; | ||||||
| 	handler = *(FunctionHandler*)QSE_HTB_VPTR(pair); | 	handler = *(FunctionHandler*)QSE_HTB_VPTR(pair); | ||||||
|  | #else | ||||||
|  | 	FunctionMap::Pair* pair = this->functionMap.search (Cstr(fi->name.ptr, fi->name.len)); | ||||||
|  | 	if (pair == QSE_NULL) | ||||||
|  | 	{ | ||||||
|  | 		run->setError (QSE_AWK_EFUNNF, &fi->name); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	FunctionHandler handler; | ||||||
|  | 	handler = pair->value; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	size_t i, nargs = qse_awk_rtx_getnargs(run->rtx); | 	size_t i, nargs = qse_awk_rtx_getnargs(run->rtx); | ||||||
|  |  | ||||||
| @ -1392,12 +1414,29 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi) | |||||||
| 	if (nargs <= QSE_COUNTOF(buf)) args = buf; | 	if (nargs <= QSE_COUNTOF(buf)) args = buf; | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
|  | 	#if defined(AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW) | ||||||
| 		args = new(run) Value[nargs]; | 		args = new(run) Value[nargs]; | ||||||
| 		if (args == QSE_NULL)  | 		if (args == QSE_NULL)  | ||||||
| 		{ | 		{ | ||||||
| 			run->setError (QSE_AWK_ENOMEM); | 			run->setError (QSE_AWK_ENOMEM); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  | 	#else | ||||||
|  | 		try { args = (Value*)::operator new (QSE_SIZEOF(Value) * nargs, this->getMmgr()); } | ||||||
|  | 		catch (...) { args = QSE_NULL; } | ||||||
|  | 		if (args == QSE_NULL)  | ||||||
|  | 		{ | ||||||
|  | 			run->setError (QSE_AWK_ENOMEM); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		for (i = 0; i < nargs; i++) | ||||||
|  | 		{ | ||||||
|  | 			// call the default constructor on the space allocated above. | ||||||
|  | 			// no exception handling is implemented here as i know  | ||||||
|  | 			// that Value::Value() doesn't throw an exception | ||||||
|  | 			new((QSE::Mmgr*)QSE_NULL, (void*)&args[i]) Value (); | ||||||
|  | 		} | ||||||
|  | 	#endif | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for (i = 0; i < nargs; i++) | 	for (i = 0; i < nargs; i++) | ||||||
| @ -1487,7 +1526,19 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (args != buf) delete[] args; | 	if (args != buf)  | ||||||
|  | 	{ | ||||||
|  | 	#if defined(AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW) | ||||||
|  | 		delete[] args; | ||||||
|  | 	#else | ||||||
|  | 		for (i = nargs; i > 0; ) | ||||||
|  | 		{ | ||||||
|  | 			--i; | ||||||
|  | 			args[i].~Value (); | ||||||
|  | 		} | ||||||
|  | 		::operator delete (args, this->getMmgr()); | ||||||
|  | 	#endif | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (n <= -1)  | 	if (n <= -1)  | ||||||
| 	{ | 	{ | ||||||
| @ -1614,16 +1665,6 @@ int Awk::addFunction ( | |||||||
| { | { | ||||||
| 	QSE_ASSERT (awk != QSE_NULL); | 	QSE_ASSERT (awk != QSE_NULL); | ||||||
|  |  | ||||||
| 	FunctionHandler* tmp = (FunctionHandler*)  |  | ||||||
| 		qse_awk_callocmem (awk, QSE_SIZEOF(handler)); |  | ||||||
| 	if (tmp == QSE_NULL) |  | ||||||
| 	{ |  | ||||||
| 		setError (QSE_AWK_ENOMEM); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	*tmp = handler; |  | ||||||
| 	 |  | ||||||
| 	fnc_spec_t spec; | 	fnc_spec_t spec; | ||||||
|  |  | ||||||
| 	QSE_MEMSET (&spec, 0, QSE_SIZEOF(spec)); | 	QSE_MEMSET (&spec, 0, QSE_SIZEOF(spec)); | ||||||
| @ -1636,18 +1677,29 @@ int Awk::addFunction ( | |||||||
| 	qse_awk_fnc_t* fnc = qse_awk_addfnc (awk, name, &spec); | 	qse_awk_fnc_t* fnc = qse_awk_addfnc (awk, name, &spec); | ||||||
| 	if (fnc == QSE_NULL)  | 	if (fnc == QSE_NULL)  | ||||||
| 	{ | 	{ | ||||||
| 		qse_awk_freemem (awk, tmp); | 		this->retrieveError (); | ||||||
| 		retrieveError (); |  | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pair_t* pair = qse_htb_upsert ( | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
| 		functionMap, (char_t*)name, qse_strlen(name), tmp, 0); | 	// handler is a pointer to a member function.  | ||||||
|  | 	// sizeof(handler) is likely to be greater than sizeof(void*) | ||||||
|  | 	// copy the handler pointer into the table. | ||||||
|  | 	// | ||||||
|  | 	// the function name exists in the underlying function table. | ||||||
|  | 	// use the pointer to the name to maintain the hash table. | ||||||
|  | 	qse_htb_pair_t* pair = qse_htb_upsert ( | ||||||
|  | 		this->functionMap, (char_t*)fnc->name.ptr, fnc->name.len, &handler, QSE_SIZEOF(handler)); | ||||||
|  | #else | ||||||
|  | 	FunctionMap::Pair* pair; | ||||||
|  | 	try { pair = this->functionMap.upsert (Cstr(fnc->name.ptr, fnc->name.len), handler); } | ||||||
|  | 	catch (...) { pair = QSE_NULL; } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	if (pair == QSE_NULL) | 	if (pair == QSE_NULL) | ||||||
| 	{ | 	{ | ||||||
| 		qse_awk_delfnc (awk, name); | 		qse_awk_delfnc (awk, name); | ||||||
| 		qse_awk_freemem (awk, tmp); | 		this->setError (QSE_AWK_ENOMEM); | ||||||
| 		setError (QSE_AWK_ENOMEM); |  | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -1659,8 +1711,15 @@ int Awk::deleteFunction (const char_t* name) | |||||||
| 	QSE_ASSERT (awk != QSE_NULL); | 	QSE_ASSERT (awk != QSE_NULL); | ||||||
|  |  | ||||||
| 	int n = qse_awk_delfnc (awk, name); | 	int n = qse_awk_delfnc (awk, name); | ||||||
| 	if (n == 0) qse_htb_delete (functionMap, name, qse_strlen(name)); | 	if (n == 0)  | ||||||
| 	else retrieveError (); | 	{ | ||||||
|  | #if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP) | ||||||
|  | 		qse_htb_delete (this->functionMap, name, qse_strlen(name)); | ||||||
|  | #else | ||||||
|  | 		this->functionMap.remove (Cstr(name, qse_strlen(name))); | ||||||
|  | #endif | ||||||
|  | 	} | ||||||
|  | 	else this->retrieveError (); | ||||||
|  |  | ||||||
| 	return n; | 	return n; | ||||||
| } | } | ||||||
|  | |||||||
| @ -36,6 +36,11 @@ struct xma_xtn_t | |||||||
| 	HeapMmgr* heap; | 	HeapMmgr* heap; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | HeapMmgr::HeapMmgr (qse_size_t heap_size): | ||||||
|  | 	Mmgr(), Mmged(QSE_NULL), xma(QSE_NULL), heap_size (heap_size) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
| HeapMmgr::HeapMmgr (Mmgr* mmgr, qse_size_t heap_size):  | HeapMmgr::HeapMmgr (Mmgr* mmgr, qse_size_t heap_size):  | ||||||
| 	Mmgr(), Mmged(mmgr), xma(QSE_NULL), heap_size (heap_size) | 	Mmgr(), Mmged(mmgr), xma(QSE_NULL), heap_size (heap_size) | ||||||
| { | { | ||||||
|  | |||||||
| @ -25,6 +25,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <qse/awk/StdAwk.hpp> | #include <qse/awk/StdAwk.hpp> | ||||||
|  | #include <qse/cmn/HeapMmgr.hpp> | ||||||
| #include <qse/cmn/opt.h> | #include <qse/cmn/opt.h> | ||||||
| #include <qse/cmn/main.h> | #include <qse/cmn/main.h> | ||||||
| #include <qse/cmn/mbwc.h> | #include <qse/cmn/mbwc.h> | ||||||
| @ -52,7 +53,7 @@ typedef QSE::StdAwk::Value Value; | |||||||
| class MyAwk: public StdAwk | class MyAwk: public StdAwk | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	MyAwk () { } | 	MyAwk (QSE::Mmgr* mmgr = QSE_NULL): StdAwk (mmgr) { } | ||||||
| 	~MyAwk () { close (); } | 	~MyAwk () { close (); } | ||||||
|  |  | ||||||
| 	int open () | 	int open () | ||||||
| @ -428,6 +429,8 @@ static int awk_main_2 (MyAwk& awk, int argc, qse_char_t* argv[]) | |||||||
|  |  | ||||||
| static int awk_main (int argc, qse_char_t* argv[]) | static int awk_main (int argc, qse_char_t* argv[]) | ||||||
| { | { | ||||||
|  | 	//QSE::HeapMmgr hm (1000000); | ||||||
|  | 	//MyAwk awk (&hm); | ||||||
| 	MyAwk awk; | 	MyAwk awk; | ||||||
|  |  | ||||||
| 	if (awk.open() <= -1) | 	if (awk.open() <= -1) | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ public: | |||||||
| //		printf ("destructor\n"); | //		printf ("destructor\n"); | ||||||
| 	} | 	} | ||||||
| 	bool operator== (const T& x) const { return this->x == x.x; } | 	bool operator== (const T& x) const { return this->x == x.x; } | ||||||
| 	qse_size_t hashCode() const { return x; } | 	qse_size_t getHashCode() const { return x; } | ||||||
|  |  | ||||||
| 	int getValue() const { return this->x; } | 	int getValue() const { return this->x; } | ||||||
| 	int getY() const { return this->y; } | 	int getY() const { return this->y; } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user