diff --git a/strbuf_helpers.c b/strbuf_helpers.c index f66c25ed..973bf90f 100644 --- a/strbuf_helpers.c +++ b/strbuf_helpers.c @@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include +#include #include #include #ifdef HAVE_NETINET_IN_H @@ -307,3 +309,28 @@ strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr) } return sb; } + +strbuf strbuf_append_strftime(strbuf sb, const char *format, const struct tm *tm) +{ + // First, try calling strftime(3) directly on the buffer in the strbuf, if there is one and it + // looks to be long enough. + const size_t need = strlen(format); // heuristic, could be better + if (strbuf_str(sb)) { + size_t avail = strbuf_remaining(sb); + if (avail > need) { + size_t n = strftime(strbuf_end(sb), avail + 1, format, tm); + if (n) { + assert(n <= avail); + sb->current += n; + return sb; + } + } + } + // If that didn't work, then call strftime(3) on a temporary buffer and concatenate the result + // into the strbuf. + const size_t len = 500; // should be enough + char *buf = alloca(len + 1); + size_t n = strftime(buf, len + 1, format, tm); + strbuf_ncat(sb, buf, n); + return sb; +} diff --git a/strbuf_helpers.h b/strbuf_helpers.h index 12edbcc8..8a0fc44c 100644 --- a/strbuf_helpers.h +++ b/strbuf_helpers.h @@ -100,7 +100,12 @@ strbuf strbuf_append_exit_status(strbuf sb, int status); */ struct sockaddr; strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *); - #define alloca_sockaddr(addr) strbuf_str(strbuf_append_sockaddr(strbuf_alloca(40), (const struct sockaddr *)(addr))) +/* Append a strftime(3) string. + * @author Andrew Bettison + */ +struct tm; +strbuf strbuf_append_strftime(strbuf sb, const char *format, const struct tm *tm); + #endif //__STRBUF_HELPERS_H__