diff --git a/log.c b/log.c index 241d8e57..2d486ebb 100644 --- a/log.c +++ b/log.c @@ -243,31 +243,11 @@ static void _log_prefix(_log_iterator *it, int level) } } -static const char *_trimbuildpath(const char *path) -{ - /* Remove common path prefix */ - int lastsep = 0; - int i; - for (i = 0; __FILE__[i] && path[i]; ++i) { - if (i && path[i - 1] == '/') - lastsep = i; - if (__FILE__[i] != path[i]) - break; - } - return &path[lastsep]; -} - static void _log_prefix_whence(_log_iterator *it, struct __sourceloc whence) { - if (whence.file && whence.file[0]) { - xprintf(it->xpf, "%s", _trimbuildpath(whence.file)); - if (whence.line) - xprintf(it->xpf, ":%u", whence.line); - if (whence.function) - xprintf(it->xpf, ":%s()", whence.function); + if ((whence.file && whence.file[0]) || (whence.function && whence.function[0])) { + xprint_sourceloc(it->xpf, whence); xputs(" ", it->xpf); - } else if (whence.function && whence.function[0]) { - xprintf(it->xpf, "%s() ", whence.function); } } diff --git a/strbuf_helpers.c b/strbuf_helpers.c index 08276624..ef498394 100644 --- a/strbuf_helpers.c +++ b/strbuf_helpers.c @@ -67,6 +67,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "strbuf_helpers.h" #include "str.h" #include "socket.h" +#include "whence.h" static inline strbuf _toprint(strbuf sb, char c) { @@ -151,6 +152,12 @@ strbuf strbuf_toprint_quoted(strbuf sb, const char quotes[2], const char *str) return _overrun_quote(sb, quotes ? quotes[1] : '\0', "..."); } +strbuf strbuf_append_sourceloc(strbuf sb, struct __sourceloc loc) +{ + xprint_sourceloc(XPRINTF_STRBUF(sb), loc); + return sb; +} + strbuf strbuf_path_join(strbuf sb, ...) { va_list ap; diff --git a/strbuf_helpers.h b/strbuf_helpers.h index 71e79aa6..ea89395c 100644 --- a/strbuf_helpers.h +++ b/strbuf_helpers.h @@ -56,6 +56,12 @@ strbuf strbuf_toprint_quoted_len(strbuf sb, const char quotes[2], const char *bu */ strbuf strbuf_toprint_quoted(strbuf sb, const char quotes[2], const char *str); +/* Append a symbolic representation of a struct __sourceloc. + * @author Andrew Bettison + */ +struct __sourceloc; +strbuf strbuf_append_sourceloc(strbuf sb, struct __sourceloc); + /* Join Unix file path segments together with separator characters '/' to form * a complete path. Any segment that starts with '/' is taken as the start of * an absolute path, and all prior segments are discarded. diff --git a/whence.c b/whence.c index bec7b442..48732f79 100644 --- a/whence.c +++ b/whence.c @@ -17,5 +17,54 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "whence.h" +#include "strbuf.h" +#include "strbuf_helpers.h" const struct __sourceloc __whence = __NOWHERE__; + +char *sourceloc_tostr(char *dstStr, ssize_t dstBufSiz, struct __sourceloc loc) +{ + strbuf b = strbuf_local(dstStr, dstBufSiz); + strbuf_append_sourceloc(b, loc); + return dstStr; +} + +size_t sourceloc_tostr_len(struct __sourceloc loc) +{ + return strbuf_count(strbuf_append_sourceloc(strbuf_local(NULL, 0), loc)); +} + +static const char *_trimbuildpath(const char *path) +{ + /* Remove common path prefix */ + int lastsep = 0; + int i; + for (i = 0; __FILE__[i] && path[i]; ++i) { + if (i && path[i - 1] == '/') + lastsep = i; + if (__FILE__[i] != path[i]) + break; + } + return &path[lastsep]; +} + +void xprint_sourceloc(XPRINTF xpf, struct __sourceloc loc) +{ + int flag = 0; + if (loc.file && loc.file[0]) { + xprintf(xpf, "%s", _trimbuildpath(loc.file)); + ++flag; + } + if (loc.line) { + if (flag) + xputc(':', xpf); + xprintf(xpf, "%u", loc.line); + ++flag; + } + if (loc.function && loc.function[0]) { + if (flag) + xputc(':', xpf); + xprintf(xpf, "%s()", loc.function); + ++flag; + } +} diff --git a/whence.h b/whence.h index 07b271f0..16805298 100644 --- a/whence.h +++ b/whence.h @@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define __SERVAL_DNA__WHENCE_H #include // for NULL +#include +#include "xprintf.h" /* * Every log message identifies the location in the source code at which the @@ -80,4 +82,11 @@ extern const struct __sourceloc __whence; // see above #define __NOWHENCE__ ((struct __sourceloc){ .file = "", .line = 0, .function = NULL }) #define __WHENCE__ (__whence.file ? __whence : __HERE__) +void xprint_sourceloc(XPRINTF, struct __sourceloc); + +#define alloca_str_sourceloc(s) (sourceloc_tostr(alloca(sourceloc_tostr_len(s) + 1), (s))) + +extern char *sourceloc_tostr(char *dstStr, ssize_t dstBufSiz, struct __sourceloc); +extern size_t sourceloc_tostr_len(struct __sourceloc); + #endif // __SERVAL_DNA__WHENCE_H