1 |
/* obstack.c - subroutines used implicitly by object stack macros |
/* obstack.c - subroutines used implicitly by object stack macros |
2 |
Copyright (C) 1988-1994,96,97,98,99,2000 Free Software Foundation, Inc. |
Copyright (C) 1988-1994,96,97,98,99,2000,2001 Free Software Foundation, Inc. |
|
|
|
3 |
This file is part of the GNU C Library. Its master source is NOT part of |
This file is part of the GNU C Library. Its master source is NOT part of |
4 |
the C library, however. The master source lives in /gd/gnu/lib. |
the C library, however. The master source lives in /gd/gnu/lib. |
5 |
|
|
6 |
The GNU C Library is free software; you can redistribute it and/or |
The GNU C Library is free software; you can redistribute it and/or |
7 |
modify it under the terms of the GNU Library General Public License as |
modify it under the terms of the GNU Lesser General Public |
8 |
published by the Free Software Foundation; either version 2 of the |
License as published by the Free Software Foundation; either |
9 |
License, or (at your option) any later version. |
version 2.1 of the License, or (at your option) any later version. |
10 |
|
|
11 |
The GNU C Library is distributed in the hope that it will be useful, |
The GNU C Library is distributed in the hope that it will be useful, |
12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
Library General Public License for more details. |
Lesser General Public License for more details. |
15 |
|
|
16 |
You should have received a copy of the GNU Library General Public |
You should have received a copy of the GNU Lesser General Public |
17 |
License along with the GNU C Library; see the file COPYING.LIB. If not, |
License along with the GNU C Library; if not, write to the Free |
18 |
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
19 |
Boston, MA 02111-1307, USA. */ |
02111-1307 USA. */ |
20 |
|
|
21 |
#ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
22 |
#include <config.h> |
# include <config.h> |
23 |
#endif |
#endif |
24 |
|
|
25 |
#include "obstack.h" |
#include "obstack.h" |
39 |
files, it is simpler to just do this in the source for each such file. */ |
files, it is simpler to just do this in the source for each such file. */ |
40 |
|
|
41 |
#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */ |
#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */ |
42 |
#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1 |
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 |
43 |
#include <gnu-versions.h> |
# include <gnu-versions.h> |
44 |
#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION |
# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION |
45 |
#define ELIDE_CODE |
# define ELIDE_CODE |
46 |
#endif |
# endif |
47 |
#endif |
#endif |
48 |
|
|
49 |
|
#if defined _LIBC && defined USE_IN_LIBIO |
50 |
|
# include <wchar.h> |
51 |
|
#endif |
52 |
|
|
53 |
#ifndef ELIDE_CODE |
#ifndef ELIDE_CODE |
54 |
|
|
55 |
|
|
56 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
57 |
#define POINTER void * |
# define POINTER void * |
58 |
#else |
# else |
59 |
#define POINTER char * |
# define POINTER char * |
60 |
#endif |
# endif |
61 |
|
|
62 |
/* Determine default alignment. */ |
/* Determine default alignment. */ |
63 |
struct fooalign {char x; double d;}; |
struct fooalign {char x; double d;}; |
64 |
#define DEFAULT_ALIGNMENT \ |
# define DEFAULT_ALIGNMENT \ |
65 |
((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0)) |
((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0)) |
66 |
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. |
/* 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 |
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. */ |
DEFAULT_ROUNDING. So we prepare for it to do that. */ |
69 |
union fooround {long x; double d;}; |
union fooround {long x; double d;}; |
70 |
#define DEFAULT_ROUNDING (sizeof (union fooround)) |
# define DEFAULT_ROUNDING (sizeof (union fooround)) |
71 |
|
|
72 |
/* When we copy a long block of data, this is the unit to do it with. |
/* 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; |
On some machines, copying successive ints does not work; |
74 |
in such a case, redefine COPYING_UNIT to `long' (if that works) |
in such a case, redefine COPYING_UNIT to `long' (if that works) |
75 |
or `char' as a last resort. */ |
or `char' as a last resort. */ |
76 |
#ifndef COPYING_UNIT |
# ifndef COPYING_UNIT |
77 |
#define COPYING_UNIT int |
# define COPYING_UNIT int |
78 |
#endif |
# endif |
79 |
|
|
80 |
|
|
81 |
/* The functions allocating more room by calling `obstack_chunk_alloc' |
/* The functions allocating more room by calling `obstack_chunk_alloc' |
84 |
abort gracefully or use longjump - but shouldn't return. This |
abort gracefully or use longjump - but shouldn't return. This |
85 |
variable by default points to the internal function |
variable by default points to the internal function |
86 |
`print_and_abort'. */ |
`print_and_abort'. */ |
87 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
88 |
static void print_and_abort (void); |
static void print_and_abort (void); |
89 |
void (*obstack_alloc_failed_handler) (void) = print_and_abort; |
void (*obstack_alloc_failed_handler) (void) = print_and_abort; |
90 |
#else |
# else |
91 |
static void print_and_abort (); |
static void print_and_abort (); |
92 |
void (*obstack_alloc_failed_handler) () = print_and_abort; |
void (*obstack_alloc_failed_handler) () = print_and_abort; |
93 |
#endif |
# endif |
94 |
|
|
95 |
/* Exit value used when `print_and_abort' is used. */ |
/* Exit value used when `print_and_abort' is used. */ |
96 |
#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H |
# if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H |
97 |
#include <stdlib.h> |
# include <stdlib.h> |
98 |
#endif |
# endif |
99 |
#ifndef EXIT_FAILURE |
# ifndef EXIT_FAILURE |
100 |
#define EXIT_FAILURE 1 |
# define EXIT_FAILURE 1 |
101 |
#endif |
# endif |
102 |
int obstack_exit_failure = EXIT_FAILURE; |
int obstack_exit_failure = EXIT_FAILURE; |
103 |
|
|
104 |
/* The non-GNU-C macros copy the obstack into this global variable |
/* The non-GNU-C macros copy the obstack into this global variable |
112 |
For free, do not use ?:, since some compilers, like the MIPS compilers, |
For free, do not use ?:, since some compilers, like the MIPS compilers, |
113 |
do not allow (expr) ? void : void. */ |
do not allow (expr) ? void : void. */ |
114 |
|
|
115 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
116 |
#define CALL_CHUNKFUN(h, size) \ |
# define CALL_CHUNKFUN(h, size) \ |
117 |
(((h) -> use_extra_arg) \ |
(((h) -> use_extra_arg) \ |
118 |
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ |
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ |
119 |
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) |
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) |
120 |
|
|
121 |
#define CALL_FREEFUN(h, old_chunk) \ |
# define CALL_FREEFUN(h, old_chunk) \ |
122 |
do { \ |
do { \ |
123 |
if ((h) -> use_extra_arg) \ |
if ((h) -> use_extra_arg) \ |
124 |
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ |
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ |
125 |
else \ |
else \ |
126 |
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ |
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ |
127 |
} while (0) |
} while (0) |
128 |
#else |
# else |
129 |
#define CALL_CHUNKFUN(h, size) \ |
# define CALL_CHUNKFUN(h, size) \ |
130 |
(((h) -> use_extra_arg) \ |
(((h) -> use_extra_arg) \ |
131 |
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ |
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ |
132 |
: (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size))) |
: (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size))) |
133 |
|
|
134 |
#define CALL_FREEFUN(h, old_chunk) \ |
# define CALL_FREEFUN(h, old_chunk) \ |
135 |
do { \ |
do { \ |
136 |
if ((h) -> use_extra_arg) \ |
if ((h) -> use_extra_arg) \ |
137 |
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ |
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ |
138 |
else \ |
else \ |
139 |
(*(void (*) ()) (h)->freefun) ((old_chunk)); \ |
(*(void (*) ()) (h)->freefun) ((old_chunk)); \ |
140 |
} while (0) |
} while (0) |
141 |
#endif |
# endif |
142 |
|
|
143 |
|
|
144 |
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). |
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). |
154 |
struct obstack *h; |
struct obstack *h; |
155 |
int size; |
int size; |
156 |
int alignment; |
int alignment; |
157 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
158 |
POINTER (*chunkfun) (long); |
POINTER (*chunkfun) (long); |
159 |
void (*freefun) (void *); |
void (*freefun) (void *); |
160 |
#else |
# else |
161 |
POINTER (*chunkfun) (); |
POINTER (*chunkfun) (); |
162 |
void (*freefun) (); |
void (*freefun) (); |
163 |
#endif |
# endif |
164 |
{ |
{ |
165 |
register struct _obstack_chunk *chunk; /* points to new chunk */ |
register struct _obstack_chunk *chunk; /* points to new chunk */ |
166 |
|
|
183 |
size = 4096 - extra; |
size = 4096 - extra; |
184 |
} |
} |
185 |
|
|
186 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
187 |
h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; |
h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; |
188 |
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; |
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; |
189 |
#else |
# else |
190 |
h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; |
h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; |
191 |
h->freefun = freefun; |
h->freefun = freefun; |
192 |
#endif |
# endif |
193 |
h->chunk_size = size; |
h->chunk_size = size; |
194 |
h->alignment_mask = alignment - 1; |
h->alignment_mask = alignment - 1; |
195 |
h->use_extra_arg = 0; |
h->use_extra_arg = 0; |
212 |
struct obstack *h; |
struct obstack *h; |
213 |
int size; |
int size; |
214 |
int alignment; |
int alignment; |
215 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
216 |
POINTER (*chunkfun) (POINTER, long); |
POINTER (*chunkfun) (POINTER, long); |
217 |
void (*freefun) (POINTER, POINTER); |
void (*freefun) (POINTER, POINTER); |
218 |
#else |
# else |
219 |
POINTER (*chunkfun) (); |
POINTER (*chunkfun) (); |
220 |
void (*freefun) (); |
void (*freefun) (); |
221 |
#endif |
# endif |
222 |
POINTER arg; |
POINTER arg; |
223 |
{ |
{ |
224 |
register struct _obstack_chunk *chunk; /* points to new chunk */ |
register struct _obstack_chunk *chunk; /* points to new chunk */ |
242 |
size = 4096 - extra; |
size = 4096 - extra; |
243 |
} |
} |
244 |
|
|
245 |
#if defined(__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
246 |
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; |
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; |
247 |
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; |
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; |
248 |
#else |
# else |
249 |
h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; |
h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; |
250 |
h->freefun = freefun; |
h->freefun = freefun; |
251 |
#endif |
# endif |
252 |
h->chunk_size = size; |
h->chunk_size = size; |
253 |
h->alignment_mask = alignment - 1; |
h->alignment_mask = alignment - 1; |
254 |
h->extra_arg = arg; |
h->extra_arg = arg; |
343 |
This is here for debugging. |
This is here for debugging. |
344 |
If you use it in a program, you are probably losing. */ |
If you use it in a program, you are probably losing. */ |
345 |
|
|
346 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
347 |
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in |
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in |
348 |
obstack.h because it is just for debugging. */ |
obstack.h because it is just for debugging. */ |
349 |
int _obstack_allocated_p (struct obstack *h, POINTER obj); |
int _obstack_allocated_p (struct obstack *h, POINTER obj); |
350 |
#endif |
# endif |
351 |
|
|
352 |
int |
int |
353 |
_obstack_allocated_p (h, obj) |
_obstack_allocated_p (h, obj) |
372 |
/* Free objects in obstack H, including OBJ and everything allocate |
/* Free objects in obstack H, including OBJ and everything allocate |
373 |
more recently than OBJ. If OBJ is zero, free everything in H. */ |
more recently than OBJ. If OBJ is zero, free everything in H. */ |
374 |
|
|
375 |
#undef obstack_free |
# undef obstack_free |
376 |
|
|
377 |
/* This function has two names with identical definitions. |
/* This function has two names with identical definitions. |
378 |
This is the first one, called from non-ANSI code. */ |
This is the first one, called from non-ANSI code. */ |
458 |
} |
} |
459 |
|
|
460 |
/* Define the error handler. */ |
/* Define the error handler. */ |
461 |
#ifndef _ |
# ifndef _ |
462 |
# if defined HAVE_LIBINTL_H || defined _LIBC |
# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC |
463 |
# include <libintl.h> |
# include <libintl.h> |
464 |
# ifndef _ |
# ifndef _ |
465 |
# define _(Str) gettext (Str) |
# define _(Str) gettext (Str) |
466 |
|
# endif |
467 |
|
# else |
468 |
|
# define _(Str) (Str) |
469 |
|
# endif |
470 |
|
# endif |
471 |
|
# if defined _LIBC && defined USE_IN_LIBIO |
472 |
|
# include <libio/iolibio.h> |
473 |
|
# define fputs(s, f) _IO_fputs (s, f) |
474 |
|
# endif |
475 |
|
|
476 |
|
# ifndef __attribute__ |
477 |
|
/* This feature is available in gcc versions 2.5 and later. */ |
478 |
|
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) |
479 |
|
# define __attribute__(Spec) /* empty */ |
480 |
# endif |
# endif |
|
# else |
|
|
# define _(Str) (Str) |
|
481 |
# endif |
# endif |
|
#endif |
|
|
#if defined _LIBC && defined USE_IN_LIBIO |
|
|
# include <libio/iolibio.h> |
|
|
# define fputs(s, f) _IO_fputs (s, f) |
|
|
#endif |
|
482 |
|
|
483 |
static void |
static void |
484 |
|
__attribute__ ((noreturn)) |
485 |
print_and_abort () |
print_and_abort () |
486 |
{ |
{ |
487 |
fputs (_("memory exhausted"), stderr); |
/* Don't change any of these strings. Yes, it would be possible to add |
488 |
fputc ('\n', stderr); |
the newline to the string and use fputs or so. But this must not |
489 |
|
happen because the "memory exhausted" message appears in other places |
490 |
|
like this and the translation should be reused instead of creating |
491 |
|
a very similar string which requires a separate translation. */ |
492 |
|
# if defined _LIBC && defined USE_IN_LIBIO |
493 |
|
if (_IO_fwide (stderr, 0) > 0) |
494 |
|
__fwprintf (stderr, L"%s\n", _("memory exhausted")); |
495 |
|
else |
496 |
|
# endif |
497 |
|
fprintf (stderr, "%s\n", _("memory exhausted")); |
498 |
exit (obstack_exit_failure); |
exit (obstack_exit_failure); |
499 |
} |
} |
500 |
|
|
501 |
#if 0 |
# if 0 |
502 |
/* These are now turned off because the applications do not use it |
/* These are now turned off because the applications do not use it |
503 |
and it uses bcopy via obstack_grow, which causes trouble on sysV. */ |
and it uses bcopy via obstack_grow, which causes trouble on sysV. */ |
504 |
|
|
505 |
/* Now define the functional versions of the obstack macros. |
/* Now define the functional versions of the obstack macros. |
506 |
Define them to simply use the corresponding macros to do the job. */ |
Define them to simply use the corresponding macros to do the job. */ |
507 |
|
|
508 |
#if defined (__STDC__) && __STDC__ |
# if defined __STDC__ && __STDC__ |
509 |
/* These function definitions do not work with non-ANSI preprocessors; |
/* These function definitions do not work with non-ANSI preprocessors; |
510 |
they won't pass through the macro names in parentheses. */ |
they won't pass through the macro names in parentheses. */ |
511 |
|
|
616 |
return obstack_copy0 (obstack, address, length); |
return obstack_copy0 (obstack, address, length); |
617 |
} |
} |
618 |
|
|
619 |
#endif /* __STDC__ */ |
# endif /* __STDC__ */ |
620 |
|
|
621 |
#endif /* 0 */ |
# endif /* 0 */ |
622 |
|
|
623 |
#endif /* !ELIDE_CODE */ |
#endif /* !ELIDE_CODE */ |