/** * @interface_method_impl{DBGCCMDHLP,pfnHlpExec} */ static DECLCALLBACK(int) dbgcHlpExec(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...) { PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); /* Save the scratch state. */ char *pszScratch = pDbgc->pszScratch; unsigned iArg = pDbgc->iArg; /* * Format the expression. */ va_list args; va_start(args, pszExpr); size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]); size_t cb = RTStrPrintfExV(dbgcStringFormatter, pDbgc, pDbgc->pszScratch, cbScratch, pszExpr, args); va_end(args); if (cb >= cbScratch) return VERR_BUFFER_OVERFLOW; /* * Execute the command. * We save and restore the arg index and scratch buffer pointer. */ pDbgc->pszScratch = pDbgc->pszScratch + cb + 1; int rc = dbgcEvalCommand(pDbgc, pszScratch, cb, false /* fNoExecute */); /* Restore the scratch state. */ pDbgc->iArg = iArg; pDbgc->pszScratch = pszScratch; return rc; }
/** * Process all commands currently in the buffer. * * @returns VBox status code. Any error indicates the termination of the console session. * @param pDbgc Debugger console instance data. * @param fNoExecute Indicates that no commands should actually be executed. */ static int dbgcProcessCommands(PDBGC pDbgc, bool fNoExecute) { /** @todo Replace this with a sh/ksh/csh/rexx like toplevel language that * allows doing function, loops, if, cases, and such. */ int rc = VINF_SUCCESS; while (pDbgc->cInputLines) { /* * Empty the log buffer if we're hooking the log. */ if (pDbgc->fLog) { rc = dbgcProcessLog(pDbgc); if (RT_FAILURE(rc)) break; } if (pDbgc->iRead == pDbgc->iWrite) { AssertMsgFailed(("The input buffer is empty while cInputLines=%d!\n", pDbgc->cInputLines)); pDbgc->cInputLines = 0; return 0; } /* * Copy the command to the parse buffer. */ char ch; char *psz = &pDbgc->achInput[pDbgc->iRead]; char *pszTrg = &pDbgc->achScratch[0]; while ((*pszTrg = ch = *psz++) != ';' && ch != '\n' ) { if (psz == &pDbgc->achInput[sizeof(pDbgc->achInput)]) psz = &pDbgc->achInput[0]; if (psz == &pDbgc->achInput[pDbgc->iWrite]) { AssertMsgFailed(("The buffer contains no commands while cInputLines=%d!\n", pDbgc->cInputLines)); pDbgc->cInputLines = 0; return 0; } pszTrg++; } *pszTrg = '\0'; /* * Advance the buffer. */ pDbgc->iRead = psz - &pDbgc->achInput[0]; if (ch == '\n') pDbgc->cInputLines--; /* * Parse and execute this command. */ pDbgc->pszScratch = pszTrg + 1; pDbgc->iArg = 0; rc = dbgcEvalCommand(pDbgc, &pDbgc->achScratch[0], pszTrg - &pDbgc->achScratch[0] - 1, fNoExecute); if ( rc == VERR_DBGC_QUIT || rc == VWRN_DBGC_CMD_PENDING) break; rc = VINF_SUCCESS; /* ignore other statuses */ } return rc; }