mirror of
https://github.com/esphome/esphome.git
synced 2026-10-18 04:02:54 +00:00
[core] Add ESP_LOGV_HEX, ESP_LOGVV_HEX and ESP_LOGD_HEX (#20931)
This commit is contained in:
@@ -160,6 +160,38 @@ int esp_idf_log_vprintf_(const char *format, va_list args); // NOLINT
|
||||
#define ESP_LOGV(tag, ...) esph_log_v(tag, __VA_ARGS__)
|
||||
#define ESP_LOGVV(tag, ...) esph_log_vv(tag, __VA_ARGS__)
|
||||
|
||||
// Log \p format with up to \p max_bytes of \p data as colon separated hex appended as its last %s argument.
|
||||
// The stack buffer exists only when the level is compiled in. Needs esphome/core/helpers.h.
|
||||
#define ESPHOME_LOG_HEX_(log_macro, tag, data, len, max_bytes, format, ...) \
|
||||
do { \
|
||||
char esph_log_hex_buf_[::esphome::format_hex_pretty_size(max_bytes)]; \
|
||||
log_macro(tag, format, __VA_ARGS__ __VA_OPT__(, )::esphome::format_hex_pretty_to(esph_log_hex_buf_, data, len)); \
|
||||
} while (0)
|
||||
#ifdef ESPHOME_LOG_HAS_DEBUG
|
||||
#define ESP_LOGD_HEX(tag, data, len, max_bytes, format, ...) \
|
||||
ESPHOME_LOG_HEX_(ESP_LOGD, tag, data, len, max_bytes, format, __VA_ARGS__)
|
||||
#else
|
||||
#define ESP_LOGD_HEX(tag, data, len, max_bytes, format, ...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
||||
#define ESP_LOGV_HEX(tag, data, len, max_bytes, format, ...) \
|
||||
ESPHOME_LOG_HEX_(ESP_LOGV, tag, data, len, max_bytes, format, __VA_ARGS__)
|
||||
#else
|
||||
#define ESP_LOGV_HEX(tag, data, len, max_bytes, format, ...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
||||
#define ESP_LOGVV_HEX(tag, data, len, max_bytes, format, ...) \
|
||||
ESPHOME_LOG_HEX_(ESP_LOGVV, tag, data, len, max_bytes, format, __VA_ARGS__)
|
||||
#else
|
||||
#define ESP_LOGVV_HEX(tag, data, len, max_bytes, format, ...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
|
||||
#define BYTE_TO_BINARY(byte) \
|
||||
((byte) &0x80 ? '1' : '0'), ((byte) &0x40 ? '1' : '0'), ((byte) &0x20 ? '1' : '0'), ((byte) &0x10 ? '1' : '0'), \
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome::testing {
|
||||
|
||||
static const char *const TAG = "log_hex_test";
|
||||
|
||||
TEST(LogHexTest, EvaluatesArgumentsOnlyWhenTheLevelIsCompiledIn) {
|
||||
static constexpr uint8_t DATA[] = {0x01, 0xAB, 0xFF};
|
||||
int debug_calls = 0;
|
||||
int verbose_calls = 0;
|
||||
int very_verbose_calls = 0;
|
||||
auto count = [](int &calls) {
|
||||
calls++;
|
||||
return sizeof(DATA);
|
||||
};
|
||||
ESP_LOGD_HEX(TAG, DATA, count(debug_calls), sizeof(DATA), "Data: %s");
|
||||
ESP_LOGV_HEX(TAG, DATA, count(verbose_calls), sizeof(DATA), "Frame %u: %s", 7u);
|
||||
ESP_LOGVV_HEX(TAG, DATA, count(very_verbose_calls), 2, "Type %02X %s: %s", 0x10, "truncated");
|
||||
#ifdef ESPHOME_LOG_HAS_DEBUG
|
||||
EXPECT_EQ(debug_calls, 1);
|
||||
#else
|
||||
EXPECT_EQ(debug_calls, 0);
|
||||
#endif
|
||||
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
||||
EXPECT_EQ(verbose_calls, 1);
|
||||
#else
|
||||
EXPECT_EQ(verbose_calls, 0);
|
||||
#endif
|
||||
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
||||
EXPECT_EQ(very_verbose_calls, 1);
|
||||
#else
|
||||
EXPECT_EQ(very_verbose_calls, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(LogHexTest, IsASingleStatement) {
|
||||
static constexpr uint8_t DATA[] = {0x12, 0x34};
|
||||
bool other_branch = false;
|
||||
if (DATA[0] == 0x12) // NOLINT(readability-braces-around-statements)
|
||||
ESP_LOGV_HEX(TAG, DATA, sizeof(DATA), sizeof(DATA), "Data: %s");
|
||||
else // NOLINT(readability-braces-around-statements)
|
||||
other_branch = true;
|
||||
EXPECT_FALSE(other_branch);
|
||||
}
|
||||
|
||||
// Stands in for a log macro so the expansion can be checked without the logger backend
|
||||
static char captured[64]; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
#define CAPTURE_LOG(tag, ...) snprintf(captured, sizeof(captured), __VA_ARGS__)
|
||||
|
||||
TEST(LogHexTest, HexTextIsTheLastArgument) {
|
||||
static constexpr uint8_t DATA[] = {0x01, 0xAB, 0xFF};
|
||||
ESPHOME_LOG_HEX_(CAPTURE_LOG, TAG, DATA, sizeof(DATA), sizeof(DATA), "Data: %s");
|
||||
EXPECT_STREQ(captured, "Data: 01:AB:FF");
|
||||
}
|
||||
|
||||
TEST(LogHexTest, ExtraArgumentsComeFirstAndLongDataIsCut) {
|
||||
static constexpr uint8_t DATA[] = {0x01, 0xAB, 0xFF};
|
||||
ESPHOME_LOG_HEX_(CAPTURE_LOG, TAG, DATA, sizeof(DATA), 2, "Type %02X %s: %s", 0x10, "truncated");
|
||||
EXPECT_STREQ(captured, "Type 10 truncated: 01:AB");
|
||||
}
|
||||
|
||||
} // namespace esphome::testing
|
||||
Reference in New Issue
Block a user