00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "obstack.h"
00028
00029
00030
00031
00032 #define OBSTACK_INTERFACE_VERSION 1
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdio.h>
00044 #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
00045 #include <gnu-versions.h>
00046 #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
00047 #define ELIDE_CODE
00048 #endif
00049 #endif
00050
00051
00052 #ifndef ELIDE_CODE
00053
00054
00055 #if defined (__STDC__) && __STDC__
00056 #define POINTER void *
00057 #else
00058 #define POINTER char *
00059 #endif
00060
00061
00062 struct fooalign {char x; double d;};
00063 #define DEFAULT_ALIGNMENT \
00064 ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
00065
00066
00067
00068 union fooround {long x; double d;};
00069 #define DEFAULT_ROUNDING (sizeof (union fooround))
00070
00071
00072
00073
00074
00075 #ifndef COPYING_UNIT
00076 #define COPYING_UNIT int
00077 #endif
00078
00079
00080
00081
00082
00083
00084 #if defined (__STDC__) && __STDC__
00085 static void print_and_abort (void);
00086 void (*obstack_alloc_failed_handler) (void) = print_and_abort;
00087 #else
00088 static void print_and_abort ();
00089 void (*obstack_alloc_failed_handler) () = print_and_abort;
00090 #endif
00091
00092
00093 #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
00094 #include <stdlib.h>
00095 #endif
00096 #ifndef EXIT_FAILURE
00097 #define EXIT_FAILURE 1
00098 #endif
00099 int obstack_exit_failure = EXIT_FAILURE;
00100
00101
00102
00103
00104 struct obstack *_obstack;
00105
00106
00107
00108
00109
00110
00111
00112 #if defined (__STDC__) && __STDC__
00113 #define CALL_CHUNKFUN(h, size) \
00114 (((h) -> use_extra_arg) \
00115 ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
00116 : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
00117
00118 #define CALL_FREEFUN(h, old_chunk) \
00119 do { \
00120 if ((h) -> use_extra_arg) \
00121 (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
00122 else \
00123 (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
00124 } while (0)
00125 #else
00126 #define CALL_CHUNKFUN(h, size) \
00127 (((h) -> use_extra_arg) \
00128 ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
00129 : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
00130
00131 #define CALL_FREEFUN(h, old_chunk) \
00132 do { \
00133 if ((h) -> use_extra_arg) \
00134 (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
00135 else \
00136 (*(void (*) ()) (h)->freefun) ((old_chunk)); \
00137 } while (0)
00138 #endif
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 int
00151 _obstack_begin (h, size, alignment, chunkfun, freefun)
00152 struct obstack *h;
00153 int size;
00154 int alignment;
00155 #if defined (__STDC__) && __STDC__
00156 POINTER (*chunkfun) (long);
00157 void (*freefun) (void *);
00158 #else
00159 POINTER (*chunkfun) ();
00160 void (*freefun) ();
00161 #endif
00162 {
00163 register struct _obstack_chunk *chunk;
00164
00165 if (alignment == 0)
00166 alignment = (int) DEFAULT_ALIGNMENT;
00167 if (size == 0)
00168
00169 {
00170
00171
00172
00173
00174
00175
00176
00177
00178 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
00179 + 4 + DEFAULT_ROUNDING - 1)
00180 & ~(DEFAULT_ROUNDING - 1));
00181 size = 4096 - extra;
00182 }
00183
00184 #if defined (__STDC__) && __STDC__
00185 h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
00186 h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
00187 #else
00188 h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
00189 h->freefun = freefun;
00190 #endif
00191 h->chunk_size = size;
00192 h->alignment_mask = alignment - 1;
00193 h->use_extra_arg = 0;
00194
00195 chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
00196 if (!chunk)
00197 (*obstack_alloc_failed_handler) ();
00198 h->next_free = h->object_base = chunk->contents;
00199 h->chunk_limit = chunk->limit
00200 = (char *) chunk + h->chunk_size;
00201 chunk->prev = 0;
00202
00203 h->maybe_empty_object = 0;
00204 h->alloc_failed = 0;
00205 return 1;
00206 }
00207
00208 int
00209 _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
00210 struct obstack *h;
00211 int size;
00212 int alignment;
00213 #if defined (__STDC__) && __STDC__
00214 POINTER (*chunkfun) (POINTER, long);
00215 void (*freefun) (POINTER, POINTER);
00216 #else
00217 POINTER (*chunkfun) ();
00218 void (*freefun) ();
00219 #endif
00220 POINTER arg;
00221 {
00222 register struct _obstack_chunk *chunk;
00223
00224 if (alignment == 0)
00225 alignment = (int) DEFAULT_ALIGNMENT;
00226 if (size == 0)
00227
00228 {
00229
00230
00231
00232
00233
00234
00235
00236
00237 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
00238 + 4 + DEFAULT_ROUNDING - 1)
00239 & ~(DEFAULT_ROUNDING - 1));
00240 size = 4096 - extra;
00241 }
00242
00243 #if defined(__STDC__) && __STDC__
00244 h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
00245 h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
00246 #else
00247 h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
00248 h->freefun = freefun;
00249 #endif
00250 h->chunk_size = size;
00251 h->alignment_mask = alignment - 1;
00252 h->extra_arg = arg;
00253 h->use_extra_arg = 1;
00254
00255 chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
00256 if (!chunk)
00257 (*obstack_alloc_failed_handler) ();
00258 h->next_free = h->object_base = chunk->contents;
00259 h->chunk_limit = chunk->limit
00260 = (char *) chunk + h->chunk_size;
00261 chunk->prev = 0;
00262
00263 h->maybe_empty_object = 0;
00264 h->alloc_failed = 0;
00265 return 1;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 void
00275 _obstack_newchunk (h, length)
00276 struct obstack *h;
00277 int length;
00278 {
00279 register struct _obstack_chunk *old_chunk = h->chunk;
00280 register struct _obstack_chunk *new_chunk;
00281 register long new_size;
00282 register long obj_size = h->next_free - h->object_base;
00283 register long i;
00284 long already;
00285
00286
00287 new_size = (obj_size + length) + (obj_size >> 3) + 100;
00288 if (new_size < h->chunk_size)
00289 new_size = h->chunk_size;
00290
00291
00292 new_chunk = CALL_CHUNKFUN (h, new_size);
00293 if (!new_chunk)
00294 (*obstack_alloc_failed_handler) ();
00295 h->chunk = new_chunk;
00296 new_chunk->prev = old_chunk;
00297 new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
00298
00299
00300
00301
00302 if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
00303 {
00304 for (i = obj_size / sizeof (COPYING_UNIT) - 1;
00305 i >= 0; i--)
00306 ((COPYING_UNIT *)new_chunk->contents)[i]
00307 = ((COPYING_UNIT *)h->object_base)[i];
00308
00309
00310
00311 already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
00312 }
00313 else
00314 already = 0;
00315
00316 for (i = already; i < obj_size; i++)
00317 new_chunk->contents[i] = h->object_base[i];
00318
00319
00320
00321
00322 if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
00323 {
00324 new_chunk->prev = old_chunk->prev;
00325 CALL_FREEFUN (h, old_chunk);
00326 }
00327
00328 h->object_base = new_chunk->contents;
00329 h->next_free = h->object_base + obj_size;
00330
00331 h->maybe_empty_object = 0;
00332 }
00333
00334
00335
00336
00337
00338 #if defined (__STDC__) && __STDC__
00339
00340
00341 int _obstack_allocated_p (struct obstack *h, POINTER obj);
00342 #endif
00343
00344 int
00345 _obstack_allocated_p (h, obj)
00346 struct obstack *h;
00347 POINTER obj;
00348 {
00349 register struct _obstack_chunk *lp;
00350 register struct _obstack_chunk *plp;
00351
00352 lp = (h)->chunk;
00353
00354
00355
00356 while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
00357 {
00358 plp = lp->prev;
00359 lp = plp;
00360 }
00361 return lp != 0;
00362 }
00363
00364
00365
00366
00367 #undef obstack_free
00368
00369
00370
00371
00372 void
00373 _obstack_free (h, obj)
00374 struct obstack *h;
00375 POINTER obj;
00376 {
00377 register struct _obstack_chunk *lp;
00378 register struct _obstack_chunk *plp;
00379
00380 lp = h->chunk;
00381
00382
00383
00384 while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
00385 {
00386 plp = lp->prev;
00387 CALL_FREEFUN (h, lp);
00388 lp = plp;
00389
00390
00391 h->maybe_empty_object = 1;
00392 }
00393 if (lp)
00394 {
00395 h->object_base = h->next_free = (char *) (obj);
00396 h->chunk_limit = lp->limit;
00397 h->chunk = lp;
00398 }
00399 else if (obj != 0)
00400
00401 abort ();
00402 }
00403
00404
00405
00406 void
00407 obstack_free (h, obj)
00408 struct obstack *h;
00409 POINTER obj;
00410 {
00411 register struct _obstack_chunk *lp;
00412 register struct _obstack_chunk *plp;
00413
00414 lp = h->chunk;
00415
00416
00417
00418 while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
00419 {
00420 plp = lp->prev;
00421 CALL_FREEFUN (h, lp);
00422 lp = plp;
00423
00424
00425 h->maybe_empty_object = 1;
00426 }
00427 if (lp)
00428 {
00429 h->object_base = h->next_free = (char *) (obj);
00430 h->chunk_limit = lp->limit;
00431 h->chunk = lp;
00432 }
00433 else if (obj != 0)
00434
00435 abort ();
00436 }
00437
00438 int
00439 _obstack_memory_used (h)
00440 struct obstack *h;
00441 {
00442 register struct _obstack_chunk* lp;
00443 register int nbytes = 0;
00444
00445 for (lp = h->chunk; lp != 0; lp = lp->prev)
00446 {
00447 nbytes += lp->limit - (char *) lp;
00448 }
00449 return nbytes;
00450 }
00451
00452
00453 #ifndef _
00454 # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
00455 # include <libintl.h>
00456 # ifndef _
00457 # define _(Str) gettext (Str)
00458 # endif
00459 # else
00460 # define _(Str) (Str)
00461 # endif
00462 #endif
00463
00464 static void
00465 print_and_abort ()
00466 {
00467 fputs (_("memory exhausted\n"), stderr);
00468 exit (obstack_exit_failure);
00469 }
00470
00471 #if 0
00472
00473
00474
00475
00476
00477
00478 #if defined (__STDC__) && __STDC__
00479
00480
00481
00482
00483
00484
00485 POINTER (obstack_base) (obstack)
00486 struct obstack *obstack;
00487 {
00488 return obstack_base (obstack);
00489 }
00490
00491 POINTER (obstack_next_free) (obstack)
00492 struct obstack *obstack;
00493 {
00494 return obstack_next_free (obstack);
00495 }
00496
00497 int (obstack_object_size) (obstack)
00498 struct obstack *obstack;
00499 {
00500 return obstack_object_size (obstack);
00501 }
00502
00503 int (obstack_room) (obstack)
00504 struct obstack *obstack;
00505 {
00506 return obstack_room (obstack);
00507 }
00508
00509 int (obstack_make_room) (obstack, length)
00510 struct obstack *obstack;
00511 int length;
00512 {
00513 return obstack_make_room (obstack, length);
00514 }
00515
00516 void (obstack_grow) (obstack, pointer, length)
00517 struct obstack *obstack;
00518 POINTER pointer;
00519 int length;
00520 {
00521 obstack_grow (obstack, pointer, length);
00522 }
00523
00524 void (obstack_grow0) (obstack, pointer, length)
00525 struct obstack *obstack;
00526 POINTER pointer;
00527 int length;
00528 {
00529 obstack_grow0 (obstack, pointer, length);
00530 }
00531
00532 void (obstack_1grow) (obstack, character)
00533 struct obstack *obstack;
00534 int character;
00535 {
00536 obstack_1grow (obstack, character);
00537 }
00538
00539 void (obstack_blank) (obstack, length)
00540 struct obstack *obstack;
00541 int length;
00542 {
00543 obstack_blank (obstack, length);
00544 }
00545
00546 void (obstack_1grow_fast) (obstack, character)
00547 struct obstack *obstack;
00548 int character;
00549 {
00550 obstack_1grow_fast (obstack, character);
00551 }
00552
00553 void (obstack_blank_fast) (obstack, length)
00554 struct obstack *obstack;
00555 int length;
00556 {
00557 obstack_blank_fast (obstack, length);
00558 }
00559
00560 POINTER (obstack_finish) (obstack)
00561 struct obstack *obstack;
00562 {
00563 return obstack_finish (obstack);
00564 }
00565
00566 POINTER (obstack_alloc) (obstack, length)
00567 struct obstack *obstack;
00568 int length;
00569 {
00570 return obstack_alloc (obstack, length);
00571 }
00572
00573 POINTER (obstack_copy) (obstack, pointer, length)
00574 struct obstack *obstack;
00575 POINTER pointer;
00576 int length;
00577 {
00578 return obstack_copy (obstack, pointer, length);
00579 }
00580
00581 POINTER (obstack_copy0) (obstack, pointer, length)
00582 struct obstack *obstack;
00583 POINTER pointer;
00584 int length;
00585 {
00586 return obstack_copy0 (obstack, pointer, length);
00587 }
00588
00589 #endif
00590
00591 #endif
00592
00593 #endif