Subversion Repositories Kolibri OS

Rev

Rev 5191 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5191 Rev 6324
Line 1... Line 1...
1
/* obstack.c - subroutines used implicitly by object stack macros
1
/* obstack.c - subroutines used implicitly by object stack macros
2
   Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
2
   Copyright (C) 1988-2015 Free Software Foundation, Inc.
-
 
3
   This file is part of the GNU C Library.
Line -... Line 4...
-
 
4
 
-
 
5
   The GNU C Library is free software; you can redistribute it and/or
-
 
6
   modify it under the terms of the GNU Lesser General Public
-
 
7
   License as published by the Free Software Foundation; either
Line 3... Line -...
3
 
-
 
4
 
-
 
5
   NOTE: This source is derived from an old version taken from the GNU C
-
 
6
   Library (glibc).
-
 
7
 
-
 
8
   This program is free software; you can redistribute it and/or modify it
-
 
9
   under the terms of the GNU General Public License as published by the
-
 
10
   Free Software Foundation; either version 2, or (at your option) any
-
 
11
   later version.
8
   version 2.1 of the License, or (at your option) any later version.
12
 
9
 
13
   This program is distributed in the hope that it will be useful,
10
   The GNU C Library is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Line 15... Line 12...
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
   GNU General Public License for more details.
13
   Lesser General Public License for more details.
17
 
14
 
18
   You should have received a copy of the GNU General Public License
-
 
Line 19... Line -...
19
   along with this program; if not, write to the Free Software
-
 
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
-
 
21
   USA.  */
-
 
Line -... Line 15...
-
 
15
   You should have received a copy of the GNU Lesser General Public
-
 
16
   License along with the GNU C Library; if not, see
-
 
17
   .  */
-
 
18
 
22
 
19
 
-
 
20
#ifdef _LIBC
Line 23... Line 21...
23
#ifdef HAVE_CONFIG_H
21
# include 
24
#include 
22
#else
25
#endif
23
# include 
26
 
-
 
Line 27... Line 24...
27
#include "obstack.h"
24
# include "obstack.h"
28
 
25
#endif
29
/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
26
 
30
   incremented whenever callers compiled using an old obstack.h can no
27
/* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in
31
   longer properly call the functions in this obstack.c.  */
28
   obstack.h must be incremented whenever callers compiled using an old
32
#define OBSTACK_INTERFACE_VERSION 1
29
   obstack.h can no longer properly call the functions in this file.  */
33
 
30
 
34
/* Comment out all this code if we are using the GNU C Library, and are not
31
/* Comment out all this code if we are using the GNU C Library, and are not
35
   actually compiling the library itself, and the installed library
-
 
36
   supports the same library interface we do.  This code is part of the GNU
-
 
37
   C Library, but also included in many other GNU distributions.  Compiling
32
   actually compiling the library itself, and the installed library
38
   and linking in this code is a waste when using the GNU C library
33
   supports the same library interface we do.  This code is part of the GNU
39
   (especially if it is a shared library).  Rather than having every GNU
34
   C Library, but also included in many other GNU distributions.  Compiling
-
 
35
   and linking in this code is a waste when using the GNU C library
-
 
36
   (especially if it is a shared library).  Rather than having every GNU
-
 
37
   program understand 'configure --with-gnu-libc' and omit the object
-
 
38
   files, it is simpler to just do this in the source for each such file.  */
40
   program understand `configure --with-gnu-libc' and omit the object
39
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
41
   files, it is simpler to just do this in the source for each such file.  */
40
# include 
42
 
41
# if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION	      \
Line -... Line 42...
-
 
42
      || (_GNU_OBSTACK_INTERFACE_VERSION == 1				      \
-
 
43
          && _OBSTACK_INTERFACE_VERSION == 2				      \
-
 
44
          && defined SIZEOF_INT && defined SIZEOF_SIZE_T		      \
-
 
45
          && SIZEOF_INT == SIZEOF_SIZE_T))
-
 
46
#  define _OBSTACK_ELIDE_CODE
-
 
47
# endif
-
 
48
#endif
-
 
49
 
-
 
50
#ifndef _OBSTACK_ELIDE_CODE
-
 
51
/* If GCC, or if an oddball (testing?) host that #defines __alignof__,
-
 
52
   use the already-supplied __alignof__.  Otherwise, this must be Gnulib
-
 
53
   (as glibc assumes GCC); defer to Gnulib's alignof_type.  */
-
 
54
# if !defined __GNUC__ && !defined __IBM__ALIGNOF__ && !defined __alignof__
-
 
55
#  if defined __cplusplus
-
 
56
template  struct alignof_helper { char __slot1; type __slot2; };
Line 43... Line 57...
43
#include 		/* Random thing to get __GNU_LIBRARY__.  */
57
#   define __alignof__(type) offsetof (alignof_helper, __slot2)
44
#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
-
 
45
#include 
-
 
46
#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
58
#  else
-
 
59
#   define __alignof__(type)						      \
Line 47... Line 60...
47
#define ELIDE_CODE
60
  offsetof (struct { char __slot1; type __slot2; }, __slot2)
48
#endif
-
 
49
#endif
-
 
50
 
-
 
-
 
61
#  endif
51
 
62
# endif
52
#ifndef ELIDE_CODE
63
# include 
53
 
64
# include 
54
 
-
 
55
#define POINTER void *
-
 
56
 
-
 
57
/* Determine default alignment.  */
-
 
58
struct fooalign {char x; double d;};
-
 
59
#define DEFAULT_ALIGNMENT  \
-
 
60
  ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
-
 
61
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
-
 
62
   But in fact it might be less smart and round addresses to as much as
-
 
63
   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
-
 
Line -... Line 65...
-
 
65
 
-
 
66
# ifndef MAX
-
 
67
#  define MAX(a,b) ((a) > (b) ? (a) : (b))
-
 
68
# endif
-
 
69
 
-
 
70
/* Determine default alignment.  */
-
 
71
 
-
 
72
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
-
 
73
   But in fact it might be less smart and round addresses to as much as
-
 
74
   DEFAULT_ROUNDING.  So we prepare for it to do that.
-
 
75
 
Line 64... Line -...
64
union fooround {long x; double d;};
-
 
65
#define DEFAULT_ROUNDING (sizeof (union fooround))
-
 
66
 
-
 
67
/* When we copy a long block of data, this is the unit to do it with.
-
 
68
   On some machines, copying successive ints does not work;
76
   DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h.  */
69
   in such a case, redefine COPYING_UNIT to `long' (if that works)
77
#define DEFAULT_ALIGNMENT MAX (__alignof__ (long double),		      \
70
   or `char' as a last resort.  */
78
                               MAX (__alignof__ (uintmax_t),		      \
71
#ifndef COPYING_UNIT
79
                                    __alignof__ (void *)))
72
#define COPYING_UNIT int
80
#define DEFAULT_ROUNDING MAX (sizeof (long double),			      \
73
#endif
-
 
74
 
-
 
75
 
-
 
76
/* The functions allocating more room by calling `obstack_chunk_alloc'
-
 
77
   jump to the handler pointed to by `obstack_alloc_failed_handler'.
81
                               MAX (sizeof (uintmax_t),			      \
78
   This variable by default points to the internal function
-
 
79
   `print_and_abort'.  */
-
 
80
static void print_and_abort (void);
-
 
81
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
82
                                    sizeof (void *)))
82
 
83
 
83
/* Exit value used when `print_and_abort' is used.  */
-
 
Line 84... Line -...
84
#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
-
 
85
#include 
-
 
86
#endif
-
 
87
#ifndef EXIT_FAILURE
-
 
88
#define EXIT_FAILURE 1
84
/* Call functions with either the traditional malloc/free calling
89
#endif
-
 
90
int obstack_exit_failure = EXIT_FAILURE;
-
 
91
 
-
 
92
/* The non-GNU-C macros copy the obstack into this global variable
-
 
93
   to avoid multiple evaluation.  */
-
 
94
 
85
   interface, or the mmalloc/mfree interface (that adds an extra first
95
struct obstack *_obstack;
86
   argument), based on the value of use_extra_arg.  */
96
 
-
 
97
/* Define a macro that either calls functions with the traditional malloc/free
-
 
98
   calling interface, or calls functions with the mmalloc/mfree interface
87
 
99
   (that adds an extra first argument), based on the state of use_extra_arg.
88
static void *
100
   For free, do not use ?:, since some compilers, like the MIPS compilers,
-
 
101
   do not allow (expr) ? void : void.  */
-
 
102
 
-
 
103
#if defined (__STDC__) && __STDC__
89
call_chunkfun (struct obstack *h, size_t size)
104
#define CALL_CHUNKFUN(h, size) \
-
 
105
  (((h) -> use_extra_arg) \
-
 
106
   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
90
{
107
   : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
-
 
108
 
91
  if (h->use_extra_arg)
109
#define CALL_FREEFUN(h, old_chunk) \
-
 
110
  do { \
-
 
111
    if ((h) -> use_extra_arg) \
-
 
112
      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
-
 
113
    else \
-
 
114
      (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
-
 
115
  } while (0)
-
 
116
#else
-
 
Line 117... Line 92...
117
#define CALL_CHUNKFUN(h, size) \
92
    return h->chunkfun.extra (h->extra_arg, size);
118
  (((h) -> use_extra_arg) \
93
  else
119
   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
94
    return h->chunkfun.plain (size);
120
   : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
-
 
121
 
-
 
Line 122... Line 95...
122
#define CALL_FREEFUN(h, old_chunk) \
95
}
123
  do { \
-
 
124
    if ((h) -> use_extra_arg) \
96
 
Line 125... Line 97...
125
      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
97
static void
126
    else \
98
call_freefun (struct obstack *h, void *old_chunk)
127
      (*(void (*) ()) (h)->freefun) ((old_chunk)); \
99
{
128
  } while (0)
100
  if (h->use_extra_arg)
129
#endif
101
    h->freefun.extra (h->extra_arg, old_chunk);
Line 130... Line 102...
130
 
102
  else
131

103
    h->freefun.plain (old_chunk);
132
/* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
104
}
133
   Objects start on multiples of ALIGNMENT (0 means use default).
105
 
134
   CHUNKFUN is the function to use to allocate chunks,
106
 
135
   and FREEFUN the function to free them.
107
/* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
136
 
108
   Objects start on multiples of ALIGNMENT (0 means use default).
Line 161... Line 133...
161
		    + 4 + DEFAULT_ROUNDING - 1)
133
		    + 4 + DEFAULT_ROUNDING - 1)
162
		   & ~(DEFAULT_ROUNDING - 1));
134
		   & ~(DEFAULT_ROUNDING - 1));
163
      size = 4096 - extra;
135
      size = 4096 - extra;
164
    }
136
    }
Line 165... Line -...
165
 
-
 
166
  h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
-
 
167
  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
137
 
168
  h->chunk_size = size;
138
  h->chunk_size = size;
169
  h->alignment_mask = alignment - 1;
-
 
Line 170... Line 139...
170
  h->use_extra_arg = 0;
139
  h->alignment_mask = alignment - 1;
171
 
140
 
172
  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
141
  chunk = (struct _obstack_chunk *) call_chunkfun (h, h->chunk_size);
-
 
142
  if (!chunk)
173
  if (!chunk)
143
    (*obstack_alloc_failed_handler) ();
174
    (*obstack_alloc_failed_handler) ();
144
  h->chunk = chunk;
175
  h->next_free = h->object_base = chunk->contents;
145
  h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
176
  h->chunk_limit = chunk->limit
146
                                               alignment - 1);
177
    = (char *) chunk + h->chunk_size;
147
  h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size;
178
  chunk->prev = 0;
148
  chunk->prev = 0;
179
  /* The initial chunk now contains no empty object.  */
149
  /* The initial chunk now contains no empty object.  */
180
  h->maybe_empty_object = 0;
150
  h->maybe_empty_object = 0;
181
  h->alloc_failed = 0;
151
  h->alloc_failed = 0;
Line 182... Line 152...
182
  return 1;
152
  return 1;
183
}
153
}
184
 
154
 
185
int
155
int
186
_obstack_begin_1 (struct obstack *h, int size, int alignment,
-
 
187
                  POINTER (*chunkfun) (POINTER, long),
-
 
188
                  void (*freefun) (POINTER, POINTER), POINTER arg)
-
 
189
{
-
 
190
  register struct _obstack_chunk *chunk; /* points to new chunk */
156
_obstack_begin (struct obstack *h,
191
 
-
 
192
  if (alignment == 0)
-
 
193
    alignment = (int) DEFAULT_ALIGNMENT;
157
                _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
194
  if (size == 0)
-
 
195
    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
-
 
196
    {
-
 
197
      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
-
 
198
	 Use the values for range checking, because if range checking is off,
-
 
199
	 the extra bytes won't be missed terribly, but if range checking is on
-
 
200
	 and we used a larger request, a whole extra 4096 bytes would be
-
 
201
	 allocated.
158
                void *(*chunkfun) (size_t),
202
 
-
 
203
	 These number are irrelevant to the new GNU malloc.  I suspect it is
159
                void (*freefun) (void *))
204
	 less sensitive to the size of the request.  */
160
{
205
      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
161
  h->chunkfun.plain = chunkfun;
206
		    + 4 + DEFAULT_ROUNDING - 1)
162
  h->freefun.plain = freefun;
Line -... Line 163...
-
 
163
  h->use_extra_arg = 0;
-
 
164
  return _obstack_begin_worker (h, size, alignment);
-
 
165
}
207
		   & ~(DEFAULT_ROUNDING - 1));
166
 
208
      size = 4096 - extra;
167
int
-
 
168
_obstack_begin_1 (struct obstack *h,
-
 
169
                  _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
209
    }
170
                  void *(*chunkfun) (void *, size_t),
210
 
171
                  void (*freefun) (void *, void *),
211
  h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
172
                  void *arg)
212
  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
173
{
213
  h->chunk_size = size;
-
 
214
  h->alignment_mask = alignment - 1;
-
 
215
  h->extra_arg = arg;
-
 
216
  h->use_extra_arg = 1;
174
  h->chunkfun.extra = chunkfun;
217
 
-
 
218
  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
-
 
219
  if (!chunk)
-
 
220
    (*obstack_alloc_failed_handler) ();
-
 
221
  h->next_free = h->object_base = chunk->contents;
-
 
222
  h->chunk_limit = chunk->limit
-
 
223
    = (char *) chunk + h->chunk_size;
-
 
224
  chunk->prev = 0;
-
 
225
  /* The initial chunk now contains no empty object.  */
175
  h->freefun.extra = freefun;
Line 226... Line 176...
226
  h->maybe_empty_object = 0;
176
  h->extra_arg = arg;
227
  h->alloc_failed = 0;
177
  h->use_extra_arg = 1;
228
  return 1;
178
  return _obstack_begin_worker (h, size, alignment);
229
}
179
}
230
 
180
 
Line 231... Line 181...
231
/* Allocate a new current chunk for the obstack *H
181
/* Allocate a new current chunk for the obstack *H
232
   on the assumption that LENGTH bytes need to be added
182
   on the assumption that LENGTH bytes need to be added
233
   to the current object, or a new object of length LENGTH allocated.
183
   to the current object, or a new object of length LENGTH allocated.
234
   Copies any partial object from the end of the old chunk
184
   Copies any partial object from the end of the old chunk
235
   to the beginning of the new one.  */
185
   to the beginning of the new one.  */
236
 
-
 
237
void
186
 
238
_obstack_newchunk (struct obstack *h, int length)
-
 
239
{
187
void
Line 240... Line 188...
240
  register struct _obstack_chunk *old_chunk = h->chunk;
188
_obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
-
 
189
{
-
 
190
  struct _obstack_chunk *old_chunk = h->chunk;
241
  register struct _obstack_chunk *new_chunk;
191
  struct _obstack_chunk *new_chunk = 0;
-
 
192
  size_t obj_size = h->next_free - h->object_base;
-
 
193
  char *object_base;
242
  register long	new_size;
194
 
243
  register long obj_size = h->next_free - h->object_base;
195
  /* Compute size for new chunk.  */
Line 244... Line 196...
244
  register long i;
196
  size_t sum1 = obj_size + length;
-
 
197
  size_t sum2 = sum1 + h->alignment_mask;
245
  long already;
198
  size_t new_size = sum2 + (obj_size >> 3) + 100;
246
 
199
  if (new_size < sum2)
247
  /* Compute size for new chunk.  */
200
    new_size = sum2;
248
  new_size = (obj_size + length) + (obj_size >> 3) + 100;
201
  if (new_size < h->chunk_size)
249
  if (new_size < h->chunk_size)
202
    new_size = h->chunk_size;
250
    new_size = h->chunk_size;
203
 
Line 251... Line 204...
251
 
204
  /* Allocate and initialize the new chunk.  */
252
  /* Allocate and initialize the new chunk.  */
-
 
253
  new_chunk = CALL_CHUNKFUN (h, new_size);
-
 
254
  if (!new_chunk)
-
 
255
    (*obstack_alloc_failed_handler) ();
-
 
256
  h->chunk = new_chunk;
-
 
257
  new_chunk->prev = old_chunk;
205
  if (obj_size <= sum1 && sum1 <= sum2)
258
  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
206
    new_chunk = (struct _obstack_chunk *) call_chunkfun (h, new_size);
259
 
-
 
260
  /* Move the existing object to the new chunk.
-
 
261
     Word at a time is fast and is safe if the object
-
 
262
     is sufficiently aligned.  */
-
 
263
  if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
-
 
264
    {
207
  if (!new_chunk)
265
      for (i = obj_size / sizeof (COPYING_UNIT) - 1;
-
 
266
	   i >= 0; i--)
-
 
267
	((COPYING_UNIT *)new_chunk->contents)[i]
208
    (*obstack_alloc_failed_handler)();
268
	  = ((COPYING_UNIT *)h->object_base)[i];
-
 
269
      /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
209
  h->chunk = new_chunk;
Line 270... Line 210...
270
	 but that can cross a page boundary on a machine
210
  new_chunk->prev = old_chunk;
271
	 which does not do strict alignment for COPYING_UNITS.  */
211
  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
272
      already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
212
 
273
    }
213
  /* Compute an aligned object_base in the new chunk */
-
 
214
  object_base =
-
 
215
    __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
-
 
216
 
274
  else
217
  /* Move the existing object to the new chunk.  */
275
    already = 0;
218
  memcpy (object_base, h->object_base, obj_size);
276
  /* Copy remaining bytes one by one.  */
219
 
277
  for (i = already; i < obj_size; i++)
220
  /* If the object just copied was the only data in OLD_CHUNK,
Line 278... Line 221...
278
    new_chunk->contents[i] = h->object_base[i];
221
     free that chunk and remove it from the chain.
279
 
222
     But not if that chunk might contain an empty object.  */
280
  /* If the object just copied was the only data in OLD_CHUNK,
223
  if (!h->maybe_empty_object
281
     free that chunk and remove it from the chain.
224
      && (h->object_base
282
     But not if that chunk might contain an empty object.  */
225
          == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
Line 296... Line 239...
296
   This is here for debugging.
239
   This is here for debugging.
297
   If you use it in a program, you are probably losing.  */
240
   If you use it in a program, you are probably losing.  */
Line 298... Line 241...
298
 
241
 
299
/* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
242
/* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
300
   obstack.h because it is just for debugging.  */
243
   obstack.h because it is just for debugging.  */
Line 301... Line 244...
301
int _obstack_allocated_p (struct obstack *h, POINTER obj);
244
int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;
302
 
245
 
303
int
246
int
304
_obstack_allocated_p (struct obstack *h, POINTER obj)
247
_obstack_allocated_p (struct obstack *h, void *obj)
305
{
248
{
Line 306... Line 249...
306
  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
249
  struct _obstack_chunk *lp;    /* below addr of any objects in this chunk */
307
  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
250
  struct _obstack_chunk *plp;   /* point to previous chunk if any */
308
 
251
 
309
  lp = (h)->chunk;
252
  lp = (h)->chunk;
310
  /* We use >= rather than > since the object cannot be exactly at
253
  /* We use >= rather than > since the object cannot be exactly at
311
     the beginning of the chunk but might be an empty object exactly
254
     the beginning of the chunk but might be an empty object exactly
312
     at the end of an adjacent chunk.  */
255
     at the end of an adjacent chunk.  */
313
  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
256
  while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
314
    {
257
    {
315
      plp = lp->prev;
258
      plp = lp->prev;
316
      lp = plp;
259
      lp = plp;
317
    }
260
    }
318
  return lp != 0;
261
  return lp != 0;
319
}
262
}
Line 320... Line -...
320

-
 
321
/* Free objects in obstack H, including OBJ and everything allocate
-
 
322
   more recently than OBJ.  If OBJ is zero, free everything in H.  */
-
 
323
 
-
 
324
#undef obstack_free
-
 
325
 
263
 
326
/* This function has two names with identical definitions.
264
/* Free objects in obstack H, including OBJ and everything allocate
327
   This is the first one, called from non-ANSI code.  */
265
   more recently than OBJ.  If OBJ is zero, free everything in H.  */
328
 
266
 
329
void
267
void
Line 330... Line 268...
330
_obstack_free (struct obstack *h, POINTER obj)
268
_obstack_free (struct obstack *h, void *obj)
331
{
269
{
332
  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
270
  struct _obstack_chunk *lp;    /* below addr of any objects in this chunk */
333
  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
271
  struct _obstack_chunk *plp;   /* point to previous chunk if any */
334
 
272
 
335
  lp = h->chunk;
273
  lp = h->chunk;
336
  /* We use >= because there cannot be an object at the beginning of a chunk.
274
  /* We use >= because there cannot be an object at the beginning of a chunk.
337
     But there can be an empty object at that address
275
     But there can be an empty object at that address
338
     at the end of another chunk.  */
276
     at the end of another chunk.  */
339
  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
277
  while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
340
    {
278
    {
341
      plp = lp->prev;
279
      plp = lp->prev;
342
      CALL_FREEFUN (h, lp);
280
      call_freefun (h, lp);
Line 354... Line 292...
354
  else if (obj != 0)
292
  else if (obj != 0)
355
    /* obj is not in any of the chunks! */
293
    /* obj is not in any of the chunks! */
356
    abort ();
294
    abort ();
357
}
295
}
Line 358... Line -...
358
 
-
 
359
/* This function is used from ANSI code.  */
-
 
360
 
-
 
361
void
-
 
362
obstack_free (struct obstack *h, POINTER obj)
-
 
363
{
-
 
364
  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
-
 
365
  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
-
 
366
 
-
 
367
  lp = h->chunk;
-
 
368
  /* We use >= because there cannot be an object at the beginning of a chunk.
-
 
369
     But there can be an empty object at that address
-
 
370
     at the end of another chunk.  */
-
 
371
  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
-
 
372
    {
-
 
373
      plp = lp->prev;
-
 
374
      CALL_FREEFUN (h, lp);
296
 
375
      lp = plp;
-
 
376
      /* If we switch chunks, we can't tell whether the new current
-
 
377
	 chunk contains an empty object, so assume that it may.  */
-
 
378
      h->maybe_empty_object = 1;
-
 
379
    }
-
 
380
  if (lp)
-
 
381
    {
-
 
382
      h->object_base = h->next_free = (char *) (obj);
-
 
383
      h->chunk_limit = lp->limit;
-
 
384
      h->chunk = lp;
-
 
385
    }
-
 
386
  else if (obj != 0)
-
 
387
    /* obj is not in any of the chunks! */
-
 
388
    abort ();
-
 
389
}
-
 
390

-
 
391
int
297
_OBSTACK_SIZE_T
392
_obstack_memory_used (struct obstack *h)
298
_obstack_memory_used (struct obstack *h)
393
{
299
{
394
  register struct _obstack_chunk* lp;
300
  struct _obstack_chunk *lp;
Line 395... Line 301...
395
  register int nbytes = 0;
301
  _OBSTACK_SIZE_T nbytes = 0;
396
 
302
 
397
  for (lp = h->chunk; lp != 0; lp = lp->prev)
303
  for (lp = h->chunk; lp != 0; lp = lp->prev)
398
    {
304
    {
399
      nbytes += lp->limit - (char *) lp;
305
      nbytes += lp->limit - (char *) lp;
400
    }
306
    }
401
  return nbytes;
307
  return nbytes;
-
 
308
}
402
}
309
 
-
 
310
# ifndef _OBSTACK_NO_ERROR_HANDLER
-
 
311
/* Define the error handler.  */
-
 
312
#  include 
403

313
 
-
 
314
/* Exit value used when 'print_and_abort' is used.  */
-
 
315
#  ifdef _LIBC
-
 
316
int obstack_exit_failure = EXIT_FAILURE;
-
 
317
#  else
-
 
318
#   ifndef EXIT_FAILURE
-
 
319
#    define EXIT_FAILURE 1
-
 
320
#   endif
-
 
321
#   define obstack_exit_failure EXIT_FAILURE
404
/* Define the error handler.  */
322
#  endif
405
#ifndef _
323
 
406
# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
324
#  if defined _LIBC || (HAVE_LIBINTL_H && ENABLE_NLS)
407
#  include 
325
#  include 
408
#  ifndef _
326
#  ifndef _
409
#   define _(Str) gettext (Str)
327
#    define _(msgid) gettext (msgid)
-
 
328
#   endif
410
#  endif
329
#  else
411
# else
330
#   ifndef _
412
#  define _(Str) (Str)
331
#    define _(msgid) (msgid)
Line 413... Line -...
413
# endif
-
 
414
#endif
-
 
415
 
-
 
416
static void
332
#   endif
417
print_and_abort (void)
-
 
418
{
-
 
419
  fputs (_("memory exhausted\n"), stderr);
-
 
420
  exit (obstack_exit_failure);
-
 
421
}
-
 
422

333
#  endif
423
#if 0
-
 
424
/* These are now turned off because the applications do not use it
334
 
425
   and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
335
#  if !(defined _Noreturn						      \
426
 
-
 
427
/* Now define the functional versions of the obstack macros.
-
 
428
   Define them to simply use the corresponding macros to do the job.  */
-
 
429
 
-
 
430
/* The function names appear in parentheses in order to prevent
336
        || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112))
431
   the macro-definitions of the names from being expanded there.  */
-
 
432
 
337
#   if ((defined __GNUC__						      \
433
POINTER (obstack_base) (struct obstack *obstack)
-
 
434
{
-
 
435
  return obstack_base (obstack);
-
 
436
}
-
 
437
 
338
	 && (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)))	      \
438
POINTER (obstack_next_free) (struct obstack *obstack)
-
 
439
{
-
 
440
  return obstack_next_free (obstack);
-
 
441
}
-
 
442
 
339
	|| (defined __SUNPRO_C && __SUNPRO_C >= 0x5110))
443
int (obstack_object_size) (struct obstack *obstack)
-
 
444
{
-
 
445
  return obstack_object_size (obstack);
-
 
446
}
340
#    define _Noreturn __attribute__ ((__noreturn__))
447
 
341
#   elif defined _MSC_VER && _MSC_VER >= 1200
448
int (obstack_room) (struct obstack *obstack)
-
 
449
{
-
 
450
  return obstack_room (obstack);
-
 
451
}
-
 
452
 
-
 
453
int (obstack_make_room) (struct obstack *obstack, int length)
-
 
454
{
-
 
455
  return obstack_make_room (obstack, length);
-
 
456
}
-
 
457
 
-
 
458
void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
-
 
459
{
-
 
460
  obstack_grow (obstack, pointer, length);
-
 
461
}
-
 
462
 
-
 
463
void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
-
 
464
{
-
 
465
  obstack_grow0 (obstack, pointer, length);
-
 
466
}
-
 
467
 
-
 
468
void (obstack_1grow) (struct obstack *obstack, int character)
-
 
469
{
-
 
470
  obstack_1grow (obstack, character);
-
 
471
}
-
 
472
 
342
#    define _Noreturn __declspec (noreturn)
473
void (obstack_blank) (struct obstack *obstack, int length)
-
 
474
{
-
 
475
  obstack_blank (obstack, length);
-
 
476
}
-
 
477
 
-
 
478
void (obstack_1grow_fast) (struct obstack *obstack, int character)
-
 
479
{
-
 
480
  obstack_1grow_fast (obstack, character);
-
 
481
}
-
 
482
 
-
 
483
void (obstack_blank_fast) (struct obstack *obstack, int length)
-
 
484
{
-
 
485
  obstack_blank_fast (obstack, length);
-
 
486
}
-
 
487
 
-
 
488
POINTER (obstack_finish) (struct obstack *obstack)
-
 
489
{
-
 
490
  return obstack_finish (obstack);
-
 
491
}
-
 
492
 
-
 
493
POINTER (obstack_alloc) (struct obstack *obstack, int length)
343
# else
Line 494... Line -...
494
{
-
 
495
  return obstack_alloc (obstack, length);
344
#    define _Noreturn
496
}
345
#   endif
497
 
346
#  endif
Line 498... Line 347...
498
POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
347
 
-
 
348
#  ifdef _LIBC
499
{
349
#   include 
-
 
350
# endif
-
 
351
 
-
 
352
static _Noreturn void
-
 
353
print_and_abort (void)
-
 
354
{
-
 
355
  /* Don't change any of these strings.  Yes, it would be possible to add
-
 
356
     the newline to the string and use fputs or so.  But this must not
-
 
357
     happen because the "memory exhausted" message appears in other places
-
 
358
     like this and the translation should be reused instead of creating
-
 
359
     a very similar string which requires a separate translation.  */
500
  return obstack_copy (obstack, pointer, length);
360
#  ifdef _LIBC
501
}
361
  (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
Line -... Line 362...
-
 
362
#  else
-
 
363
  fprintf (stderr, "%s\n", _("memory exhausted"));
-
 
364
#  endif
-
 
365
  exit (obstack_exit_failure);
-
 
366
}
502
 
367
 
503
POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
-
 
-
 
368
/* The functions allocating more room by calling 'obstack_chunk_alloc'
-
 
369
   jump to the handler pointed to by 'obstack_alloc_failed_handler'.
504
{
370
   This can be set to a user defined function which should either