|
|
1.1 ! root 1: /* obstack.h - object stack macros ! 2: Copyright (C) 1988 Free Software Foundation, Inc. ! 3: ! 4: NO WARRANTY ! 5: ! 6: BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY ! 7: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT ! 8: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, ! 9: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" ! 10: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, ! 11: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ! 12: FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY ! 13: AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE ! 14: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR ! 15: CORRECTION. ! 16: ! 17: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. ! 18: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY ! 19: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE ! 20: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR ! 21: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE ! 22: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR ! 23: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR ! 24: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS ! 25: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH ! 26: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. ! 27: ! 28: GENERAL PUBLIC LICENSE TO COPY ! 29: ! 30: 1. You may copy and distribute verbatim copies of this source file ! 31: as you receive it, in any medium, provided that you conspicuously and ! 32: appropriately publish on each copy a valid copyright notice "Copyright ! 33: (C) 1988 Free Software Foundation, Inc."; and include following the ! 34: copyright notice a verbatim copy of the above disclaimer of warranty ! 35: and of this License. You may charge a distribution fee for the ! 36: physical act of transferring a copy. ! 37: ! 38: 2. You may modify your copy or copies of this source file or ! 39: any portion of it, and copy and distribute such modifications under ! 40: the terms of Paragraph 1 above, provided that you also do the following: ! 41: ! 42: a) cause the modified files to carry prominent notices stating ! 43: that you changed the files and the date of any change; and ! 44: ! 45: b) cause the whole of any work that you distribute or publish, ! 46: that in whole or in part contains or is a derivative of this ! 47: program or any part thereof, to be licensed at no charge to all ! 48: third parties on terms identical to those contained in this ! 49: License Agreement (except that you may choose to grant more extensive ! 50: warranty protection to some or all third parties, at your option). ! 51: ! 52: c) You may charge a distribution fee for the physical act of ! 53: transferring a copy, and you may at your option offer warranty ! 54: protection in exchange for a fee. ! 55: ! 56: Mere aggregation of another unrelated program with this program (or its ! 57: derivative) on a volume of a storage or distribution medium does not bring ! 58: the other program under the scope of these terms. ! 59: ! 60: 3. You may copy and distribute this program or any portion of it in ! 61: compiled, executable or object code form under the terms of Paragraphs ! 62: 1 and 2 above provided that you do the following: ! 63: ! 64: a) accompany it with the complete corresponding machine-readable ! 65: source code, which must be distributed under the terms of ! 66: Paragraphs 1 and 2 above; or, ! 67: ! 68: b) accompany it with a written offer, valid for at least three ! 69: years, to give any third party free (except for a nominal ! 70: shipping charge) a complete machine-readable copy of the ! 71: corresponding source code, to be distributed under the terms of ! 72: Paragraphs 1 and 2 above; or, ! 73: ! 74: c) accompany it with the information you received as to where the ! 75: corresponding source code may be obtained. (This alternative is ! 76: allowed only for noncommercial distribution and only if you ! 77: received the program in object code or executable form alone.) ! 78: ! 79: For an executable file, complete source code means all the source code for ! 80: all modules it contains; but, as a special exception, it need not include ! 81: source code for modules which are standard libraries that accompany the ! 82: operating system on which the executable file runs. ! 83: ! 84: 4. You may not copy, sublicense, distribute or transfer this program ! 85: except as expressly provided under this License Agreement. Any attempt ! 86: otherwise to copy, sublicense, distribute or transfer this program is void and ! 87: your rights to use the program under this License agreement shall be ! 88: automatically terminated. However, parties who have received computer ! 89: software programs from you with this License Agreement will not have ! 90: their licenses terminated so long as such parties remain in full compliance. ! 91: ! 92: 5. If you wish to incorporate parts of this program into other free ! 93: programs whose distribution conditions are different, write to the Free ! 94: Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet ! 95: worked out a simple rule that can be stated here, but we will often permit ! 96: this. We will be guided by the two goals of preserving the free status of ! 97: all derivatives our free software and of promoting the sharing and reuse of ! 98: software. ! 99: ! 100: ! 101: In other words, you are welcome to use, share and improve this program. ! 102: You are forbidden to forbid anyone else to use, share and improve ! 103: what you give them. Help stamp out software-hoarding! */ ! 104: ! 105: ! 106: /* Summary: ! 107: ! 108: All the apparent functions defined here are macros. The idea ! 109: is that you would use these pre-tested macros to solve a ! 110: very specific set of problems, and they would run fast. ! 111: Caution: no side-effects in arguments please!! They may be ! 112: evaluated MANY times!! ! 113: ! 114: These macros operate a stack of objects. Each object starts life ! 115: small, and may grow to maturity. (Consider building a word syllable ! 116: by syllable.) An object can move while it is growing. Once it has ! 117: been "finished" it never changes address again. So the "top of the ! 118: stack" is typically an immature growing object, while the rest of the ! 119: stack is of mature, fixed size and fixed address objects. ! 120: ! 121: These routines grab large chunks of memory, using a function you ! 122: supply, called `obstack_chunk_alloc'. On occasion, they free chunks, ! 123: by calling `obstack_chunk_free'. You must define them and declare ! 124: them before using any obstack macros. ! 125: ! 126: Each independent stack is represented by a `struct obstack'. ! 127: Each of the obstack macros expects a pointer to such a structure ! 128: as the first argument. ! 129: ! 130: One motivation for this package is the problem of growing char strings ! 131: in symbol tables. Unless you are "facist pig with a read-only mind" ! 132: [Gosper's immortal quote from HAKMEM item 154, out of context] you ! 133: would not like to put any arbitrary upper limit on the length of your ! 134: symbols. ! 135: ! 136: In practice this often means you will build many short symbols and a ! 137: few long symbols. At the time you are reading a symbol you don't know ! 138: how long it is. One traditional method is to read a symbol into a ! 139: buffer, realloc()ating the buffer every time you try to read a symbol ! 140: that is longer than the buffer. This is beaut, but you still will ! 141: want to copy the symbol from the buffer to a more permanent ! 142: symbol-table entry say about half the time. ! 143: ! 144: With obstacks, you can work differently. Use one obstack for all symbol ! 145: names. As you read a symbol, grow the name in the obstack gradually. ! 146: When the name is complete, finalize it. Then, if the symbol exists already, ! 147: free the newly read name. ! 148: ! 149: The way we do this is to take a large chunk, allocating memory from ! 150: low addresses. When you want to build a aymbol in the chunk you just ! 151: add chars above the current "high water mark" in the chunk. When you ! 152: have finished adding chars, because you got to the end of the symbol, ! 153: you know how long the chars are, and you can create a new object. ! 154: Mostly the chars will not burst over the highest address of the chunk, ! 155: because you would typically expect a chunk to be (say) 100 times as ! 156: long as an average object. ! 157: ! 158: In case that isn't clear, when we have enough chars to make up ! 159: the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) ! 160: so we just point to it where it lies. No moving of chars is ! 161: needed and this is the second win: potentially long strings need ! 162: never be explicitly shuffled. Once an object is formed, it does not ! 163: change its address during its lifetime. ! 164: ! 165: When the chars burst over a chunk boundary, we allocate a larger ! 166: chunk, and then copy the partly formed object from the end of the old ! 167: chunk to the beggining of the new larger chunk. We then carry on ! 168: accreting characters to the end of the object as we normaly would. ! 169: ! 170: A special macro is provided to add a single char at a time to a ! 171: growing object. This allows the use of register variables, which ! 172: break the ordinary 'growth' macro. ! 173: ! 174: Summary: ! 175: We allocate large chunks. ! 176: We carve out one object at a time from the current chunk. ! 177: Once carved, an object never moves. ! 178: We are free to append data of any size to the currently ! 179: growing object. ! 180: Exactly one object is growing in an obstack at any one time. ! 181: You can run one obstack per control block. ! 182: You may have as many control blocks as you dare. ! 183: Because of the way we do it, you can `unwind' a obstack ! 184: back to a previous state. (You may remove objects much ! 185: as you would with a stack.) ! 186: */ ! 187: ! 188: ! 189: /* Don't do the contents of this file more than once. */ ! 190: ! 191: #ifndef __OBSTACKS__ ! 192: #define __OBSTACKS__ ! 193: ! 194: /* We use subtraction of (char *)0 instead of casting to int ! 195: because on word-addressable machines a simple cast to int ! 196: may ignore the byte-within-word field of the pointer. */ ! 197: ! 198: #ifndef __PTR_TO_INT ! 199: #define __PTR_TO_INT(P) ((P) - (char *)0) ! 200: #endif ! 201: ! 202: #ifndef __INT_TO_PTR ! 203: #define __INT_TO_PTR(P) ((P) + (char *)0) ! 204: #endif ! 205: ! 206: struct _obstack_chunk /* Lives at front of each chunk. */ ! 207: { ! 208: char *limit; /* 1 past end of this chunk */ ! 209: struct _obstack_chunk *prev; /* address of prior chunk or NULL */ ! 210: char contents[4]; /* objects begin here */ ! 211: }; ! 212: ! 213: struct obstack /* control current object in current chunk */ ! 214: { ! 215: long chunk_size; /* preferred size to allocate chunks in */ ! 216: struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */ ! 217: char *object_base; /* address of object we are building */ ! 218: char *next_free; /* where to add next char to current object */ ! 219: char *chunk_limit; /* address of char after current chunk */ ! 220: int temp; /* Temporary for some macros. */ ! 221: int alignment_mask; /* Mask of alignment for each object. */ ! 222: struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ ! 223: void (*freefun) (); /* User's function to free a chunk. */ ! 224: }; ! 225: ! 226: #ifdef __STDC__ ! 227: ! 228: /* Do the function-declarations after the structs ! 229: but before defining the macros. */ ! 230: ! 231: void obstack_init (struct obstack *obstack); ! 232: ! 233: void * obstack_alloc (struct obstack *obstack, int size); ! 234: ! 235: void * obstack_copy (struct obstack *obstack, void *address, int size); ! 236: void * obstack_copy0 (struct obstack *obstack, void *address, int size); ! 237: ! 238: void obstack_free (struct obstack *obstack, void *block); ! 239: ! 240: void obstack_blank (struct obstack *obstack, int size); ! 241: ! 242: void obstack_grow (struct obstack *obstack, void *data, int size); ! 243: void obstack_grow0 (struct obstack *obstack, void *data, int size); ! 244: ! 245: void obstack_1grow (struct obstack *obstack, int data_char); ! 246: ! 247: void * obstack_finish (struct obstack *obstack); ! 248: ! 249: int obstack_object_size (struct obstack *obstack); ! 250: ! 251: int obstack_room (struct obstack *obstack); ! 252: void obstack_1grow_fast (struct obstack *obstack, int data_char); ! 253: void obstack_blank_fast (struct obstack *obstack, int size); ! 254: ! 255: void * obstack_base (struct obstack *obstack); ! 256: void * obstack_next_free (struct obstack *obstack); ! 257: int obstack_alignment_mask (struct obstack *obstack); ! 258: int obstack_chunk_size (struct obstack *obstack); ! 259: ! 260: #endif /* __STDC__ */ ! 261: ! 262: /* Non-ANSI C cannot really support alternative functions for these macros, ! 263: so we do not declare them. */ ! 264: ! 265: /* Pointer to beginning of object being allocated or to be allocated next. ! 266: Note that this might not be the final address of the object ! 267: because a new chunk might be needed to hold the final size. */ ! 268: ! 269: #define obstack_base(h) ((h)->object_base) ! 270: ! 271: /* Size for allocating ordinary chunks. */ ! 272: ! 273: #define obstack_chunk_size(h) ((h)->chunk_size) ! 274: ! 275: /* Pointer to next byte not yet allocated in current chunk. */ ! 276: ! 277: #define obstack_next_free(h) ((h)->next_free) ! 278: ! 279: /* Mask specifying low bits that should be clear in address of an object. */ ! 280: ! 281: #define obstack_alignment_mask(h) ((h)->alignment_mask) ! 282: ! 283: #define obstack_init(h) \ ! 284: _obstack_begin ((h), 0, 0, obstack_chunk_alloc, obstack_chunk_free) ! 285: ! 286: #define obstack_begin(h, size) \ ! 287: _obstack_begin ((h), (size), 0, obstack_chunk_alloc, obstack_chunk_free) ! 288: ! 289: #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) ! 290: ! 291: #define obstack_blank_fast(h,n) ((h)->next_free += (n)) ! 292: ! 293: #ifdef __GNUC__ ! 294: ! 295: /* For GNU C we can define these macros to compute all args only once ! 296: without using a global variable. ! 297: Also, we can avoid using the `temp' slot, to make faster code. */ ! 298: ! 299: #define obstack_object_size(OBSTACK) \ ! 300: ({ struct obstack *__o = (OBSTACK); \ ! 301: (unsigned) (__o->next_free - __o->object_base); }) ! 302: ! 303: #define obstack_room(OBSTACK) \ ! 304: ({ struct obstack *__o = (OBSTACK); \ ! 305: (unsigned) (__o->chunk_limit - __o->next_free); }) ! 306: ! 307: #define obstack_grow(OBSTACK,where,length) \ ! 308: ({ struct obstack *__o = (OBSTACK); \ ! 309: int __len = (length); \ ! 310: ((__o->next_free + __len > __o->chunk_limit) \ ! 311: ? _obstack_newchunk (__o, __len) : 0); \ ! 312: bcopy (where, __o->next_free, __len); \ ! 313: __o->next_free += __len; \ ! 314: (void) 0; }) ! 315: ! 316: #define obstack_grow0(OBSTACK,where,length) \ ! 317: ({ struct obstack *__o = (OBSTACK); \ ! 318: int __len = (length); \ ! 319: ((__o->next_free + __len + 1 > __o->chunk_limit) \ ! 320: ? _obstack_newchunk (__o, __len + 1) : 0), \ ! 321: bcopy (where, __o->next_free, __len), \ ! 322: __o->next_free += __len, \ ! 323: *(__o->next_free)++ = 0; \ ! 324: (void) 0; }) ! 325: ! 326: #define obstack_1grow(OBSTACK,datum) \ ! 327: ({ struct obstack *__o = (OBSTACK); \ ! 328: ((__o->next_free + 1 > __o->chunk_limit) \ ! 329: ? _obstack_newchunk (__o, 1) : 0), \ ! 330: *(__o->next_free)++ = (datum); \ ! 331: (void) 0; }) ! 332: ! 333: #define obstack_blank(OBSTACK,length) \ ! 334: ({ struct obstack *__o = (OBSTACK); \ ! 335: int __len = (length); \ ! 336: ((__o->next_free + __len > __o->chunk_limit) \ ! 337: ? _obstack_newchunk (__o, __len) : 0); \ ! 338: __o->next_free += __len; \ ! 339: (void) 0; }) ! 340: ! 341: #define obstack_alloc(OBSTACK,length) \ ! 342: ({ struct obstack *__h = (OBSTACK); \ ! 343: obstack_blank (__h, (length)); \ ! 344: obstack_finish (__h); }) ! 345: ! 346: #define obstack_copy(OBSTACK,where,length) \ ! 347: ({ struct obstack *__h = (OBSTACK); \ ! 348: obstack_grow (__h, (where), (length)); \ ! 349: obstack_finish (__h); }) ! 350: ! 351: #define obstack_copy0(OBSTACK,where,length) \ ! 352: ({ struct obstack *__h = (OBSTACK); \ ! 353: obstack_grow0 (__h, (where), (length)); \ ! 354: obstack_finish (__h); }) ! 355: ! 356: #define obstack_finish(OBSTACK) \ ! 357: ({ struct obstack *__o = (OBSTACK); \ ! 358: void *value = (void *) __o->object_base; \ ! 359: __o->next_free \ ! 360: = __INT_TO_PTR ((__PTR_TO_INT (__o->next_free)+__o->alignment_mask)\ ! 361: & ~ (__o->alignment_mask)); \ ! 362: ((__o->next_free - (char *)__o->chunk \ ! 363: > __o->chunk_limit - (char *)__o->chunk) \ ! 364: ? (__o->next_free = __o->chunk_limit) : 0); \ ! 365: __o->object_base = __o->next_free; \ ! 366: value; }) ! 367: ! 368: #define obstack_free(OBSTACK, OBJ) \ ! 369: ({ struct obstack *__o = (OBSTACK); \ ! 370: void *__obj = (OBJ); \ ! 371: if (__obj >= (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ ! 372: __o->next_free = __o->object_base = __obj; \ ! 373: else (obstack_free) (__o, __obj); }) ! 374: ! 375: #else /* not __GNUC__ */ ! 376: ! 377: /* The non-GNU macros copy the obstack-pointer into this global variable ! 378: to avoid multiple evaluation. */ ! 379: ! 380: extern struct obstack *_obstack; ! 381: ! 382: #define obstack_object_size(h) \ ! 383: (unsigned) (_obstack = (h), (h)->next_free - (h)->object_base) ! 384: ! 385: #define obstack_room(h) \ ! 386: (unsigned) (_obstack = (h), (h)->chunk_limit - (h)->next_free) ! 387: ! 388: #define obstack_grow(h,where,length) \ ! 389: ( (h)->temp = (length), \ ! 390: (((h)->next_free + (h)->temp > (h)->chunk_limit) \ ! 391: ? _obstack_newchunk ((h), (h)->temp) : 0), \ ! 392: bcopy (where, (h)->next_free, (h)->temp), \ ! 393: (h)->next_free += (h)->temp) ! 394: ! 395: #define obstack_grow0(h,where,length) \ ! 396: ( (h)->temp = (length), \ ! 397: (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ ! 398: ? _obstack_newchunk ((h), (h)->temp + 1) : 0), \ ! 399: bcopy (where, (h)->next_free, (h)->temp), \ ! 400: (h)->next_free += (h)->temp, \ ! 401: *((h)->next_free)++ = 0) ! 402: ! 403: #define obstack_1grow(h,datum) \ ! 404: ( (((h)->next_free + 1 > (h)->chunk_limit) \ ! 405: ? _obstack_newchunk ((h), 1) : 0), \ ! 406: *((h)->next_free)++ = (datum)) ! 407: ! 408: #define obstack_blank(h,length) \ ! 409: ( (h)->temp = (length), \ ! 410: (((h)->next_free + (h)->temp > (h)->chunk_limit) \ ! 411: ? _obstack_newchunk ((h), (h)->temp) : 0), \ ! 412: (h)->next_free += (h)->temp) ! 413: ! 414: #define obstack_alloc(h,length) \ ! 415: (obstack_blank ((h), (length)), obstack_finish ((h))) ! 416: ! 417: #define obstack_copy(h,where,length) \ ! 418: (obstack_grow ((h), (where), (length)), obstack_finish ((h))) ! 419: ! 420: #define obstack_copy0(h,where,length) \ ! 421: (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) ! 422: ! 423: #define obstack_finish(h) \ ! 424: ( (h)->temp = __PTR_TO_INT ((h)->object_base), \ ! 425: (h)->next_free \ ! 426: = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ ! 427: & ~ ((h)->alignment_mask)), \ ! 428: (((h)->next_free - (char *)(h)->chunk \ ! 429: > (h)->chunk_limit - (char *)(h)->chunk) \ ! 430: ? ((h)->next_free = (h)->chunk_limit) : 0), \ ! 431: (h)->object_base = (h)->next_free, \ ! 432: __INT_TO_PTR ((h)->temp)) ! 433: ! 434: #ifdef __STDC__ ! 435: #define obstack_free(h,obj) \ ! 436: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ ! 437: (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ ! 438: ? (int) ((h)->next_free = (h)->object_base \ ! 439: = (h)->temp + (char *) (h)->chunk) \ ! 440: : ((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0))) ! 441: #else ! 442: #define obstack_free(h,obj) \ ! 443: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ ! 444: (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ ! 445: ? (int) ((h)->next_free = (h)->object_base \ ! 446: = (h)->temp + (char *) (h)->chunk) \ ! 447: : (int) _obstack_free ((h), (h)->temp + (char *) (h)->chunk))) ! 448: #endif ! 449: ! 450: #endif /* not __GNUC__ */ ! 451: ! 452: #endif /* not __OBSTACKS__ */ ! 453:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.