Merged changes from SH:List

Fixed bug where natives did not use the debugger (experimental)
Removed array size detection :(
This commit is contained in:
David Anderson 2006-01-06 14:37:58 +00:00
parent 0c745590ec
commit 3d00b8c545
4 changed files with 252 additions and 281 deletions

View File

@ -79,15 +79,6 @@
#endif #endif
#endif #endif
#if HAVE_ALLOCA_H
#include <alloca.h>
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
#if !defined alloca
#define alloca(n) _alloca(n)
#endif
#endif
#if !defined arraysize #if !defined arraysize
#define arraysize(array) (sizeof(array) / sizeof((array)[0])) #define arraysize(array) (sizeof(array) / sizeof((array)[0]))
#endif #endif

View File

@ -450,6 +450,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
amx_err = AMX_ERR_NOTFOUND;*/ amx_err = AMX_ERR_NOTFOUND;*/
//if (!amx_err) //if (!amx_err)
size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name); size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name);
#if 0
} else if (error == AMX_ERR_BOUNDS) { } else if (error == AMX_ERR_BOUNDS) {
tagAMX_DBG *pDbg = m_pAmxDbg; tagAMX_DBG *pDbg = m_pAmxDbg;
int symbols = pDbg->hdr->symbols; int symbols = pDbg->hdr->symbols;
@ -649,6 +650,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
_msgbuf[0] = '\0'; _msgbuf[0] = '\0';
size += _snprintf(buffer, maxLength, "%s", _msgbuf); size += _snprintf(buffer, maxLength, "%s", _msgbuf);
#endif //0 - NOT USED!
} }
return size; return size;

View File

@ -31,6 +31,7 @@
#include "amxmodx.h" #include "amxmodx.h"
#include "sh_stack.h" #include "sh_stack.h"
#include "natives.h" #include "natives.h"
#include "Debugger.h"
#ifdef __linux__ #ifdef __linux__
#include <malloc.h> #include <malloc.h>
@ -87,18 +88,26 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
for (int i=numParams; i>=1; i--) for (int i=numParams; i>=1; i--)
amx_Push(pNative->amx, params[i]); amx_Push(pNative->amx, params[i]);
} }
if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE) Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
{ if (pDebugger)
g_NativeStack.pop(); pDebugger->BeginExec();
LogError(pNative->amx, err, ""); err=amx_Exec(pNative->amx, &ret, pNative->func);
return 0; if (err != AMX_ERR_NONE)
}
if (g_errorNum)
{ {
if (pDebugger && pDebugger->ErrorExists())
{
//don't care
} else if (err != -1) {
//nothing logged the error
LogError(amx, err, NULL);
}
amx->error = AMX_ERR_NONE;
} else if (g_errorNum) {
g_NativeStack.pop(); g_NativeStack.pop();
LogError(amx, g_errorNum, g_errorStr); LogError(amx, g_errorNum, g_errorStr);
return ret;
} }
if (pDebugger)
pDebugger->EndExec();
g_NativeStack.pop(); g_NativeStack.pop();
return ret; return ret;

View File

@ -11,311 +11,280 @@
#ifndef _INCLUDE_SMM_LIST_H #ifndef _INCLUDE_SMM_LIST_H
#define _INCLUDE_SMM_LIST_H #define _INCLUDE_SMM_LIST_H
#include "sh_stack.h" #include <new>
#include <malloc.h>
//namespace SourceHook //namespace SourceHook
//{ //{
//This class is from CSDM for AMX Mod X //This class is from CSDM for AMX Mod X
template <class T> /*
class List A circular, doubly-linked list with one sentinel node
{
public: Empty:
class iterator; m_Head = sentinel
friend class iterator; m_Head->next = m_Head;
class ListNode m_Head->prev = m_Head;
One element:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node1
node1->next = m_Head
node1->prev = m_Head
Two elements:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node2
node1->next = node2
node1->prev = m_Head
node2->next = m_Head
node2->prev = node1
*/
template <class T>
class List
{ {
public: public:
ListNode(const T & o) : obj(o) { }; class iterator;
ListNode() { }; friend class iterator;
void Set(const T & o) { obj = o; } class ListNode
~ListNode()
{ {
public:
ListNode(const T & o) : obj(o) { };
ListNode() { };
T obj;
ListNode *next;
ListNode *prev;
}; };
T obj; private:
ListNode *next; // Initializes the sentinel node.
ListNode *prev; // BAIL used malloc instead of new in order to bypass the need for a constructor.
}; ListNode *_Initialize()
private:
ListNode *_Initialize()
{
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
n->next = NULL;
n->prev = NULL;
return n;
}
public:
List() : m_Head(_Initialize()), m_Size(0)
{
}
List(const List &src) : m_Head(_Initialize()), m_Size(0)
{
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
push_back( (*iter) );
}
~List()
{
clear();
if (m_Head)
{ {
free(m_Head); ListNode *n = (ListNode *)malloc(sizeof(ListNode));
m_Head = NULL; n->next = n;
n->prev = n;
return n;
} }
} public:
void unshift(const T &obj) List() : m_Head(_Initialize()), m_Size(0)
{
if (!m_Head->next)
{ {
push_back(obj);
return;
} }
List(const List &src) : m_Head(_Initialize()), m_Size(0)
ListNode *node;
if (m_FreeStack.empty())
{ {
node = new ListNode(obj); iterator iter;
} else { for (iter=src.begin(); iter!=src.end(); iter++)
node = m_FreeStack.front(); push_back( (*iter) );
m_FreeStack.pop();
node->Set(obj);
} }
~List()
//is the list one item circular?
/*bool realign = false;
if (m_Head->next == m_Head->prev)
{ {
m_Head->next->next = clear();
}*/
node->next = m_Head->next; // Don't forget to free the sentinel
node->prev = m_Head; if (m_Head)
m_Head->next->prev = node; {
m_Head->next = node; free(m_Head);
m_Head = NULL;
m_Size++; }
}
void push_back(const T &obj)
{
ListNode *node;
if (m_FreeStack.empty())
{
node = new ListNode(obj);
} else {
node = m_FreeStack.front();
m_FreeStack.pop();
node->Set(obj);
} }
void push_back(const T &obj)
if (!m_Head->prev)
{ {
//link in the node as the first item ListNode *node = new ListNode(obj);
node->next = m_Head;
node->prev = m_Head;
m_Head->prev = node;
m_Head->next = node;
} else {
node->prev = m_Head->prev; node->prev = m_Head->prev;
node->next = m_Head; node->next = m_Head;
m_Head->prev->next = node; m_Head->prev->next = node;
m_Head->prev = node; m_Head->prev = node;
m_Size++;
} }
m_Size++; size_t size()
}
size_t size()
{
return m_Size;
}
void clear()
{
ListNode *node = m_Head->next;
ListNode *temp;
m_Head->next = NULL;
m_Head->prev = NULL;
while (node && node != m_Head)
{ {
temp = node->next; return m_Size;
delete node;
node = temp;
}
m_Size = 0;
while (!m_FreeStack.empty())
{
delete m_FreeStack.front();
m_FreeStack.pop();
}
}
bool empty()
{
return (m_Head->next == NULL);
}
T & back()
{
return m_Head->prev->obj;
}
private:
#if defined __GNUC__
CStack<List::ListNode *> m_FreeStack;
#else
typename CStack<List::ListNode *> m_FreeStack;
#endif
ListNode *m_Head;
size_t m_Size;
public:
class iterator
{
friend class List;
public:
iterator()
{
m_This = NULL;
}
iterator(const List &src)
{
m_This = src.m_Head;
}
iterator(ListNode *n) : m_This(n)
{
}
iterator(const iterator &where)
{
m_This = where.m_This;
}
//pre decrement
iterator & operator--()
{
if (m_This)
m_This = m_This->prev;
return *this;
}
//post decrement
iterator operator--(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->prev;
return old;
} }
//pre increment void clear()
iterator & operator++()
{ {
if (m_This) ListNode *node = m_Head->next;
m_This = m_This->next; ListNode *temp;
return *this; m_Head->next = m_Head;
} m_Head->prev = m_Head;
//post increment
iterator operator++(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->next;
return old;
}
const T & operator * () const // Iterate through the nodes until we find g_Head (the sentinel) again
{ while (node != m_Head)
return m_This->obj; {
temp = node->next;
delete node;
node = temp;
}
m_Size = 0;
} }
T & operator * () bool empty()
{ {
return m_This->obj; return (m_Size == 0);
} }
T & back()
T * operator -> ()
{ {
return &(m_This->obj); return m_Head->prev->obj;
}
const T * operator -> () const
{
return &(m_This->obj);
}
bool operator != (const iterator &where) const
{
return (m_This != where.m_This);
}
bool operator ==(const iterator &where) const
{
return (m_This == where.m_This);
} }
private: private:
ListNode *m_This; ListNode *m_Head;
}; size_t m_Size;
public: public:
iterator begin() const class iterator
{
if (m_Size)
return iterator(m_Head->next);
else
return iterator(m_Head);
}
iterator end() const
{
return iterator(m_Head);
}
iterator erase(iterator &where)
{
ListNode *pNode = where.m_This;
iterator iter(where);
iter++;
//If we are both the head and tail...
if (m_Head->next == pNode && m_Head->prev == pNode)
{ {
m_Head->next = NULL; friend class List;
m_Head->prev = NULL; public:
} else if (m_Head->next == pNode) { iterator()
//we are only the first {
pNode->next->prev = m_Head; m_This = NULL;
m_Head->next = pNode->next; }
} else if (m_Head->prev == pNode) { iterator(const List &src)
//we are the tail {
pNode->prev->next = m_Head; m_This = src.m_Head;
m_Head->prev = pNode->prev; }
} else { iterator(ListNode *n) : m_This(n)
//middle unlink {
}
iterator(const iterator &where)
{
m_This = where.m_This;
}
//pre decrement
iterator & operator--()
{
if (m_This)
m_This = m_This->prev;
return *this;
}
//post decrement
iterator operator--(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->prev;
return old;
}
//pre increment
iterator & operator++()
{
if (m_This)
m_This = m_This->next;
return *this;
}
//post increment
iterator operator++(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->next;
return old;
}
const T & operator * () const
{
return m_This->obj;
}
T & operator * ()
{
return m_This->obj;
}
T * operator -> ()
{
return &(m_This->obj);
}
const T * operator -> () const
{
return &(m_This->obj);
}
bool operator != (const iterator &where) const
{
return (m_This != where.m_This);
}
bool operator ==(const iterator &where) const
{
return (m_This == where.m_This);
}
private:
ListNode *m_This;
};
public:
iterator begin() const
{
return iterator(m_Head->next);
}
iterator end() const
{
return iterator(m_Head);
}
iterator erase(iterator &where)
{
ListNode *pNode = where.m_This;
iterator iter(where);
iter++;
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
pNode->prev->next = pNode->next; pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev; pNode->next->prev = pNode->prev;
delete pNode;
m_Size--;
return iter;
} }
m_FreeStack.push(pNode); iterator insert(iterator where, const T &obj)
m_Size--;
return iter;
}
public:
void remove(const T & obj)
{
iterator b;
for (b=begin(); b!=end(); b++)
{ {
if ( (*b) == obj ) // Insert obj right before where
ListNode *node = new ListNode(obj);
ListNode *pWhereNode = where.m_This;
pWhereNode->prev->next = node;
node->prev = pWhereNode->prev;
pWhereNode->prev = node;
node->next = pWhereNode;
m_Size++;
return iterator(node);
}
public:
void remove(const T & obj)
{
iterator b;
for (b=begin(); b!=end(); b++)
{ {
erase( b ); if ( (*b) == obj )
break; {
erase( b );
break;
}
} }
} }
} template <typename U>
template <typename U> iterator find(const U & equ)
iterator find(const U & equ)
{
iterator iter;
for (iter=begin(); iter!=end(); iter++)
{ {
if ( (*iter) == equ ) iterator iter;
return iter; for (iter=begin(); iter!=end(); iter++)
{
if ( (*iter) == equ )
return iter;
}
return end();
} }
return end(); List & operator =(const List &src)
} {
List & operator =(List &src) clear();
{ iterator iter;
clear(); for (iter=src.begin(); iter!=src.end(); iter++)
iterator iter; push_back( (*iter) );
for (iter=src.begin(); iter!=src.end(); iter++) return *this;
push_back( (*iter) ); }
return *this; };
}
};
//}; //NAMESPACE //}; //NAMESPACE
#endif //_INCLUDE_CSDM_LIST_H #endif //_INCLUDE_CSDM_LIST_H