Skip to content

Commit

Permalink
Add squirrel debugger interface
Browse files Browse the repository at this point in the history
  • Loading branch information
bluehazzard committed Jan 19, 2015
1 parent 1fa5d5a commit 9ea66a9
Show file tree
Hide file tree
Showing 16 changed files with 1,617 additions and 197 deletions.
12 changes: 12 additions & 0 deletions src/CodeBlocks-unix.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -3093,6 +3093,12 @@
<Unit filename="sdk/scripting/squirrel/sqcompiler.cpp">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqdbgserver.cpp">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqdbgserver.h">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqdebug.cpp">
<Option target="Squirrel" />
</Unit>
Expand All @@ -3108,6 +3114,12 @@
<Unit filename="sdk/scripting/squirrel/sqobject.cpp">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqrdbg.cpp">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqrdbg.h">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqstate.cpp">
<Option target="Squirrel" />
</Unit>
Expand Down
6 changes: 6 additions & 0 deletions src/CodeBlocks.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -3334,6 +3334,12 @@
<Unit filename="sdk/scripting/squirrel/sqcompiler.cpp">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqdbgserver.cpp">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqdbgserver.h">
<Option target="Squirrel" />
</Unit>
<Unit filename="sdk/scripting/squirrel/sqdebug.cpp">
<Option target="Squirrel" />
</Unit>
Expand Down
4 changes: 4 additions & 0 deletions src/include/filefilters.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ namespace FileFilters
extern const DLLIMPORT wxString RESOURCEBIN_EXT;
extern const DLLIMPORT wxString XML_EXT;
extern const DLLIMPORT wxString SCRIPT_EXT;
extern const DLLIMPORT wxString SQ_SCRIPT_EXT;
extern const DLLIMPORT wxString CB_SCRIPT_PLUGIN_EXT;

// a dot *and* the extension, e.g. ".exe"
extern const DLLIMPORT wxString WORKSPACE_DOT_EXT;
Expand Down Expand Up @@ -155,6 +157,8 @@ namespace FileFilters
extern const DLLIMPORT wxString RESOURCEBIN_DOT_EXT;
extern const DLLIMPORT wxString XML_DOT_EXT;
extern const DLLIMPORT wxString SCRIPT_DOT_EXT;
extern const DLLIMPORT wxString SQ_SCRIPT_DOT_EXT;
extern const DLLIMPORT wxString CB_SCRIPT_PLUGIN_DOT_EXT;
}

#endif // FILEFILTERS_H
310 changes: 169 additions & 141 deletions src/include/scripting/squirrel/sqdbgserver.h
Original file line number Diff line number Diff line change
@@ -1,148 +1,176 @@
#ifndef _SQ_DBGSERVER_H_
#define _SQ_DBGSERVER_H_

#define MAX_BP_PATH 512
#define MAX_MSG_LEN 2049

#include <set>
#include <string>
#ifndef _SQ_DBGSERVER_H_
#define _SQ_DBGSERVER_H_

#define MAX_BP_PATH 512
#define MAX_MSG_LEN 2049

#include <set>
#include <map>
#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();

#ifdef _WIN32
#include <winsock.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>

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;
#include <sys/time.h>

};
#define SOCKET int
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1

#ifdef _WIN32
#define sqdbg_closesocket(x) closesocket((x))
#else
#define sqdbg_closesocket(x) close((x))
#include <unistd.h>
#define Sleep(x) usleep((x)*1000)
#endif



typedef std::basic_string<SQChar> SQDBGString;

struct BreakPoint{
BreakPoint(){_line=0;}
BreakPoint(SQInteger line, const SQChar *src){ _line = line; _src = src; }
BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }
bool operator<(const BreakPoint& bp) const
{
if(_line<bp._line)
return true;
if(_line==bp._line){
if(_src < bp._src){
return true;
}
return false;
}
return false;
}
bool operator==(const BreakPoint& other)
{
if(_line==other._line
&& (_src==other._src))
return true;
return false;
}
SQInteger _line;
SQDBGString _src;
};

struct Watch{
Watch() { _id = 0; }
Watch(SQInteger 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; }
SQInteger _id;
SQDBGString _exp;
};

struct VMState {
VMState() { _nestedcalls = 0;}
SQInteger _nestedcalls;
};
typedef std::map<HSQUIRRELVM,VMState*> VMStateMap;
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(HSQUIRRELVM v,SQInteger type,SQInteger 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,SQInteger &id);
void Terminated();
//
void BreakExecution();
void Send(const SQChar *s,...);
void SendChunk(const SQChar *chunk);
void Break(HSQUIRRELVM v,SQInteger line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);

void InformNewFileLoaded(HSQUIRRELVM v,const SQChar *src);

void SerializeState(HSQUIRRELVM v);
//COMMANDS
void AddBreakpoint(BreakPoint &bp);
void AddWatch(Watch &w);
void RemoveWatch(SQInteger id);
void RemoveBreakpoint(BreakPoint &bp);

//
void SetErrorHandlers(HSQUIRRELVM v);
VMState *GetVMState(HSQUIRRELVM v);

//XML RELATED STUFF///////////////////////
#define MAX_NESTING 10
struct XMLElementState {
SQChar name[256];
bool haschildren;
};

XMLElementState xmlstate[MAX_NESTING];
SQInteger _xmlcurrentement;

void BeginDocument();
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;

bool _ready;
bool _autoupdate;
HSQOBJECT _serializefunc;
SQCharVec _scratchstring;

SQInteger _line;
SQDBGString _src;
SQDBGString _break_type;
VMStateMap _vmstate;
};

#ifdef _WIN32
#define sqdbg_closesocket(x) closesocket((x))
#else
#define sqdbg_closesocket(x) close((x))
#endif

#endif //_SQ_DBGSERVER_H_
Loading

0 comments on commit 9ea66a9

Please sign in to comment.