-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFF_Trace.cpp
More file actions
133 lines (114 loc) · 3.64 KB
/
FF_Trace.cpp
File metadata and controls
133 lines (114 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*!
\file
\brief Implements a centralized trace class
\author Flying Domotic
Have a look at FF_Trace.h for details.
Please prefer using macro in FF_Trace.h instead of calling class directly.
*/
#include "FF_Trace.h"
/*!
Class initialization
*/
FF_Trace::FF_Trace() {
// Clear all callbacks
for (uint8_t i = 0; i < FF_TRACE_MAX_TRACE; i++) {
callbacks[i] = NULL;
}
// Init level to info
currentLevel = FF_TRACE_LEVEL_INFO;
}
/*!
Register one callback to call when a message should be displayed
/param _callback: callback routine to be called when a message is to be displayed
*/
void FF_Trace::registerCallback(const traceCallback_t _callback) {
// Find an empty slot to insert callback
for (uint8_t i = 0; i < FF_TRACE_MAX_TRACE; i++) {
if (callbacks[i] == NULL) {
callbacks[i] = _callback;
return;
}
// No slot available, do nothing...
}
}
/*!
Send a message to all registered routines using printf format
A first try is done with a 200 bytes buffer.
If too short, a sufficiently long one is dynamically allocated.
IF dynamic allocation fails, only the first 200 bytes of message are displayed.
Else, full message is shown.
/param _level: level associated to this message
/param _file: calling source file name with extension
/param _line: calling source file line
/param _function: calling calling source function name
/param _format: (printf) format string to use
/param ...: associated parameters (depends on format string contents)
*/
#ifndef FF_TRACE_NO_SOURCE_INFO
void FF_Trace::printf(const traceLevel_t _level, const char* _file, const uint16_t _line, const char* _function, const char* _format, ...) {
#else
void FF_Trace::printf(const traceLevel_t _level, const char* _format, ...) {
#endif
// Check level against internal one
if (_level <= currentLevel) {
// Make the message
char msg[200]; // Allocate 200 bytes for message (larger buffer allocated dynamically if needed)
va_list arguments;
va_start(arguments, _format);
int size = vsnprintf(msg, sizeof(msg), _format, arguments);
va_end(arguments);
// Was buffer large enough?
if (size < (int) sizeof(msg)) {
// Call all registered callbacks
for (uint8_t i = 0; i < FF_TRACE_MAX_TRACE; i++) {
if (callbacks[i] != NULL) {
#ifndef FF_TRACE_NO_SOURCE_INFO
(callbacks[i])(_level, _file, _line, _function, msg);
#else
(callbacks[i])(_level, msg);
#endif
}
}
} else {
// Use dynamic buffer allocation (on stack)
char buffer[size+1];
va_list arguments;
va_start(arguments, _format);
vsnprintf(buffer, size, _format, arguments);
va_end(arguments);
// Call all registered callbacks with dynamic string
for (uint8_t i = 0; i < FF_TRACE_MAX_TRACE; i++) {
if (callbacks[i] != NULL) {
#ifndef FF_TRACE_NO_SOURCE_INFO
(callbacks[i])(_level, _file, _line, _function, buffer);
#else
(callbacks[i])(_level, buffer);
#endif
}
}
}
}
}
/*!
Set current message level
/param _level: minimum level required to display message
*/
void FF_Trace::setLevel(const traceLevel_t _level) {
// Save given level
currentLevel = _level;
}
/*!
Return current message level
/return Current stored level
*/
traceLevel_t FF_Trace::getLevel(void) {
// Return internal level
return currentLevel;
}
char * FF_Trace::textLevel(traceLevel_t _level) {
static char unknownValue[] = "????";
if (_level >= FF_TRACE_LEVEL_NONE && _level <= FF_TRACE_LEVEL_VERBOSE) {
return levelName[_level];
}
return unknownValue;
}