Command option extraction for GDB monitor commands
This commit is contained in:
@@ -8,6 +8,7 @@ target_sources(
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/GdbDebugServerConfig.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/GdbDebugServerConfig.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/Connection.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/Connection.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/DebugSession.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/DebugSession.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/ResponsePackets/SupportedFeaturesResponse.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/CommandPacket.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/CommandPacket.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/SupportedFeaturesQuery.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/SupportedFeaturesQuery.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/ReadRegisters.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/ReadRegisters.cpp
|
||||||
@@ -24,7 +25,6 @@ target_sources(
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/BloomVersionMachine.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/BloomVersionMachine.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/GenerateSvd.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/GenerateSvd.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/Detach.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/Detach.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/ResponsePackets/SupportedFeaturesResponse.cpp
|
|
||||||
|
|
||||||
# AVR GDB RSP Server
|
# AVR GDB RSP Server
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/AvrGdbRsp.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/AvrGdbRsp.cpp
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Bloom::DebugServer::Gdb::CommandPackets
|
|||||||
|
|
||||||
GenerateSvd::GenerateSvd(Monitor&& monitorPacket)
|
GenerateSvd::GenerateSvd(Monitor&& monitorPacket)
|
||||||
: Monitor(std::move(monitorPacket))
|
: Monitor(std::move(monitorPacket))
|
||||||
, sendOutput(this->command.find("--out") != std::string::npos)
|
, sendOutput(this->commandOptions.contains("out"))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void GenerateSvd::handle(DebugSession& debugSession, TargetControllerConsole&) {
|
void GenerateSvd::handle(DebugSession& debugSession, TargetControllerConsole&) {
|
||||||
|
|||||||
@@ -13,18 +13,82 @@ namespace Bloom::DebugServer::Gdb::CommandPackets
|
|||||||
Monitor::Monitor(const RawPacket& rawPacket)
|
Monitor::Monitor(const RawPacket& rawPacket)
|
||||||
: CommandPacket(rawPacket)
|
: CommandPacket(rawPacket)
|
||||||
{
|
{
|
||||||
if (this->data.size() > 6) {
|
if (this->data.size() <= 6) {
|
||||||
const auto decodedCommand = Packet::hexToData(
|
return;
|
||||||
std::string(this->data.begin() + 6, this->data.end())
|
|
||||||
);
|
|
||||||
|
|
||||||
this->command = std::string(decodedCommand.begin(), decodedCommand.end());
|
|
||||||
this->command.erase(this->command.find_last_not_of(" ") + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto decodedCommand = Packet::hexToData(
|
||||||
|
std::string(this->data.begin() + 6, this->data.end())
|
||||||
|
);
|
||||||
|
|
||||||
|
this->command = std::string(decodedCommand.begin(), decodedCommand.end());
|
||||||
|
this->command.erase(this->command.find_last_not_of(" ") + 1);
|
||||||
|
|
||||||
|
this->commandOptions = this->extractCommandOptions(this->command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Monitor::handle(DebugSession& debugSession, TargetControllerConsole& targetControllerConsole) {
|
void Monitor::handle(DebugSession& debugSession, TargetControllerConsole& targetControllerConsole) {
|
||||||
Logger::error("Unknown custom GDB command (\"" + this->command + "\") received.");
|
Logger::error("Unknown custom GDB command (\"" + this->command + "\") received.");
|
||||||
debugSession.connection.writePacket(EmptyResponsePacket());
|
debugSession.connection.writePacket(EmptyResponsePacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::optional<std::string>> Monitor::extractCommandOptions(const std::string& command) {
|
||||||
|
auto output = std::map<std::string, std::optional<std::string>>();
|
||||||
|
|
||||||
|
for (std::string::size_type cmdIndex = 1; cmdIndex < command.size(); ++cmdIndex) {
|
||||||
|
const auto cmdChar = command.at(cmdIndex);
|
||||||
|
|
||||||
|
if (cmdChar == '-') {
|
||||||
|
if (command.at(cmdIndex - 1) != '-') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto option = std::string();
|
||||||
|
auto optionValue = std::optional<std::string>();
|
||||||
|
|
||||||
|
bool quoted = false;
|
||||||
|
|
||||||
|
auto optIndex = std::string::size_type(0);
|
||||||
|
for (optIndex = cmdIndex + 1; optIndex < command.size(); ++optIndex) {
|
||||||
|
const auto optChar = command.at(optIndex);
|
||||||
|
|
||||||
|
if (!option.empty() && ((!quoted && optChar == ' ') || (quoted && optChar == '"'))) {
|
||||||
|
output.insert(std::pair(option, optionValue));
|
||||||
|
|
||||||
|
option.clear();
|
||||||
|
optionValue.reset();
|
||||||
|
quoted = false;
|
||||||
|
|
||||||
|
cmdIndex = optIndex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optionValue.has_value()) {
|
||||||
|
if (optChar == '"' && !quoted && optionValue->empty()) {
|
||||||
|
quoted = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
optionValue->push_back(optChar);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optChar == '=') {
|
||||||
|
optionValue = std::string();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
option.push_back(optChar);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!option.empty()) {
|
||||||
|
output.insert(std::pair(option, optionValue));
|
||||||
|
cmdIndex = optIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "CommandPacket.hpp"
|
#include "CommandPacket.hpp"
|
||||||
|
|
||||||
@@ -17,11 +20,29 @@ namespace Bloom::DebugServer::Gdb::CommandPackets
|
|||||||
*/
|
*/
|
||||||
std::string command;
|
std::string command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mapping of any command options included in this->command. A command option must begin with "--" and
|
||||||
|
* can optionally have a value.
|
||||||
|
*
|
||||||
|
* The key of this map is the option name. The map value is the option value, or std::nullopt if no value was
|
||||||
|
* provided.
|
||||||
|
*/
|
||||||
|
std::map<std::string, std::optional<std::string>> commandOptions;
|
||||||
|
|
||||||
explicit Monitor(const RawPacket& rawPacket);
|
explicit Monitor(const RawPacket& rawPacket);
|
||||||
|
|
||||||
void handle(
|
void handle(
|
||||||
DebugSession& debugSession,
|
DebugSession& debugSession,
|
||||||
TargetController::TargetControllerConsole& targetControllerConsole
|
TargetController::TargetControllerConsole& targetControllerConsole
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Extracts command options from a command string.
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::map<std::string, std::optional<std::string>> extractCommandOptions(const std::string& command);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user