FastLED 3.9.15
Loading...
Searching...
No Matches
log.cpp.hpp
Go to the documentation of this file.
1
3
4#include "fl/log/log.h"
6#include "fl/stl/strstream.h"
7#include "fl/stl/string.h"
8#include "fl/stl/move.h"
9
10namespace fl {
11namespace detail {
12
13// =============================================================================
14// Centralised log emit (#2963 Proposal B, Option 3)
15// =============================================================================
16// Rewrites `body` in place to hold "<file>(<line>): <KIND>: <user>" then
17// emits via `fl::println(body.c_str())`. `body` is an rvalue reference
18// bound to the FL_WARN/FL_ERROR/FL_INFO temporary in the CALLER's
19// stack frame — its lifetime extends to the end of the full
20// expression, exactly as the OLD inline macro's temp did. So
21// `body.c_str()` here has the same async-handler-safe lifetime as
22// before (Path C / Option 1's `prefixed` local broke this by
23// introducing an extra stack-frame teardown between println and
24// the full-expression end; Option 3 reuses the caller's temp and
25// avoids that hazard).
26//
27// Single out-of-line compilation of the prefix-format chain. Per
28// FL_WARN call site, the inlined `<< file << "(" << line << "): KIND: "`
29// burst (~30-50 B) collapses to one `log_emit` call (~4 B).
30
31FL_NO_INLINE void log_emit(log_kind kind, const char* file, int line, fl::sstream& body) FL_NOEXCEPT {
32 const char* tag;
33 switch (kind) {
34 case log_kind::WARN: tag = "): WARN: "; break;
35 case log_kind::ERROR: tag = "): ERROR: "; break;
36 case log_kind::INFO:
37 default: tag = "): INFO: "; break;
38 }
39 // Snapshot the user-supplied payload (the only thing `body`
40 // contains at entry — the macro fed it only `<< X`).
41 fl::string user_payload(body.str());
42 // Reset body's buffer and rebuild prefix-then-payload INTO body.
43 // body is in the caller's frame; the c_str() pointer we hand to
44 // println below lives until the end of the FL_WARN expression.
45 body.clear();
46 body << file << "(" << line << tag << user_payload.c_str();
47 fl::println(body.c_str());
48}
49
50} // namespace detail
51
52// ============================================================================
53// Debug Output Helpers
54// ============================================================================
55
56const char *fastled_file_offset(const char *file) {
57 const char *p = file;
58 const char *last_slash = nullptr;
59
60 while (*p) {
61 // Check for "src/" or "src\\" (handle both Unix and Windows paths)
62 if (p[0] == 's' && p[1] == 'r' && p[2] == 'c' && (p[3] == '/' || p[3] == '\\')) {
63 return p; // Skip past "src/" or "src\\"
64 }
65 // Track both forward slash and backslash
66 if (*p == '/' || *p == '\\') {
67 last_slash = p;
68 }
69 p++;
70 }
71 // If "src/" or "src\\" not found but we found at least one slash, return after the
72 // last slash
73 if (last_slash) {
74 return last_slash + 1;
75 }
76 return file; // If no slashes found at all, return original path
77}
78
79// NOTE: AsyncLogger implementation moved to fl/log/async_logger.cpp
80// Background flush infrastructure and async_log_service also moved there
81
82} // namespace fl
ISR-safe async logger using SPSC queue backend (zero heap allocation)
const char * c_str() const FL_NOEXCEPT
Centralized logging categories for FastLED hardware interfaces and subsystems.
FL_NO_INLINE void log_emit(log_kind kind, const char *file, int line, fl::sstream &body) FL_NOEXCEPT
Definition log.cpp.hpp:31
Compile-time linker keep-alive hook for a single fl::Bus.
Definition bus_traits.h:48
void println(const char *str) FL_NOEXCEPT
const char * fastled_file_offset(const char *file)
Definition log.cpp.hpp:56
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NO_INLINE
#define FL_NOEXCEPT