-/*\r
- see copyright notice in sqrdbg.h\r
-*/\r
-#include <squirrel.h>\r
-#include "sqrdbg.h"\r
-#include "sqdbgserver.h"\r
-int debug_hook(HSQUIRRELVM v);\r
-int error_handler(HSQUIRRELVM v);\r
-\r
-#include "serialize_state.inl"\r
-\r
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)\r
-{\r
- sockaddr_in bindaddr;\r
-#ifdef _WIN32\r
- WSADATA wsadata; \r
- if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){\r
- return NULL;\r
- } \r
-#endif \r
- \r
- SQDbgServer *rdbg = new SQDbgServer(v);\r
- rdbg->_autoupdate = autoupdate?true:false;\r
- rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);\r
- bindaddr.sin_family = AF_INET;\r
- bindaddr.sin_port = htons(port);\r
- bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);\r
- if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){\r
- delete rdbg;\r
- sq_throwerror(v,_SC("failed to bind the socket"));\r
- return NULL;\r
- }\r
- if(!rdbg->Init()) {\r
- delete rdbg;\r
- sq_throwerror(v,_SC("failed to initialize the debugger"));\r
- return NULL;\r
- }\r
- \r
- return rdbg;\r
-}\r
-\r
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)\r
-{\r
- if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {\r
- sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));\r
- }\r
- sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);\r
- sq_addref(rdbg->_v,&rdbg->_serializefunc);\r
- sq_pop(rdbg->_v,1);\r
-\r
- sockaddr_in cliaddr;\r
- socklen_t addrlen=sizeof(cliaddr);\r
- if(listen(rdbg->_accept,0)==SOCKET_ERROR)\r
- return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));\r
- rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);\r
- //do not accept any other connection\r
- sqdbg_closesocket(rdbg->_accept);\r
- rdbg->_accept = INVALID_SOCKET;\r
- if(rdbg->_endpoint==INVALID_SOCKET){\r
- return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));\r
- }\r
- while(!rdbg->_ready){\r
- sq_rdbg_update(rdbg);\r
- }\r
- return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)\r
-{\r
- TIMEVAL time;\r
- time.tv_sec=0;\r
- time.tv_usec=0;\r
- fd_set read_flags;\r
- FD_ZERO(&read_flags);\r
- FD_SET(rdbg->_endpoint, &read_flags);\r
- select(FD_SETSIZE, &read_flags, NULL, NULL, &time);\r
-\r
- if(FD_ISSET(rdbg->_endpoint,&read_flags)){\r
- char temp[1024];\r
- int size=0;\r
- char c,prev=0;\r
- memset(&temp,0,sizeof(temp));\r
- int res;\r
- FD_CLR(rdbg->_endpoint, &read_flags);\r
- while((res = recv(rdbg->_endpoint,&c,1,0))>0){\r
- \r
- if(c=='\n')break;\r
- if(c!='\r'){\r
- temp[size]=c;\r
- prev=c;\r
- size++;\r
- }\r
- }\r
- switch(res){\r
- case 0:\r
- return sq_throwerror(rdbg->_v,_SC("disconnected"));\r
- case SOCKET_ERROR:\r
- return sq_throwerror(rdbg->_v,_SC("socket error"));\r
- }\r
- \r
- temp[size]=0;\r
- temp[size+1]=0;\r
- rdbg->ParseMsg(temp);\r
- }\r
- return SQ_OK;\r
-}\r
-\r
-int debug_hook(HSQUIRRELVM v)\r
-{\r
- SQUserPointer up;\r
- int event_type,line;\r
- const SQChar *src,*func;\r
- sq_getinteger(v,2,&event_type);\r
- sq_getstring(v,3,&src);\r
- sq_getinteger(v,4,&line);\r
- sq_getstring(v,5,&func);\r
- sq_getuserpointer(v,-1,&up);\r
- HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;\r
- rdbg->Hook(event_type,line,src,func);\r
- if(rdbg->_autoupdate) {\r
- if(SQ_FAILED(sq_rdbg_update(rdbg)))\r
- return sq_throwerror(v,_SC("socket failed"));\r
- }\r
- return 0;\r
-}\r
-\r
-int error_handler(HSQUIRRELVM v)\r
-{\r
- SQUserPointer up;\r
- const SQChar *sErr=NULL;\r
- const SQChar *fn=_SC("unknown");\r
- const SQChar *src=_SC("unknown");\r
- int line=-1;\r
- SQStackInfos si;\r
- sq_getuserpointer(v,-1,&up);\r
- HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;\r
- if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))\r
- {\r
- if(si.funcname)fn=si.funcname;\r
- if(si.source)src=si.source;\r
- line=si.line;\r
- scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);\r
- }\r
- if(sq_gettop(v)>=1){\r
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {\r
- scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);\r
- rdbg->Break(si.line,src,_SC("error"),sErr);\r
- }\r
- else{\r
- scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));\r
- rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));\r
- }\r
- }\r
- rdbg->BreakExecution();\r
- return 0;\r
-}\r
-\r
-\r
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)\r
-{\r
- delete rdbg;\r
-#ifdef _WIN32\r
- WSACleanup();\r
-#endif\r
- return SQ_OK;\r
-}\r
+/*
+ see copyright notice in sqrdbg.h
+*/
+#include <squirrel.h>
+#include "sqrdbg.h"
+#include "sqdbgserver.h"
+int debug_hook(HSQUIRRELVM v);
+int error_handler(HSQUIRRELVM v);
+
+#include "serialize_state.inl"
+
+HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)
+{
+ sockaddr_in bindaddr;
+#ifdef _WIN32
+ WSADATA wsadata;
+ if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){
+ return NULL;
+ }
+#endif
+
+ SQDbgServer *rdbg = new SQDbgServer(v);
+ rdbg->_autoupdate = autoupdate?true:false;
+ rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);
+ bindaddr.sin_family = AF_INET;
+ bindaddr.sin_port = htons(port);
+ bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);
+ if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){
+ delete rdbg;
+ sq_throwerror(v,_SC("failed to bind the socket"));
+ return NULL;
+ }
+ if(!rdbg->Init()) {
+ delete rdbg;
+ sq_throwerror(v,_SC("failed to initialize the debugger"));
+ return NULL;
+ }
+
+ return rdbg;
+}
+
+SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)
+{
+ if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {
+ sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));
+ }
+ sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);
+ sq_addref(rdbg->_v,&rdbg->_serializefunc);
+ sq_pop(rdbg->_v,1);
+
+ sockaddr_in cliaddr;
+ socklen_t addrlen=sizeof(cliaddr);
+ if(listen(rdbg->_accept,0)==SOCKET_ERROR)
+ return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));
+ rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);
+ //do not accept any other connection
+ sqdbg_closesocket(rdbg->_accept);
+ rdbg->_accept = INVALID_SOCKET;
+ if(rdbg->_endpoint==INVALID_SOCKET){
+ return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));
+ }
+ while(!rdbg->_ready){
+ sq_rdbg_update(rdbg);
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)
+{
+ TIMEVAL time;
+ time.tv_sec=0;
+ time.tv_usec=0;
+ fd_set read_flags;
+ FD_ZERO(&read_flags);
+ FD_SET(rdbg->_endpoint, &read_flags);
+ select(FD_SETSIZE, &read_flags, NULL, NULL, &time);
+
+ if(FD_ISSET(rdbg->_endpoint,&read_flags)){
+ char temp[1024];
+ int size=0;
+ char c,prev=0;
+ memset(&temp,0,sizeof(temp));
+ int res;
+ FD_CLR(rdbg->_endpoint, &read_flags);
+ while((res = recv(rdbg->_endpoint,&c,1,0))>0){
+
+ if(c=='\n')break;
+ if(c!='\r'){
+ temp[size]=c;
+ prev=c;
+ size++;
+ }
+ }
+ switch(res){
+ case 0:
+ return sq_throwerror(rdbg->_v,_SC("disconnected"));
+ case SOCKET_ERROR:
+ return sq_throwerror(rdbg->_v,_SC("socket error"));
+ }
+
+ temp[size]=0;
+ temp[size+1]=0;
+ rdbg->ParseMsg(temp);
+ }
+ return SQ_OK;
+}
+
+int debug_hook(HSQUIRRELVM v)
+{
+ SQUserPointer up;
+ int event_type,line;
+ const SQChar *src,*func;
+ sq_getinteger(v,2,&event_type);
+ sq_getstring(v,3,&src);
+ sq_getinteger(v,4,&line);
+ sq_getstring(v,5,&func);
+ sq_getuserpointer(v,-1,&up);
+ HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;
+ rdbg->Hook(event_type,line,src,func);
+ if(rdbg->_autoupdate) {
+ if(SQ_FAILED(sq_rdbg_update(rdbg)))
+ return sq_throwerror(v,_SC("socket failed"));
+ }
+ return 0;
+}
+
+int error_handler(HSQUIRRELVM v)
+{
+ SQUserPointer up;
+ const SQChar *sErr=NULL;
+ const SQChar *fn=_SC("unknown");
+ const SQChar *src=_SC("unknown");
+ int line=-1;
+ SQStackInfos si;
+ sq_getuserpointer(v,-1,&up);
+ HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;
+ if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))
+ {
+ if(si.funcname)fn=si.funcname;
+ if(si.source)src=si.source;
+ line=si.line;
+ scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);
+ }
+ if(sq_gettop(v)>=1){
+ if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
+ scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
+ rdbg->Break(si.line,src,_SC("error"),sErr);
+ }
+ else{
+ scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
+ rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));
+ }
+ }
+ rdbg->BreakExecution();
+ return 0;
+}
+
+
+SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)
+{
+ delete rdbg;
+#ifdef _WIN32
+ WSACleanup();
+#endif
+ return SQ_OK;
+}