149 lines
3.3 KiB
C++
Executable File
149 lines
3.3 KiB
C++
Executable File
#ifndef _SQ_DBGSERVER_H_
|
|
#define _SQ_DBGSERVER_H_
|
|
|
|
#define MAX_BP_PATH 512
|
|
#define MAX_MSG_LEN 2049
|
|
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
/*
|
|
see copyright notice in sqrdbg.h
|
|
*/
|
|
#include <winsock.h>
|
|
|
|
typedef std::basic_string<SQChar> SQDBGString;
|
|
|
|
inline bool dbg_less(const SQChar *x,const SQChar *y)
|
|
{
|
|
int n = 0;
|
|
do {
|
|
int xl = *x == '\\' ? '/' : tolower(*x);
|
|
int yl = *y == '\\' ? '/' : tolower(*y);
|
|
int diff = xl - yl;
|
|
if(diff != 0)
|
|
return diff > 0?true:false;
|
|
x++; y++;
|
|
}while(*x != 0 && *y != 0);
|
|
return false;
|
|
}
|
|
|
|
struct BreakPoint{
|
|
BreakPoint(){_line=0;}
|
|
BreakPoint(int line, const SQChar *src){ _line = line; _src = src; }
|
|
BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }
|
|
inline bool operator<(const BreakPoint& bp) const
|
|
{
|
|
if(_line<bp._line)
|
|
return true;
|
|
if(_line==bp._line){
|
|
return dbg_less(_src.c_str(),bp._src.c_str());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int _line;
|
|
SQDBGString _src;
|
|
};
|
|
|
|
struct Watch{
|
|
Watch() { _id = 0; }
|
|
Watch(int id,const SQChar *exp) { _id = id; _exp = exp; }
|
|
Watch(const Watch &w) { _id = w._id; _exp = w._exp; }
|
|
bool operator<(const Watch& w) const { return _id<w._id; }
|
|
bool operator==(const Watch& w) const { return _id == w._id; }
|
|
int _id;
|
|
SQDBGString _exp;
|
|
};
|
|
|
|
typedef std::set<BreakPoint> BreakPointSet;
|
|
typedef BreakPointSet::iterator BreakPointSetItor;
|
|
|
|
typedef std::set<Watch> WatchSet;
|
|
typedef WatchSet::iterator WatchSetItor;
|
|
|
|
typedef std::vector<SQChar> SQCharVec;
|
|
struct SQDbgServer{
|
|
public:
|
|
enum eDbgState{
|
|
eDBG_Running,
|
|
eDBG_StepOver,
|
|
eDBG_StepInto,
|
|
eDBG_StepReturn,
|
|
eDBG_Suspended,
|
|
eDBG_Disabled,
|
|
};
|
|
|
|
SQDbgServer(HSQUIRRELVM v);
|
|
~SQDbgServer();
|
|
bool Init();
|
|
//returns true if a message has been received
|
|
bool WaitForClient();
|
|
bool ReadMsg();
|
|
void BusyWait();
|
|
void Hook(int type,int line,const SQChar *src,const SQChar *func);
|
|
void ParseMsg(const char *msg);
|
|
bool ParseBreakpoint(const char *msg,BreakPoint &out);
|
|
bool ParseWatch(const char *msg,Watch &out);
|
|
bool ParseRemoveWatch(const char *msg,int &id);
|
|
void Terminated();
|
|
//
|
|
void BreakExecution();
|
|
void Send(const SQChar *s,...);
|
|
void SendChunk(const SQChar *chunk);
|
|
void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);
|
|
|
|
|
|
void SerializeState();
|
|
//COMMANDS
|
|
void AddBreakpoint(BreakPoint &bp);
|
|
void AddWatch(Watch &w);
|
|
void RemoveWatch(int id);
|
|
void RemoveBreakpoint(BreakPoint &bp);
|
|
|
|
//
|
|
void SetErrorHandlers();
|
|
|
|
//XML RELATED STUFF///////////////////////
|
|
#define MAX_NESTING 10
|
|
struct XMLElementState {
|
|
SQChar name[256];
|
|
bool haschildren;
|
|
};
|
|
|
|
XMLElementState xmlstate[MAX_NESTING];
|
|
int _xmlcurrentement;
|
|
|
|
void BeginDocument() { _xmlcurrentement = -1; }
|
|
void BeginElement(const SQChar *name);
|
|
void Attribute(const SQChar *name, const SQChar *value);
|
|
void EndElement(const SQChar *name);
|
|
void EndDocument();
|
|
|
|
const SQChar *escape_xml(const SQChar *x);
|
|
//////////////////////////////////////////////
|
|
HSQUIRRELVM _v;
|
|
HSQOBJECT _debugroot;
|
|
eDbgState _state;
|
|
SOCKET _accept;
|
|
SOCKET _endpoint;
|
|
BreakPointSet _breakpoints;
|
|
WatchSet _watches;
|
|
int _recursionlevel;
|
|
int _maxrecursion;
|
|
int _nestedcalls;
|
|
bool _ready;
|
|
bool _autoupdate;
|
|
HSQOBJECT _serializefunc;
|
|
SQCharVec _scratchstring;
|
|
|
|
};
|
|
|
|
#ifdef _WIN32
|
|
#define sqdbg_closesocket(x) closesocket((x))
|
|
#else
|
|
#define sqdbg_closesocket(x) close((x))
|
|
#endif
|
|
|
|
#endif //_SQ_DBGSERVER_H_
|