xref: /netbsd-src/external/gpl2/grep/dist/lib/obstack.c (revision 8317e0eadbe4a6e37b4843ded3588b919349e8da)
1 /*	$NetBSD: obstack.c,v 1.2 2018/06/13 17:32:29 kamil Exp $	*/
2 
3 /* obstack.c - subroutines used implicitly by object stack macros
4    Copyright (C) 1988-1994,96,97,98,99 Free Software Foundation, Inc.
5 
6    This file is part of the GNU C Library.  Its master source is NOT part of
7    the C library, however.  The master source lives in /gd/gnu/lib.
8 
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Library General Public License as
11    published by the Free Software Foundation; either version 2 of the
12    License, or (at your option) any later version.
13 
14    The GNU C Library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Library General Public License for more details.
18 
19    You should have received a copy of the GNU Library General Public
20    License along with the GNU C Library; see the file COPYING.LIB.  If not,
21    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22    Boston, MA 02111-1307, USA.  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include "obstack.h"
29 
30 /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
31    incremented whenever callers compiled using an old obstack.h can no
32    longer properly call the functions in this obstack.c.  */
33 #define OBSTACK_INTERFACE_VERSION 1
34 
35 /* Comment out all this code if we are using the GNU C Library, and are not
36    actually compiling the library itself, and the installed library
37    supports the same library interface we do.  This code is part of the GNU
38    C Library, but also included in many other GNU distributions.  Compiling
39    and linking in this code is a waste when using the GNU C library
40    (especially if it is a shared library).  Rather than having every GNU
41    program understand `configure --with-gnu-libc' and omit the object
42    files, it is simpler to just do this in the source for each such file.  */
43 
44 #include <stdio.h>		/* Random thing to get __GNU_LIBRARY__.  */
45 #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
46 #include <gnu-versions.h>
47 #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
48 #define ELIDE_CODE
49 #endif
50 #endif
51 
52 
53 #ifndef ELIDE_CODE
54 
55 
56 #if defined (__STDC__) && __STDC__
57 #define POINTER void *
58 #else
59 #define POINTER char *
60 #endif
61 
62 /* Determine default alignment.  */
63 struct fooalign {char x; double d;};
64 
65 #if defined(__NetBSD__)
66 #include <sys/param.h>
67 #endif
68 
69 #ifndef __NetBSD_Prereq__
70 #define __NetBSD_Prereq__(a,b,c) 0
71 #endif
72 
73 #if __NetBSD_Prereq__(8,0,0)
74 #include <stdalign.h>
75 // Avoid Undefined Behavior
76 #define DEFAULT_ALIGNMENT ((int)alignof(struct fooalign))
77 #else
78 #define DEFAULT_ALIGNMENT  \
79   ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
80 #endif
81 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
82    But in fact it might be less smart and round addresses to as much as
83    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
84 union fooround {long x; double d;};
85 #define DEFAULT_ROUNDING (sizeof (union fooround))
86 
87 /* When we copy a long block of data, this is the unit to do it with.
88    On some machines, copying successive ints does not work;
89    in such a case, redefine COPYING_UNIT to `long' (if that works)
90    or `char' as a last resort.  */
91 #ifndef COPYING_UNIT
92 #define COPYING_UNIT int
93 #endif
94 
95 
96 /* The functions allocating more room by calling `obstack_chunk_alloc'
97    jump to the handler pointed to by `obstack_alloc_failed_handler'.
98    This can be set to a user defined function which should either
99    abort gracefully or use longjump - but shouldn't return.  This
100    variable by default points to the internal function
101    `print_and_abort'.  */
102 #if defined (__STDC__) && __STDC__
103 static void print_and_abort (void);
104 void (*obstack_alloc_failed_handler) (void) = print_and_abort;
105 #else
106 static void print_and_abort ();
107 void (*obstack_alloc_failed_handler) () = print_and_abort;
108 #endif
109 
110 /* Exit value used when `print_and_abort' is used.  */
111 #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
112 #include <stdlib.h>
113 #endif
114 #ifndef EXIT_FAILURE
115 #define EXIT_FAILURE 1
116 #endif
117 int obstack_exit_failure = EXIT_FAILURE;
118 
119 /* The non-GNU-C macros copy the obstack into this global variable
120    to avoid multiple evaluation.  */
121 
122 struct obstack *_obstack;
123 
124 /* Define a macro that either calls functions with the traditional malloc/free
125    calling interface, or calls functions with the mmalloc/mfree interface
126    (that adds an extra first argument), based on the state of use_extra_arg.
127    For free, do not use ?:, since some compilers, like the MIPS compilers,
128    do not allow (expr) ? void : void.  */
129 
130 #if defined (__STDC__) && __STDC__
131 #define CALL_CHUNKFUN(h, size) \
132   (((h) -> use_extra_arg) \
133    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
134    : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
135 
136 #define CALL_FREEFUN(h, old_chunk) \
137   do { \
138     if ((h) -> use_extra_arg) \
139       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
140     else \
141       (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
142   } while (0)
143 #else
144 #define CALL_CHUNKFUN(h, size) \
145   (((h) -> use_extra_arg) \
146    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
147    : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
148 
149 #define CALL_FREEFUN(h, old_chunk) \
150   do { \
151     if ((h) -> use_extra_arg) \
152       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
153     else \
154       (*(void (*) ()) (h)->freefun) ((old_chunk)); \
155   } while (0)
156 #endif
157 
158 
159 /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
160    Objects start on multiples of ALIGNMENT (0 means use default).
161    CHUNKFUN is the function to use to allocate chunks,
162    and FREEFUN the function to free them.
163 
164    Return nonzero if successful, calls obstack_alloc_failed_handler if
165    allocation fails.  */
166 
167 int
168 _obstack_begin (h, size, alignment, chunkfun, freefun)
169      struct obstack *h;
170      int size;
171      int alignment;
172 #if defined (__STDC__) && __STDC__
173      POINTER (*chunkfun) (long);
174      void (*freefun) (void *);
175 #else
176      POINTER (*chunkfun) ();
177      void (*freefun) ();
178 #endif
179 {
180   register struct _obstack_chunk *chunk; /* points to new chunk */
181 
182   if (alignment == 0)
183     alignment = (int) DEFAULT_ALIGNMENT;
184   if (size == 0)
185     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
186     {
187       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
188 	 Use the values for range checking, because if range checking is off,
189 	 the extra bytes won't be missed terribly, but if range checking is on
190 	 and we used a larger request, a whole extra 4096 bytes would be
191 	 allocated.
192 
193 	 These number are irrelevant to the new GNU malloc.  I suspect it is
194 	 less sensitive to the size of the request.  */
195       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
196 		    + 4 + DEFAULT_ROUNDING - 1)
197 		   & ~(DEFAULT_ROUNDING - 1));
198       size = 4096 - extra;
199     }
200 
201 #if defined (__STDC__) && __STDC__
202   h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
203   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
204 #else
205   h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
206   h->freefun = freefun;
207 #endif
208   h->chunk_size = size;
209   h->alignment_mask = alignment - 1;
210   h->use_extra_arg = 0;
211 
212   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
213   if (!chunk)
214     (*obstack_alloc_failed_handler) ();
215   h->next_free = h->object_base = chunk->contents;
216   h->chunk_limit = chunk->limit
217     = (char *) chunk + h->chunk_size;
218   chunk->prev = 0;
219   /* The initial chunk now contains no empty object.  */
220   h->maybe_empty_object = 0;
221   h->alloc_failed = 0;
222   return 1;
223 }
224 
225 int
226 _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
227      struct obstack *h;
228      int size;
229      int alignment;
230 #if defined (__STDC__) && __STDC__
231      POINTER (*chunkfun) (POINTER, long);
232      void (*freefun) (POINTER, POINTER);
233 #else
234      POINTER (*chunkfun) ();
235      void (*freefun) ();
236 #endif
237      POINTER arg;
238 {
239   register struct _obstack_chunk *chunk; /* points to new chunk */
240 
241   if (alignment == 0)
242     alignment = (int) DEFAULT_ALIGNMENT;
243   if (size == 0)
244     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
245     {
246       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
247 	 Use the values for range checking, because if range checking is off,
248 	 the extra bytes won't be missed terribly, but if range checking is on
249 	 and we used a larger request, a whole extra 4096 bytes would be
250 	 allocated.
251 
252 	 These number are irrelevant to the new GNU malloc.  I suspect it is
253 	 less sensitive to the size of the request.  */
254       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
255 		    + 4 + DEFAULT_ROUNDING - 1)
256 		   & ~(DEFAULT_ROUNDING - 1));
257       size = 4096 - extra;
258     }
259 
260 #if defined(__STDC__) && __STDC__
261   h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
262   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
263 #else
264   h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
265   h->freefun = freefun;
266 #endif
267   h->chunk_size = size;
268   h->alignment_mask = alignment - 1;
269   h->extra_arg = arg;
270   h->use_extra_arg = 1;
271 
272   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
273   if (!chunk)
274     (*obstack_alloc_failed_handler) ();
275   h->next_free = h->object_base = chunk->contents;
276   h->chunk_limit = chunk->limit
277     = (char *) chunk + h->chunk_size;
278   chunk->prev = 0;
279   /* The initial chunk now contains no empty object.  */
280   h->maybe_empty_object = 0;
281   h->alloc_failed = 0;
282   return 1;
283 }
284 
285 /* Allocate a new current chunk for the obstack *H
286    on the assumption that LENGTH bytes need to be added
287    to the current object, or a new object of length LENGTH allocated.
288    Copies any partial object from the end of the old chunk
289    to the beginning of the new one.  */
290 
291 void
292 _obstack_newchunk (h, length)
293      struct obstack *h;
294      int length;
295 {
296   register struct _obstack_chunk *old_chunk = h->chunk;
297   register struct _obstack_chunk *new_chunk;
298   register long	new_size;
299   register long obj_size = h->next_free - h->object_base;
300   register long i;
301   long already;
302 
303   /* Compute size for new chunk.  */
304   new_size = (obj_size + length) + (obj_size >> 3) + 100;
305   if (new_size < h->chunk_size)
306     new_size = h->chunk_size;
307 
308   /* Allocate and initialize the new chunk.  */
309   new_chunk = CALL_CHUNKFUN (h, new_size);
310   if (!new_chunk)
311     (*obstack_alloc_failed_handler) ();
312   h->chunk = new_chunk;
313   new_chunk->prev = old_chunk;
314   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
315 
316   /* Move the existing object to the new chunk.
317      Word at a time is fast and is safe if the object
318      is sufficiently aligned.  */
319   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
320     {
321       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
322 	   i >= 0; i--)
323 	((COPYING_UNIT *)new_chunk->contents)[i]
324 	  = ((COPYING_UNIT *)h->object_base)[i];
325       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
326 	 but that can cross a page boundary on a machine
327 	 which does not do strict alignment for COPYING_UNITS.  */
328       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
329     }
330   else
331     already = 0;
332   /* Copy remaining bytes one by one.  */
333   for (i = already; i < obj_size; i++)
334     new_chunk->contents[i] = h->object_base[i];
335 
336   /* If the object just copied was the only data in OLD_CHUNK,
337      free that chunk and remove it from the chain.
338      But not if that chunk might contain an empty object.  */
339   if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
340     {
341       new_chunk->prev = old_chunk->prev;
342       CALL_FREEFUN (h, old_chunk);
343     }
344 
345   h->object_base = new_chunk->contents;
346   h->next_free = h->object_base + obj_size;
347   /* The new chunk certainly contains no empty object yet.  */
348   h->maybe_empty_object = 0;
349 }
350 
351 /* Return nonzero if object OBJ has been allocated from obstack H.
352    This is here for debugging.
353    If you use it in a program, you are probably losing.  */
354 
355 #if defined (__STDC__) && __STDC__
356 /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
357    obstack.h because it is just for debugging.  */
358 int _obstack_allocated_p (struct obstack *h, POINTER obj);
359 #endif
360 
361 int
362 _obstack_allocated_p (h, obj)
363      struct obstack *h;
364      POINTER obj;
365 {
366   register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
367   register struct _obstack_chunk *plp;	/* point to previous chunk if any */
368 
369   lp = (h)->chunk;
370   /* We use >= rather than > since the object cannot be exactly at
371      the beginning of the chunk but might be an empty object exactly
372      at the end of an adjacent chunk.  */
373   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
374     {
375       plp = lp->prev;
376       lp = plp;
377     }
378   return lp != 0;
379 }
380 
381 /* Free objects in obstack H, including OBJ and everything allocate
382    more recently than OBJ.  If OBJ is zero, free everything in H.  */
383 
384 #undef obstack_free
385 
386 /* This function has two names with identical definitions.
387    This is the first one, called from non-ANSI code.  */
388 
389 void
390 _obstack_free (h, obj)
391      struct obstack *h;
392      POINTER obj;
393 {
394   register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
395   register struct _obstack_chunk *plp;	/* point to previous chunk if any */
396 
397   lp = h->chunk;
398   /* We use >= because there cannot be an object at the beginning of a chunk.
399      But there can be an empty object at that address
400      at the end of another chunk.  */
401   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
402     {
403       plp = lp->prev;
404       CALL_FREEFUN (h, lp);
405       lp = plp;
406       /* If we switch chunks, we can't tell whether the new current
407 	 chunk contains an empty object, so assume that it may.  */
408       h->maybe_empty_object = 1;
409     }
410   if (lp)
411     {
412       h->object_base = h->next_free = (char *) (obj);
413       h->chunk_limit = lp->limit;
414       h->chunk = lp;
415     }
416   else if (obj != 0)
417     /* obj is not in any of the chunks! */
418     abort ();
419 }
420 
421 /* This function is used from ANSI code.  */
422 
423 void
424 obstack_free (h, obj)
425      struct obstack *h;
426      POINTER obj;
427 {
428   register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
429   register struct _obstack_chunk *plp;	/* point to previous chunk if any */
430 
431   lp = h->chunk;
432   /* We use >= because there cannot be an object at the beginning of a chunk.
433      But there can be an empty object at that address
434      at the end of another chunk.  */
435   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
436     {
437       plp = lp->prev;
438       CALL_FREEFUN (h, lp);
439       lp = plp;
440       /* If we switch chunks, we can't tell whether the new current
441 	 chunk contains an empty object, so assume that it may.  */
442       h->maybe_empty_object = 1;
443     }
444   if (lp)
445     {
446       h->object_base = h->next_free = (char *) (obj);
447       h->chunk_limit = lp->limit;
448       h->chunk = lp;
449     }
450   else if (obj != 0)
451     /* obj is not in any of the chunks! */
452     abort ();
453 }
454 
455 int
456 _obstack_memory_used (h)
457      struct obstack *h;
458 {
459   register struct _obstack_chunk* lp;
460   register int nbytes = 0;
461 
462   for (lp = h->chunk; lp != 0; lp = lp->prev)
463     {
464       nbytes += lp->limit - (char *) lp;
465     }
466   return nbytes;
467 }
468 
469 /* Define the error handler.  */
470 #ifndef _
471 # ifdef HAVE_LIBINTL_H
472 #  include <libintl.h>
473 #  ifndef _
474 #   define _(Str) gettext (Str)
475 #  endif
476 # else
477 #  define _(Str) (Str)
478 # endif
479 #endif
480 #if defined _LIBC && defined USE_IN_LIBIO
481 # include <libio/iolibio.h>
482 # define fputs(s, f) _IO_fputs (s, f)
483 #endif
484 
485 static void
486 print_and_abort ()
487 {
488   fputs (_("memory exhausted"), stderr);
489   fputc ('\n', stderr);
490   exit (obstack_exit_failure);
491 }
492 
493 #if 0
494 /* These are now turned off because the applications do not use it
495    and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
496 
497 /* Now define the functional versions of the obstack macros.
498    Define them to simply use the corresponding macros to do the job.  */
499 
500 #if defined (__STDC__) && __STDC__
501 /* These function definitions do not work with non-ANSI preprocessors;
502    they won't pass through the macro names in parentheses.  */
503 
504 /* The function names appear in parentheses in order to prevent
505    the macro-definitions of the names from being expanded there.  */
506 
507 POINTER (obstack_base) (obstack)
508      struct obstack *obstack;
509 {
510   return obstack_base (obstack);
511 }
512 
513 POINTER (obstack_next_free) (obstack)
514      struct obstack *obstack;
515 {
516   return obstack_next_free (obstack);
517 }
518 
519 int (obstack_object_size) (obstack)
520      struct obstack *obstack;
521 {
522   return obstack_object_size (obstack);
523 }
524 
525 int (obstack_room) (obstack)
526      struct obstack *obstack;
527 {
528   return obstack_room (obstack);
529 }
530 
531 int (obstack_make_room) (obstack, length)
532      struct obstack *obstack;
533      int length;
534 {
535   return obstack_make_room (obstack, length);
536 }
537 
538 void (obstack_grow) (obstack, pointer, length)
539      struct obstack *obstack;
540      POINTER pointer;
541      int length;
542 {
543   obstack_grow (obstack, pointer, length);
544 }
545 
546 void (obstack_grow0) (obstack, pointer, length)
547      struct obstack *obstack;
548      POINTER pointer;
549      int length;
550 {
551   obstack_grow0 (obstack, pointer, length);
552 }
553 
554 void (obstack_1grow) (obstack, character)
555      struct obstack *obstack;
556      int character;
557 {
558   obstack_1grow (obstack, character);
559 }
560 
561 void (obstack_blank) (obstack, length)
562      struct obstack *obstack;
563      int length;
564 {
565   obstack_blank (obstack, length);
566 }
567 
568 void (obstack_1grow_fast) (obstack, character)
569      struct obstack *obstack;
570      int character;
571 {
572   obstack_1grow_fast (obstack, character);
573 }
574 
575 void (obstack_blank_fast) (obstack, length)
576      struct obstack *obstack;
577      int length;
578 {
579   obstack_blank_fast (obstack, length);
580 }
581 
582 POINTER (obstack_finish) (obstack)
583      struct obstack *obstack;
584 {
585   return obstack_finish (obstack);
586 }
587 
588 POINTER (obstack_alloc) (obstack, length)
589      struct obstack *obstack;
590      int length;
591 {
592   return obstack_alloc (obstack, length);
593 }
594 
595 POINTER (obstack_copy) (obstack, pointer, length)
596      struct obstack *obstack;
597      POINTER pointer;
598      int length;
599 {
600   return obstack_copy (obstack, pointer, length);
601 }
602 
603 POINTER (obstack_copy0) (obstack, pointer, length)
604      struct obstack *obstack;
605      POINTER pointer;
606      int length;
607 {
608   return obstack_copy0 (obstack, pointer, length);
609 }
610 
611 #endif /* __STDC__ */
612 
613 #endif /* 0 */
614 
615 #endif	/* !ELIDE_CODE */
616