Add dynstr_vprepend

This commit is contained in:
Xavier Del Campo Romero 2020-10-08 08:41:22 +02:00
parent 8bd1123857
commit c862d84d0b
2 changed files with 48 additions and 38 deletions

View File

@ -60,49 +60,46 @@ enum dynstr_err dynstr_append(struct dynstr *const d, const char *const format,
return dynstr_vappend(d, format, ap);
}
enum dynstr_err dynstr_vprepend(struct dynstr *const d, const char *const format, va_list ap)
{
const size_t src_len = vsnprintf(NULL, 0, format, ap);
const size_t new_len = d->len + src_len + 1;
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];
}
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);
{
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;
return dynstr_vprepend(d, format, ap);
}
enum dynstr_err dynstr_dup(struct dynstr *const dst, const struct dynstr *const src)

View File

@ -134,6 +134,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