Skip to content

Commit 6982156

Browse files
authored
Merge pull request #36 from sunxfancy/dev
Bugfix: log every and log first macro implementations
2 parents 7305395 + 1d4afff commit 6982156

File tree

3 files changed

+61
-43
lines changed

3 files changed

+61
-43
lines changed

include/zeroerr/log.h

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
#include "zeroerr/print.h"
1010

1111
#include <chrono>
12+
#include <iosfwd>
1213
#include <map>
1314
#include <string>
1415
#include <vector>
15-
#include <iosfwd>
1616

1717
ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
1818

@@ -80,7 +80,7 @@ namespace zeroerr {
8080

8181
#define ZEROERR_LOG_EVERY_(n, ACTION, ...) \
8282
do { \
83-
unsigned counter = 0; \
83+
static unsigned counter = 0; \
8484
if (counter == 0) { \
8585
counter = n; \
8686
ACTION(__VA_ARGS__); \
@@ -98,12 +98,14 @@ namespace zeroerr {
9898

9999
#define ZEROERR_LOG_IF_EVERY_(n, cond, ACTION, ...) \
100100
do { \
101-
unsigned counter = 0; \
102-
if (counter == 0 && (cond)) { \
103-
counter = n; \
104-
ACTION(__VA_ARGS__); \
101+
if (cond) { \
102+
static unsigned counter = 0; \
103+
if (counter == 0) { \
104+
counter = n; \
105+
ACTION(__VA_ARGS__); \
106+
} \
107+
--counter; \
105108
} \
106-
--counter; \
107109
} while (0)
108110

109111
#define INFO_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_INFO, __VA_ARGS__)
@@ -114,7 +116,7 @@ namespace zeroerr {
114116

115117
#define ZEROERR_LOG_FIRST(cond, ACTION, ...) \
116118
do { \
117-
bool first = true; \
119+
static bool first = true; \
118120
if (first && (cond)) { \
119121
first = false; \
120122
ACTION(__VA_ARGS__); \
@@ -129,8 +131,9 @@ namespace zeroerr {
129131

130132
#define ZEROERR_LOG_FIRST_(n, cond, ACTION, ...) \
131133
do { \
132-
unsigned counter = n; \
133-
if (n-- && (cond)) { \
134+
static unsigned counter = n; \
135+
if (counter && (cond)) { \
136+
counter--; \
134137
ACTION(__VA_ARGS__); \
135138
} \
136139
} while (0)
@@ -227,24 +230,24 @@ enum LogSeverity {
227230

228231
/**
229232
* @brief LogInfo is a struct to store the meta data of the log message.
230-
* @details LogInfo is a struct to store the meta data of the log message.
233+
* @details LogInfo is a struct to store the meta data of the log message.
231234
* It contains filename, function, message, category, line number, size, and severity.
232235
* Those data is initialized when the first log message is created using a static
233236
* local variable in the function where the log message is put.
234-
*
237+
*
235238
* For example:
236239
* void foo() {
237240
* log("Hello, {name}!", "John");
238241
* }
239-
*
240-
* The inner implementation could be considered as (not exactly
242+
*
243+
* The inner implementation could be considered as (not exactly
241244
* since message is allocated from a pool):
242245
* void foo() {
243-
* static LogInfo log_info{
244-
* __FILE__, __func__, "Hello, {name}!",
245-
* ZEROERR_LOG_CATEGORY,
246-
* __LINE__,
247-
* sizeof("Hello, world!"),
246+
* static LogInfo log_info{
247+
* __FILE__, __func__, "Hello, {name}!",
248+
* ZEROERR_LOG_CATEGORY,
249+
* __LINE__,
250+
* sizeof("Hello, world!"),
248251
* LogSeverity::INFO_l);
249252
* LogMessage* logdata = new LogMessageImpl<std::string>("John");
250253
* logdata->info = &log_info;
@@ -498,11 +501,11 @@ class LogStream {
498501
* The log message is structured as a tuple of the arguments in the inner
499502
* implementation class LogMessageImpl. After the log message is created, it
500503
* used type erasure to return a LogMessage pointer to the caller.
501-
*
504+
*
502505
* The stored data type is determined by the to_store_type_t<T> template.
503506
* For all the string type in raw pointer like const char* or char[],
504507
* it will be converted to std::string.
505-
* All reference type (including right value reference) will be converted
508+
* All reference type (including right value reference) will be converted
506509
* to the original type.
507510
*/
508511
template <typename... T>

test/log_test.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,19 @@ TEST_CASE("log_test") {
2020
ERR_IF(1 == 1, "1 == 1");
2121

2222
for (int i = 0; i < 10; ++i) {
23-
LOG_EVERY_(3, "log every 3 times {i}", i);
23+
LOG_EVERY_(3, "log every 3 times: {i}", i);
24+
}
25+
26+
for (int i = 0; i < 10; ++i) {
27+
LOG_FIRST(i % 2 == 0, "log first even number: {i}", i);
28+
}
29+
30+
for (int i = 0; i < 10; ++i) {
31+
LOG_FIRST(i % 2 == 1, "log first odd number: {i}", i);
32+
}
33+
34+
for (int i = 0; i < 10; ++i) {
35+
LOG_IF_EVERY_(3, i % 2 == 1, "log every 3 times odd number: {i}", i);
2436
}
2537
}
2638

zeroerr.hpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3387,10 +3387,10 @@ std::string format(const char* fmt, T... args) {
33873387

33883388

33893389
#include <chrono>
3390+
#include <iosfwd>
33903391
#include <map>
33913392
#include <string>
33923393
#include <vector>
3393-
#include <iosfwd>
33943394

33953395
ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
33963396

@@ -3458,7 +3458,7 @@ namespace zeroerr {
34583458

34593459
#define ZEROERR_LOG_EVERY_(n, ACTION, ...) \
34603460
do { \
3461-
unsigned counter = 0; \
3461+
static unsigned counter = 0; \
34623462
if (counter == 0) { \
34633463
counter = n; \
34643464
ACTION(__VA_ARGS__); \
@@ -3476,12 +3476,14 @@ namespace zeroerr {
34763476

34773477
#define ZEROERR_LOG_IF_EVERY_(n, cond, ACTION, ...) \
34783478
do { \
3479-
unsigned counter = 0; \
3480-
if (counter == 0 && (cond)) { \
3481-
counter = n; \
3482-
ACTION(__VA_ARGS__); \
3479+
if (cond) { \
3480+
static unsigned counter = 0; \
3481+
if (counter == 0) { \
3482+
counter = n; \
3483+
ACTION(__VA_ARGS__); \
3484+
} \
3485+
--counter; \
34833486
} \
3484-
--counter; \
34853487
} while (0)
34863488

34873489
#define INFO_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_INFO, __VA_ARGS__)
@@ -3492,7 +3494,7 @@ namespace zeroerr {
34923494

34933495
#define ZEROERR_LOG_FIRST(cond, ACTION, ...) \
34943496
do { \
3495-
bool first = true; \
3497+
static bool first = true; \
34963498
if (first && (cond)) { \
34973499
first = false; \
34983500
ACTION(__VA_ARGS__); \
@@ -3507,8 +3509,9 @@ namespace zeroerr {
35073509

35083510
#define ZEROERR_LOG_FIRST_(n, cond, ACTION, ...) \
35093511
do { \
3510-
unsigned counter = n; \
3511-
if (n-- && (cond)) { \
3512+
static unsigned counter = n; \
3513+
if (counter && (cond)) { \
3514+
counter--; \
35123515
ACTION(__VA_ARGS__); \
35133516
} \
35143517
} while (0)
@@ -3605,24 +3608,24 @@ enum LogSeverity {
36053608

36063609
/**
36073610
* @brief LogInfo is a struct to store the meta data of the log message.
3608-
* @details LogInfo is a struct to store the meta data of the log message.
3611+
* @details LogInfo is a struct to store the meta data of the log message.
36093612
* It contains filename, function, message, category, line number, size, and severity.
36103613
* Those data is initialized when the first log message is created using a static
36113614
* local variable in the function where the log message is put.
3612-
*
3615+
*
36133616
* For example:
36143617
* void foo() {
36153618
* log("Hello, {name}!", "John");
36163619
* }
3617-
*
3618-
* The inner implementation could be considered as (not exactly
3620+
*
3621+
* The inner implementation could be considered as (not exactly
36193622
* since message is allocated from a pool):
36203623
* void foo() {
3621-
* static LogInfo log_info{
3622-
* __FILE__, __func__, "Hello, {name}!",
3623-
* ZEROERR_LOG_CATEGORY,
3624-
* __LINE__,
3625-
* sizeof("Hello, world!"),
3624+
* static LogInfo log_info{
3625+
* __FILE__, __func__, "Hello, {name}!",
3626+
* ZEROERR_LOG_CATEGORY,
3627+
* __LINE__,
3628+
* sizeof("Hello, world!"),
36263629
* LogSeverity::INFO_l);
36273630
* LogMessage* logdata = new LogMessageImpl<std::string>("John");
36283631
* logdata->info = &log_info;
@@ -3876,11 +3879,11 @@ class LogStream {
38763879
* The log message is structured as a tuple of the arguments in the inner
38773880
* implementation class LogMessageImpl. After the log message is created, it
38783881
* used type erasure to return a LogMessage pointer to the caller.
3879-
*
3882+
*
38803883
* The stored data type is determined by the to_store_type_t<T> template.
38813884
* For all the string type in raw pointer like const char* or char[],
38823885
* it will be converted to std::string.
3883-
* All reference type (including right value reference) will be converted
3886+
* All reference type (including right value reference) will be converted
38843887
* to the original type.
38853888
*/
38863889
template <typename... T>

0 commit comments

Comments
 (0)