Reputation: 2343
Is there a way to make the log-level checking in my LOGGING
-macro (shown below) to happen during compile-time? It should be possible as it is already known during compile time whether the condition (if (pLogLevel <= LOG_LEVEL)) is true or false. Here is an example of how the macro could be used:
LOGGING(LOG_DEBUG, "FALSE - Wrong Marker\n");
Originally I thought that #if
directives within a #define
could help me, but this article showed me that this would not be possible. This is the source code to my problem:
#ifndef __LOGGING_H__
#define __LOGGING_H__ 1
#include <time.h>
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERROR 3
#define LOG_WARN 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DEBUG 7
#define LOG_NONE 8
/* set the global logging level here */
#define LOG_LEVEL LOG_INFO
void print_timestamp(void);
#if LOG_LEVEL == LOG_DEBUG
#define _LOG_PREAMBLE \
fprintf(stdout, "%s:%d ", __FILE__, __LINE__);
#else
#define _LOG_PREAMBLE \
print_timestamp();
#endif
#if LOG_LEVEL == LOG_EMERG
#define _LOG_LEVEL fprintf(stdout, "EMERG ");
#elif LOG_LEVEL == LOG_ALERT
#define _LOG_LEVEL fprintf(stdout, "ALERT ");
#elif LOG_LEVEL == LOG_CRIT
#define _LOG_LEVEL fprintf(stdout, "CRIT ");
#elif LOG_LEVEL == LOG_ERROR
#define _LOG_LEVEL fprintf(stdout, "ERROR ");
#elif LOG_LEVEL == LOG_WARN
#define _LOG_LEVEL fprintf(stdout, "WARN ");
#elif LOG_LEVEL == LOG_NOTICE
#define _LOG_LEVEL fprintf(stdout, "NOTICE ");
#elif LOG_LEVEL == LOG_INFO
#define _LOG_LEVEL fprintf(stdout, "INFO ");
#elif LOG_LEVEL == LOG_INFO
#define _LOG_LEVEL fprintf(stdout, "DEBUG ");
#else
#define _LOG_LEVEL
#endif
#define LOGGING(pLogLevel, ...) \
/* change this to compile time conditional if possible */ \
if (pLogLevel <= LOG_LEVEL) \
{ \
_LOG_PREAMBLE \
_LOG_LEVEL \
fprintf(stdout, ##__VA_ARGS__); \
}
#endif /* __LOGGING_H__ */
Upvotes: 2
Views: 2285
Reputation: 17583
One approach would be to combine the log level into the logging macro.
This would create a set of macros that would be turned on or off depending on the log level.
You would use these macros and they would appear or not depending on the log level at the time of the compile. So they would be used like the following.
LOGGING_LEVEL_DEBUG("a Debug log.");
//.... some code
LOGGING_LEVEL_EMERG("a Emerge log.");
So the macros definitions would look something like the following:
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERROR 3
#define LOG_WARN 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DEBUG 7
#define LOG_NONE 8
/* set the global logging level here */
#define LOG_LEVEL LOG_INFO
void print_timestamp(void);
#if LOG_LEVEL >= LOG_DEBUG
#define _LOG_PREAMBLE \
fprintf(stdout, "%s:%d ", __FILE__, __LINE__);
#else
#define _LOG_PREAMBLE \
print_timestamp();
#endif
#if LOG_LEVEL >= LOG_EMERG
#define LOGGING_LEVEL_EMERG(...) \
{ \
_LOG_PREAMBLE \
fprintf(stdout, "EMERG "); \
fprintf(stdout, ##__VA_ARGS__); \
}
#else
#define LOGGING_LEVEL_EMERG(...)
#endif
#if LOG_LEVEL >= LOG_ALERT
#define LOGGING_LEVEL_ALERT(...) \
{ \
_LOG_PREAMBLE \
fprintf(stdout, "ALERT "); \
fprintf(stdout, ##__VA_ARGS__); \
}
#else
#define LOGGING_LEVEL_ALERT(...)
#endif
Upvotes: 2
Reputation: 477040
You could define the macros themselves conditionally:
#if LOG_LEVEL > 0
# define LOG(...) printf(__VA_ARGS__)
#else
# define LOG(...)
#endif
#if LOG_LEVEL > 1
// and so forth
Upvotes: 0