Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# ChangeLog

## v0.2.3 - 2025-07-03

### Bugfixes:

* fix(log): update CXX log trace guard
* fix(repo): forcing compiling CXX files with GNU++20 @martinroger (#13)

## v0.2.2 - 2025-06-27

### Enhancements:
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ endif()
target_compile_options(${COMPONENT_LIB}
PUBLIC
-Wno-missing-field-initializers
$<$<COMPILE_LANGUAGE:CXX>:-std=gnu++20>
)

if(NOT ESP_PLATFORM)
Expand Down
2 changes: 1 addition & 1 deletion idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "0.2.2"
version: "0.2.3"
description: esp-lib-utils is a library designed for ESP SoCs to provide utility functions, including logging, checking, and memory.
url: https://github.com/esp-arduino-libs/esp-lib-utils
repository: https://github.com/esp-arduino-libs/esp-lib-utils.git
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=esp-lib-utils
version=0.2.2
version=0.2.3
author=espressif
maintainer=espressif
sentence=esp-lib-utils is a library designed for ESP SoCs to provide utility functions, including logging, checking, and memory.
Expand Down
2 changes: 1 addition & 1 deletion src/esp_utils_versions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/* Library Version */
#define ESP_UTILS_VERSION_MAJOR 0
#define ESP_UTILS_VERSION_MINOR 2
#define ESP_UTILS_VERSION_PATCH 2
#define ESP_UTILS_VERSION_PATCH 3

/* File `esp_utils_conf.h` */
#define ESP_UTILS_CONF_VERSION_MAJOR 1
Expand Down
10 changes: 5 additions & 5 deletions src/log/esp_utils_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
#endif

#ifndef ESP_UTILS_LOG_TAG
#define ESP_UTILS_LOG_TAG "Utils"
# define ESP_UTILS_LOG_TAG "Utils"
#endif

#define ESP_UTILS_LOG_LEVEL(level, format, ...) do { \
if (level == ESP_UTILS_LOG_LEVEL_DEBUG) { ESP_UTILS_IMPL_LOGD(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
else if (level == ESP_UTILS_LOG_LEVEL_INFO) { ESP_UTILS_IMPL_LOGI(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
else if (level == ESP_UTILS_LOG_LEVEL_WARNING) { ESP_UTILS_IMPL_LOGW(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
else if (level == ESP_UTILS_LOG_LEVEL_ERROR) { ESP_UTILS_IMPL_LOGE(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
if (level == ESP_UTILS_LOG_LEVEL_DEBUG) { ESP_UTILS_LOGD_IMPL(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
else if (level == ESP_UTILS_LOG_LEVEL_INFO) { ESP_UTILS_LOGI_IMPL(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
else if (level == ESP_UTILS_LOG_LEVEL_WARNING) { ESP_UTILS_LOGW_IMPL(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
else if (level == ESP_UTILS_LOG_LEVEL_ERROR) { ESP_UTILS_LOGE_IMPL(ESP_UTILS_LOG_TAG, format, ##__VA_ARGS__); } \
else { } \
} while(0)

Expand Down
74 changes: 37 additions & 37 deletions src/log/esp_utils_log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@
#include <algorithm>
#include <cstdio>
#include <type_traits>
#include <memory>
#include <utility>
#include <string>
#include <source_location>
#include "esp_utils_log.h"

namespace esp_utils {
namespace detail {

std::string parseFunctionName(const char *func_name);

// Template for string NTTP parameters
template <size_t N>
struct FixedString {
Expand Down Expand Up @@ -47,33 +50,50 @@ struct FixedString {
};

// Log trace RAII class
template<FixedString file, int line, FixedString func>
template <FixedString TAG>
class log_trace_guard {
public:
log_trace_guard()
{
const char *fname = esp_utils_log_extract_file_name(file.c_str());
printf("[D][" ESP_UTILS_LOG_TAG "][%s:%04d](%s): Enter\n", fname ? fname : "??", line, func.c_str());
}

explicit log_trace_guard(const void *this_ptr)
log_trace_guard(const void *this_ptr = nullptr, const std::source_location &loc = std::source_location::current())
: _this_ptr(this_ptr)
{
const char *fname = esp_utils_log_extract_file_name(file.c_str());
printf("[D][" ESP_UTILS_LOG_TAG "][%s:%04d](%s): (@%p) Enter\n", fname ? fname : "??", line, func.c_str(), _this_ptr);
_line = static_cast<int>(loc.line());
_func_name = parseFunctionName(loc.function_name());
if (_func_name.empty()) {
_func_name = "???";
}
_file_name = std::string(esp_utils_log_extract_file_name(loc.file_name()));
if (_file_name.empty()) {
_file_name = "???";
}

if (_this_ptr) {
ESP_UTILS_LOGD_IMPL_FUNC(
TAG.c_str(), "[%s:%04d](%s): (@%p) Enter", _file_name.c_str(), _line, _func_name.c_str(), _this_ptr
);
} else {
ESP_UTILS_LOGD_IMPL_FUNC(
TAG.c_str(), "[%s:%04d](%s): Enter", _file_name.c_str(), _line, _func_name.c_str()
);
}
}

~log_trace_guard()
{
const char *fname = esp_utils_log_extract_file_name(file.c_str());
if (_this_ptr) {
printf("[D][" ESP_UTILS_LOG_TAG "][%s:%04d](%s): (@%p) Exit\n", fname ? fname : "??", line, func.c_str(), _this_ptr);
ESP_UTILS_LOGD_IMPL_FUNC(
TAG.c_str(), "[%s:%04d](%s): (@%p) Exit", _file_name.c_str(), _line, _func_name.c_str(), _this_ptr
);
} else {
printf("[D][" ESP_UTILS_LOG_TAG "][%s:%04d](%s): Exit\n", fname ? fname : "??", line, func.c_str());
ESP_UTILS_LOGD_IMPL_FUNC(
TAG.c_str(), "[%s:%04d](%s): Exit", _file_name.c_str(), _line, _func_name.c_str()
);
}
}

private:
int _line = 0;
std::string _func_name;
std::string _file_name;
const void *_this_ptr = nullptr;
};

Expand All @@ -85,29 +105,9 @@ class log_trace_guard {
# define ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS() ESP_UTILS_LOGD("(@%p) Enter", this)
# define ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS() ESP_UTILS_LOGD("(@%p) Exit", this)

# define ESP_UTILS_MAKE_FS(str) []{ constexpr esp_utils::detail::FixedString<sizeof(str)> s(str); return s; }()
# define ESP_UTILS_LOG_TRACE_GUARD() \
[[maybe_unused]] auto _log_trace_guard_ = [] { \
using namespace esp_utils::detail; \
constexpr auto __file = ESP_UTILS_MAKE_FS(__FILE__); \
constexpr auto __func = ESP_UTILS_MAKE_FS(__func__); \
std::unique_ptr<log_trace_guard<__file, __LINE__, __func>> _g; \
if constexpr (ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG) { \
_g = std::make_unique<log_trace_guard<__file, __LINE__, __func>>(); \
} \
return _g; \
}()
# define ESP_UTILS_LOG_TRACE_GUARD_WITH_THIS() \
[[maybe_unused]] auto _log_trace_guard_ = [this] { \
using namespace esp_utils::detail; \
constexpr auto __file = ESP_UTILS_MAKE_FS(__FILE__); \
constexpr auto __func = ESP_UTILS_MAKE_FS(__func__); \
std::unique_ptr<log_trace_guard<__file, __LINE__, __func>> _g; \
if constexpr (ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG) { \
_g = std::make_unique<log_trace_guard<__file, __LINE__, __func>>(this); \
} \
return _g; \
}()
# define ESP_UTILS_LOG_MAKE_FS(str) []{ constexpr esp_utils::detail::FixedString<sizeof(str)> s(str); return s; }()
# define ESP_UTILS_LOG_TRACE_GUARD() esp_utils::detail::log_trace_guard<ESP_UTILS_LOG_MAKE_FS(ESP_UTILS_LOG_TAG)> _log_trace_guard_{}
# define ESP_UTILS_LOG_TRACE_GUARD_WITH_THIS() esp_utils::detail::log_trace_guard<ESP_UTILS_LOG_MAKE_FS(ESP_UTILS_LOG_TAG)> _log_trace_guard_{this}
#else
# define ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS()
# define ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS()
Expand Down
23 changes: 0 additions & 23 deletions src/log/impl/esp_utils_log_impl.c

This file was deleted.

64 changes: 64 additions & 0 deletions src/log/impl/esp_utils_log_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <cstring>
#include <string>
#include <string_view>
#include "check/esp_utils_check.h"

/**
* @brief Extract filename from file path
*
* @param[in] file_path File path
*
* @return File name
*/
extern "C" const char *esp_utils_log_extract_file_name(const char *file_path)
{
ESP_UTILS_CHECK_NULL_RETURN(file_path, nullptr, "File path is null");

const char *filename = strrchr(file_path, '/');
if (!filename) {
filename = strrchr(file_path, '\\'); // Windows path compatibility
}

return filename ? filename + 1 : file_path;
}

namespace esp_utils {
namespace detail {

std::string parseFunctionName(const char *func_name)
{
std::string_view sig(func_name);

// Part before the first '(' parenthesis
size_t paren_pos = sig.find('(');
if (paren_pos == std::string_view::npos) {
return {};
}

std::string_view before_paren = sig.substr(0, paren_pos);

// Find the last "::"
size_t last_colon = before_paren.rfind("::");
if (last_colon == std::string_view::npos) {
// Case without ::, find the last space
size_t last_space = before_paren.rfind(' ');
if (last_space == std::string_view::npos) {
return std::string(before_paren); // No space found, return entire part
}
std::string_view func_name_result = before_paren.substr(last_space + 1);

return std::string(func_name_result);
}

std::string_view func_name_result = before_paren.substr(last_colon + 2);

return std::string(func_name_result);
}

} // namespace detail
} // namespace esp_utils
14 changes: 10 additions & 4 deletions src/log/impl/esp_utils_log_impl_esp.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@

#include "esp_log.h"

#define ESP_UTILS_IMPL_LOGD(TAG, format, ...) ESP_LOGD(TAG, "[%s:%04d](%s): " format, \

#define ESP_UTILS_LOGD_IMPL_FUNC(TAG, format, ...) ESP_LOGD(TAG, format, ##__VA_ARGS__)
#define ESP_UTILS_LOGI_IMPL_FUNC(TAG, format, ...) ESP_LOGI(TAG, format, ##__VA_ARGS__)
#define ESP_UTILS_LOGW_IMPL_FUNC(TAG, format, ...) ESP_LOGW(TAG, format, ##__VA_ARGS__)
#define ESP_UTILS_LOGE_IMPL_FUNC(TAG, format, ...) ESP_LOGE(TAG, format, ##__VA_ARGS__)

#define ESP_UTILS_LOGD_IMPL(TAG, format, ...) ESP_UTILS_LOGD_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#define ESP_UTILS_IMPL_LOGI(TAG, format, ...) ESP_LOGI(TAG, "[%s:%04d](%s): " format, \
#define ESP_UTILS_LOGI_IMPL(TAG, format, ...) ESP_UTILS_LOGI_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#define ESP_UTILS_IMPL_LOGW(TAG, format, ...) ESP_LOGW(TAG, "[%s:%04d](%s): " format, \
#define ESP_UTILS_LOGW_IMPL(TAG, format, ...) ESP_UTILS_LOGW_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#define ESP_UTILS_IMPL_LOGE(TAG, format, ...) ESP_LOGE(TAG, "[%s:%04d](%s): " format, \
#define ESP_UTILS_LOGE_IMPL(TAG, format, ...) ESP_UTILS_LOGE_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
13 changes: 9 additions & 4 deletions src/log/impl/esp_utils_log_impl_std.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@

#include <stdio.h>

#define ESP_UTILS_IMPL_LOGD(TAG, format, ...) printf("[D][" TAG "][%s:%04d](%s): " format "\n", \
#define ESP_UTILS_LOGD_IMPL_FUNC(TAG, format, ...) printf("[D][%s]" format "\n", TAG, ##__VA_ARGS__)
#define ESP_UTILS_LOGI_IMPL_FUNC(TAG, format, ...) printf("[I][%s]" format "\n", TAG, ##__VA_ARGS__)
#define ESP_UTILS_LOGW_IMPL_FUNC(TAG, format, ...) printf("[W][%s]" format "\n", TAG, ##__VA_ARGS__)
#define ESP_UTILS_LOGE_IMPL_FUNC(TAG, format, ...) printf("[E][%s]" format "\n", TAG, ##__VA_ARGS__)

#define ESP_UTILS_LOGD_IMPL(TAG, format, ...) ESP_UTILS_LOGD_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#define ESP_UTILS_IMPL_LOGI(TAG, format, ...) printf("[I][" TAG "][%s:%04d](%s): " format "\n", \
#define ESP_UTILS_LOGI_IMPL(TAG, format, ...) ESP_UTILS_LOGI_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#define ESP_UTILS_IMPL_LOGW(TAG, format, ...) printf("[W][" TAG "][%s:%04d](%s): " format "\n", \
#define ESP_UTILS_LOGW_IMPL(TAG, format, ...) ESP_UTILS_LOGW_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#define ESP_UTILS_IMPL_LOGE(TAG, format, ...) printf("[E][" TAG "][%s:%04d](%s): " format "\n", \
#define ESP_UTILS_LOGE_IMPL(TAG, format, ...) ESP_UTILS_LOGE_IMPL_FUNC(TAG, "[%s:%04d](%s): " format, \
Comment on lines +10 to +21
Copy link

Copilot AI Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The pair of macros _IMPL_FUNC and _IMPL can be confusing to maintain. Adding a brief comment or renaming to clarify their distinct roles (format-wrapping vs. tagged invocation) may aid future contributors.

Copilot uses AI. Check for mistakes.
esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
17 changes: 17 additions & 0 deletions test_apps/main/test_on_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,27 @@

using namespace esp_utils;

class LogTestClass {
public:
LogTestClass() = default;

void print()
{
ESP_UTILS_LOG_TRACE_GUARD_WITH_THIS();

ESP_UTILS_LOGI("File: %s", __FILE__);
ESP_UTILS_LOGI("Line: %d", __LINE__);
ESP_UTILS_LOGI("Time: %s", __DATE__);
}
};

TEST_CASE("Test log functions on cpp", "[utils][log][CPP]")
{
ESP_UTILS_LOG_TRACE_GUARD();

LogTestClass log_test_class;
log_test_class.print();

ESP_UTILS_LOGD("This is a debug message");
ESP_UTILS_LOGI("This is an info message");
ESP_UTILS_LOGW("This is a warning message");
Expand Down
Loading