|
|
1.1 ! root 1: /* obstack.c - subroutines used implicitly by object stack macros ! 2: Copyright (C) 1988 Free Software Foundation, Inc. ! 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 1, 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: ! 20: #ifdef __STDC__ ! 21: #define POINTER void * ! 22: #else ! 23: #define POINTER char * ! 24: #endif ! 25: ! 26: /* Determine default alignment. */ ! 27: struct fooalign {char x; double d;}; ! 28: #define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0) ! 29: /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. ! 30: But in fact it might be less smart and round addresses to as much as ! 31: DEFAULT_ROUNDING. So we prepare for it to do that. */ ! 32: union fooround {long x; double d;}; ! 33: #define DEFAULT_ROUNDING (sizeof (union fooround)) ! 34: ! 35: /* When we copy a long block of data, this is the unit to do it with. ! 36: On some machines, copying successive ints does not work; ! 37: in such a case, redefine COPYING_UNIT to `long' (if that works) ! 38: or `char' as a last resort. */ ! 39: #ifndef COPYING_UNIT ! 40: #define COPYING_UNIT int ! 41: #endif ! 42: ! 43: /* The non-GNU-C macros copy the obstack into this global variable ! 44: to avoid multiple evaluation. */ ! 45: ! 46: struct obstack *_obstack = 0; ! 47: ! 48: /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). ! 49: Objects start on multiples of ALIGNMENT (0 means use default). ! 50: CHUNKFUN is the function to use to allocate chunks, ! 51: and FREEFUN the function to free them. */ ! 52: ! 53: void ! 54: _obstack_begin( ! 55: struct obstack *h, ! 56: int size, ! 57: int alignment, ! 58: void *(*chunkfun)(long n), ! 59: void (*freefun)() ) ! 60: { ! 61: register struct _obstack_chunk* chunk; /* points to new chunk */ ! 62: ! 63: if (alignment == 0) ! 64: alignment = DEFAULT_ALIGNMENT; ! 65: if (size == 0) ! 66: /* Default size is what GNU malloc can fit in a 4096-byte block. */ ! 67: { ! 68: /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. ! 69: Use the values for range checking, because if range checking is off, ! 70: the extra bytes won't be missed terribly, but if range checking is on ! 71: and we used a larger request, a whole extra 4096 bytes would be ! 72: allocated. ! 73: ! 74: These number are irrelevant to the new GNU malloc. I suspect it is ! 75: less sensitive to the size of the request. */ ! 76: int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) ! 77: + 4 + DEFAULT_ROUNDING - 1) ! 78: & ~(DEFAULT_ROUNDING - 1)); ! 79: size = 4096 - extra; ! 80: } ! 81: ! 82: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; ! 83: h->freefun = freefun; ! 84: h->chunk_size = size; ! 85: h->alignment_mask = alignment - 1; ! 86: ! 87: chunk = h->chunk = (*h->chunkfun) (h->chunk_size); ! 88: h->next_free = h->object_base = chunk->contents; ! 89: h->chunk_limit = chunk->limit ! 90: = (char *) chunk + h->chunk_size; ! 91: chunk->prev = 0; ! 92: } ! 93: ! 94: /* Allocate a new current chunk for the obstack *H ! 95: on the assumption that LENGTH bytes need to be added ! 96: to the current object, or a new object of length LENGTH allocated. ! 97: Copies any partial object from the end of the old chunk ! 98: to the beginning of the new one. */ ! 99: ! 100: void ! 101: _obstack_newchunk( ! 102: struct obstack *h, ! 103: int length) ! 104: { ! 105: register struct _obstack_chunk* old_chunk = h->chunk; ! 106: register struct _obstack_chunk* new_chunk; ! 107: register long new_size; ! 108: register int obj_size = h->next_free - h->object_base; ! 109: register int i; ! 110: int already; ! 111: ! 112: /* Compute size for new chunk. */ ! 113: new_size = (obj_size + length) + (obj_size >> 3) + 100; ! 114: if (new_size < h->chunk_size) ! 115: new_size = h->chunk_size; ! 116: ! 117: /* Allocate and initialize the new chunk. */ ! 118: new_chunk = h->chunk = (*h->chunkfun) (new_size); ! 119: new_chunk->prev = old_chunk; ! 120: new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; ! 121: ! 122: /* Move the existing object to the new chunk. ! 123: Word at a time is fast and is safe if the object ! 124: is sufficiently aligned. */ ! 125: if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) ! 126: { ! 127: for (i = obj_size / sizeof (COPYING_UNIT) - 1; ! 128: i >= 0; i--) ! 129: ((COPYING_UNIT *)new_chunk->contents)[i] ! 130: = ((COPYING_UNIT *)h->object_base)[i]; ! 131: /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, ! 132: but that can cross a page boundary on a machine ! 133: which does not do strict alignment for COPYING_UNITS. */ ! 134: already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); ! 135: } ! 136: else ! 137: already = 0; ! 138: /* Copy remaining bytes one by one. */ ! 139: for (i = already; i < obj_size; i++) ! 140: new_chunk->contents[i] = h->object_base[i]; ! 141: ! 142: h->object_base = new_chunk->contents; ! 143: h->next_free = h->object_base + obj_size; ! 144: } ! 145: ! 146: #ifdef DEBUG ! 147: /* Return nonzero if object OBJ has been allocated from obstack H. ! 148: This is here for debugging. ! 149: If you use it in a program, you are probably losing. */ ! 150: ! 151: static ! 152: int ! 153: _obstack_allocated_p( ! 154: struct obstack *h, ! 155: POINTER obj) ! 156: { ! 157: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ ! 158: register struct _obstack_chunk* plp; /* point to previous chunk if any */ ! 159: ! 160: lp = (h)->chunk; ! 161: while (lp != 0 && ((POINTER)lp > obj || (POINTER)(lp)->limit < obj)) ! 162: { ! 163: plp = lp -> prev; ! 164: lp = plp; ! 165: } ! 166: return lp != 0; ! 167: } ! 168: #endif /* DEBUG */ ! 169: ! 170: /* Free objects in obstack H, including OBJ and everything allocate ! 171: more recently than OBJ. If OBJ is zero, free everything in H. */ ! 172: #undef obstack_free ! 173: void ! 174: obstack_free( ! 175: struct obstack *h, ! 176: POINTER obj) ! 177: { ! 178: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ ! 179: register struct _obstack_chunk* plp; /* point to previous chunk if any */ ! 180: ! 181: lp = (h)->chunk; ! 182: /* We use >= because there cannot be an object at the beginning of a chunk. ! 183: But there can be an empty object at that address ! 184: at the end of another chunk. */ ! 185: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) ! 186: { ! 187: plp = lp -> prev; ! 188: (*h->freefun) (lp); ! 189: lp = plp; ! 190: } ! 191: if (lp) ! 192: { ! 193: (h)->object_base = (h)->next_free = (char *)(obj); ! 194: (h)->chunk_limit = lp->limit; ! 195: (h)->chunk = lp; ! 196: } ! 197: else if (obj != 0) ! 198: /* obj is not in any of the chunks! */ ! 199: abort (); ! 200: } ! 201: ! 202: ! 203: #if 0 ! 204: /* These are now turned off because the applications do not use it ! 205: and it uses bcopy via obstack_grow, which causes trouble on sysV. */ ! 206: ! 207: /* Now define the functional versions of the obstack macros. ! 208: Define them to simply use the corresponding macros to do the job. */ ! 209: ! 210: #ifdef __STDC__ ! 211: /* These function definitions do not work with non-ANSI preprocessors; ! 212: they won't pass through the macro names in parentheses. */ ! 213: ! 214: /* The function names appear in parentheses in order to prevent ! 215: the macro-definitions of the names from being expanded there. */ ! 216: ! 217: POINTER (obstack_base) (obstack) ! 218: struct obstack *obstack; ! 219: { ! 220: return obstack_base (obstack); ! 221: } ! 222: ! 223: POINTER (obstack_next_free) (obstack) ! 224: struct obstack *obstack; ! 225: { ! 226: return obstack_next_free (obstack); ! 227: } ! 228: ! 229: int (obstack_object_size) (obstack) ! 230: struct obstack *obstack; ! 231: { ! 232: return obstack_object_size (obstack); ! 233: } ! 234: ! 235: int (obstack_room) (obstack) ! 236: struct obstack *obstack; ! 237: { ! 238: return obstack_room (obstack); ! 239: } ! 240: ! 241: void (obstack_grow) (obstack, pointer, length) ! 242: struct obstack *obstack; ! 243: POINTER pointer; ! 244: int length; ! 245: { ! 246: obstack_grow (obstack, pointer, length); ! 247: } ! 248: ! 249: void (obstack_grow0) (obstack, pointer, length) ! 250: struct obstack *obstack; ! 251: POINTER pointer; ! 252: int length; ! 253: { ! 254: obstack_grow0 (obstack, pointer, length); ! 255: } ! 256: ! 257: void (obstack_1grow) (obstack, character) ! 258: struct obstack *obstack; ! 259: int character; ! 260: { ! 261: obstack_1grow (obstack, character); ! 262: } ! 263: ! 264: void (obstack_blank) (obstack, length) ! 265: struct obstack *obstack; ! 266: int length; ! 267: { ! 268: obstack_blank (obstack, length); ! 269: } ! 270: ! 271: void (obstack_1grow_fast) (obstack, character) ! 272: struct obstack *obstack; ! 273: int character; ! 274: { ! 275: obstack_1grow_fast (obstack, character); ! 276: } ! 277: ! 278: void (obstack_blank_fast) (obstack, length) ! 279: struct obstack *obstack; ! 280: int length; ! 281: { ! 282: obstack_blank_fast (obstack, length); ! 283: } ! 284: ! 285: POINTER (obstack_finish) (obstack) ! 286: struct obstack *obstack; ! 287: { ! 288: return obstack_finish (obstack); ! 289: } ! 290: ! 291: POINTER (obstack_alloc) (obstack, length) ! 292: struct obstack *obstack; ! 293: int length; ! 294: { ! 295: return obstack_alloc (obstack, length); ! 296: } ! 297: ! 298: POINTER (obstack_copy) (obstack, pointer, length) ! 299: struct obstack *obstack; ! 300: POINTER pointer; ! 301: int length; ! 302: { ! 303: return obstack_copy (obstack, pointer, length); ! 304: } ! 305: ! 306: POINTER (obstack_copy0) (obstack, pointer, length) ! 307: struct obstack *obstack; ! 308: POINTER pointer; ! 309: int length; ! 310: { ! 311: return obstack_copy0 (obstack, pointer, length); ! 312: } ! 313: ! 314: #endif /* __STDC__ */ ! 315: ! 316: #endif /* 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.