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
#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
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
#endif

View File

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

View File

@ -31,6 +31,7 @@
#include "amxmodx.h"
#include "sh_stack.h"
#include "natives.h"
#include "Debugger.h"
#ifdef __linux__
#include <malloc.h>
@ -87,18 +88,26 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
for (int i=numParams; i>=1; 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();
LogError(pNative->amx, err, "");
return 0;
if (pDebugger && pDebugger->ErrorExists())
{
//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();
LogError(amx, g_errorNum, g_errorStr);
return ret;
}
if (pDebugger)
pDebugger->EndExec();
g_NativeStack.pop();
return ret;

View File

@ -11,15 +11,38 @@
#ifndef _INCLUDE_SMM_LIST_H
#define _INCLUDE_SMM_LIST_H
#include "sh_stack.h"
#include <new>
#include <malloc.h>
//namespace SourceHook
//{
//This class is from CSDM for AMX Mod X
template <class T>
class List
{
public:
//This class is from CSDM for AMX Mod X
/*
A circular, doubly-linked list with one sentinel node
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;
friend class iterator;
class ListNode
@ -27,23 +50,21 @@ public:
public:
ListNode(const T & o) : obj(o) { };
ListNode() { };
void Set(const T & o) { obj = o; }
~ListNode()
{
};
T obj;
ListNode *next;
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 *n = (ListNode *)malloc(sizeof(ListNode));
n->next = NULL;
n->prev = NULL;
n->next = n;
n->prev = n;
return n;
}
public:
public:
List() : m_Head(_Initialize()), m_Size(0)
{
}
@ -56,111 +77,58 @@ public:
~List()
{
clear();
// Don't forget to free the sentinel
if (m_Head)
{
free(m_Head);
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)
{
ListNode *node;
if (m_FreeStack.empty())
{
node = new ListNode(obj);
} else {
node = m_FreeStack.front();
m_FreeStack.pop();
node->Set(obj);
}
ListNode *node = new ListNode(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->next = m_Head;
m_Head->prev->next = node;
m_Head->prev = node;
}
m_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)
m_Head->next = m_Head;
m_Head->prev = m_Head;
// Iterate through the nodes until we find g_Head (the sentinel) again
while (node != m_Head)
{
temp = node->next;
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);
return (m_Size == 0);
}
T & back()
{
return m_Head->prev->obj;
}
private:
#if defined __GNUC__
CStack<List::ListNode *> m_FreeStack;
#else
typename CStack<List::ListNode *> m_FreeStack;
#endif
private:
ListNode *m_Head;
size_t m_Size;
public:
public:
class iterator
{
friend class List;
@ -241,13 +209,10 @@ public:
private:
ListNode *m_This;
};
public:
public:
iterator begin() const
{
if (m_Size)
return iterator(m_Head->next);
else
return iterator(m_Head);
}
iterator end() const
{
@ -259,31 +224,35 @@ public:
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;
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
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev;
}
m_FreeStack.push(pNode);
delete pNode;
m_Size--;
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)
{
iterator b;
@ -307,7 +276,7 @@ public:
}
return end();
}
List & operator =(List &src)
List & operator =(const List &src)
{
clear();
iterator iter;
@ -315,7 +284,7 @@ public:
push_back( (*iter) );
return *this;
}
};
};
//}; //NAMESPACE
#endif //_INCLUDE_CSDM_LIST_H