113564Sdl/* This file is automatically generated. DO NOT EDIT! */ 213564Sdl/* Generated from: NetBSD: mknative-gdb,v 1.16 2023/07/31 17:09:59 christos Exp */ 313564Sdl/* Generated from: NetBSD: mknative.common,v 1.16 2018/04/15 15:13:37 christos Exp */ 413564Sdl 513564Sdl/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ 613564Sdl/* Variable-sized buffer with on-stack default allocation. 713564Sdl Copyright (C) 2015-2022 Free Software Foundation, Inc. 813564Sdl This file is part of the GNU C Library. 913564Sdl 1013564Sdl The GNU C Library is free software; you can redistribute it and/or 1113564Sdl modify it under the terms of the GNU Lesser General Public 1213564Sdl License as published by the Free Software Foundation; either 1313564Sdl version 2.1 of the License, or (at your option) any later version. 1413564Sdl 1513564Sdl The GNU C Library is distributed in the hope that it will be useful, 1613564Sdl but WITHOUT ANY WARRANTY; without even the implied warranty of 1713564Sdl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1813564Sdl Lesser General Public License for more details. 1913564Sdl 2013564Sdl You should have received a copy of the GNU Lesser General Public 2113564Sdl License along with the GNU C Library; if not, see 2213564Sdl <https://www.gnu.org/licenses/>. */ 2313564Sdl 2413564Sdl#ifndef _SCRATCH_BUFFER_H 2513564Sdl#define _SCRATCH_BUFFER_H 2613564Sdl 2713564Sdl/* Scratch buffers with a default stack allocation and fallback to 2813564Sdl heap allocation. It is expected that this function is used in this 2913564Sdl way: 3013564Sdl 3113564Sdl struct scratch_buffer tmpbuf; 3213564Sdl scratch_buffer_init (&tmpbuf); 3313564Sdl 3413564Sdl while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) 3513564Sdl if (!scratch_buffer_grow (&tmpbuf)) 3613564Sdl return -1; 3713564Sdl 3813564Sdl scratch_buffer_free (&tmpbuf); 3913564Sdl return 0; 4013564Sdl 4113564Sdl The allocation functions (scratch_buffer_grow, 4213564Sdl scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make 4313564Sdl sure that the heap allocation, if any, is freed, so that the code 4413564Sdl above does not have a memory leak. The buffer still remains in a 4513564Sdl state that can be deallocated using scratch_buffer_free, so a loop 4613564Sdl like this is valid as well: 4713564Sdl 4813564Sdl struct scratch_buffer tmpbuf; 4913564Sdl scratch_buffer_init (&tmpbuf); 5013564Sdl 5113564Sdl while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) 5213564Sdl if (!scratch_buffer_grow (&tmpbuf)) 5313564Sdl break; 5413564Sdl 5513564Sdl scratch_buffer_free (&tmpbuf); 5613564Sdl 5713564Sdl scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed 5813564Sdl to grow the buffer by at least 512 bytes. This means that when 5913564Sdl using the scratch buffer as a backing store for a non-character 6013564Sdl array whose element size, in bytes, is 512 or smaller, the scratch 6113564Sdl buffer only has to grow once to make room for at least one more 6213564Sdl element. 6313564Sdl*/ 6413564Sdl 6513564Sdl#include <stdbool.h> 6613564Sdl#include <stddef.h> 6713564Sdl#include <stdlib.h> 6813564Sdl 6913564Sdl/* Scratch buffer. Must be initialized with scratch_buffer_init 7013564Sdl before its use. */ 7113564Sdlstruct scratch_buffer { 7213564Sdl void *data; /* Pointer to the beginning of the scratch area. */ 7313564Sdl size_t length; /* Allocated space at the data pointer, in bytes. */ 7413564Sdl union { max_align_t __align; char __c[1024]; } __space; 7513564Sdl}; 7613564Sdl 7713564Sdl/* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space 7813564Sdl and BUFFER->length reflects the available space. */ 7913564Sdlstatic inline void 8013564Sdlscratch_buffer_init (struct scratch_buffer *buffer) 8113564Sdl{ 8213564Sdl buffer->data = buffer->__space.__c; 8313564Sdl buffer->length = sizeof (buffer->__space); 8413564Sdl} 8513564Sdl 8613564Sdl/* Deallocates *BUFFER (if it was heap-allocated). */ 8713564Sdlstatic inline void 8813564Sdlscratch_buffer_free (struct scratch_buffer *buffer) 8913564Sdl{ 9013564Sdl if (buffer->data != buffer->__space.__c) 9113564Sdl free (buffer->data); 9213564Sdl} 9313564Sdl 9413564Sdl/* Grow *BUFFER by some arbitrary amount. The buffer contents is NOT 9513564Sdl preserved. Return true on success, false on allocation failure (in 9613564Sdl which case the old buffer is freed). On success, the new buffer is 9713564Sdl larger than the previous size. On failure, *BUFFER is deallocated, 9813564Sdl but remains in a free-able state, and errno is set. */ 9913564Sdlbool __libc_scratch_buffer_grow (struct scratch_buffer *buffer); 10013564Sdl 10113564Sdl/* Alias for __libc_scratch_buffer_grow. */ 10213564Sdlstatic inline _GL_ATTRIBUTE_ALWAYS_INLINE bool 10313564Sdlscratch_buffer_grow (struct scratch_buffer *buffer) 10413564Sdl{ 10513564Sdl return _GL_LIKELY (__libc_scratch_buffer_grow (buffer)); 10613564Sdl} 10713564Sdl 10813564Sdl/* Like __libc_scratch_buffer_grow, but preserve the old buffer 10913564Sdl contents on success, as a prefix of the new buffer. */ 11013564Sdlbool __libc_scratch_buffer_grow_preserve (struct scratch_buffer *buffer); 11113564Sdl 11213564Sdl/* Alias for __libc_scratch_buffer_grow_preserve. */ 11313564Sdlstatic inline _GL_ATTRIBUTE_ALWAYS_INLINE bool 11413564Sdlscratch_buffer_grow_preserve (struct scratch_buffer *buffer) 11513564Sdl{ 11613564Sdl return _GL_LIKELY (__libc_scratch_buffer_grow_preserve (buffer)); 11713564Sdl} 11813564Sdl 11913564Sdl/* Grow *BUFFER so that it can store at least NELEM elements of SIZE 12013564Sdl bytes. The buffer contents are NOT preserved. Both NELEM and SIZE 12113564Sdl can be zero. Return true on success, false on allocation failure 12213564Sdl (in which case the old buffer is freed, but *BUFFER remains in a 12313564Sdl free-able state, and errno is set). It is unspecified whether this 12413564Sdl function can reduce the array size. */ 12513564Sdlbool __libc_scratch_buffer_set_array_size (struct scratch_buffer *buffer, 12613564Sdl size_t nelem, size_t size); 12713564Sdl 12813564Sdl/* Alias for __libc_scratch_set_array_size. */ 12913564Sdlstatic inline _GL_ATTRIBUTE_ALWAYS_INLINE bool 13013564Sdlscratch_buffer_set_array_size (struct scratch_buffer *buffer, 13113564Sdl size_t nelem, size_t size) 13213564Sdl{ 13313564Sdl return _GL_LIKELY (__libc_scratch_buffer_set_array_size 13413564Sdl (buffer, nelem, size)); 13513564Sdl} 13613564Sdl 13713564Sdl/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block, 13813564Sdl deallocating *BUFFER if it was heap-allocated. SIZE must be at 13913564Sdl most *BUFFER's size. Return NULL (setting errno) on memory 14013564Sdl exhaustion. */ 14113564Sdlvoid *__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, 14213564Sdl size_t size); 14313564Sdl 14413564Sdl/* Alias for __libc_scratch_dupfree. */ 14513564Sdlstatic inline _GL_ATTRIBUTE_ALWAYS_INLINE void * 14613564Sdlscratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) 14713564Sdl{ 14813564Sdl void *r = __libc_scratch_buffer_dupfree (buffer, size); 14913564Sdl return _GL_LIKELY (r != NULL) ? r : NULL; 15013564Sdl} 15113564Sdl 15213564Sdl#endif /* _SCRATCH_BUFFER_H */ 15313564Sdl