diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2020-10-08 08:41:22 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2020-10-08 11:24:24 +0200 |
| commit | c862d84d0b6827106a53bc571c81eb523b05c50f (patch) | |
| tree | 1583dabc26fd09226f9032e218e06fa022704154 | |
| parent | 8bd1123857aef03c9aefb0658e3a8a562984a52e (diff) | |
Add dynstr_vprepend
| -rw-r--r-- | dynstr.c | 61 | ||||
| -rw-r--r-- | include/dynstr.h | 13 |
2 files changed, 42 insertions, 32 deletions
@@ -60,51 +60,48 @@ enum dynstr_err dynstr_append(struct dynstr *const d, const char *const format, return dynstr_vappend(d, format, ap); } -enum dynstr_err dynstr_prepend(struct dynstr *const d, const char *const format, ...) +enum dynstr_err dynstr_vprepend(struct dynstr *const d, const char *const format, va_list ap) { - va_list ap; + const size_t src_len = vsnprintf(NULL, 0, format, ap); + const size_t new_len = d->len + src_len + 1; - va_start(ap, format); + d->str = realloc(d->str, new_len * sizeof *d->str); + if (d->str && d->len) { - 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]; - } + /* Keep byte that will be removed by later call to vsprintf. */ + const char c = *d->str; - 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 + for (size_t i = new_len - 1, j = d->len; j <= d->len; i--, j--) { - return DYNSTR_ERR_ALLOC; + d->str[i] = d->str[j]; } - d->len += src_len; + vsprintf(d->str, format, ap); + d->str[src_len] = c; + } + else if (!d->len) + { + vsprintf(d->str + d->len, format, ap); + } + else + { + return DYNSTR_ERR_ALLOC; } + va_end(ap); + d->len += src_len; return DYNSTR_OK; } +enum dynstr_err dynstr_prepend(struct dynstr *const d, const char *const format, ...) +{ + va_list ap; + + va_start(ap, format); + return dynstr_vprepend(d, format, ap); +} + 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 2c36865..38c05c5 100644 --- a/include/dynstr.h +++ b/include/dynstr.h @@ -135,6 +135,19 @@ enum dynstr_err dynstr_vappend(struct dynstr *d, const char *format, va_list ap) enum dynstr_err dynstr_prepend(struct dynstr *d, const char *format, ...); /** + * This function takes a string literal in printf format and a variable + * argument list, 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. + * @param ap Variable argument list. + * @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_vprepend(struct dynstr *d, const char *format, va_list ap); + +/** * This function duplicates a dynamic string to another instance. * @attention Destination instance must be initialized before calling * this function. |
