aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2020-10-08 08:41:22 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2020-10-08 11:24:24 +0200
commitc862d84d0b6827106a53bc571c81eb523b05c50f (patch)
tree1583dabc26fd09226f9032e218e06fa022704154
parent8bd1123857aef03c9aefb0658e3a8a562984a52e (diff)
Add dynstr_vprepend
-rw-r--r--dynstr.c61
-rw-r--r--include/dynstr.h13
2 files changed, 42 insertions, 32 deletions
diff --git a/dynstr.c b/dynstr.c
index e9ef185..92930f2 100644
--- a/dynstr.c
+++ b/dynstr.c
@@ -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.