xref: /freebsd-12.1/gnu/usr.bin/grep/obstack.c (revision abbcaa0a)
1 /* obstack.c - subroutines used implicitly by object stack macros
2    Copyright (C) 1988, 1993 Free Software Foundation, Inc.
3 
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 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, write to the Free Software
16 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
17 
18 #include "obstack.h"
19 
20 /* This is just to get __GNU_LIBRARY__ defined.  */
21 #include <stdio.h>
22 
23 /* Comment out all this code if we are using the GNU C Library, and are not
24    actually compiling the library itself.  This code is part of the GNU C
25    Library, but also included in many other GNU distributions.  Compiling
26    and linking in this code is a waste when using the GNU C library
27    (especially if it is a shared library).  Rather than having every GNU
28    program understand `configure --with-gnu-libc' and omit the object files,
29    it is simpler to just do this in the source for each such file.  */
30 
31 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
32 
33 
34 #ifdef __STDC__
35 #define POINTER void *
36 #else
37 #define POINTER char *
38 #endif
39 
40 /* Determine default alignment.  */
41 struct fooalign {char x; double d;};
42 #define DEFAULT_ALIGNMENT  \
43   ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
44 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
45    But in fact it might be less smart and round addresses to as much as
46    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
47 union fooround {long x; double d;};
48 #define DEFAULT_ROUNDING (sizeof (union fooround))
49 
50 /* When we copy a long block of data, this is the unit to do it with.
51    On some machines, copying successive ints does not work;
52    in such a case, redefine COPYING_UNIT to `long' (if that works)
53    or `char' as a last resort.  */
54 #ifndef COPYING_UNIT
55 #define COPYING_UNIT int
56 #endif
57 
58 /* The non-GNU-C macros copy the obstack into this global variable
59    to avoid multiple evaluation.  */
60 
61 struct obstack *_obstack;
62 
63 /* Define a macro that either calls functions with the traditional malloc/free
64    calling interface, or calls functions with the mmalloc/mfree interface
65    (that adds an extra first argument), based on the state of use_extra_arg.
66    For free, do not use ?:, since some compilers, like the MIPS compilers,
67    do not allow (expr) ? void : void.  */
68 
69 #define CALL_CHUNKFUN(h, size) \
70   (((h) -> use_extra_arg) \
71    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
72    : (*(h)->chunkfun) ((size)))
73 
74 #define CALL_FREEFUN(h, old_chunk) \
75   do { \
76     if ((h) -> use_extra_arg) \
77       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
78     else \
79       (*(h)->freefun) ((old_chunk)); \
80   } while (0)
81 
82 
83 /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
84    Objects start on multiples of ALIGNMENT (0 means use default).
85    CHUNKFUN is the function to use to allocate chunks,
86    and FREEFUN the function to free them.  */
87 
88 void
89 _obstack_begin (h, size, alignment, chunkfun, freefun)
90      struct obstack *h;
91      int size;
92      int alignment;
93      POINTER (*chunkfun) ();
94      void (*freefun) ();
95 {
96   register struct _obstack_chunk* chunk; /* points to new chunk */
97 
98   if (alignment == 0)
99     alignment = DEFAULT_ALIGNMENT;
100   if (size == 0)
101     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
102     {
103       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
104 	 Use the values for range checking, because if range checking is off,
105 	 the extra bytes won't be missed terribly, but if range checking is on
106 	 and we used a larger request, a whole extra 4096 bytes would be
107 	 allocated.
108 
109 	 These number are irrelevant to the new GNU malloc.  I suspect it is
110 	 less sensitive to the size of the request.  */
111       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
112 		    + 4 + DEFAULT_ROUNDING - 1)
113 		   & ~(DEFAULT_ROUNDING - 1));
114       size = 4096 - extra;
115     }
116 
117   h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
118   h->freefun = freefun;
119   h->chunk_size = size;
120   h->alignment_mask = alignment - 1;
121   h->use_extra_arg = 0;
122 
123   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
124   h->next_free = h->object_base = chunk->contents;
125   h->chunk_limit = chunk->limit
126     = (char *) chunk + h->chunk_size;
127   chunk->prev = 0;
128   /* The initial chunk now contains no empty object.  */
129   h->maybe_empty_object = 0;
130 }
131 
132 void
133 _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
134      struct obstack *h;
135      int size;
136      int alignment;
137      POINTER (*chunkfun) ();
138      void (*freefun) ();
139      POINTER arg;
140 {
141   register struct _obstack_chunk* chunk; /* points to new chunk */
142 
143   if (alignment == 0)
144     alignment = DEFAULT_ALIGNMENT;
145   if (size == 0)
146     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
147     {
148       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
149 	 Use the values for range checking, because if range checking is off,
150 	 the extra bytes won't be missed terribly, but if range checking is on
151 	 and we used a larger request, a whole extra 4096 bytes would be
152 	 allocated.
153 
154 	 These number are irrelevant to the new GNU malloc.  I suspect it is
155 	 less sensitive to the size of the request.  */
156       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
157 		    + 4 + DEFAULT_ROUNDING - 1)
158 		   & ~(DEFAULT_ROUNDING - 1));
159       size = 4096 - extra;
160     }
161 
162   h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
163   h->freefun = freefun;
164   h->chunk_size = size;
165   h->alignment_mask = alignment - 1;
166   h->extra_arg = arg;
167   h->use_extra_arg = 1;
168 
169   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
170   h->next_free = h->object_base = chunk->contents;
171   h->chunk_limit = chunk->limit
172     = (char *) chunk + h->chunk_size;
173   chunk->prev = 0;
174   /* The initial chunk now contains no empty object.  */
175   h->maybe_empty_object = 0;
176 }
177 
178 /* Allocate a new current chunk for the obstack *H
179    on the assumption that LENGTH bytes need to be added
180    to the current object, or a new object of length LENGTH allocated.
181    Copies any partial object from the end of the old chunk
182    to the beginning of the new one.  */
183 
184 void
185 _obstack_newchunk (h, length)
186      struct obstack *h;
187      int length;
188 {
189   register struct _obstack_chunk*	old_chunk = h->chunk;
190   register struct _obstack_chunk*	new_chunk;
191   register long	new_size;
192   register int obj_size = h->next_free - h->object_base;
193   register int i;
194   int already;
195 
196   /* Compute size for new chunk.  */
197   new_size = (obj_size + length) + (obj_size >> 3) + 100;
198   if (new_size < h->chunk_size)
199     new_size = h->chunk_size;
200 
201   /* Allocate and initialize the new chunk.  */
202   new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size);
203   new_chunk->prev = old_chunk;
204   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
205 
206   /* Move the existing object to the new chunk.
207      Word at a time is fast and is safe if the object
208      is sufficiently aligned.  */
209   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
210     {
211       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
212 	   i >= 0; i--)
213 	((COPYING_UNIT *)new_chunk->contents)[i]
214 	  = ((COPYING_UNIT *)h->object_base)[i];
215       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
216 	 but that can cross a page boundary on a machine
217 	 which does not do strict alignment for COPYING_UNITS.  */
218       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
219     }
220   else
221     already = 0;
222   /* Copy remaining bytes one by one.  */
223   for (i = already; i < obj_size; i++)
224     new_chunk->contents[i] = h->object_base[i];
225 
226   /* If the object just copied was the only data in OLD_CHUNK,
227      free that chunk and remove it from the chain.
228      But not if that chunk might contain an empty object.  */
229   if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
230     {
231       new_chunk->prev = old_chunk->prev;
232       CALL_FREEFUN (h, old_chunk);
233     }
234 
235   h->object_base = new_chunk->contents;
236   h->next_free = h->object_base + obj_size;
237   /* The new chunk certainly contains no empty object yet.  */
238   h->maybe_empty_object = 0;
239 }
240 
241 /* Return nonzero if object OBJ has been allocated from obstack H.
242    This is here for debugging.
243    If you use it in a program, you are probably losing.  */
244 
245 int
246 _obstack_allocated_p (h, obj)
247      struct obstack *h;
248      POINTER obj;
249 {
250   register struct _obstack_chunk*  lp;	/* below addr of any objects in this chunk */
251   register struct _obstack_chunk*  plp;	/* point to previous chunk if any */
252 
253   lp = (h)->chunk;
254   /* We use >= rather than > since the object cannot be exactly at
255      the beginning of the chunk but might be an empty object exactly
256      at the end of an adjacent chunk. */
257   while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
258     {
259       plp = lp->prev;
260       lp = plp;
261     }
262   return lp != 0;
263 }
264 
265 /* Free objects in obstack H, including OBJ and everything allocate
266    more recently than OBJ.  If OBJ is zero, free everything in H.  */
267 
268 #undef obstack_free
269 
270 /* This function has two names with identical definitions.
271    This is the first one, called from non-ANSI code.  */
272 
273 void
274 _obstack_free (h, obj)
275      struct obstack *h;
276      POINTER obj;
277 {
278   register struct _obstack_chunk*  lp;	/* below addr of any objects in this chunk */
279   register struct _obstack_chunk*  plp;	/* point to previous chunk if any */
280 
281   lp = h->chunk;
282   /* We use >= because there cannot be an object at the beginning of a chunk.
283      But there can be an empty object at that address
284      at the end of another chunk.  */
285   while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
286     {
287       plp = lp->prev;
288       CALL_FREEFUN (h, lp);
289       lp = plp;
290       /* If we switch chunks, we can't tell whether the new current
291 	 chunk contains an empty object, so assume that it may.  */
292       h->maybe_empty_object = 1;
293     }
294   if (lp)
295     {
296       h->object_base = h->next_free = (char *)(obj);
297       h->chunk_limit = lp->limit;
298       h->chunk = lp;
299     }
300   else if (obj != 0)
301     /* obj is not in any of the chunks! */
302     abort ();
303 }
304 
305 /* This function is used from ANSI code.  */
306 
307 void
308 obstack_free (h, obj)
309      struct obstack *h;
310      POINTER obj;
311 {
312   register struct _obstack_chunk*  lp;	/* below addr of any objects in this chunk */
313   register struct _obstack_chunk*  plp;	/* point to previous chunk if any */
314 
315   lp = h->chunk;
316   /* We use >= because there cannot be an object at the beginning of a chunk.
317      But there can be an empty object at that address
318      at the end of another chunk.  */
319   while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
320     {
321       plp = lp->prev;
322       CALL_FREEFUN (h, lp);
323       lp = plp;
324       /* If we switch chunks, we can't tell whether the new current
325 	 chunk contains an empty object, so assume that it may.  */
326       h->maybe_empty_object = 1;
327     }
328   if (lp)
329     {
330       h->object_base = h->next_free = (char *)(obj);
331       h->chunk_limit = lp->limit;
332       h->chunk = lp;
333     }
334   else if (obj != 0)
335     /* obj is not in any of the chunks! */
336     abort ();
337 }
338 
339 #if 0
340 /* These are now turned off because the applications do not use it
341    and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
342 
343 /* Now define the functional versions of the obstack macros.
344    Define them to simply use the corresponding macros to do the job.  */
345 
346 #ifdef __STDC__
347 /* These function definitions do not work with non-ANSI preprocessors;
348    they won't pass through the macro names in parentheses.  */
349 
350 /* The function names appear in parentheses in order to prevent
351    the macro-definitions of the names from being expanded there.  */
352 
353 POINTER (obstack_base) (obstack)
354      struct obstack *obstack;
355 {
356   return obstack_base (obstack);
357 }
358 
359 POINTER (obstack_next_free) (obstack)
360      struct obstack *obstack;
361 {
362   return obstack_next_free (obstack);
363 }
364 
365 int (obstack_object_size) (obstack)
366      struct obstack *obstack;
367 {
368   return obstack_object_size (obstack);
369 }
370 
371 int (obstack_room) (obstack)
372      struct obstack *obstack;
373 {
374   return obstack_room (obstack);
375 }
376 
377 void (obstack_grow) (obstack, pointer, length)
378      struct obstack *obstack;
379      POINTER pointer;
380      int length;
381 {
382   obstack_grow (obstack, pointer, length);
383 }
384 
385 void (obstack_grow0) (obstack, pointer, length)
386      struct obstack *obstack;
387      POINTER pointer;
388      int length;
389 {
390   obstack_grow0 (obstack, pointer, length);
391 }
392 
393 void (obstack_1grow) (obstack, character)
394      struct obstack *obstack;
395      int character;
396 {
397   obstack_1grow (obstack, character);
398 }
399 
400 void (obstack_blank) (obstack, length)
401      struct obstack *obstack;
402      int length;
403 {
404   obstack_blank (obstack, length);
405 }
406 
407 void (obstack_1grow_fast) (obstack, character)
408      struct obstack *obstack;
409      int character;
410 {
411   obstack_1grow_fast (obstack, character);
412 }
413 
414 void (obstack_blank_fast) (obstack, length)
415      struct obstack *obstack;
416      int length;
417 {
418   obstack_blank_fast (obstack, length);
419 }
420 
421 POINTER (obstack_finish) (obstack)
422      struct obstack *obstack;
423 {
424   return obstack_finish (obstack);
425 }
426 
427 POINTER (obstack_alloc) (obstack, length)
428      struct obstack *obstack;
429      int length;
430 {
431   return obstack_alloc (obstack, length);
432 }
433 
434 POINTER (obstack_copy) (obstack, pointer, length)
435      struct obstack *obstack;
436      POINTER pointer;
437      int length;
438 {
439   return obstack_copy (obstack, pointer, length);
440 }
441 
442 POINTER (obstack_copy0) (obstack, pointer, length)
443      struct obstack *obstack;
444      POINTER pointer;
445      int length;
446 {
447   return obstack_copy0 (obstack, pointer, length);
448 }
449 
450 #endif /* __STDC__ */
451 
452 #endif /* 0 */
453 
454 #endif	/* _LIBC or not __GNU_LIBRARY__.  */
455