Use ifdef to split pre_setup signatures for const correctness

When MAC suffix is not used, pre_setup takes const char* parameters
so string literals stay in flash. When MAC suffix is used, it takes
mutable char* for the static buffers that get overwritten with the
actual MAC address. This avoids const_cast entirely.

Also adds ESPHOME_NAME_ADD_MAC_SUFFIX define for static analysis.
This commit is contained in:
J. Nick Koston
2026-03-05 15:20:20 -10:00
parent 2b799b1ede
commit 0f10a13631
3 changed files with 31 additions and 26 deletions
+24 -15
View File
@@ -138,26 +138,35 @@ static constexpr uint32_t TEARDOWN_TIMEOUT_REBOOT_MS = 1000; // 1 second for qu
class Application {
public:
void pre_setup(char *name, size_t name_len, char *friendly_name, size_t friendly_name_len, bool name_add_mac_suffix) {
#ifdef ESPHOME_NAME_ADD_MAC_SUFFIX
/// Pre-setup with MAC suffix: overwrites placeholder in mutable static buffers with actual MAC.
void pre_setup(char *name, size_t name_len, char *friendly_name, size_t friendly_name_len) {
arch_init();
this->name_add_mac_suffix_ = name_add_mac_suffix;
if (name_add_mac_suffix) {
// MAC address length: 12 hex chars + null terminator
constexpr size_t mac_address_len = 13;
// MAC address suffix length (last 6 characters of 12-char MAC address string)
constexpr size_t mac_address_suffix_len = 6;
char mac_addr[mac_address_len];
get_mac_address_into_buffer(mac_addr);
// Overwrite the placeholder suffix in the static buffers with actual MAC
memcpy(name + name_len - mac_address_suffix_len, mac_addr + mac_address_suffix_len, mac_address_suffix_len);
if (friendly_name_len > 0) {
memcpy(friendly_name + friendly_name_len - mac_address_suffix_len, mac_addr + mac_address_suffix_len,
mac_address_suffix_len);
}
this->name_add_mac_suffix_ = true;
// MAC address length: 12 hex chars + null terminator
constexpr size_t mac_address_len = 13;
// MAC address suffix length (last 6 characters of 12-char MAC address string)
constexpr size_t mac_address_suffix_len = 6;
char mac_addr[mac_address_len];
get_mac_address_into_buffer(mac_addr);
// Overwrite the placeholder suffix in the mutable static buffers with actual MAC
memcpy(name + name_len - mac_address_suffix_len, mac_addr + mac_address_suffix_len, mac_address_suffix_len);
if (friendly_name_len > 0) {
memcpy(friendly_name + friendly_name_len - mac_address_suffix_len, mac_addr + mac_address_suffix_len,
mac_address_suffix_len);
}
this->name_ = StringRef(name, name_len);
this->friendly_name_ = StringRef(friendly_name, friendly_name_len);
}
#else
/// Pre-setup without MAC suffix: StringRef points directly at const string literals in flash.
void pre_setup(const char *name, size_t name_len, const char *friendly_name, size_t friendly_name_len) {
arch_init();
this->name_add_mac_suffix_ = false;
this->name_ = StringRef(name, name_len);
this->friendly_name_ = StringRef(friendly_name, friendly_name_len);
}
#endif
#ifdef USE_DEVICES
void register_device(Device *device) { this->devices_.push_back(device); }
+6 -11
View File
@@ -568,11 +568,11 @@ async def to_code(config: ConfigType) -> None:
"""Create a name expression for pre_setup.
With MAC suffix: emits a static mutable buffer with placeholder suffix.
Without: casts the string literal to char*.
Without: passes the string literal directly as const char*.
Returns (expression, length).
"""
if not value:
return cg.RawExpression('(char *) ""'), 0
return cg.RawExpression('""'), 0
if name_add_mac_suffix:
value_with_placeholder = f"{value}{sep}XXXXXX"
cg.add_global(
@@ -581,10 +581,7 @@ async def to_code(config: ConfigType) -> None:
)
)
return cg.RawExpression(var_name), len(value_with_placeholder)
return (
cg.RawExpression(f"(char *) {cpp_string_escape(value)}"),
len(value),
)
return cg.RawExpression(cpp_string_escape(value)), len(value)
name_expr, name_len = _make_app_name_expr(
name, _APP_NAME_BUF_VAR, _APP_NAME_MAC_SEP
@@ -592,11 +589,9 @@ async def to_code(config: ConfigType) -> None:
friendly_expr, friendly_len = _make_app_name_expr(
friendly_name, _APP_FRIENDLY_NAME_BUF_VAR, _APP_FRIENDLY_NAME_MAC_SEP
)
cg.add(
cg.App.pre_setup(
name_expr, name_len, friendly_expr, friendly_len, name_add_mac_suffix
)
)
if name_add_mac_suffix:
cg.add_define("ESPHOME_NAME_ADD_MAC_SUFFIX")
cg.add(cg.App.pre_setup(name_expr, name_len, friendly_expr, friendly_len))
# Define component count for static allocation
cg.add_define("ESPHOME_COMPONENT_COUNT", len(CORE.component_ids))
+1
View File
@@ -13,6 +13,7 @@
#define ESPHOME_PROJECT_VERSION "v2"
#define ESPHOME_PROJECT_VERSION_30 "v2"
#define ESPHOME_VARIANT "ESP32"
#define ESPHOME_NAME_ADD_MAC_SUFFIX
#define ESPHOME_DEBUG_SCHEDULER
#define ESPHOME_DEBUG_API