diff --git a/headers/private/kernel/debug.h b/headers/private/kernel/debug.h index 4badc0c87f..6d44ee7bf5 100644 --- a/headers/private/kernel/debug.h +++ b/headers/private/kernel/debug.h @@ -116,6 +116,8 @@ extern void unset_all_debug_variables(); extern bool evaluate_debug_expression(const char* expression, uint64* result, bool silent); extern int evaluate_debug_command(const char* command); +extern status_t parse_next_debug_command_argument(const char** expressionString, + char* buffer, size_t bufferSize); extern status_t add_debugger_command_etc(const char* name, debugger_command_hook func, const char* description, diff --git a/src/system/kernel/debug/debug_parser.cpp b/src/system/kernel/debug/debug_parser.cpp index 4c5a232610..2a03c10c97 100644 --- a/src/system/kernel/debug/debug_parser.cpp +++ b/src/system/kernel/debug/debug_parser.cpp @@ -329,7 +329,7 @@ public: _QuotedString(); break; } - + default: { fCurrentChar--; @@ -472,6 +472,9 @@ class ExpressionParser { uint64 EvaluateCommand( const char* expressionString, int& returnCode); + status_t ParseNextCommandArgument( + const char** expressionString, char* buffer, + size_t bufferSize); private: uint64 _ParseExpression(); @@ -550,6 +553,35 @@ ExpressionParser::EvaluateCommand(const char* expressionString, } +status_t +ExpressionParser::ParseNextCommandArgument(const char** expressionString, + char* buffer, size_t bufferSize) +{ + fTokenizer.SetTo(*expressionString); + fTokenizer.SetCommandMode(true); + + if (fTokenizer.NextToken().type == TOKEN_END_OF_LINE) + return B_ENTRY_NOT_FOUND; + + fTokenizer.RewindToken(); + + char* argv[2]; + int argc = 0; + if (!_ParseArgument(argc, argv)) + return B_BAD_VALUE; + + strlcpy(buffer, argv[0], bufferSize); + + const Token& token = fTokenizer.NextToken(); + if (token.type == TOKEN_END_OF_LINE) + *expressionString = NULL; + else + *expressionString += token.position; + + return B_OK; +} + + uint64 ExpressionParser::_ParseExpression() { @@ -1100,3 +1132,39 @@ evaluate_debug_command(const char* commandLine) return returnCode; } + + +status_t +parse_next_debug_command_argument(const char** expressionString, char* buffer, + size_t bufferSize) +{ + if (sNextJumpBufferIndex >= kJumpBufferCount) { + kprintf_unfiltered("parse_next_debug_command_argument(): Out of jump " + "buffers for exception handling\n"); + return B_ERROR; + } + + status_t error; + void* temporaryStorageMark = allocate_temp_storage(0); + // get a temporary storage mark, so we can cleanup everything that + // is allocated during the evaluation + + if (setjmp(sJumpBuffers[sNextJumpBufferIndex++]) == 0) { + error = ExpressionParser().ParseNextCommandArgument(expressionString, + buffer, bufferSize); + } else { + if (sExceptionPosition >= 0) { + kprintf_unfiltered("%s, at position: %d, in command line: %s\n", + sExceptionMessage, sExceptionPosition, *expressionString); + } else + kprintf_unfiltered("%s", sExceptionMessage); + error = B_BAD_VALUE; + } + + sNextJumpBufferIndex--; + + // cleanup temp allocations + free_temp_storage(temporaryStorageMark); + + return error; +}