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