Use __builtin_strrchr to get file base name

Prior to this change, pinelog used __FILE__ in the backtrace call.
However, this has a limitation that if used in a build system with
sources in subdirectories and/or a separate build directory, the
relative path to the file is used, giving us a backtrace like this.

    ../../daemon/x52d_main.c:51

This change checks if the compiler supports the __builtin_strrchr to
compute the file basename at compile time. If the compiler does not
support it, it falls back to using __FILE__ directly. This should not be
an issue on a modern compiler like gcc or clang.
master
nirenjan 2021-08-25 12:11:53 -07:00
parent aa0a5545d0
commit 204aadead0
2 changed files with 24 additions and 7 deletions

View File

@ -134,34 +134,44 @@ void pinelog_log_message(int level, const char *file, int line, const char *fmt,
#define pinelog_exit exit #define pinelog_exit exit
#endif #endif
// Base filename
#if defined __has_builtin
# if __has_builtin(__builtin_strrchr)
# define PINELOG_FILE __builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__
# endif
#endif
#ifndef PINELOG_FILE
# define PINELOG_FILE __FILE__
#endif
#define PINELOG_FATAL(fmt, ...) do { \ #define PINELOG_FATAL(fmt, ...) do { \
if (PINELOG_LVL_FATAL <= pinelog_get_level()) { \ if (PINELOG_LVL_FATAL <= pinelog_get_level()) { \
pinelog_log_message(PINELOG_LVL_FATAL, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \ pinelog_log_message(PINELOG_LVL_FATAL, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
} \ } \
pinelog_exit(1); \ pinelog_exit(1); \
} while (0) } while (0)
#define PINELOG_ERROR(fmt, ...) do { \ #define PINELOG_ERROR(fmt, ...) do { \
if (PINELOG_LVL_ERROR <= pinelog_get_level()) { \ if (PINELOG_LVL_ERROR <= pinelog_get_level()) { \
pinelog_log_message(PINELOG_LVL_ERROR, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \ pinelog_log_message(PINELOG_LVL_ERROR, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
} \ } \
} while (0) } while (0)
#define PINELOG_WARN(fmt, ...) do { \ #define PINELOG_WARN(fmt, ...) do { \
if (PINELOG_LVL_WARNING <= pinelog_get_level()) { \ if (PINELOG_LVL_WARNING <= pinelog_get_level()) { \
pinelog_log_message(PINELOG_LVL_WARNING, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \ pinelog_log_message(PINELOG_LVL_WARNING, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
} \ } \
} while(0) } while(0)
#define PINELOG_INFO(fmt, ...) do { \ #define PINELOG_INFO(fmt, ...) do { \
if (PINELOG_LVL_INFO <= pinelog_get_level()) { \ if (PINELOG_LVL_INFO <= pinelog_get_level()) { \
pinelog_log_message(PINELOG_LVL_INFO, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \ pinelog_log_message(PINELOG_LVL_INFO, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
} \ } \
} while(0) } while(0)
#define PINELOG_DEBUG(fmt, ...) do { \ #define PINELOG_DEBUG(fmt, ...) do { \
if (PINELOG_LVL_DEBUG <= pinelog_get_level()) { \ if (PINELOG_LVL_DEBUG <= pinelog_get_level()) { \
pinelog_log_message(PINELOG_LVL_DEBUG, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \ pinelog_log_message(PINELOG_LVL_DEBUG, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
} \ } \
} while(0) } while(0)
@ -169,7 +179,7 @@ void pinelog_log_message(int level, const char *file, int line, const char *fmt,
#ifndef PINELOG_DISABLE_TRACE #ifndef PINELOG_DISABLE_TRACE
#define PINELOG_TRACE(fmt, ...) do { \ #define PINELOG_TRACE(fmt, ...) do { \
if (PINELOG_LVL_TRACE <= pinelog_get_level()) { \ if (PINELOG_LVL_TRACE <= pinelog_get_level()) { \
pinelog_log_message(PINELOG_LVL_TRACE, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \ pinelog_log_message(PINELOG_LVL_TRACE, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
} \ } \
} while(0) } while(0)
#else #else

View File

@ -98,9 +98,16 @@ static int test_setup(int level, int filter, const char *file, int line)
} }
if (PINELOG_SHOW_BACKTRACE) { if (PINELOG_SHOW_BACKTRACE) {
char * basename = strrchr(file, '/');
if (basename != NULL) {
basename++;
} else {
// Override the const
basename = (char *)file;
}
expected_len += snprintf(&expected_output[expected_len], expected_len += snprintf(&expected_output[expected_len],
sizeof(expected_output) - expected_len, sizeof(expected_output) - expected_len,
"%s:%d ", file, line); "%s:%d ", basename, line);
} }
return 1; return 1;