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:
parent
cb62c4ecd1
commit
a212a8ebf2
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_
|
||||
#define _QSE_HASHABLE_HPP_
|
||||
|
||||
#include <qse/Types.hpp>
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
@ -9,7 +9,7 @@ pkginclude_HEADERS = \
|
||||
if ENABLE_CXX
|
||||
pkginclude_HEADERS += \
|
||||
Types.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \
|
||||
Exception.hpp
|
||||
Exception.hpp Cstr.hpp
|
||||
endif
|
||||
|
||||
install-data-hook:
|
||||
|
@ -52,7 +52,7 @@ build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@ENABLE_CXX_TRUE@am__append_1 = \
|
||||
@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
|
||||
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 \
|
||||
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 \
|
||||
Exception.hpp
|
||||
Exception.hpp Cstr.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
|
@ -81,6 +81,12 @@ public:
|
||||
|
||||
/** redefines a structure of a character pointer and length */
|
||||
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_
|
||||
|
||||
#include <qse/awk/awk.h>
|
||||
#include <qse/cmn/htb.h>
|
||||
|
||||
#include <qse/cmn/chr.h>
|
||||
#include <qse/Uncopyable.hpp>
|
||||
#include <qse/Types.hpp>
|
||||
#include <qse/cmn/Mmged.hpp>
|
||||
#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
|
||||
/// AWK Interpreter
|
||||
|
||||
@ -49,8 +59,6 @@ QSE_BEGIN_NAMESPACE(QSE)
|
||||
class QSE_EXPORT Awk: public Uncopyable, public Types, public Mmged
|
||||
{
|
||||
public:
|
||||
typedef qse_htb_t htb_t;
|
||||
typedef qse_htb_pair_t pair_t;
|
||||
|
||||
// define a primitive handle
|
||||
typedef qse_awk_t awk_t;
|
||||
@ -522,6 +530,7 @@ public:
|
||||
public:
|
||||
friend class Awk;
|
||||
|
||||
#if defined(QSE_AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
|
||||
// initialization
|
||||
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
|
||||
void operator delete (void* p);
|
||||
void operator delete[] (void* p);
|
||||
#endif
|
||||
|
||||
///
|
||||
/// The Index class encapsulates an index of an arrayed value.
|
||||
@ -634,7 +644,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
IndexIterator (pair_t* pair, size_t buckno)
|
||||
IndexIterator (qse_htb_pair_t* pair, size_t buckno)
|
||||
{
|
||||
this->pair = pair;
|
||||
this->buckno = buckno;
|
||||
@ -939,7 +949,7 @@ public:
|
||||
/// The Awk() function creates an interpreter without fully
|
||||
/// initializing it. You must call open() for full initialization
|
||||
/// before calling other functions.
|
||||
Awk (Mmgr* mmgr);
|
||||
Awk (Mmgr* mmgr = QSE_NULL);
|
||||
|
||||
/// The ~Awk() function destroys an interpreter. Make sure to have
|
||||
/// called close() for finalization before the destructor is executed.
|
||||
@ -1333,7 +1343,21 @@ protected:
|
||||
errstr_t dflerrstr;
|
||||
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_writer;
|
||||
|
@ -88,8 +88,7 @@ public:
|
||||
const char_t* ptr;
|
||||
};
|
||||
|
||||
StdAwk (Mmgr* mmgr = StdMmgr::getDFL()):
|
||||
Awk (mmgr), console_cmgr (QSE_NULL)
|
||||
StdAwk (Mmgr* mmgr = QSE_NULL): Awk(mmgr), console_cmgr(QSE_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ struct HashListHasher
|
||||
{
|
||||
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
|
||||
{
|
||||
return v.hashCode();
|
||||
return v.getHashCode();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -49,6 +49,8 @@ QSE_BEGIN_NAMESPACE(QSE)
|
||||
class QSE_EXPORT HeapMmgr: public Mmgr, public Mmged
|
||||
{
|
||||
public:
|
||||
HeapMmgr (qse_size_t heap_size);
|
||||
|
||||
/// The constructor function accepts an memory manager \a mmgr that
|
||||
/// is used to create a heap of the size \a heap_size.
|
||||
HeapMmgr (Mmgr* mmgr, qse_size_t heap_size);
|
||||
|
@ -246,13 +246,14 @@ Awk::Value::IntIndex::IntIndex (int_t x)
|
||||
#undef NTOC
|
||||
}
|
||||
|
||||
#if defined(QSE_AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
|
||||
void* Awk::Value::operator new (size_t n, Run* run) throw ()
|
||||
{
|
||||
void* ptr = qse_awk_rtx_allocmem (run->rtx, QSE_SIZEOF(run) + n);
|
||||
if (ptr == QSE_NULL) return QSE_NULL;
|
||||
|
||||
*(Run**)ptr = run;
|
||||
return (char*)ptr+QSE_SIZEOF(run);
|
||||
return (char*)ptr + QSE_SIZEOF(run);
|
||||
}
|
||||
|
||||
void* Awk::Value::operator new[] (size_t n, Run* run) throw ()
|
||||
@ -261,7 +262,7 @@ void* Awk::Value::operator new[] (size_t n, Run* run) throw ()
|
||||
if (ptr == QSE_NULL) return QSE_NULL;
|
||||
|
||||
*(Run**)ptr = run;
|
||||
return (char*)ptr+QSE_SIZEOF(run);
|
||||
return (char*)ptr + QSE_SIZEOF(run);
|
||||
}
|
||||
|
||||
#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
|
||||
@ -269,30 +270,31 @@ void Awk::Value::operator delete (void* ptr, Run* run)
|
||||
{
|
||||
// this placement delete is to be called when the constructor
|
||||
// throws an exception and it's caught by the caller.
|
||||
qse_awk_rtx_freemem (run->rtx, (char*)ptr-QSE_SIZEOF(run));
|
||||
qse_awk_rtx_freemem (run->rtx, (char*)ptr - QSE_SIZEOF(run));
|
||||
}
|
||||
|
||||
void Awk::Value::operator delete[] (void* ptr, Run* run)
|
||||
{
|
||||
// this placement delete is to be called when the constructor
|
||||
// throws an exception and it's caught by the caller.
|
||||
qse_awk_rtx_freemem (run->rtx, (char*)ptr-QSE_SIZEOF(run));
|
||||
qse_awk_rtx_freemem (run->rtx, (char*)ptr - QSE_SIZEOF(run));
|
||||
}
|
||||
#endif
|
||||
|
||||
void Awk::Value::operator delete (void* ptr)
|
||||
{
|
||||
// this delete is to be called for normal destruction.
|
||||
void* p = (char*)ptr-QSE_SIZEOF(Run*);
|
||||
void* p = (char*)ptr - QSE_SIZEOF(Run*);
|
||||
qse_awk_rtx_freemem ((*(Run**)p)->rtx, p);
|
||||
}
|
||||
|
||||
void Awk::Value::operator delete[] (void* ptr)
|
||||
{
|
||||
// this delete is to be called for normal destruction.
|
||||
void* p = (char*)ptr-QSE_SIZEOF(Run*);
|
||||
void* p = (char*)ptr - QSE_SIZEOF(Run*);
|
||||
qse_awk_rtx_freemem ((*(Run**)p)->rtx, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
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):
|
||||
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),
|
||||
pipe_handler (QSE_NULL), file_handler (QSE_NULL),
|
||||
console_handler (QSE_NULL), runctx (this)
|
||||
@ -1108,16 +1115,12 @@ void Awk::retrieveError (Run* run)
|
||||
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 ()
|
||||
{
|
||||
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;
|
||||
|
||||
@ -1129,73 +1132,80 @@ int Awk::open ()
|
||||
prm.modsym = modsym;
|
||||
|
||||
qse_awk_errnum_t errnum;
|
||||
awk = qse_awk_open (this->getMmgr(), QSE_SIZEOF(xtn_t), &prm, &errnum);
|
||||
if (awk == QSE_NULL)
|
||||
this->awk = qse_awk_open (this->getMmgr(), QSE_SIZEOF(xtn_t), &prm, &errnum);
|
||||
if (this->awk == QSE_NULL)
|
||||
{
|
||||
this->setError (errnum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
dflerrstr = qse_awk_geterrstr (awk);
|
||||
qse_awk_seterrstr (awk, xerrstr);
|
||||
dflerrstr = qse_awk_geterrstr (this->awk);
|
||||
qse_awk_seterrstr (this->awk, xerrstr);
|
||||
|
||||
functionMap = qse_htb_open (
|
||||
qse_awk_getmmgr(awk), QSE_SIZEOF(this), 512, 70,
|
||||
#if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP)
|
||||
this->functionMap = qse_htb_open (
|
||||
qse_awk_getmmgr(this->awk), QSE_SIZEOF(this), 512, 70,
|
||||
QSE_SIZEOF(qse_char_t), 1
|
||||
);
|
||||
if (functionMap == QSE_NULL)
|
||||
if (this->functionMap == QSE_NULL)
|
||||
{
|
||||
qse_awk_close (awk);
|
||||
awk = QSE_NULL;
|
||||
qse_awk_close (this->awk);
|
||||
this->awk = QSE_NULL;
|
||||
|
||||
this->setError (QSE_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*(Awk**)QSE_XTN(functionMap) = this;
|
||||
*(Awk**)QSE_XTN(this->functionMap) = this;
|
||||
|
||||
static qse_htb_style_t style =
|
||||
{
|
||||
{
|
||||
QSE_HTB_COPIER_INLINE,
|
||||
QSE_HTB_COPIER_DEFAULT
|
||||
QSE_HTB_COPIER_DEFAULT, // keep the key pointer only
|
||||
QSE_HTB_COPIER_INLINE // copy the value into the pair
|
||||
},
|
||||
{
|
||||
QSE_HTB_FREEER_DEFAULT,
|
||||
free_function_map_value
|
||||
QSE_HTB_FREEER_DEFAULT, // free nothing
|
||||
QSE_HTB_FREEER_DEFAULT // free nothing
|
||||
},
|
||||
QSE_HTB_COMPER_DEFAULT,
|
||||
QSE_HTB_KEEPER_DEFAULT,
|
||||
QSE_HTB_SIZER_DEFAULT,
|
||||
QSE_HTB_HASHER_DEFAULT
|
||||
};
|
||||
qse_htb_setstyle (functionMap, &style);
|
||||
qse_htb_setstyle (this->functionMap, &style);
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Awk::close ()
|
||||
{
|
||||
fini_runctx ();
|
||||
clearArguments ();
|
||||
this->fini_runctx ();
|
||||
this->clearArguments ();
|
||||
|
||||
if (functionMap != QSE_NULL)
|
||||
#if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP)
|
||||
if (this->functionMap)
|
||||
{
|
||||
qse_htb_close (functionMap);
|
||||
functionMap = QSE_NULL;
|
||||
qse_htb_close (this->functionMap);
|
||||
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)
|
||||
{
|
||||
qse_awk_close (awk);
|
||||
awk = QSE_NULL;
|
||||
}
|
||||
|
||||
clearError ();
|
||||
this->clearError ();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
pair_t* pair;
|
||||
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)
|
||||
{
|
||||
run->setError (QSE_AWK_EFUNNF, &fi->name);
|
||||
@ -1384,6 +1395,17 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi)
|
||||
|
||||
FunctionHandler handler;
|
||||
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);
|
||||
|
||||
@ -1392,12 +1414,29 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi)
|
||||
if (nargs <= QSE_COUNTOF(buf)) args = buf;
|
||||
else
|
||||
{
|
||||
#if defined(AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
|
||||
args = new(run) Value[nargs];
|
||||
if (args == QSE_NULL)
|
||||
{
|
||||
run->setError (QSE_AWK_ENOMEM);
|
||||
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++)
|
||||
@ -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)
|
||||
{
|
||||
@ -1614,16 +1665,6 @@ int Awk::addFunction (
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
if (fnc == QSE_NULL)
|
||||
{
|
||||
qse_awk_freemem (awk, tmp);
|
||||
retrieveError ();
|
||||
this->retrieveError ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
pair_t* pair = qse_htb_upsert (
|
||||
functionMap, (char_t*)name, qse_strlen(name), tmp, 0);
|
||||
#if defined(QSE_AWK_USE_HTB_FOR_FUNCTION_MAP)
|
||||
// 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)
|
||||
{
|
||||
qse_awk_delfnc (awk, name);
|
||||
qse_awk_freemem (awk, tmp);
|
||||
setError (QSE_AWK_ENOMEM);
|
||||
this->setError (QSE_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1659,8 +1711,15 @@ int Awk::deleteFunction (const char_t* name)
|
||||
QSE_ASSERT (awk != QSE_NULL);
|
||||
|
||||
int n = qse_awk_delfnc (awk, name);
|
||||
if (n == 0) qse_htb_delete (functionMap, name, qse_strlen(name));
|
||||
else retrieveError ();
|
||||
if (n == 0)
|
||||
{
|
||||
#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;
|
||||
}
|
||||
|
@ -36,6 +36,11 @@ struct xma_xtn_t
|
||||
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):
|
||||
Mmgr(), Mmged(mmgr), xma(QSE_NULL), heap_size (heap_size)
|
||||
{
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/cmn/HeapMmgr.hpp>
|
||||
#include <qse/cmn/opt.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
@ -52,7 +53,7 @@ typedef QSE::StdAwk::Value Value;
|
||||
class MyAwk: public StdAwk
|
||||
{
|
||||
public:
|
||||
MyAwk () { }
|
||||
MyAwk (QSE::Mmgr* mmgr = QSE_NULL): StdAwk (mmgr) { }
|
||||
~MyAwk () { close (); }
|
||||
|
||||
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[])
|
||||
{
|
||||
//QSE::HeapMmgr hm (1000000);
|
||||
//MyAwk awk (&hm);
|
||||
MyAwk awk;
|
||||
|
||||
if (awk.open() <= -1)
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
// printf ("destructor\n");
|
||||
}
|
||||
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 getY() const { return this->y; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user