19 #include "C4Version.h"
32 : fInit(false), fConnected(false)
38 for (
auto & it : StackTrace)
40 if (pDebug ==
this) pDebug =
nullptr;
57 {
LogFatal(
"C4Aul debugger failed to initialize!");
return false; }
59 LogF(
"C4Aul debugger initialized on port %d", iPort);
65 Log(
"C4Aul debugger waiting for connection...");
81 rOutBuf.
Write(rPacket, iPos);
83 uint8_t *pPos = getMBufPtr<uint8_t>(rOutBuf, iPos +
iSize);
84 *pPos =
'\r'; *(pPos + 1) =
'\n';
90 const char *pSep =
reinterpret_cast<const char *
>(memchr(rInBuf.
getData(),
'\n', rInBuf.
getSize()));
94 int iSize = pSep - getBufPtr<char>(rInBuf) + 1,
96 if (iLength && *(pSep - 1) ==
'\r')
103 ProcessLineResult result = ProcessLine(Buf);
105 SendLine(result.okay ?
"OK" :
"ERR", result.answer.length() > 0 ? result.answer.c_str() :
nullptr);
107 else if (!Password.
getSize() || Password == Buf)
110 SendLine(
"HLO",
"This is " C4ENGINECAPTION
", " C4VERSION);
111 Log(
"C4Aul debugger connected successfully!");
121 assert(pNetIO ==
this);
123 if (fConnected)
return false;
125 if (!AllowedAddr.
IsNull())
141 LogF(
"C4AulDebug lost connection (%s)", szReason);
157 if (!szHost || !*szHost)
return true;
160 return !AllowedAddr.
IsNull();
183 if (!fInit)
return true;
184 fInit = fConnected =
false;
190 if (!fInit)
return true;
193 fInit = fConnected =
false;
199 if (!fConnected)
return;
200 SendLine(
"LOG", szLine);
203 C4AulDebug::ProcessLineResult C4AulDebug::ProcessLine(
const StdStrBuf &Line)
210 if (*szData) szData++;
212 const char *szCmd = Cmd.
getData();
214 return ProcessLineResult(
false,
"Yeah, like I'm going to explain that /here/");
226 eState = DS_StepOver;
241 return ProcessLineResult(
true,
"Game unpaused.");
246 return ProcessLineResult(
true,
"Game paused.");
252 SendLine(RelativePath(script->ScriptName));
261 string scriptPath = szData;
262 size_t colonPos = scriptPath.find(
':');
263 if (colonPos == string::npos)
264 return ProcessLineResult(
false,
"Missing line in breakpoint request");
265 int line = atoi(&scriptPath[colonPos+1]);
266 scriptPath.erase(colonPos);
281 for (
auto fname = props->EnumerateOwnFuncs(); fname; fname = props->EnumerateOwnFuncs(fname))
284 if (!props->GetPropertyByS(fname, &val))
continue;
287 auto sfunc = func->
SFunc();
288 if (!sfunc)
continue;
289 if (sfunc->pOrgScript != sh)
continue;
290 for (
auto chunk = sfunc->GetCode(); chunk->bccType !=
AB_EOFN; chunk++)
295 if (lineOfThisOne == line)
305 found->
Par.i = !found->
Par.i;
307 return ProcessLineResult(
false,
"Can't set breakpoint (wrong line?)");
310 return ProcessLineResult(
false,
"Can't find script");
314 std::list<StdStrBuf*>::iterator it = StackTrace.begin();
315 for (it++; it != StackTrace.end(); it++)
317 SendLine(
"AT", (*it)->getData());
331 val = &pCtx->
Pars[varIndex];
340 SendLine(
"VAR", output.
getData());
343 return ProcessLineResult(
false,
"Can't do that");
345 return ProcessLineResult(
true,
"");
348 bool C4AulDebug::SendLine(
const char *szType,
const char *szData)
359 if (eState == DS_Stop)
379 if (iCallDepth > iStepCallDepth)
385 if (iCallDepth >= iStepCallDepth)
405 iStepCallDepth = iCallDepth;
420 SendLine(
"STP",
"Stepped");
423 ObtainStackTrace(pCtx, pCPos);
424 SendLine(
"POS", StackTrace.front()->getData());
427 while (fConnected && eState == DS_Stop)
440 SendLine(
"EVR",
FormatString(
"%s=%s", script, result).getData());
443 const char* C4AulDebug::RelativePath(
StdStrBuf &path)
445 const char* p = path.
getData();
457 for (
auto & it : StackTrace)
467 StackTrace.push_back(format);
C4AulScriptEngine ScriptEngine
C4Application Application
bool Log(const char *szMessage)
bool LogF(const char *strMessage,...)
bool LogFatal(const char *szMessage)
const char * GetC4VName(const C4V_Type Type)
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
StdStrBuf FormatString(const char *szFmt,...)
const char * GetRelativePathS(const char *strPath, const char *strRelativeTo)
bool GetParentPath(const char *szFilename, char *szBuffer)
void DebugStep(C4AulBCC *pCPos, C4Value *stackTop)
static bool InitDebug(const char *szPassword, const char *szHost)
void SetEngine(class C4AulExec *pnExec)
void ControlScriptEvaluated(const char *script, const char *result)
bool Init(uint16_t iPort) override
bool Listen(uint16_t iPort, bool fWait)
bool SetAllowed(const char *szHost)
void OnLog(const char *szLine)
void SetPassword(const char *szPassword)
C4AulScriptContext * GetContext(int iLevel)
int GetContextDepth() const
virtual C4AulScriptFunc * SFunc()
int GetLineOfCode(C4AulBCC *bcc)
C4ScriptHost * pOrgScript
int GetParCount() const override
const char * AtRelativePath(const char *filename)
void DoInput(C4PacketType eCtrlType, C4ControlPacket *pPkt, C4ControlDeliveryType eDelivery)
const char * GetName() const
bool Send(const C4NetIOPacket &rPacket) override
bool Init(uint16_t iPort=addr_t::IPPORT_NONE) override
void SetCallback(CBClass *pnCallback) override
bool Execute(int iMaxTime=TO_INF, pollfd *readyfds=nullptr) override
virtual C4Object * GetObject()
C4PropList * GetPrototype() const
virtual C4PropListStatic * GetPropList()
StdStrBuf GetDataString(int depth=10, const class C4PropListStatic *ignore_reference_parent=nullptr) const
C4AulFunc * getFunction() const
int32_t GetItemNr(const char *strName) const
void Write(const void *pnData, size_t inSize, size_t iAt=0)
const void * getData() const
bool ScheduleProcs(int iTimeout=1000/36)
void Add(StdSchedulerProc *pProc)
void CopyUntil(const char *szString, char cUntil)
const char * getData() const
const char * getPtr(size_t i) const
void SetAddress(const sockaddr *addr)
StdStrBuf ToString(int flags=0) const
static const uint16_t IPPORT_NONE
HostAddress GetHost() const