diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2020-08-03 23:47:18 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2020-08-03 23:47:18 +0200 |
| commit | fe3c74983c4ffc00d27e72cd76785f7bf2fefb47 (patch) | |
| tree | b3e6082098f4b8263185e1b71c7c58b567b732aa | |
| parent | 3b94bbd2bd9e391ab0dcb8a116403f9d537c9886 (diff) | |
| download | dynstr-fe3c74983c4ffc00d27e72cd76785f7bf2fefb47.tar.gz | |
dynstr_prepend(), fixed typo in comment
| -rw-r--r-- | dynstr.c | 45 | ||||
| -rw-r--r-- | include/dynstr.h | 14 |
2 files changed, 58 insertions, 1 deletions
@@ -59,6 +59,51 @@ enum dynstr_err dynstr_append(struct dynstr *const d, const char *const format, return DYNSTR_OK; } +enum dynstr_err dynstr_prepend(struct dynstr *const d, const char *const format, ...) +{ + va_list ap; + + va_start(ap, format); + + { + const size_t src_len = vsnprintf(NULL, 0, format, ap); + const size_t new_len = d->len + src_len + 1; + va_end(ap); + + d->str = realloc(d->str, new_len * sizeof *d->str); + + if (d->str && d->len) + { + /* Keep byte that will be removed by later call to vsprintf. */ + const char c = *d->str; + + for (size_t i = new_len - 1, j = d->len; j <= d->len; i--, j--) + { + d->str[i] = d->str[j]; + } + + va_start(ap, format); + vsprintf(d->str, format, ap); + va_end(ap); + d->str[src_len] = c; + } + else if (!d->len) + { + va_start(ap, format); + vsprintf(d->str + d->len, format, ap); + va_end(ap); + } + else + { + return DYNSTR_ERR_ALLOC; + } + + d->len += src_len; + } + + return DYNSTR_OK; +} + enum dynstr_err dynstr_dup(struct dynstr *const dst, const struct dynstr *const src) { if (!dst->str && !dst->len) diff --git a/include/dynstr.h b/include/dynstr.h index dcdd8a1..7283de5 100644 --- a/include/dynstr.h +++ b/include/dynstr.h @@ -48,7 +48,7 @@ #define dynstr_append_or_ret_zero(...) if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return 0 /** - * Convenience macro that calls dynstr_append and returns zero if failed. + * Convenience macro that calls dynstr_append and returns one if failed. */ #define dynstr_append_or_ret_nonzero(...) if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return 1 @@ -96,6 +96,18 @@ void dynstr_init(struct dynstr *d); enum dynstr_err dynstr_append(struct dynstr *d, const char *format, ...); /** + * This function takes a string literal in printf format and a variable + * number of arguments, calculates its size and prepends it into the + * beginning of the dynamic string. + * @param d Dynamic string where new string will be prepended. + * @param format String literal in printf format. + * @return Returns one of the following error codes: + * # DYNSTR_OK if successful. + * # DYNSTR_ERR_ALLOC if no more memory is available. + */ +enum dynstr_err dynstr_prepend(struct dynstr *d, const char *format, ...); + +/** * This function duplicates a dynamic string to another instance. * @attention Destination instance must be initialized before calling * this function. |
