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