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