Bump to m4 1.4.19
[platform/upstream/m4.git] / lib / scratch_buffer.h
1 /* Variable-sized buffer with on-stack default allocation.
2    Copyright (C) 2017-2021 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16
17 /* Written by Paul Eggert, 2017.  */
18
19 #ifndef _GL_SCRATCH_BUFFER_H
20 #define _GL_SCRATCH_BUFFER_H
21
22 /* Scratch buffers with a default stack allocation and fallback to
23    heap allocation.  It is expected that this function is used in this
24    way:
25
26      struct scratch_buffer tmpbuf;
27      scratch_buffer_init (&tmpbuf);
28
29      while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length))
30        if (!scratch_buffer_grow (&tmpbuf))
31          return -1;
32
33      scratch_buffer_free (&tmpbuf);
34      return 0;
35
36    The allocation functions (scratch_buffer_grow,
37    scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make
38    sure that the heap allocation, if any, is freed, so that the code
39    above does not have a memory leak.  The buffer still remains in a
40    state that can be deallocated using scratch_buffer_free, so a loop
41    like this is valid as well:
42
43      struct scratch_buffer tmpbuf;
44      scratch_buffer_init (&tmpbuf);
45
46      while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length))
47        if (!scratch_buffer_grow (&tmpbuf))
48          break;
49
50      scratch_buffer_free (&tmpbuf);
51
52    scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed
53    to grow the buffer by at least 512 bytes.  This means that when
54    using the scratch buffer as a backing store for a non-character
55    array whose element size, in bytes, is 512 or smaller, the scratch
56    buffer only has to grow once to make room for at least one more
57    element.
58 */
59
60 /* Scratch buffer.  Must be initialized with scratch_buffer_init
61    before its use.  */
62 struct scratch_buffer;
63
64 /* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space
65    and BUFFER->length reflects the available space.  */
66 #if 0
67 extern void scratch_buffer_init (struct scratch_buffer *buffer);
68 #endif
69
70 /* Deallocates *BUFFER (if it was heap-allocated).  */
71 #if 0
72 extern void scratch_buffer_free (struct scratch_buffer *buffer);
73 #endif
74
75 /* Grow *BUFFER by some arbitrary amount.  The buffer contents is NOT
76    preserved.  Return true on success, false on allocation failure (in
77    which case the old buffer is freed).  On success, the new buffer is
78    larger than the previous size.  On failure, *BUFFER is deallocated,
79    but remains in a free-able state, and errno is set.  */
80 #if 0
81 extern bool scratch_buffer_grow (struct scratch_buffer *buffer);
82 #endif
83
84 /* Like scratch_buffer_grow, but preserve the old buffer
85    contents on success, as a prefix of the new buffer.  */
86 #if 0
87 extern bool scratch_buffer_grow_preserve (struct scratch_buffer *buffer);
88 #endif
89
90 /* Grow *BUFFER so that it can store at least NELEM elements of SIZE
91    bytes.  The buffer contents are NOT preserved.  Both NELEM and SIZE
92    can be zero.  Return true on success, false on allocation failure
93    (in which case the old buffer is freed, but *BUFFER remains in a
94    free-able state, and errno is set).  It is unspecified whether this
95    function can reduce the array size.  */
96 #if 0
97 extern bool scratch_buffer_set_array_size (struct scratch_buffer *buffer,
98                                            size_t nelem, size_t size);
99 #endif
100
101 /* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block,
102    deallocating *BUFFER if it was heap-allocated.  SIZE must be at
103    most *BUFFER's size.  Return NULL (setting errno) on memory
104    exhaustion.  */
105 #if 0
106 extern void *scratch_buffer_dupfree (struct scratch_buffer *buffer,
107                                      size_t size);
108 #endif
109
110
111 /* The implementation is imported from glibc.  */
112
113 #include <libc-config.h>
114
115 /* Avoid possible conflicts with symbols exported by the GNU libc.  */
116 #define __libc_scratch_buffer_dupfree gl_scratch_buffer_dupfree
117 #define __libc_scratch_buffer_grow gl_scratch_buffer_grow
118 #define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve
119 #define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size
120
121 #include <malloc/scratch_buffer.h>
122
123 #endif /* _GL_SCRATCH_BUFFER_H */