137Srgrimes/* This file is automatically generated. DO NOT EDIT! */ 237Srgrimes/* Generated from: NetBSD: mknative-gdb,v 1.16 2023/07/31 17:09:59 christos Exp */ 337Srgrimes/* Generated from: NetBSD: mknative.common,v 1.16 2018/04/15 15:13:37 christos Exp */ 437Srgrimes 537Srgrimes/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ 637Srgrimes/* Variable-sized buffer with on-stack default allocation. 737Srgrimes Copyright (C) 2015-2022 Free Software Foundation, Inc. 837Srgrimes This file is part of the GNU C Library. 937Srgrimes 103190Spst The GNU C Library is free software; you can redistribute it and/or 115170Sache modify it under the terms of the GNU Lesser General Public 1237Srgrimes License as published by the Free Software Foundation; either 133196Spst version 2.1 of the License, or (at your option) any later version. 1437Srgrimes 1537Srgrimes The GNU C Library is distributed in the hope that it will be useful, 16377Srgrimes but WITHOUT ANY WARRANTY; without even the implied warranty of 1737Srgrimes MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 189775Sache Lesser General Public License for more details. 1937Srgrimes 2037Srgrimes You should have received a copy of the GNU Lesser General Public 2137Srgrimes License along with the GNU C Library; if not, see 2237Srgrimes <https://www.gnu.org/licenses/>. */ 2337Srgrimes 245183Swollman#ifndef _SCRATCH_BUFFER_H 2537Srgrimes#define _SCRATCH_BUFFER_H 265183Swollman 275183Swollman/* Scratch buffers with a default stack allocation and fallback to 285183Swollman heap allocation. It is expected that this function is used in this 2937Srgrimes way: 3037Srgrimes 3137Srgrimes struct scratch_buffer tmpbuf; 32645Srgrimes scratch_buffer_init (&tmpbuf); 3337Srgrimes 341715Swollman while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) 3537Srgrimes if (!scratch_buffer_grow (&tmpbuf)) 3637Srgrimes return -1; 37591Srgrimes 38500Sjtc scratch_buffer_free (&tmpbuf); 39591Srgrimes return 0; 401662Sache 411662Sache The allocation functions (scratch_buffer_grow, 421662Sache scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make 433169Spst sure that the heap allocation, if any, is freed, so that the code 44831Sats above does not have a memory leak. The buffer still remains in a 45831Sats state that can be deallocated using scratch_buffer_free, so a loop 464652Sats like this is valid as well: 47831Sats 48 struct scratch_buffer tmpbuf; 49 scratch_buffer_init (&tmpbuf); 50 51 while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) 52 if (!scratch_buffer_grow (&tmpbuf)) 53 break; 54 55 scratch_buffer_free (&tmpbuf); 56 57 scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed 58 to grow the buffer by at least 512 bytes. This means that when 59 using the scratch buffer as a backing store for a non-character 60 array whose element size, in bytes, is 512 or smaller, the scratch 61 buffer only has to grow once to make room for at least one more 62 element. 63*/ 64 65#include <stdbool.h> 66#include <stddef.h> 67#include <stdlib.h> 68 69/* Scratch buffer. Must be initialized with scratch_buffer_init 70 before its use. */ 71struct scratch_buffer { 72 void *data; /* Pointer to the beginning of the scratch area. */ 73 size_t length; /* Allocated space at the data pointer, in bytes. */ 74 union { max_align_t __align; char __c[1024]; } __space; 75}; 76 77/* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space 78 and BUFFER->length reflects the available space. */ 79static inline void 80scratch_buffer_init (struct scratch_buffer *buffer) 81{ 82 buffer->data = buffer->__space.__c; 83 buffer->length = sizeof (buffer->__space); 84} 85 86/* Deallocates *BUFFER (if it was heap-allocated). */ 87static inline void 88scratch_buffer_free (struct scratch_buffer *buffer) 89{ 90 if (buffer->data != buffer->__space.__c) 91 free (buffer->data); 92} 93 94/* Grow *BUFFER by some arbitrary amount. The buffer contents is NOT 95 preserved. Return true on success, false on allocation failure (in 96 which case the old buffer is freed). On success, the new buffer is 97 larger than the previous size. On failure, *BUFFER is deallocated, 98 but remains in a free-able state, and errno is set. */ 99bool __libc_scratch_buffer_grow (struct scratch_buffer *buffer); 100 101/* Alias for __libc_scratch_buffer_grow. */ 102static inline _GL_ATTRIBUTE_ALWAYS_INLINE bool 103scratch_buffer_grow (struct scratch_buffer *buffer) 104{ 105 return _GL_LIKELY (__libc_scratch_buffer_grow (buffer)); 106} 107 108/* Like __libc_scratch_buffer_grow, but preserve the old buffer 109 contents on success, as a prefix of the new buffer. */ 110bool __libc_scratch_buffer_grow_preserve (struct scratch_buffer *buffer); 111 112/* Alias for __libc_scratch_buffer_grow_preserve. */ 113static inline _GL_ATTRIBUTE_ALWAYS_INLINE bool 114scratch_buffer_grow_preserve (struct scratch_buffer *buffer) 115{ 116 return _GL_LIKELY (__libc_scratch_buffer_grow_preserve (buffer)); 117} 118 119/* Grow *BUFFER so that it can store at least NELEM elements of SIZE 120 bytes. The buffer contents are NOT preserved. Both NELEM and SIZE 121 can be zero. Return true on success, false on allocation failure 122 (in which case the old buffer is freed, but *BUFFER remains in a 123 free-able state, and errno is set). It is unspecified whether this 124 function can reduce the array size. */ 125bool __libc_scratch_buffer_set_array_size (struct scratch_buffer *buffer, 126 size_t nelem, size_t size); 127 128/* Alias for __libc_scratch_set_array_size. */ 129static inline _GL_ATTRIBUTE_ALWAYS_INLINE bool 130scratch_buffer_set_array_size (struct scratch_buffer *buffer, 131 size_t nelem, size_t size) 132{ 133 return _GL_LIKELY (__libc_scratch_buffer_set_array_size 134 (buffer, nelem, size)); 135} 136 137/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block, 138 deallocating *BUFFER if it was heap-allocated. SIZE must be at 139 most *BUFFER's size. Return NULL (setting errno) on memory 140 exhaustion. */ 141void *__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, 142 size_t size); 143 144/* Alias for __libc_scratch_dupfree. */ 145static inline _GL_ATTRIBUTE_ALWAYS_INLINE void * 146scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) 147{ 148 void *r = __libc_scratch_buffer_dupfree (buffer, size); 149 return _GL_LIKELY (r != NULL) ? r : NULL; 150} 151 152#endif /* _SCRATCH_BUFFER_H */ 153