1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 // This is test verifies that the logging backend:
16 //
17 // - Compiles as plain C
18 // - Runs when compiled as C
19 //
20 // Unfortunately, since we do not know where the log sink actually goes, the
21 // logging functionality itself is not verified beyond compiling and running.
22
23 #define PW_LOG_MODULE_NAME "CTS"
24
25 #include "pw_log/log.h"
26
27 #ifdef __cplusplus
28 #error "This file must be compiled as plain C to verify C compilation works."
29 #endif // __cplusplus
30
LoggingFromFunctionPlainC(void)31 static void LoggingFromFunctionPlainC(void) { PW_LOG_INFO("From a function!"); }
32
33 static void CustomFormatStringTest(void);
34
BasicLogTestPlainC(void)35 void BasicLogTestPlainC(void) {
36 int n = 3;
37
38 // Debug level
39 PW_LOG_DEBUG("This log statement should be at DEBUG level; no args");
40 for (int i = 0; i < n; ++i) {
41 PW_LOG_DEBUG("Counting: %d", i);
42 }
43 PW_LOG_DEBUG("Here is a string: %s; with another string %s", "foo", "bar");
44
45 // Info level
46 PW_LOG_INFO("This log statement should be at INFO level; no args");
47 for (int i = 0; i < n; ++i) {
48 PW_LOG_INFO("Counting: %d", i);
49 }
50 PW_LOG_INFO("Here is a string: %s; with another string %s", "foo", "bar");
51
52 // Warn level
53 PW_LOG_WARN("This log statement should be at WARN level; no args");
54 for (int i = 0; i < n; ++i) {
55 PW_LOG_WARN("Counting: %d", i);
56 }
57 PW_LOG_WARN("Here is a string: %s; with another string %s", "foo", "bar");
58
59 // Error level.
60 PW_LOG_ERROR("This log statement should be at ERROR level; no args");
61 for (int i = 0; i < n; ++i) {
62 PW_LOG_ERROR("Counting: %d", i);
63 }
64 PW_LOG_ERROR("Here is a string: %s; with another string %s", "foo", "bar");
65
66 // Critical level.
67 PW_LOG_CRITICAL("This log is the last one; device should reboot");
68
69 // Core log macro, with manually specified level and flags.
70 PW_LOG(PW_LOG_LEVEL_DEBUG,
71 PW_LOG_LEVEL,
72 PW_LOG_MODULE_NAME,
73 0,
74 "A manual DEBUG-level message");
75 PW_LOG(PW_LOG_LEVEL_DEBUG,
76 PW_LOG_LEVEL,
77 PW_LOG_MODULE_NAME,
78 1,
79 "A manual DEBUG-level message; with a flag");
80
81 PW_LOG(PW_LOG_LEVEL_INFO,
82 PW_LOG_LEVEL,
83 PW_LOG_MODULE_NAME,
84 0,
85 "A manual INFO-level message");
86 PW_LOG(PW_LOG_LEVEL_INFO,
87 PW_LOG_LEVEL,
88 PW_LOG_MODULE_NAME,
89 1,
90 "A manual INFO-level message; with a flag");
91
92 PW_LOG(PW_LOG_LEVEL_WARN,
93 PW_LOG_LEVEL,
94 PW_LOG_MODULE_NAME,
95 0,
96 "A manual WARN-level message");
97 PW_LOG(PW_LOG_LEVEL_WARN,
98 PW_LOG_LEVEL,
99 PW_LOG_MODULE_NAME,
100 1,
101 "A manual WARN-level message; with a flag");
102
103 PW_LOG(PW_LOG_LEVEL_ERROR,
104 PW_LOG_LEVEL,
105 PW_LOG_MODULE_NAME,
106 0,
107 "A manual ERROR-level message");
108 PW_LOG(PW_LOG_LEVEL_ERROR,
109 PW_LOG_LEVEL,
110 PW_LOG_MODULE_NAME,
111 1,
112 "A manual ERROR-level message; with a flag");
113
114 PW_LOG(PW_LOG_LEVEL_CRITICAL,
115 PW_LOG_LEVEL,
116 PW_LOG_MODULE_NAME,
117 0,
118 "A manual CRITICAL-level message");
119 PW_LOG(PW_LOG_LEVEL_CRITICAL,
120 PW_LOG_LEVEL,
121 PW_LOG_MODULE_NAME,
122 1,
123 "A manual CRITICAL-level message; with a flag");
124
125 // Log levels other than the standard ones work; what each backend does is
126 // implementation defined.
127 PW_LOG(
128 0, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, "Custom log level: 0");
129 PW_LOG(
130 1, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, "Custom log level: 1");
131 PW_LOG(
132 2, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, "Custom log level: 2");
133 PW_LOG(
134 3, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, "Custom log level: 3");
135 PW_LOG(100,
136 PW_LOG_LEVEL,
137 PW_LOG_MODULE_NAME,
138 PW_LOG_FLAGS,
139 "Custom log level: 100");
140
141 // Logging from a function.
142 LoggingFromFunctionPlainC();
143
144 // Changing the module name mid-file.
145 #undef PW_LOG_MODULE_NAME
146 #define PW_LOG_MODULE_NAME "XYZ"
147 PW_LOG_INFO("This has a custom module name");
148 PW_LOG_INFO("So does this");
149
150 CustomFormatStringTest();
151 }
152
153 #undef PW_LOG
154 #define PW_LOG(level, verbosity, module, flags, message, ...) \
155 DoNothingFakeFunction(module, \
156 "%d/%d/%d: incoming transmission [" message "]", \
157 level, \
158 __LINE__, \
159 flags PW_COMMA_ARGS(__VA_ARGS__))
160
161 static void DoNothingFakeFunction(const char* module, const char* f, ...)
162 PW_PRINTF_FORMAT(2, 3);
163
DoNothingFakeFunction(const char * module,const char * f,...)164 static void DoNothingFakeFunction(const char* module, const char* f, ...) {
165 (void)module;
166 (void)f;
167 }
168
CustomFormatStringTest(void)169 static void CustomFormatStringTest(void) {
170 PW_LOG_DEBUG("Abc");
171 PW_LOG_INFO("Abc %d", 123);
172 PW_LOG_WARN("Abc %d %s", 123, "four");
173 }
174