66#pragma GCC diagnostic push
77#pragma GCC diagnostic ignored "-Wvarargs"
88
9- #define ERR_LEVEL_FMT " [ERROR] "
10- #define INFO_LEVEL_FMT " [INFO] "
11- #define DEBUG_LEVEL_FMT " [DEBUG] "
12- #define WARN_LEVEL_FMT " [WARN] "
9+ static const char ERROR_LOG_LEVEL[] PROGMEM = " [ERROR] " ;
10+ static const char WARN_LOG_LEVEL[] PROGMEM = " [WARN] " ;
11+ static const char INFO_LOG_LEVEL[] PROGMEM = " [INFO] " ;
12+ static const char DEBUG_LOG_LEVEL[] PROGMEM = " [DEBUG] " ;
13+ static const char NONE_LOG_LEVEL[] PROGMEM = " " ;
1314
14- LogClass Log (&Serial3);
15+ /* *
16+ * @return A pointer to the given @p level flash string.
17+ */
18+ static const __FlashStringHelper* getLogLevelString (const LogLevel level) {
19+
20+ switch (level) {
21+ case LogLevel::ERROR:
22+ return reinterpret_cast <const __FlashStringHelper*>(ERROR_LOG_LEVEL);
23+
24+ case LogLevel::WARN:
25+ return reinterpret_cast <const __FlashStringHelper*>(WARN_LOG_LEVEL);
26+
27+ case LogLevel::INFO:
28+ return reinterpret_cast <const __FlashStringHelper*>(INFO_LOG_LEVEL);
29+
30+ case LogLevel::DEBUG:
31+ return reinterpret_cast <const __FlashStringHelper*>(DEBUG_LOG_LEVEL);
1532
16- int16_t printf_putchar (char c, FILE* fp) {
17- ((class Print *)(fdev_get_udata (fp)))->write ((uint8_t )c);
33+ default :
34+ return reinterpret_cast <const __FlashStringHelper*>(NONE_LOG_LEVEL);
35+ }
36+ }
37+
38+ /* *
39+ * @brief We have to declare this outside the class scope for interoperability
40+ * with fdev_setup_stream. This is safe as we won't ever come into a situation
41+ * where this is not called atomically.
42+ */
43+ static int16_t fdev_putchar (char data, FILE* file) {
44+ ((class Print *)(fdev_get_udata (file)))->write ((uint8_t )data);
1845 return 0 ;
1946}
2047
21- void LogClass::print (const char * str, const char level[]) {
22- this ->uart ->printf (" %s%s\r\n " , level, str);
48+ /* *
49+ * @brief The instance of the LogClass defined in the header file. Declared here
50+ * so that we have an Arduino style with not having to instantiate the class
51+ * explicitly.
52+ */
53+ LogClass Log (&Serial3);
54+
55+ void LogClass::print (const LogLevel level, const char * str) {
56+ if (log_level < level) {
57+ return ;
58+ }
59+
60+ uart->print (getLogLevelString (level));
61+ uart->println (str);
62+ }
63+
64+ void LogClass::print (const LogLevel level, const __FlashStringHelper* str) {
65+ if (log_level < level) {
66+ return ;
67+ }
68+
69+ uart->print (getLogLevelString (level));
70+ uart->println (str);
71+ }
72+
73+ void LogClass::printf (const LogLevel level, const char * str, va_list args) {
74+
75+ if (log_level < level) {
76+ return ;
77+ }
78+
79+ uart->print (getLogLevelString (level));
80+
81+ FILE file;
82+
83+ fdev_setup_stream (&file, fdev_putchar, NULL , _FDEV_SETUP_WRITE);
84+ fdev_set_udata (&file, this ->uart );
85+ vfprintf (&file, str, args);
86+ fdev_close ();
87+ }
88+
89+ void LogClass::printf (const LogLevel level,
90+ const __FlashStringHelper* str,
91+ va_list args) {
92+
93+ if (log_level < level) {
94+ return ;
95+ }
96+
97+ uart->print (getLogLevelString (level));
98+
99+ FILE file;
100+
101+ fdev_setup_stream (&file, fdev_putchar, NULL , _FDEV_SETUP_WRITE);
102+ fdev_set_udata (&file, this ->uart );
103+ vfprintf_P (&file, reinterpret_cast <const char *>(str), args);
104+ fdev_close ();
23105}
24106
25107LogClass::LogClass (UartClass* uart) {
@@ -37,147 +119,145 @@ LogLevel LogClass::getLogLevel(void) { return log_level; }
37119
38120bool LogClass::setLogLevelStr (const char * log_level) {
39121 LogLevel ll = LogLevel::NONE;
40- if (strstr (log_level, " debug" ) != NULL ) {
122+ if (strstr_P (log_level, PSTR ( " debug" ) ) != NULL ) {
41123 ll = LogLevel::DEBUG;
42- } else if (strstr (log_level, " info" ) != NULL ) {
124+ } else if (strstr_P (log_level, PSTR ( " info" ) ) != NULL ) {
43125 ll = LogLevel::INFO;
44- } else if (strstr (log_level, " warn" ) != NULL ) {
126+ } else if (strstr_P (log_level, PSTR ( " warn" ) ) != NULL ) {
45127 ll = LogLevel::WARN;
46- } else if (strstr (log_level, " error" ) != NULL ) {
128+ } else if (strstr_P (log_level, PSTR ( " error" ) ) != NULL ) {
47129 ll = LogLevel::ERROR;
48- }
49-
50- if (ll == LogLevel::NONE) {
130+ } else {
51131 return false ;
52132 }
53133
54134 this ->setLogLevel (ll);
135+
55136 return true ;
56137}
57138
58139void LogClass::begin (const uint32_t baud_rate) { this ->uart ->begin (baud_rate); }
59140
60141void LogClass::end (void ) { this ->uart ->end (); }
61142
62- void LogClass::info (const char str[]) {
63- if (log_level >= LogLevel::INFO) {
64- this ->print (str, INFO_LEVEL_FMT);
65- }
66- }
67-
68- void LogClass::info (const String str) { this ->info (str.c_str ()); }
69-
70- void LogClass::infof (const char * format, ...) {
71- if (log_level >= LogLevel::INFO) {
72-
73- // Append format with [ERROR]
74- char nFormat[strlen (format) + sizeof (INFO_LEVEL_FMT)] = INFO_LEVEL_FMT;
75- strcpy (nFormat + sizeof (INFO_LEVEL_FMT) - 1 , format);
143+ void LogClass::error (const char str[]) { this ->print (LogLevel::ERROR, str); }
76144
77- FILE f;
78- va_list ap;
79-
80- fdev_setup_stream (&f, printf_putchar, NULL , _FDEV_SETUP_WRITE);
81- fdev_set_udata (&f, this ->uart );
145+ void LogClass::error (const String str) {
146+ this ->print (LogLevel::ERROR, str.c_str ());
147+ }
82148
83- va_start (ap, nFormat);
84- vfprintf (&f, nFormat, ap);
85- va_end (ap);
86- }
149+ void LogClass::error (const __FlashStringHelper* str) {
150+ this ->print (LogLevel::ERROR, str);
87151}
88152
89- void LogClass::debug (const char str[]) {
90- if (log_level >= LogLevel::DEBUG) {
91- this ->print (str, DEBUG_LEVEL_FMT);
92- }
153+ void LogClass::errorf (const char * format, ...) {
154+ va_list args;
155+ va_start (args, format);
156+ this ->printf (LogLevel::ERROR, format, args);
157+ va_end (args);
93158}
94159
95- void LogClass::debug (const String str) { this ->debug (str.c_str ()); }
160+ void LogClass::errorf (const __FlashStringHelper* format, ...) {
161+ va_list args;
162+ va_start (args, format);
163+ this ->printf (LogLevel::ERROR, format, args);
164+ va_end (args);
165+ }
96166
97- void LogClass::debugf (const char * format, ...) {
98- if (log_level >= LogLevel::DEBUG) {
167+ void LogClass::warn (const char str[]) { this ->print (LogLevel::WARN, str); }
99168
100- // Append format with [ERROR]
101- char nFormat[strlen (format) + sizeof (DEBUG_LEVEL_FMT)] =
102- DEBUG_LEVEL_FMT;
103- strcpy (nFormat + sizeof (DEBUG_LEVEL_FMT) - 1 , format);
169+ void LogClass::warn (const String str) {
170+ this ->print (LogLevel::WARN, str.c_str ());
171+ }
104172
105- FILE f;
106- va_list ap;
173+ void LogClass::warn (const __FlashStringHelper* str) {
174+ this ->print (LogLevel::WARN, str);
175+ }
107176
108- fdev_setup_stream (&f, printf_putchar, NULL , _FDEV_SETUP_WRITE);
109- fdev_set_udata (&f, this ->uart );
110- va_start (ap, nFormat);
111- vfprintf (&f, nFormat, ap);
112- va_end (ap);
113- }
177+ void LogClass::warnf (const char * format, ...) {
178+ va_list args;
179+ va_start (args, format);
180+ this ->printf (LogLevel::WARN, format, args);
181+ va_end (args);
114182}
115183
116- void LogClass::raw (const char str[]) { this ->print (str, " " ); }
184+ void LogClass::warnf (const __FlashStringHelper* format, ...) {
185+ va_list args;
186+ va_start (args, format);
187+ this ->printf (LogLevel::WARN, format, args);
188+ va_end (args);
189+ }
117190
118- void LogClass::raw (const String str) { this ->raw ( str. c_str () ); }
191+ void LogClass::info (const char str[] ) { this ->print (LogLevel::INFO, str); }
119192
120- void LogClass::rawf (const char * format, ... ) {
121- FILE f ;
122- va_list ap;
193+ void LogClass::info (const String str ) {
194+ this -> print (LogLevel::INFO, str. c_str ()) ;
195+ }
123196
124- fdev_setup_stream (&f, printf_putchar, NULL , _FDEV_SETUP_WRITE);
125- fdev_set_udata (&f, this ->uart );
126- va_start (ap, format);
127- vfprintf (&f, format, ap);
128- va_end (ap);
197+ void LogClass::info (const __FlashStringHelper* str) {
198+ this ->print (LogLevel::INFO, str);
129199}
130200
131- void LogClass::error (const char str[]) {
132- if (log_level >= LogLevel::ERROR) {
133- this ->print (str, ERR_LEVEL_FMT);
134- }
201+ void LogClass::infof (const char * format, ...) {
202+ va_list args;
203+ va_start (args, format);
204+ this ->printf (LogLevel::INFO, format, args);
205+ va_end (args);
135206}
136207
137- void LogClass::error (const String str) { this ->error (str.c_str ()); }
208+ void LogClass::infof (const __FlashStringHelper* format, ...) {
209+ va_list args;
210+ va_start (args, format);
211+ this ->printf (LogLevel::INFO, format, args);
212+ va_end (args);
213+ }
138214
139- void LogClass::errorf (const char * format, ...) {
140- if (log_level >= LogLevel::ERROR) {
215+ void LogClass::debug (const char str[]) { this ->print (LogLevel::DEBUG, str); }
141216
142- // Append format with [ERROR]
143- char nFormat[ strlen (format) + sizeof (ERR_LEVEL_FMT)] = ERR_LEVEL_FMT ;
144- strcpy (nFormat + sizeof (ERR_LEVEL_FMT) - 1 , format);
217+ void LogClass::debug ( const String str) {
218+ this -> print (LogLevel::DEBUG, str. c_str ()) ;
219+ }
145220
146- FILE f;
147- va_list ap;
221+ void LogClass::debug (const __FlashStringHelper* str) {
222+ this ->print (LogLevel::DEBUG, str);
223+ }
148224
149- fdev_setup_stream (&f, printf_putchar, NULL , _FDEV_SETUP_WRITE);
150- fdev_set_udata (&f, this ->uart );
151- va_start (ap, nFormat);
152- vfprintf (&f, nFormat, ap);
153- va_end (ap);
154- }
225+ void LogClass::debugf (const char * format, ...) {
226+ va_list args;
227+ va_start (args, format);
228+ this ->printf (LogLevel::DEBUG, format, args);
229+ va_end (args);
155230}
156231
157- void LogClass::warn (const char str[]) {
158- if (log_level >= LogLevel::WARN) {
159- this ->print (str, WARN_LEVEL_FMT);
160- }
232+ void LogClass::debugf (const __FlashStringHelper* format, ...) {
233+ va_list args;
234+ va_start (args, format);
235+ this ->printf (LogLevel::DEBUG, format, args);
236+ va_end (args);
161237}
162238
163- void LogClass::warn (const String str) { this ->warn ( str. c_str () ); }
239+ void LogClass::raw (const char str[] ) { this ->print (LogLevel::NONE, str); }
164240
165- void LogClass::warnf (const char * format, ...) {
166- if (log_level >= LogLevel::WARN) {
241+ void LogClass::raw (const String str) {
242+ this ->print (LogLevel::NONE, str.c_str ());
243+ }
167244
168- // Append format with [ERROR]
169- char nFormat[ strlen (format) + sizeof (WARN_LEVEL_FMT)] = WARN_LEVEL_FMT ;
170- strcpy (nFormat + sizeof (WARN_LEVEL_FMT) - 1 , format);
245+ void LogClass::raw ( const __FlashStringHelper* str) {
246+ this -> print (LogLevel::NONE, str) ;
247+ }
171248
172- FILE f;
173- va_list ap;
249+ void LogClass::rawf (const char * format, ...) {
250+ va_list args;
251+ va_start (args, format);
252+ this ->printf (LogLevel::NONE, format, args);
253+ va_end (args);
254+ }
174255
175- fdev_setup_stream (&f, printf_putchar, NULL , _FDEV_SETUP_WRITE);
176- fdev_set_udata (&f, this ->uart );
177- va_start (ap, nFormat);
178- vfprintf (&f, nFormat, ap);
179- va_end (ap);
180- }
256+ void LogClass::rawf (const __FlashStringHelper* format, ...) {
257+ va_list args;
258+ va_start (args, format);
259+ this ->printf (LogLevel::NONE, format, args);
260+ va_end (args);
181261}
182262
183263#pragma GCC diagnostic pop
0 commit comments