|
|
1.1 root 1: /* obstack.c - subroutines used implicitly by object stack macros 1.1.1.3 ! root 2: Copyright (C) 1988, 1993 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 root 34: #ifdef __STDC__ 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, 86: and FREEFUN the function to free them. */ 87: 88: void 89: _obstack_begin (h, size, alignment, chunkfun, freefun) 90: struct obstack *h; 91: int size; 92: int alignment; 93: POINTER (*chunkfun) (); 94: void (*freefun) (); 95: { 96: register struct _obstack_chunk* chunk; /* points to new chunk */ 97: 98: if (alignment == 0) 99: alignment = DEFAULT_ALIGNMENT; 100: if (size == 0) 101: /* Default size is what GNU malloc can fit in a 4096-byte block. */ 102: { 103: /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. 104: Use the values for range checking, because if range checking is off, 105: the extra bytes won't be missed terribly, but if range checking is on 106: and we used a larger request, a whole extra 4096 bytes would be 107: allocated. 108: 109: These number are irrelevant to the new GNU malloc. I suspect it is 110: less sensitive to the size of the request. */ 111: int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) 112: + 4 + DEFAULT_ROUNDING - 1) 113: & ~(DEFAULT_ROUNDING - 1)); 114: size = 4096 - extra; 115: } 116: 117: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; 118: h->freefun = freefun; 119: h->chunk_size = size; 120: h->alignment_mask = alignment - 1; 1.1.1.2 root 121: h->use_extra_arg = 0; 122: 123: chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); 124: h->next_free = h->object_base = chunk->contents; 125: h->chunk_limit = chunk->limit 126: = (char *) chunk + h->chunk_size; 127: chunk->prev = 0; 128: /* The initial chunk now contains no empty object. */ 129: h->maybe_empty_object = 0; 130: } 131: 132: void 133: _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) 134: struct obstack *h; 135: int size; 136: int alignment; 137: POINTER (*chunkfun) (); 138: void (*freefun) (); 139: POINTER arg; 140: { 141: register struct _obstack_chunk* chunk; /* points to new chunk */ 142: 143: if (alignment == 0) 144: alignment = DEFAULT_ALIGNMENT; 145: if (size == 0) 146: /* Default size is what GNU malloc can fit in a 4096-byte block. */ 147: { 148: /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. 149: Use the values for range checking, because if range checking is off, 150: the extra bytes won't be missed terribly, but if range checking is on 151: and we used a larger request, a whole extra 4096 bytes would be 152: allocated. 153: 154: These number are irrelevant to the new GNU malloc. I suspect it is 155: less sensitive to the size of the request. */ 156: int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) 157: + 4 + DEFAULT_ROUNDING - 1) 158: & ~(DEFAULT_ROUNDING - 1)); 159: size = 4096 - extra; 160: } 161: 162: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; 163: h->freefun = freefun; 164: h->chunk_size = size; 165: h->alignment_mask = alignment - 1; 166: h->extra_arg = arg; 167: h->use_extra_arg = 1; 1.1 root 168: 1.1.1.2 root 169: chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); 1.1 root 170: h->next_free = h->object_base = chunk->contents; 171: h->chunk_limit = chunk->limit 172: = (char *) chunk + h->chunk_size; 173: chunk->prev = 0; 174: /* The initial chunk now contains no empty object. */ 175: h->maybe_empty_object = 0; 176: } 177: 178: /* Allocate a new current chunk for the obstack *H 179: on the assumption that LENGTH bytes need to be added 180: to the current object, or a new object of length LENGTH allocated. 181: Copies any partial object from the end of the old chunk 182: to the beginning of the new one. */ 183: 184: void 185: _obstack_newchunk (h, length) 186: struct obstack *h; 187: int length; 188: { 189: register struct _obstack_chunk* old_chunk = h->chunk; 190: register struct _obstack_chunk* new_chunk; 191: register long new_size; 192: register int obj_size = h->next_free - h->object_base; 193: register int i; 194: int already; 195: 196: /* Compute size for new chunk. */ 197: new_size = (obj_size + length) + (obj_size >> 3) + 100; 198: if (new_size < h->chunk_size) 199: new_size = h->chunk_size; 200: 201: /* Allocate and initialize the new chunk. */ 1.1.1.2 root 202: new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size); 1.1 root 203: new_chunk->prev = old_chunk; 204: new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; 205: 206: /* Move the existing object to the new chunk. 207: Word at a time is fast and is safe if the object 208: is sufficiently aligned. */ 209: if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) 210: { 211: for (i = obj_size / sizeof (COPYING_UNIT) - 1; 212: i >= 0; i--) 213: ((COPYING_UNIT *)new_chunk->contents)[i] 214: = ((COPYING_UNIT *)h->object_base)[i]; 215: /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, 216: but that can cross a page boundary on a machine 217: which does not do strict alignment for COPYING_UNITS. */ 218: already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); 219: } 220: else 221: already = 0; 222: /* Copy remaining bytes one by one. */ 223: for (i = already; i < obj_size; i++) 224: new_chunk->contents[i] = h->object_base[i]; 225: 226: /* If the object just copied was the only data in OLD_CHUNK, 227: free that chunk and remove it from the chain. 228: But not if that chunk might contain an empty object. */ 229: if (h->object_base == old_chunk->contents && ! h->maybe_empty_object) 230: { 231: new_chunk->prev = old_chunk->prev; 1.1.1.2 root 232: CALL_FREEFUN (h, old_chunk); 1.1 root 233: } 234: 235: h->object_base = new_chunk->contents; 236: h->next_free = h->object_base + obj_size; 237: /* The new chunk certainly contains no empty object yet. */ 238: h->maybe_empty_object = 0; 239: } 240: 241: /* Return nonzero if object OBJ has been allocated from obstack H. 242: This is here for debugging. 243: If you use it in a program, you are probably losing. */ 244: 245: int 246: _obstack_allocated_p (h, obj) 247: struct obstack *h; 248: POINTER obj; 249: { 250: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ 251: register struct _obstack_chunk* plp; /* point to previous chunk if any */ 252: 253: lp = (h)->chunk; 254: /* We use >= rather than > since the object cannot be exactly at 255: the beginning of the chunk but might be an empty object exactly 256: at the end of an adjacent chunk. */ 257: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) 258: { 259: plp = lp->prev; 260: lp = plp; 261: } 262: return lp != 0; 263: } 264: 265: /* Free objects in obstack H, including OBJ and everything allocate 266: more recently than OBJ. If OBJ is zero, free everything in H. */ 267: 268: #undef obstack_free 269: 270: /* This function has two names with identical definitions. 271: This is the first one, called from non-ANSI code. */ 272: 273: void 274: _obstack_free (h, obj) 275: struct obstack *h; 276: POINTER obj; 277: { 278: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ 279: register struct _obstack_chunk* plp; /* point to previous chunk if any */ 280: 281: lp = h->chunk; 282: /* We use >= because there cannot be an object at the beginning of a chunk. 283: But there can be an empty object at that address 284: at the end of another chunk. */ 285: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) 286: { 287: plp = lp->prev; 1.1.1.2 root 288: CALL_FREEFUN (h, lp); 1.1 root 289: lp = plp; 290: /* If we switch chunks, we can't tell whether the new current 291: chunk contains an empty object, so assume that it may. */ 292: h->maybe_empty_object = 1; 293: } 294: if (lp) 295: { 296: h->object_base = h->next_free = (char *)(obj); 297: h->chunk_limit = lp->limit; 298: h->chunk = lp; 299: } 300: else if (obj != 0) 301: /* obj is not in any of the chunks! */ 302: abort (); 303: } 304: 305: /* This function is used from ANSI code. */ 306: 307: void 308: obstack_free (h, obj) 309: struct obstack *h; 310: POINTER obj; 311: { 312: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ 313: register struct _obstack_chunk* plp; /* point to previous chunk if any */ 314: 315: lp = h->chunk; 316: /* We use >= because there cannot be an object at the beginning of a chunk. 317: But there can be an empty object at that address 318: at the end of another chunk. */ 319: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) 320: { 321: plp = lp->prev; 1.1.1.2 root 322: CALL_FREEFUN (h, lp); 1.1 root 323: lp = plp; 324: /* If we switch chunks, we can't tell whether the new current 325: chunk contains an empty object, so assume that it may. */ 326: h->maybe_empty_object = 1; 327: } 328: if (lp) 329: { 330: h->object_base = h->next_free = (char *)(obj); 331: h->chunk_limit = lp->limit; 332: h->chunk = lp; 333: } 334: else if (obj != 0) 335: /* obj is not in any of the chunks! */ 336: abort (); 337: } 338: 339: #if 0 340: /* These are now turned off because the applications do not use it 341: and it uses bcopy via obstack_grow, which causes trouble on sysV. */ 342: 343: /* Now define the functional versions of the obstack macros. 344: Define them to simply use the corresponding macros to do the job. */ 345: 346: #ifdef __STDC__ 347: /* These function definitions do not work with non-ANSI preprocessors; 348: they won't pass through the macro names in parentheses. */ 349: 350: /* The function names appear in parentheses in order to prevent 351: the macro-definitions of the names from being expanded there. */ 352: 353: POINTER (obstack_base) (obstack) 354: struct obstack *obstack; 355: { 356: return obstack_base (obstack); 357: } 358: 359: POINTER (obstack_next_free) (obstack) 360: struct obstack *obstack; 361: { 362: return obstack_next_free (obstack); 363: } 364: 365: int (obstack_object_size) (obstack) 366: struct obstack *obstack; 367: { 368: return obstack_object_size (obstack); 369: } 370: 371: int (obstack_room) (obstack) 372: struct obstack *obstack; 373: { 374: return obstack_room (obstack); 375: } 376: 377: void (obstack_grow) (obstack, pointer, length) 378: struct obstack *obstack; 379: POINTER pointer; 380: int length; 381: { 382: obstack_grow (obstack, pointer, length); 383: } 384: 385: void (obstack_grow0) (obstack, pointer, length) 386: struct obstack *obstack; 387: POINTER pointer; 388: int length; 389: { 390: obstack_grow0 (obstack, pointer, length); 391: } 392: 393: void (obstack_1grow) (obstack, character) 394: struct obstack *obstack; 395: int character; 396: { 397: obstack_1grow (obstack, character); 398: } 399: 400: void (obstack_blank) (obstack, length) 401: struct obstack *obstack; 402: int length; 403: { 404: obstack_blank (obstack, length); 405: } 406: 407: void (obstack_1grow_fast) (obstack, character) 408: struct obstack *obstack; 409: int character; 410: { 411: obstack_1grow_fast (obstack, character); 412: } 413: 414: void (obstack_blank_fast) (obstack, length) 415: struct obstack *obstack; 416: int length; 417: { 418: obstack_blank_fast (obstack, length); 419: } 420: 421: POINTER (obstack_finish) (obstack) 422: struct obstack *obstack; 423: { 424: return obstack_finish (obstack); 425: } 426: 427: POINTER (obstack_alloc) (obstack, length) 428: struct obstack *obstack; 429: int length; 430: { 431: return obstack_alloc (obstack, length); 432: } 433: 434: POINTER (obstack_copy) (obstack, pointer, length) 435: struct obstack *obstack; 436: POINTER pointer; 437: int length; 438: { 439: return obstack_copy (obstack, pointer, length); 440: } 441: 442: POINTER (obstack_copy0) (obstack, pointer, length) 443: struct obstack *obstack; 444: POINTER pointer; 445: int length; 446: { 447: return obstack_copy0 (obstack, pointer, length); 448: } 449: 450: #endif /* __STDC__ */ 451: 452: #endif /* 0 */ 1.1.1.3 ! root 453: ! 454: #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.