diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-05-23 17:03:17 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-05-23 17:03:17 -0400 |
commit | 28bbaeac8058653a4a46ae439c37d251a550f4f9 (patch) | |
tree | 558ad73913a747c1e59b1ac582f5fca0ed20708d | |
parent | ecd079c32272783144d881647f81eea8cce39386 (diff) | |
download | bfs-28bbaeac8058653a4a46ae439c37d251a550f4f9.tar.xz |
dstring: Add a printf()-style creation API
-rw-r--r-- | dstring.c | 28 | ||||
-rw-r--r-- | dstring.h | 14 |
2 files changed, 42 insertions, 0 deletions
@@ -15,6 +15,9 @@ ****************************************************************************/ #include "dstring.h" +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -117,6 +120,31 @@ int dstrapp(char **str, char c) { return dstrcat_impl(str, &c, 1); } +char *dstrprintf(const char *format, ...) { + va_list args; + + va_start(args, format); + int len = vsnprintf(NULL, 0, format, args); + va_end(args); + + assert(len > 0); + + char *str = dstralloc(len); + if (!str) { + return NULL; + } + + va_start(args, format); + len = vsnprintf(str, len + 1, format, args); + va_end(args); + + struct dstring *header = dstrheader(str); + assert(len == header->capacity); + header->length = len; + + return str; +} + void dstrfree(char *dstr) { if (dstr) { free(dstrheader(dstr)); @@ -21,6 +21,7 @@ #ifndef BFS_DSTRING_H #define BFS_DSTRING_H +#include "util.h" #include <stddef.h> /** @@ -106,6 +107,19 @@ int dstrncat(char **dest, const char *src, size_t n); int dstrapp(char **str, char c); /** + * Create a dynamic string from a format string. + * + * @param format + * The format string to fill in. + * @param ... + * Any arguments for the format string. + * @return + * The created string, or NULL on failure. + */ +BFS_FORMATTER(1, 2) +char *dstrprintf(const char *format, ...); + +/** * Free a dynamic string. * * @param dstr |