Refactored GDB monitor help command handler

This commit is contained in:
Nav
2024-08-26 21:33:51 +01:00
parent cb9059c691
commit 1ef9ee7297
6 changed files with 43 additions and 76 deletions

View File

@@ -44,7 +44,6 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/VContStepExecution.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/VContRangeStep.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/EepromFill.cpp
)
if (NOT EXCLUDE_INSIGHT)
@@ -53,31 +52,4 @@ if (NOT EXCLUDE_INSIGHT)
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/ActivateInsight.cpp
)
set(
ACTIVATE_INSIGHT_HELP_TEXT
"\n insight Activates the Insight GUI.\n"
)
endif ()
configure_file(
"./Gdb/Resources/GdbHelpMonitorInfo.txt.in"
"${COMPILED_RESOURCES_BUILD_DIR}/Gdb/GdbHelpMonitorInfo.txt"
@ONLY
)
set_source_files_properties(
"${COMPILED_RESOURCES_BUILD_DIR}/Gdb/GdbHelpMonitorInfo.txt"
PROPERTIES QT_RESOURCE_ALIAS "/Gdb/Resources/GdbHelpMonitorInfo.txt"
)
# DebugServer resources
qt_add_resources(
Bloom
"DebugServerResources"
PREFIX
"/compiled/src/DebugServer"
FILES
# GDB RSP Server
"${COMPILED_RESOURCES_BUILD_DIR}/Gdb/GdbHelpMonitorInfo.txt"
)

View File

@@ -1,26 +1,21 @@
#include "HelpMonitorInfo.hpp"
#include <QFile>
#include <QString>
#include <string>
#include "src/DebugServer/Gdb/ResponsePackets/ErrorResponsePacket.hpp"
#include "src/DebugServer/Gdb/ResponsePackets/ResponsePacket.hpp"
#include "src/Services/PathService.hpp"
#include "src/Services/StringService.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/Targets/TargetFamily.hpp"
namespace DebugServer::Gdb::CommandPackets
{
using Services::TargetControllerService;
using Services::StringService;
using ResponsePackets::ErrorResponsePacket;
using ResponsePackets::ResponsePacket;
using ::Exceptions::Exception;
HelpMonitorInfo::HelpMonitorInfo(Monitor&& monitorPacket)
: Monitor(std::move(monitorPacket))
{}
@@ -28,34 +23,47 @@ namespace DebugServer::Gdb::CommandPackets
void HelpMonitorInfo::handle(
DebugSession& debugSession,
const TargetDescriptor& gdbTargetDescriptor,
const Targets::TargetDescriptor&,
const Targets::TargetDescriptor& targetDescriptor,
TargetControllerService&
) {
Logger::info("Handling HelpMonitorInfo packet");
try {
/*
* The file GdbHelpMonitorInfo.txt is included in the binary image as a resource.
* See src/DebugServer/CMakeLists.txt for more.
*/
auto helpFile = QFile{
QString::fromStdString(":/compiled/src/DebugServer/Gdb/Resources/GdbHelpMonitorInfo.txt")
};
static constexpr auto LEFT_PADDING = std::string::size_type{3};
static constexpr auto RIGHT_PADDING = std::string::size_type{26};
if (!helpFile.open(QIODevice::ReadOnly)) {
throw Exception{
"Failed to open GDB monitor info help file - please report this issue at "
+ Services::PathService::homeDomainName() + "/report-issue"
};
}
static const auto leftPadding = std::string{LEFT_PADDING, ' ', std::string::allocator_type{}};
static const auto leftRightPadding = std::string{
LEFT_PADDING + RIGHT_PADDING,
' ',
std::string::allocator_type{}
};
debugSession.connection.writePacket(ResponsePacket{Services::StringService::toHex(
"\n" + QTextStream{&helpFile}.readAll().toUtf8().toStdString() + "\n"
)});
auto output = std::string{"\nSupported Bloom commands:\n\n"};
output += leftPadding + StringService::padRight("help", ' ', RIGHT_PADDING);
output += "Displays this help text.\n";
output += leftPadding + StringService::padRight("version", ' ', RIGHT_PADDING);
output += "Outputs Bloom's version information.\n";
output += leftPadding + StringService::padRight("version machine", ' ', RIGHT_PADDING);
output += "Outputs Bloom's version information in JSON format.\n";
} catch (const Exception& exception) {
Logger::error(exception.getMessage());
debugSession.connection.writePacket(ErrorResponsePacket{});
#ifndef EXCLUDE_INSIGHT
output += leftPadding + StringService::padRight("insight", ' ', RIGHT_PADDING);
output += "Activates the Insight GUI.\n";
#endif
output += "\n\n";
output += leftPadding + StringService::padRight("reset", ' ', RIGHT_PADDING);
output += "Resets the target and holds it in a stopped state.\n\n";
if (targetDescriptor.family == Targets::TargetFamily::AVR_8) {
output += leftPadding + StringService::padRight("eeprom fill [VALUE]", ' ', RIGHT_PADDING);
output += "Fills the target's EEPROM with the specified value. The value should be in hexadecimal\n";
output += leftRightPadding + "format: \"monitor eeprom fill AABBCC\". If the specified value is smaller than the EEPROM\n";
output += leftRightPadding + "memory segment size, it will be repeated across the entire segment address range. If the\n";
output += leftRightPadding + "value size is not a multiple of the segment size, the value will be truncated in the final\n";
output += leftRightPadding + "repetition. The value size must not exceed the segment size.\n";
}
debugSession.connection.writePacket(ResponsePacket{Services::StringService::toHex(output)});
}
}

View File

@@ -6,11 +6,6 @@
namespace DebugServer::Gdb::CommandPackets
{
/**
* The HelpMonitorInfo class implements a structure for the "monitor help" GDB command.
*
* We just respond with some help info on the available "monitor" commands.
*/
class HelpMonitorInfo: public Monitor
{
public:

View File

@@ -1,14 +0,0 @@
Supported Bloom commands:
help Displays this help text.
version Outputs Bloom's version information.
version machine Outputs Bloom's version information in JSON format.
@ACTIVATE_INSIGHT_HELP_TEXT@
reset Resets the target and holds it in a stopped state.
eeprom fill [VALUE] Fills the target's EEPROM with the specified value. The value should be in hexadecimal
format: "monitor eeprom fill AABBCC". If the specified value is smaller than the EEPROM
memory segment size, it will be repeated across the entire segment address range. If the
value size is not a multiple of the segment size, the value will be truncated in the final
repetition. The value size must not exceed the segment size.

View File

@@ -42,6 +42,11 @@ namespace Services
return str;
}
std::string StringService::padRight(std::string str, char padChar, std::size_t padSize) {
str.insert(str.end(), str.size() < padSize ? padSize - str.size() : 0, padChar);
return str;
}
std::string StringService::toHex(std::uint64_t value) {
auto stream = std::stringstream{};
stream << std::hex << std::setfill('0') << std::setw(16) << static_cast<unsigned int>(value);

View File

@@ -16,6 +16,7 @@ namespace Services
static bool isAscii(const std::string& str);
static std::string replaceUnprintable(std::string str);
static std::string padRight(std::string str, char padChar, std::size_t padSize);
static std::string toHex(std::uint64_t value);
static std::string toHex(std::uint32_t value);