Compare commits

..

1 Commits

Author SHA1 Message Date
J. Nick Koston
9cbee92589 [tormatic] Use stack buffers instead of str_sprintf in debug methods 2026-01-14 15:36:35 -10:00
3 changed files with 20 additions and 10 deletions

View File

@@ -55,6 +55,7 @@ enum MessageType : uint16_t {
COMMAND = 0x0106,
};
// Max string length: 7 ("Unknown"/"Command"). Update print() buffer sizes if adding longer strings.
inline const char *message_type_to_str(MessageType t) {
switch (t) {
case STATUS:
@@ -83,7 +84,11 @@ struct MessageHeader {
}
std::string print() {
return str_sprintf("MessageHeader: seq %d, len %d, type %s", this->seq, this->len, message_type_to_str(this->type));
// 64 bytes: "MessageHeader: seq " + uint16 + ", len " + uint32 + ", type " + type + safety margin
char buf[64];
snprintf(buf, sizeof(buf), "MessageHeader: seq %d, len %d, type %s", this->seq, this->len,
message_type_to_str(this->type));
return buf;
}
void byteswap() {
@@ -131,6 +136,7 @@ inline CoverOperation gate_status_to_cover_operation(GateStatus s) {
return COVER_OPERATION_IDLE;
}
// Max string length: 11 ("Ventilating"). Update print() buffer sizes if adding longer strings.
inline const char *gate_status_to_str(GateStatus s) {
switch (s) {
case PAUSED:
@@ -170,7 +176,12 @@ struct StatusReply {
GateStatus state;
uint8_t trailer = 0x0;
std::string print() { return str_sprintf("StatusReply: state %s", gate_status_to_str(this->state)); }
std::string print() {
// 48 bytes: "StatusReply: state " (19) + state (11) + safety margin
char buf[48];
snprintf(buf, sizeof(buf), "StatusReply: state %s", gate_status_to_str(this->state));
return buf;
}
void byteswap(){};
} __attribute__((packed));
@@ -202,7 +213,12 @@ struct CommandRequestReply {
CommandRequestReply() = default;
CommandRequestReply(GateStatus state) { this->state = state; }
std::string print() { return str_sprintf("CommandRequestReply: state %s", gate_status_to_str(this->state)); }
std::string print() {
// 56 bytes: "CommandRequestReply: state " (27) + state (11) + safety margin
char buf[56];
snprintf(buf, sizeof(buf), "CommandRequestReply: state %s", gate_status_to_str(this->state));
return buf;
}
void byteswap() { this->type = convert_big_endian(this->type); }
} __attribute__((packed));

View File

@@ -563,11 +563,9 @@ inline uint32_t fnv1_hash_object_id(const char *str, size_t len) {
}
/// snprintf-like function returning std::string of maximum length \p len (excluding null terminator).
/// @warning Allocates heap memory. Use snprintf() with a stack buffer instead.
std::string __attribute__((format(printf, 1, 3))) str_snprintf(const char *fmt, size_t len, ...);
/// sprintf-like function returning std::string.
/// @warning Allocates heap memory. Use snprintf() with a stack buffer instead.
std::string __attribute__((format(printf, 1, 2))) str_sprintf(const char *fmt, ...);
/// Concatenate a name with a separator and suffix using an efficient stack-based approach.

View File

@@ -690,8 +690,6 @@ HEAP_ALLOCATING_HELPERS = {
"str_truncate": "removal (function is unused)",
"str_upper_case": "removal (function is unused)",
"str_snake_case": "removal (function is unused)",
"str_sprintf": "snprintf() with a stack buffer",
"str_snprintf": "snprintf() with a stack buffer",
}
@@ -708,9 +706,7 @@ HEAP_ALLOCATING_HELPERS = {
r"get_mac_address(?!_)|"
r"str_truncate|"
r"str_upper_case|"
r"str_snake_case|"
r"str_sprintf|"
r"str_snprintf"
r"str_snake_case"
r")\s*\(" + CPP_RE_EOL,
include=cpp_include,
exclude=[