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)
pDebugger->BeginExec();
err=amx_Exec(pNative->amx, &ret, pNative->func);
if (err != AMX_ERR_NONE)
{ {
g_NativeStack.pop(); if (pDebugger && pDebugger->ErrorExists())
LogError(pNative->amx, err, ""); {
return 0; //don't care
} else if (err != -1) {
//nothing logged the error
LogError(amx, err, NULL);
} }
if (g_errorNum) 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,15 +11,38 @@
#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:
m_Head = sentinel
m_Head->next = m_Head;
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:
class iterator; class iterator;
friend class iterator; friend class iterator;
class ListNode class ListNode
@ -27,23 +50,21 @@ public:
public: public:
ListNode(const T & o) : obj(o) { }; ListNode(const T & o) : obj(o) { };
ListNode() { }; ListNode() { };
void Set(const T & o) { obj = o; }
~ListNode()
{
};
T obj; T obj;
ListNode *next; ListNode *next;
ListNode *prev; ListNode *prev;
}; };
private: private:
// Initializes the sentinel node.
// BAIL used malloc instead of new in order to bypass the need for a constructor.
ListNode *_Initialize() ListNode *_Initialize()
{ {
ListNode *n = (ListNode *)malloc(sizeof(ListNode)); ListNode *n = (ListNode *)malloc(sizeof(ListNode));
n->next = NULL; n->next = n;
n->prev = NULL; n->prev = n;
return n; return n;
} }
public: public:
List() : m_Head(_Initialize()), m_Size(0) List() : m_Head(_Initialize()), m_Size(0)
{ {
} }
@ -56,111 +77,58 @@ public:
~List() ~List()
{ {
clear(); clear();
// Don't forget to free the sentinel
if (m_Head) if (m_Head)
{ {
free(m_Head); free(m_Head);
m_Head = NULL; m_Head = NULL;
} }
} }
void unshift(const T &obj)
{
if (!m_Head->next)
{
push_back(obj);
return;
}
ListNode *node;
if (m_FreeStack.empty())
{
node = new ListNode(obj);
} else {
node = m_FreeStack.front();
m_FreeStack.pop();
node->Set(obj);
}
//is the list one item circular?
/*bool realign = false;
if (m_Head->next == m_Head->prev)
{
m_Head->next->next =
}*/
node->next = m_Head->next;
node->prev = m_Head;
m_Head->next->prev = node;
m_Head->next = node;
m_Size++;
}
void push_back(const T &obj) void push_back(const T &obj)
{ {
ListNode *node; ListNode *node = new ListNode(obj);
if (m_FreeStack.empty())
{
node = new ListNode(obj);
} else {
node = m_FreeStack.front();
m_FreeStack.pop();
node->Set(obj);
}
if (!m_Head->prev)
{
//link in the node as the first item
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; return m_Size;
} }
void clear() void clear()
{ {
ListNode *node = m_Head->next; ListNode *node = m_Head->next;
ListNode *temp; ListNode *temp;
m_Head->next = NULL; m_Head->next = m_Head;
m_Head->prev = NULL; m_Head->prev = m_Head;
while (node && node != m_Head)
// Iterate through the nodes until we find g_Head (the sentinel) again
while (node != m_Head)
{ {
temp = node->next; temp = node->next;
delete node; delete node;
node = temp; node = temp;
} }
m_Size = 0; m_Size = 0;
while (!m_FreeStack.empty())
{
delete m_FreeStack.front();
m_FreeStack.pop();
}
} }
bool empty() bool empty()
{ {
return (m_Head->next == NULL); return (m_Size == 0);
} }
T & back() T & back()
{ {
return m_Head->prev->obj; return m_Head->prev->obj;
} }
private: private:
#if defined __GNUC__
CStack<List::ListNode *> m_FreeStack;
#else
typename CStack<List::ListNode *> m_FreeStack;
#endif
ListNode *m_Head; ListNode *m_Head;
size_t m_Size; size_t m_Size;
public: public:
class iterator class iterator
{ {
friend class List; friend class List;
@ -241,13 +209,10 @@ public:
private: private:
ListNode *m_This; ListNode *m_This;
}; };
public: public:
iterator begin() const iterator begin() const
{ {
if (m_Size)
return iterator(m_Head->next); return iterator(m_Head->next);
else
return iterator(m_Head);
} }
iterator end() const iterator end() const
{ {
@ -259,31 +224,35 @@ public:
iterator iter(where); iterator iter(where);
iter++; iter++;
//If we are both the head and tail...
if (m_Head->next == pNode && m_Head->prev == pNode) // Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
{
m_Head->next = NULL;
m_Head->prev = NULL;
} else if (m_Head->next == pNode) {
//we are only the first
pNode->next->prev = m_Head;
m_Head->next = pNode->next;
} else if (m_Head->prev == pNode) {
//we are the tail
pNode->prev->next = m_Head;
m_Head->prev = pNode->prev;
} else {
//middle unlink
pNode->prev->next = pNode->next; pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev; pNode->next->prev = pNode->prev;
}
m_FreeStack.push(pNode); delete pNode;
m_Size--; m_Size--;
return iter; return iter;
} }
public:
iterator insert(iterator where, const T &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) void remove(const T & obj)
{ {
iterator b; iterator b;
@ -307,7 +276,7 @@ public:
} }
return end(); return end();
} }
List & operator =(List &src) List & operator =(const List &src)
{ {
clear(); clear();
iterator iter; iterator iter;
@ -315,7 +284,7 @@ public:
push_back( (*iter) ); push_back( (*iter) );
return *this; return *this;
} }
}; };
//}; //NAMESPACE //}; //NAMESPACE
#endif //_INCLUDE_CSDM_LIST_H #endif //_INCLUDE_CSDM_LIST_H