aboutsummaryrefslogtreecommitdiff
path: root/dynstr.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2020-08-03 23:47:18 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2020-08-03 23:47:18 +0200
commitfe3c74983c4ffc00d27e72cd76785f7bf2fefb47 (patch)
treeb3e6082098f4b8263185e1b71c7c58b567b732aa /dynstr.c
parent3b94bbd2bd9e391ab0dcb8a116403f9d537c9886 (diff)
downloaddynstr-fe3c74983c4ffc00d27e72cd76785f7bf2fefb47.tar.gz
dynstr_prepend(), fixed typo in comment
Diffstat (limited to 'dynstr.c')
-rw-r--r--dynstr.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/dynstr.c b/dynstr.c
index 847b75f..97f03bc 100644
--- a/dynstr.c
+++ b/dynstr.c
@@ -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)