FastLED 3.10.8
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
14 switch (kind) {
15 case log_kind::WARN: return "WARN";
16 case log_kind::ERROR: return "ERROR";
17 case log_kind::INFO: return "INFO";
18 }
19 return "LOG";
20}
21
22// Writes "<file>(<line>): <KIND>: " with plain prints. Deliberately not
23// fl::printf: every log site reaches this prefix, so a format string here
24// linked the whole printf engine into images whose own logs never format
25// anything (~3 KB on the LPC845; FastLED#4671).
26FL_NO_INLINE void log_emit_prefix(log_kind kind, const char* file,
27 int line) FL_NO_EXCEPT {
28 char digits[12]; // "-2147483648" + NUL
29 char* p = digits + sizeof(digits);
30 *--p = '\0';
31 unsigned magnitude = line < 0 ? 0u - static_cast<unsigned>(line)
32 : static_cast<unsigned>(line);
33 do {
34 *--p = static_cast<char>('0' + magnitude % 10u);
35 magnitude /= 10u;
36 } while (magnitude != 0u);
37 if (line < 0) {
38 *--p = '-';
39 }
40 fl::print(file);
41 fl::print("(");
42 fl::print(p);
43 fl::print("): ");
45 fl::print(": ");
46}
47
49
50// =============================================================================
51// Centralised log emit (#2963 Proposal B, Option 3)
52// =============================================================================
53// Rewrites `body` in place to hold "<file>(<line>): <KIND>: <user>" then
54// emits via `fl::println(body.c_str())`. `body` is an rvalue reference
55// bound to the FL_WARN/FL_ERROR/FL_INFO temporary in the CALLER's
56// stack frame — its lifetime extends to the end of the full
57// expression, exactly as the OLD inline macro's temp did. So
58// `body.c_str()` here has the same async-handler-safe lifetime as
59// before (Path C / Option 1's `prefixed` local broke this by
60// introducing an extra stack-frame teardown between println and
61// the full-expression end; Option 3 reuses the caller's temp and
62// avoids that hazard).
63//
64// Single out-of-line compilation of the prefix-format chain. Per
65// FL_WARN call site, the inlined `<< file << "(" << line << "): KIND: "`
66// burst (~30-50 B) collapses to one `log_emit` call (~4 B).
67
68FL_NO_INLINE void log_emit(log_kind kind, const char* file, int line, fl::sstream& body) FL_NO_EXCEPT {
69 const char* tag;
70 switch (kind) {
71 case log_kind::WARN: tag = "): WARN: "; break;
72 case log_kind::ERROR: tag = "): ERROR: "; break;
73 case log_kind::INFO:
74 default: tag = "): INFO: "; break;
75 }
76 // Snapshot the user-supplied payload (the only thing `body`
77 // contains at entry — the macro fed it only `<< X`).
78 fl::string user_payload(body.str());
79 // Reset body's buffer and rebuild prefix-then-payload INTO body.
80 // body is in the caller's frame; the c_str() pointer we hand to
81 // println below lives until the end of the FL_WARN expression.
82 body.clear();
83 body << file << "(" << line << tag << user_payload.c_str();
84 fl::println(body.c_str());
85}
86
87FL_NO_INLINE void log_emit_literal(log_kind kind, const char* file, int line,
88 const char* body) FL_NO_EXCEPT {
89 // Prefix + literal + newline, with no formatter involved.
90 log_emit_prefix(kind, file, line);
91 fl::print(body);
93}
94
95} // namespace detail
96
97// ============================================================================
98// Debug Output Helpers
99// ============================================================================
100
101const char *fastled_file_offset(const char *file) FL_NO_EXCEPT {
102 const char *p = file;
103 const char *last_slash = nullptr;
104
105 while (*p) {
106 // Check for "src/" or "src\\" (handle both Unix and Windows paths)
107 if (p[0] == 's' && p[1] == 'r' && p[2] == 'c' && (p[3] == '/' || p[3] == '\\')) {
108 return p; // Skip past "src/" or "src\\"
109 }
110 // Track both forward slash and backslash
111 if (*p == '/' || *p == '\\') {
112 last_slash = p;
113 }
114 p++;
115 }
116 // If "src/" or "src\\" not found but we found at least one slash, return after the
117 // last slash
118 if (last_slash) {
119 return last_slash + 1;
120 }
121 return file; // If no slashes found at all, return original path
122}
123
124// NOTE: AsyncLogger implementation moved to fl/log/async_logger.cpp
125// Background flush infrastructure and async_log_service also moved there
126
127} // namespace fl
ISR-safe async logger using SPSC queue backend (zero heap allocation)
const char * c_str() const FL_NO_EXCEPT
#define FL_NO_INLINE
Centralized logging categories for FastLED hardware interfaces and subsystems.
FL_NO_INLINE const char * log_kind_name(log_kind kind) FL_NO_EXCEPT
Definition log.cpp.hpp:13
FL_NO_INLINE void log_emit_prefix(log_kind kind, const char *file, int line) FL_NO_EXCEPT
Definition log.cpp.hpp:26
FL_NO_INLINE void log_emit_newline() FL_NO_EXCEPT
Definition log.cpp.hpp:48
FL_NO_INLINE void log_emit(log_kind kind, const char *file, int line, fl::sstream &body) FL_NO_EXCEPT
Definition log.cpp.hpp:68
FL_NO_INLINE void log_emit_literal(log_kind kind, const char *file, int line, const char *body) FL_NO_EXCEPT
Definition log.cpp.hpp:87
Compile-time linker keep-alive hook for a single fl::Bus.
Definition bus_info.h:57
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
void print(const char *str) FL_NO_EXCEPT
void println(const char *str) FL_NO_EXCEPT
constexpr int numeric_limits< char >::digits
const char * fastled_file_offset(const char *file) FL_NO_EXCEPT
Definition log.cpp.hpp:101
Base definition for an LED controller.
Definition crgb.hpp:179