scratch_buffer.gl.h revision 1.1
1/* This file is automatically generated. DO NOT EDIT! */ 2/* Generated from: NetBSD: mknative-gdb,v 1.16 2023/07/31 17:09:59 christos Exp */ 3/* Generated from: NetBSD: mknative.common,v 1.16 2018/04/15 15:13:37 christos Exp */ 4 5/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ 6/* Variable-sized buffer with on-stack default allocation. 7 Copyright (C) 2015-2022 Free Software Foundation, Inc. 8 This file is part of the GNU C Library. 9 10 The GNU C Library is free software; you can redistribute it and/or 11 modify it under the terms of the GNU Lesser General Public 12 License as published by the Free Software Foundation; either 13 version 2.1 of the License, or (at your option) any later version. 14 15 The GNU C Library is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 Lesser General Public License for more details. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with the GNU C Library; if not, see 22 <https://www.gnu.org/licenses/>. */ 23 24#ifndef _SCRATCH_BUFFER_H 25#define _SCRATCH_BUFFER_H 26 27/* Scratch buffers with a default stack allocation and fallback to 28 heap allocation. It is expected that this function is used in this 29 way: 30 31 struct scratch_buffer tmpbuf; 32 scratch_buffer_init (&tmpbuf); 33 34 while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) 35 if (!scratch_buffer_grow (&tmpbuf)) 36 return -1; 37 38 scratch_buffer_free (&tmpbuf); 39 return 0; 40 41 The allocation functions (scratch_buffer_grow, 42 scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make 43 sure that the heap allocation, if any, is freed, so that the code 44 above does not have a memory leak. The buffer still remains in a 45 state that can be deallocated using scratch_buffer_free, so a loop 46 like this is valid as well: 47 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