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