aboutsummaryrefslogtreecommitdiff
path: root/dynstr.c
diff options
context:
space:
mode:
authorXaviDCR92 <xavi.dcr@tutanota.com>2020-03-21 13:14:48 +0100
committerXaviDCR92 <xavi.dcr@tutanota.com>2020-03-21 13:14:48 +0100
commit34643b8a8d954b77d1928f39f380e3c09b05e7dc (patch)
treee382b10966d891e9f4b51a9ffd00848c8415c006 /dynstr.c
parent0cc52ff5be45ec4c5e2c427261b46dab9d9b77be (diff)
downloaddynstr-34643b8a8d954b77d1928f39f380e3c09b05e7dc.tar.gz
Various changes and improvements
- Replaced int by specific, more meaningful error codes. - C99 states realloc can be safely called using NULL pointers. - New function dynstr_dup().
Diffstat (limited to 'dynstr.c')
-rw-r--r--dynstr.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/dynstr.c b/dynstr.c
index 8779fbf..025f1fc 100644
--- a/dynstr.c
+++ b/dynstr.c
@@ -26,7 +26,7 @@ void dynstr_init(struct dynstr *const d)
memset(d, 0, sizeof *d);
}
-int dynstr_append(struct dynstr *const d, const char *const format, ...)
+enum dynstr_err dynstr_append(struct dynstr *const d, const char *const format, ...)
{
va_list ap;
@@ -34,19 +34,10 @@ int dynstr_append(struct dynstr *const d, const char *const format, ...)
{
const size_t src_len = vsnprintf(NULL, 0, format, ap);
- size_t new_len;
+ const size_t new_len = d->len + src_len + 1;
va_end(ap);
- if (!d->str)
- {
- new_len = src_len + 1;
- d->str = malloc(new_len * sizeof *d->str);
- }
- else
- {
- new_len = d->len + src_len + 1;
- d->str = realloc(d->str, new_len * sizeof *d->str);
- }
+ d->str = realloc(d->str, new_len * sizeof *d->str);
if (d->str)
{
@@ -57,11 +48,43 @@ int dynstr_append(struct dynstr *const d, const char *const format, ...)
}
else
{
- return 1;
+ return DYNSTR_ERR_ALLOC;
}
}
- return 0;
+ return DYNSTR_OK;
+}
+
+enum dynstr_err dynstr_dup(struct dynstr *const dst, const struct dynstr *const src)
+{
+ if (!dst->str && !dst->len)
+ {
+ if (src->len && src->str)
+ {
+ const size_t sz = (src->len + 1) * sizeof *dst->str;
+ dst->str = realloc(dst->str, sz);
+
+ if (dst->str)
+ {
+ memcpy(dst->str, src->str, sz);
+ dst->len = src->len;
+ }
+ else
+ {
+ return DYNSTR_ERR_ALLOC;
+ }
+ }
+ else
+ {
+ return DYNSTR_ERR_SRC;
+ }
+ }
+ else
+ {
+ return DYNSTR_ERR_INIT;
+ }
+
+ return DYNSTR_OK;
}
void dynstr_free(struct dynstr *const d)