| /* A buffer that accumulates a string by piecewise concatenation, from the end | |
| to the start. | |
| Copyright (C) 2021-2026 Free Software Foundation, Inc. | |
| This file is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU Lesser General Public License as | |
| published by the Free Software Foundation, either version 3 of the | |
| License, or (at your option) any later version. | |
| This file is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU Lesser General Public License for more details. | |
| You should have received a copy of the GNU Lesser General Public License | |
| along with this program. If not, see <https://www.gnu.org/licenses/>. */ | |
| /* Written by Bruno Haible <bruno@clisp.org>, 2025. */ | |
| /* Before including this file, you may define: | |
| SBR_NO_PREPENDF Provides for more efficient code, assuming that | |
| sbr_prependvf and sbr_prependf will not be called | |
| and that 'struct string_buffer_reversed' instances | |
| are not used across different compilation units. | |
| */ | |
| #ifndef _STRING_BUFFER_REVERSED_H | |
| #define _STRING_BUFFER_REVERSED_H | |
| /* This file uses _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_RETURNS_NONNULL, | |
| _GL_ATTRIBUTE_CAPABILITY_TYPE, _GL_ATTRIBUTE_ACQUIRE_CAPABILITY, | |
| _GL_ATTRIBUTE_RELEASE_CAPABILITY. */ | |
| #if !_GL_CONFIG_H_INCLUDED | |
| #error "Please include config.h first." | |
| #endif | |
| #include <stdarg.h> | |
| #include <stdlib.h> | |
| #include "attribute.h" | |
| #include "string-desc.h" | |
| typedef char * _GL_ATTRIBUTE_CAPABILITY_TYPE ("memory resource") | |
| sbr_heap_allocated_pointer_t; | |
| /* A string buffer type. */ | |
| struct string_buffer_reversed | |
| { | |
| /* data[allocated-length .. allocated-1] are used. */ | |
| sbr_heap_allocated_pointer_t data; | |
| size_t length; /* used bytes, <= allocated */ | |
| size_t allocated; /* allocated bytes */ | |
| bool oom; /* true if there was an out-of-memory error */ | |
| bool error; /* true if there was an error other than out-of-memory */ | |
| char space[1024]; /* stack allocated space */ | |
| }; | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| /* ================== Functions in module 'string-buffer' ================== */ | |
| /* Initializes BUFFER to the empty string. */ | |
| extern void sbr_init (struct string_buffer_reversed *buffer) | |
| _GL_ATTRIBUTE_ACQUIRE_CAPABILITY (buffer->data); | |
| /* Prepends the character C to BUFFER. | |
| Returns 0, or -1 in case of out-of-memory error. */ | |
| extern int sbr_prepend1 (struct string_buffer_reversed *buffer, char c); | |
| /* Prepends the contents of the memory area S to BUFFER. | |
| Returns 0, or -1 in case of out-of-memory error. */ | |
| extern int sbr_prepend_desc (struct string_buffer_reversed *buffer, | |
| string_desc_t s); | |
| /* Prepends the contents of the C string STR to BUFFER. | |
| Returns 0, or -1 in case of out-of-memory error. */ | |
| extern int sbr_prepend_c (struct string_buffer_reversed *buffer, | |
| const char *str); | |
| #ifndef SBR_NO_PREPENDF | |
| /* Prepends the result of the printf-compatible FORMATSTRING with the argument | |
| list LIST to BUFFER. | |
| Returns 0, or -1 with errno set in case of error. | |
| Error code EOVERFLOW can only occur when a width > INT_MAX is used. | |
| Therefore, if the format string is valid and does not use %ls/%lc | |
| directives nor widths, the only possible error code is ENOMEM. */ | |
| extern int sbr_prependvf (struct string_buffer_reversed *buffer, | |
| const char *formatstring, va_list list) | |
| #if (__GNUC__ + (__GNUC_MINOR__ >= 4) > 4) && !defined __clang__ | |
| ATTRIBUTE_FORMAT ((__gnu_printf__, 2, 0)) | |
| #else | |
| ATTRIBUTE_FORMAT ((__printf__, 2, 0)) | |
| #endif | |
| ; | |
| /* Prepends the result of the printf-compatible FORMATSTRING with the following | |
| arguments to BUFFER. | |
| Returns 0, or -1 with errno set in case of error. | |
| Error code EOVERFLOW can only occur when a width > INT_MAX is used. | |
| Therefore, if the format string is valid and does not use %ls/%lc | |
| directives nor widths, the only possible error code is ENOMEM. */ | |
| extern int sbr_prependf (struct string_buffer_reversed *buffer, | |
| const char *formatstring, ...) | |
| #if (__GNUC__ + (__GNUC_MINOR__ >= 4) > 4) && !defined __clang__ | |
| ATTRIBUTE_FORMAT ((__gnu_printf__, 2, 3)) | |
| #else | |
| ATTRIBUTE_FORMAT ((__printf__, 2, 3)) | |
| #endif | |
| ; | |
| #endif | |
| /* Frees the memory held by BUFFER. */ | |
| extern void sbr_free (struct string_buffer_reversed *buffer) | |
| _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data); | |
| /* Returns a read-only view of the current contents of BUFFER. | |
| The result is only valid until the next operation on BUFFER. */ | |
| extern string_desc_t sbr_contents (struct string_buffer_reversed *buffer); | |
| /* Ensures the contents of BUFFER is followed by a NUL byte (without | |
| incrementing the length of the contents). | |
| Then returns a read-only view of the current contents of BUFFER, | |
| that is, the current contents of BUFFER as a C string. | |
| The result is only valid until the next operation on BUFFER. */ | |
| extern const char * sbr_contents_c (struct string_buffer_reversed *buffer); | |
| /* Returns the contents of BUFFER and frees all other memory held by BUFFER. | |
| Returns (0, NULL) upon failure or if there was an error earlier. | |
| It is the responsibility of the caller to sd_free() the result. */ | |
| extern rw_string_desc_t sbr_dupfree (struct string_buffer_reversed *buffer) | |
| _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data); | |
| /* Returns the contents of BUFFER (with an added trailing NUL, that is, | |
| as a C string), and frees all other memory held by BUFFER. | |
| Returns NULL upon failure or if there was an error earlier. | |
| It is the responsibility of the caller to free() the result. */ | |
| extern char * sbr_dupfree_c (struct string_buffer_reversed *buffer) | |
| _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data); | |
| /* ================== Functions in module 'xstring-buffer' ================== */ | |
| #if GNULIB_XSTRING_BUFFER_REVERSED | |
| /* The following functions invoke xalloc_die () in case of out-of-memory | |
| error. */ | |
| /* Prepends the character C to BUFFER. */ | |
| extern void sbr_xprepend1 (struct string_buffer_reversed *buffer, char c); | |
| /* Prepends the contents of the memory area S to BUFFER. */ | |
| extern void sbr_xprepend_desc (struct string_buffer_reversed *buffer, | |
| string_desc_t s); | |
| /* Prepends the contents of the C string STR to BUFFER. */ | |
| extern void sbr_xprepend_c (struct string_buffer_reversed *buffer, | |
| const char *str); | |
| # ifndef SBR_NO_PREPENDF | |
| /* Prepends the result of the printf-compatible FORMATSTRING with the argument | |
| list LIST to BUFFER. | |
| Returns 0, or -1 in case of error other than out-of-memory error. | |
| Error code EOVERFLOW can only occur when a width > INT_MAX is used. | |
| Therefore, if the format string is valid and does not use %ls/%lc | |
| directives nor widths, no error is possible. */ | |
| extern int sbr_xprependvf (struct string_buffer_reversed *buffer, | |
| const char *formatstring, va_list list) | |
| #if (__GNUC__ + (__GNUC_MINOR__ >= 4) > 4) && !defined __clang__ | |
| ATTRIBUTE_FORMAT ((__gnu_printf__, 2, 0)) | |
| #else | |
| ATTRIBUTE_FORMAT ((__printf__, 2, 0)) | |
| #endif | |
| ; | |
| /* Prepends the result of the printf-compatible FORMATSTRING with the following | |
| arguments to BUFFER. | |
| Returns 0, or -1 in case of error other than out-of-memory error. | |
| Error code EOVERFLOW can only occur when a width > INT_MAX is used. | |
| Therefore, if the format string is valid and does not use %ls/%lc | |
| directives nor widths, no error is possible. */ | |
| extern int sbr_xprependf (struct string_buffer_reversed *buffer, | |
| const char *formatstring, ...) | |
| #if (__GNUC__ + (__GNUC_MINOR__ >= 4) > 4) && !defined __clang__ | |
| ATTRIBUTE_FORMAT ((__gnu_printf__, 2, 3)) | |
| #else | |
| ATTRIBUTE_FORMAT ((__printf__, 2, 3)) | |
| #endif | |
| ; | |
| # endif | |
| /* Returns the contents of BUFFER and frees all other memory held by BUFFER. | |
| Returns (0, NULL) if there was an error earlier. | |
| It is the responsibility of the caller to sd_free() the result. */ | |
| extern rw_string_desc_t sbr_xdupfree (struct string_buffer_reversed *buffer) | |
| _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data); | |
| /* Returns the contents of BUFFER (with an added trailing NUL, that is, | |
| as a C string), and frees all other memory held by BUFFER. | |
| Returns NULL if there was an error earlier. | |
| It is the responsibility of the caller to free() the result. */ | |
| extern char * sbr_xdupfree_c (struct string_buffer_reversed *buffer) | |
| _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE | |
| # ifdef SBR_NO_PREPENDF | |
| _GL_ATTRIBUTE_RETURNS_NONNULL /* because buffer->error is always false */ | |
| # endif | |
| _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data); | |
| #endif /* GNULIB_XSTRING_BUFFER_REVERSED */ | |
| /* ========================================================================== */ | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| #endif /* _STRING_BUFFER_REVERSED_H */ |