Mercurial > code
changeset 672:c49478852aaf
buf: now separate library
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 24 Mar 2022 07:29:36 +0100 |
parents | 2bee2b6b6386 |
children | a7c0227f64f5 |
files | c/buf/Makefile c/buf/buf-test.c c/buf/buf.c.in c/buf/buf.h.in |
diffstat | 4 files changed, 0 insertions(+), 917 deletions(-) [+] |
line wrap: on
line diff
--- a/c/buf/Makefile Thu Mar 24 07:29:22 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -# -# Makefile -- simple string buffer for C -# -# Copyright (c) 2016-2019 David Demelier <markand@malikania.fr> -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -.POSIX: - -CC= cc -SED= sed -CFLAGS= -O3 -DNDEBUG -NAMESPACE= - -NAMESPACE_L= `echo ${NAMESPACE} | tr "[[:upper:]]" "[[:lower:]]"` -NAMESPACE_U= `echo ${NAMESPACE} | tr "[[:lower:]]" "[[:upper:]]"` - -INCS= -I../../extern/libgreatest - -all: ${NAMESPACE}buf.h ${NAMESPACE}buf.c - -${NAMESPACE}buf.h ${NAMESPACE}buf.c: buf.h.in buf.c.in - sed "s/%ns%/${NAMESPACE_L}/g;s/%NS%/${NAMESPACE_U}/g" < buf.h.in > ${NAMESPACE}buf.h - sed "s/%ns%/${NAMESPACE_L}/g;s/%NS%/${NAMESPACE_U}/g" < buf.c.in > ${NAMESPACE}buf.c - -buf-test: buf.h buf.c buf-test.c - ${CC} ${INCS} ${CFLAGS} buf.c buf-test.c -o $@ ${LDFLAGS} - -tests: buf-test - ./buf-test - -clean: - rm -f buf.h buf.c buf-test - -.PHONY: all clean tests
--- a/c/buf/buf-test.c Thu Mar 24 07:29:22 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,302 +0,0 @@ -/* - * test.c -- test basic buffers - * - * Copyright (c) 2016-2019 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define GREATEST_USE_ABBREVS 0 -#include <greatest.h> - -#include "buf.h" - -GREATEST_TEST -init(void) -{ - struct buf b; - - /* No allocation with buf_init. */ - buf_init(&b); - GREATEST_ASSERT(!b.data); - GREATEST_ASSERT(!b.capacity); - GREATEST_ASSERT(!b.length); - - /* Must stay zero'ed. */ - buf_finish(&b); - GREATEST_ASSERT(!b.data); - GREATEST_ASSERT(!b.capacity); - GREATEST_ASSERT(!b.length); - - GREATEST_PASS(); -} - -GREATEST_SUITE(basics) -{ - GREATEST_RUN_TEST(init); -} - -GREATEST_TEST -reserve(void) -{ - struct buf b; - - /* Reserve allocates but does not change length. */ - buf_init(&b); - buf_reserve(&b, 100U); - GREATEST_ASSERT(b.data); - GREATEST_ASSERT_EQ(b.length, 0U); - GREATEST_ASSERT_EQ(b.capacity, 100U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_TEST -resize(void) -{ - struct buf b; - - /* Resize actually change the length with the specified character. */ - buf_init(&b); - buf_resize(&b, 10, 'a'); - GREATEST_ASSERT_STR_EQ(b.data, "aaaaaaaaaa"); - GREATEST_ASSERT_EQ(b.length, 10U); - GREATEST_ASSERT_EQ(b.capacity, 10U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_TEST -shrink(void) -{ - struct buf b; - - /* Reserve and then shrink, it should be 0. */ - buf_init(&b); - buf_reserve(&b, 10U); - buf_shrink(&b); - GREATEST_ASSERT(b.data); - GREATEST_ASSERT_EQ(b.length, 0U); - GREATEST_ASSERT_EQ(b.capacity, 0U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_SUITE(allocs) -{ - GREATEST_RUN_TEST(reserve); - GREATEST_RUN_TEST(resize); -} - -GREATEST_TEST -output_char(void) -{ - struct buf b; - - buf_init(&b); - - /* This will allocate one byte and then increase by power of two. */ - buf_putc(&b, 'a'); - GREATEST_ASSERT_STR_EQ(b.data, "a"); - GREATEST_ASSERT_EQ(b.length, 1U); - GREATEST_ASSERT_EQ(b.capacity, 1U); - - buf_putc(&b, 'b'); - GREATEST_ASSERT_STR_EQ(b.data, "ab"); - GREATEST_ASSERT_EQ(b.length, 2U); - GREATEST_ASSERT_EQ(b.capacity, 2U); - - buf_putc(&b, 'c'); - GREATEST_ASSERT_STR_EQ(b.data, "abc"); - GREATEST_ASSERT_EQ(b.length, 3U); - GREATEST_ASSERT_EQ(b.capacity, 4U); - - /* No reallocation since there is still one byte left. */ - buf_putc(&b, 'd'); - GREATEST_ASSERT_STR_EQ(b.data, "abcd"); - GREATEST_ASSERT_EQ(b.length, 4U); - GREATEST_ASSERT_EQ(b.capacity, 4U); - - /* New reallocation here. */ - buf_putc(&b, 'e'); - GREATEST_ASSERT_STR_EQ(b.data, "abcde"); - GREATEST_ASSERT_EQ(b.length, 5U); - GREATEST_ASSERT_EQ(b.capacity, 8U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_TEST -output_string(void) -{ - struct buf b; - - buf_init(&b); - - /* This will allocate an initial buffer of 10. */ - buf_puts(&b, "abcdefghij"); - GREATEST_ASSERT_STR_EQ(b.data, "abcdefghij"); - GREATEST_ASSERT_EQ(b.length, 10U); - GREATEST_ASSERT_EQ(b.capacity, 10U); - - /* This will multiply the capacity to 20 and increase length to 14. */ - buf_puts(&b, "klmn"); - GREATEST_ASSERT_STR_EQ(b.data, "abcdefghijklmn"); - GREATEST_ASSERT_EQ(b.length, 14U); - GREATEST_ASSERT_EQ(b.capacity, 20U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_TEST -output_printf(void) -{ - struct buf b; - - buf_init(&b); - - /* This will allocate string of 6 characters. */ - buf_printf(&b, "%d%d", 123, 456); - GREATEST_ASSERT_STR_EQ(b.data, "123456"); - GREATEST_ASSERT_EQ(b.length, 6U); - GREATEST_ASSERT_EQ(b.capacity, 6U); - - /* This will multiply the capacity to 12 and increase length to 10. */ - buf_printf(&b, "%s", "hoho"); - GREATEST_ASSERT_STR_EQ(b.data, "123456hoho"); - GREATEST_ASSERT_EQ(b.length, 10U); - GREATEST_ASSERT_EQ(b.capacity, 12U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_SUITE(output) -{ - GREATEST_RUN_TEST(output_char); - GREATEST_RUN_TEST(output_string); - GREATEST_RUN_TEST(output_printf); -} - -GREATEST_TEST -clones_sub(void) -{ - struct buf b = { 0 }; - struct buf s1, s2; - - buf_puts(&b, "0123456789"); - - /* Copy only the portion from 1 to 3. */ - buf_sub(&s1, &b, 1, 3); - GREATEST_ASSERT_STR_EQ(s1.data, "123"); - GREATEST_ASSERT_EQ(s1.length, 3U); - GREATEST_ASSERT_EQ(s1.capacity, 3U); - buf_finish(&s1); - - /* Copy whole string starting from 4. */ - buf_sub(&s2, &b, 4, -1); - GREATEST_ASSERT_STR_EQ(s2.data, "456789"); - GREATEST_ASSERT_EQ(s2.length, 6U); - GREATEST_ASSERT_EQ(s2.capacity, 6U); - buf_finish(&s2); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_TEST -clones_dup(void) -{ - struct buf b = { 0 }; - struct buf d; - - buf_puts(&b, "0123456789"); - buf_dup(&d, &b); - GREATEST_ASSERT(b.data != d.data); - GREATEST_ASSERT_STR_EQ(d.data, "0123456789"); - GREATEST_ASSERT_EQ(d.length, 10U); - GREATEST_ASSERT_EQ(d.capacity, 10U); - buf_finish(&d); - - GREATEST_PASS(); -} - -GREATEST_SUITE(clones) -{ - GREATEST_RUN_TEST(clones_sub); - GREATEST_RUN_TEST(clones_dup); -} - -GREATEST_TEST -misc_erase(void) -{ - struct buf b = { 0 }; - - buf_puts(&b, "0123456789"); - - /* Only remove portion from 1 to 3, capacity must not change. */ - buf_erase(&b, 1, 3); - GREATEST_ASSERT_STR_EQ(b.data, "0456789"); - GREATEST_ASSERT_EQ(b.length, 7U); - GREATEST_ASSERT_EQ(b.capacity, 10U); - - /* Remove from 4 to the end. */ - buf_erase(&b, 1, -1); - GREATEST_ASSERT_STR_EQ(b.data, "0"); - GREATEST_ASSERT_EQ(b.length, 1U); - GREATEST_ASSERT_EQ(b.capacity, 10U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_TEST -misc_clear(void) -{ - struct buf b = { 0 }; - - /* Clear should only reduce the length capacity must not change. */ - buf_puts(&b, "hello world"); - buf_clear(&b); - GREATEST_ASSERT_STR_EQ(b.data, ""); - GREATEST_ASSERT_EQ(b.length, 0U); - GREATEST_ASSERT_EQ(b.capacity, 11U); - buf_finish(&b); - - GREATEST_PASS(); -} - -GREATEST_SUITE(misc) -{ - GREATEST_RUN_TEST(misc_erase); - GREATEST_RUN_TEST(misc_clear); -} - -GREATEST_MAIN_DEFS(); - -int -main(int argc, char **argv) -{ - GREATEST_MAIN_BEGIN(); - GREATEST_RUN_SUITE(basics); - GREATEST_RUN_SUITE(allocs); - GREATEST_RUN_SUITE(output); - GREATEST_RUN_SUITE(clones); - GREATEST_RUN_SUITE(misc); - GREATEST_MAIN_END(); -}
--- a/c/buf/buf.c.in Thu Mar 24 07:29:22 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,331 +0,0 @@ -/* - * %ns%buf.c -- simple string buffer for C - * - * Copyright (c) 2016-2019 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "%ns%buf.h" - -/* - * User/developer options. - * - * - %NS%BUF_MALLOC: defaults to malloc - * - %NS%BUF_REALLOC: defaults to realloc - * - %NS%BUF_FREE: defaults to free - */ - -#if !defined(%NS%BUF_MALLOC) -# define %NS%BUF_MALLOC malloc -#endif - -#if !defined(%NS%BUF_REALLOC) -# define %NS%BUF_REALLOC realloc -#endif - -#if !defined(%NS%BUF_FREE) -# define %NS%BUF_FREE free -#endif - -/* - * Try to increase the buffer length by a power of two until we have enough - * space to fit `desired'. - * - * Detects overflow and return false if happened or reallocation could not - * occur. - */ -static bool -growdbl(struct %ns%buf *b, size_t desired) -{ - size_t newcap = b->capacity; - void *newptr; - - while (desired > newcap - b->length) { - const size_t r = newcap * 2; - - if (r / newcap != 2) { - errno = EOVERFLOW; - return false; - } - - newcap = r; - } - - /* At this step we must have enough room. */ - assert(newcap - b->length >= desired); - - if (!(newptr = %NS%BUF_REALLOC(b->data, newcap + 1))) - return false; - - b->data = newptr; - b->capacity = newcap; - - return true; -} - -/* - * Try to allocate just enough space for the `desired' amount of space. This is - * only used when the buffer is already too large but hasn't reached SIZE_MAX - * yet. - * - * Returns false if allocation failed. - */ -static bool -growmin(struct %ns%buf *b, size_t desired) -{ - size_t newcap; - void *newptr; - - if (desired >= SIZE_MAX - b->length) { - errno = ENOMEM; - return false; - } - - /* Don't forget to keep what's remaining between capacity and length. */ - newcap = b->capacity + (desired - (b->capacity - b->length)); - - /* Try to reallocate. */ - if (!(newptr = %NS%BUF_REALLOC(b->data, newcap + 1))) - return false; - - b->data = newptr; - b->capacity = newcap; - - return true; -} - -static bool -grow(struct %ns%buf *b, size_t desired) -{ - const size_t avail = b->capacity - b->length; - - if (avail >= desired) - return true; - - if (!b->capacity) { - if (!(b->data = %NS%BUF_MALLOC(desired + 1))) - return false; - - b->capacity = desired; - } else if (!growdbl(b, desired) && !growmin(b, desired)) - return false; - - return true; -} - -void -%ns%buf_init(struct %ns%buf *b) -{ - assert(b); - - memset(b, 0, sizeof (struct %ns%buf)); -} - -bool -%ns%buf_reserve(struct %ns%buf *b, size_t amount) -{ - if (!grow(b, amount)) - return false; - - return true; -} - -bool -%ns%buf_resize(struct %ns%buf *b, size_t amount, char ch) -{ - if (!grow(b, amount)) - return false; - - memset(&b->data[b->length], ch, amount); - b->length += amount; - b->data[b->length] = 0; - - return true; -} - -bool -%ns%buf_shrink(struct %ns%buf *b) -{ - void *newptr = %NS%BUF_REALLOC(b->data, b->length + 1); - - if (!newptr) - return false; - - b->data = newptr; - b->capacity = b->length; - - return true; -} - -void -%ns%buf_erase(struct %ns%buf *b, size_t pos, size_t count) -{ - assert(b); - assert(pos <= b->length); - - if (count > b->length - pos) { - /* Optimize whole erase at pos. */ - b->data[pos] = 0; - b->length = pos; - } else { - memmove(&b->data[pos], &b->data[pos + count], b->length - count); - b->length -= count; - } -} - -bool -%ns%buf_putc(struct %ns%buf *b, char c) -{ - assert(b); - - if (!grow(b, 1)) - return false; - - b->data[b->length++] = c; - b->data[b->length] = 0; - - return true; -} - -bool -%ns%buf_puts(struct %ns%buf *b, const char *s) -{ - assert(b); - assert(s); - - const size_t len = strlen(s); - - if (!grow(b, len)) - return false; - - strcpy(&b->data[b->length], s); - b->length += len; - - return true; -} - -bool -%ns%buf_printf(struct %ns%buf *b, const char *fmt, ...) -{ - assert(b); - assert(fmt); - - va_list ap; - bool ret; - - va_start(ap, fmt); - ret = %ns%buf_vprintf(b, fmt, ap); - va_end(ap); - - return ret; -} - -bool -%ns%buf_vprintf(struct %ns%buf *b, const char *fmt, va_list args) -{ - assert(b); - assert(fmt); - - va_list ap; - int amount; - - /* Determine length. */ - va_copy(ap, args); - amount = vsnprintf(NULL, 0, fmt, ap); - va_end(ap); - - if (amount < 0) - return false; - - /* Do actual copy. */ - if (!grow(b, amount)) - return false; - - va_copy(ap, args); - amount = vsprintf(&b->data[b->length], fmt, ap); - va_end(ap); - - if (amount < 0) - return false; - - b->length += amount; - - return true; -} - -bool -%ns%buf_sub(struct %ns%buf *b, const struct %ns%buf *src, size_t pos, size_t count) -{ - assert(b); - assert(src); - assert(pos <= src->length); - - memset(b, 0, sizeof (struct %ns%buf)); - - if (count >= src->length) - count = src->length - pos; - if (!(b->data = %NS%BUF_MALLOC(count + 1))) - return false; - - strncpy(b->data, &src->data[pos], count); - b->length = count; - b->capacity = count; - b->data[b->length] = 0; - - return true; -} - -bool -%ns%buf_dup(struct %ns%buf *b, const struct %ns%buf *src) -{ - assert(b); - assert(src); - - memset(b, 0, sizeof (struct %ns%buf)); - - if (!(b->data = %NS%BUF_MALLOC(src->length + 1))) - return false; - - strcpy(b->data, src->data); - b->capacity = src->length; - b->length = src->length; - - return true; -} - -void -%ns%buf_clear(struct %ns%buf *b) -{ - assert(b); - - if (b->data) - b->data[b->length = 0] = 0; -} - -void -%ns%buf_finish(struct %ns%buf *b) -{ - assert(b); - - %NS%BUF_FREE(b->data); - b->data = NULL; - b->capacity = b->length = 0; -}
--- a/c/buf/buf.h.in Thu Mar 24 07:29:22 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* - * %ns%buf.h -- simple string buffer for C - * - * Copyright (c) 2016-2019 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef %NS%BUF_H -#define %NS%BUF_H - -/** - * \file %ns%buf.h - * \brief Simple string buffer for C - * - * This module is meant to be copied directly into your source code and adapted - * to your needs. - * - * # Allocation strategy - * - * This module will always try to allocate twice the existing buffer capacity - * unless it reaches an overflow. If overflow occurs, it will try to reallocate - * only the required portion instead. In any case, on 64-bits machine the - * maximum number is usually around 18.5PB which is far from what the system - * will allow. - * - * Functions use standard `malloc(3)`, `realloc(3)` and `free(3)` functions, if - * custom allocations are desired, simply edit %ns%buf.c and adapt BUF_ macros - * at the top of the file. - */ - -#include <stdarg.h> -#include <stdbool.h> -#include <stddef.h> - -/** - * \brief Buffer structure. - * - * You can initialize this structure with 0 before use. - * - * You may modify the data member yourself but make sure length member is set - * accordingly if you change its length. - * - * The capacity member contains the available size **without** including the - * null terminator, this means that a capacity of 5 means you can write 5 - * characters plus the null terminator as every function always allocate one - * more byte to terminate strings. - */ -struct %ns%buf { - char *data; /*!< (RW) String data. */ - size_t length; /*!< (RO) String length */ - size_t capacity; /*!< (RO) Capacity **not** including null */ -}; - -/** - * Initialize the string. - * - * This is equivalent to `memset(b, 0, sizeof (struct buf))`. - * - * \pre b != NULL - * \param b the buffer to initialize to 0 - */ -void -%ns%buf_init(struct %ns%buf *b); - -/** - * Reserve more storage to avoid reallocations. - * - * This function only change capacity and may reallocate the buffer, length - * is unchanged. - * - * \pre b != NULL - * \param b the buffer to grow - * \param desired the additional space to request - * \return false on error and sets errno - */ -bool -%ns%buf_reserve(struct %ns%buf *b, size_t desired); - -/** - * Resize the string and sets character into the new storage area. - * - * In contrast to \ref %ns%buf_reserve, this function change the string length - * and update the new storage with the given character. Use '\0' if you only - * want to change the length. - * - * \pre b != NULL - * \param b the buffer to grow - * \param desired the additional space to request - * \param ch the character to fill (use '\0' if not needed) - * \return false on error and sets errno - */ -bool -%ns%buf_resize(struct %ns%buf *b, size_t desired, char ch); - -/** - * Reallocate the string to the string's length. - * - * If the function could not reallocate the memory, the old string buffer is - * kept so it is not strictly necessary to check the result. - * - * \pre b != NULL - * \param b the buffer to grow - * \return true if the string buffer was actually shrinked - */ -bool -%ns%buf_shrink(struct %ns%buf *b); - -/** - * Erase a portion of the string. - * - * \pre b != NULL - * \pre pos <= b->length - * \param b the string buffer - * \param pos the beginning of the portion - * \param count the number of characters to remove or -1 to remove up to the end - */ -void -%ns%buf_erase(struct %ns%buf *b, size_t pos, size_t count); - -/** - * Put a single character. - * - * \note This function can be slow for large amount of data - * \pre b != NULL - * \param b the string buffer - * \param c the character to append - * \return false on error and sets errno - */ -bool -%ns%buf_putc(struct %ns%buf *b, char c); - -/** - * Put a string. - * - * \pre b != NULL - * \pre s != NULL - * \param b the string buffer - * \param s the string to append - * \return false on error and sets errno - */ -bool -%ns%buf_puts(struct %ns%buf *b, const char *s); - -/** - * Append to the string using printf(3) format. - * - * \pre b != NULL - * \pre fmt != NULL - * \param b the string buffer - * \param fmt the printf(3) format string - * \param ... additional arguments - * \return false on error and sets errno - */ -bool -%ns%buf_printf(struct %ns%buf *b, const char *fmt, ...); - -/** - * Similar to \ref %ns%buf_printf but using `va_list`. - * - * \pre b != NULL - * \pre fmt != NULL - * \param b the string buffer - * \param fmt the printf(3) format string - * \param ap the variadic arguments pointer - * \return false on error and sets errno - */ -bool -%ns%buf_vprintf(struct %ns%buf *b, const char *fmt, va_list ap); - -/** - * Cut a portion of the string pointed by src into b. - * - * The pointer b must not contain data as it will be overriden and may be let - * uninitialized. - * - * \pre b != NULL - * \pre src != NULL - * \pre pos <= b->length - * \param b the string buffer - * \param src the source origin - * \param pos the beginning of the portion - * \param count the number of characters to remove or -1 to split up to the end - * \return false on error and sets errno - */ -bool -%ns%buf_sub(struct %ns%buf *b, const struct %ns%buf *src, size_t pos, size_t count); - -/** - * Duplicate a string buffer. - * - * The pointer b must not contain data as it will be overriden and may be let - * uninitialized. - * - * \pre b != NULL - * \pre src != NULL - * \param b the string buffer - * \param src the source origin - * \return false on error and sets errno - */ -bool -%ns%buf_dup(struct %ns%buf *b, const struct %ns%buf *src); - -/** - * Clear the buffer. - * - * This function only change the string length, use \ref %ns%buf_shrink if you - * want to reduce memory usage. - * - * \pre b != NULL - * \param b the string to update - */ -void -%ns%buf_clear(struct %ns%buf *b); - -/** - * Clear the buffer. - * - * This function will effectively free the data member and set all members to - * 0. - * - * \pre b != NULL - * \param b the buffer to clear - */ -void -%ns%buf_finish(struct %ns%buf *b); - -#endif /* !%NS%BUF_H */