|
|
1.1 root 1: /* obstack.h - object stack macros 1.1.1.3 ! 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: /* Summary: 19: 20: All the apparent functions defined here are macros. The idea 21: is that you would use these pre-tested macros to solve a 22: very specific set of problems, and they would run fast. 23: Caution: no side-effects in arguments please!! They may be 24: evaluated MANY times!! 25: 26: These macros operate a stack of objects. Each object starts life 27: small, and may grow to maturity. (Consider building a word syllable 28: by syllable.) An object can move while it is growing. Once it has 29: been "finished" it never changes address again. So the "top of the 30: stack" is typically an immature growing object, while the rest of the 31: stack is of mature, fixed size and fixed address objects. 32: 33: These routines grab large chunks of memory, using a function you 34: supply, called `obstack_chunk_alloc'. On occasion, they free chunks, 35: by calling `obstack_chunk_free'. You must define them and declare 36: them before using any obstack macros. 37: 38: Each independent stack is represented by a `struct obstack'. 39: Each of the obstack macros expects a pointer to such a structure 40: as the first argument. 41: 42: One motivation for this package is the problem of growing char strings 43: in symbol tables. Unless you are "fascist pig with a read-only mind" 1.1.1.2 root 44: --Gosper's immortal quote from HAKMEM item 154, out of context--you 1.1 root 45: would not like to put any arbitrary upper limit on the length of your 46: symbols. 47: 48: In practice this often means you will build many short symbols and a 49: few long symbols. At the time you are reading a symbol you don't know 50: how long it is. One traditional method is to read a symbol into a 51: buffer, realloc()ating the buffer every time you try to read a symbol 52: that is longer than the buffer. This is beaut, but you still will 53: want to copy the symbol from the buffer to a more permanent 54: symbol-table entry say about half the time. 55: 56: With obstacks, you can work differently. Use one obstack for all symbol 57: names. As you read a symbol, grow the name in the obstack gradually. 58: When the name is complete, finalize it. Then, if the symbol exists already, 59: free the newly read name. 60: 61: The way we do this is to take a large chunk, allocating memory from 62: low addresses. When you want to build a symbol in the chunk you just 63: add chars above the current "high water mark" in the chunk. When you 64: have finished adding chars, because you got to the end of the symbol, 65: you know how long the chars are, and you can create a new object. 66: Mostly the chars will not burst over the highest address of the chunk, 67: because you would typically expect a chunk to be (say) 100 times as 68: long as an average object. 69: 70: In case that isn't clear, when we have enough chars to make up 71: the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) 72: so we just point to it where it lies. No moving of chars is 73: needed and this is the second win: potentially long strings need 74: never be explicitly shuffled. Once an object is formed, it does not 75: change its address during its lifetime. 76: 77: When the chars burst over a chunk boundary, we allocate a larger 78: chunk, and then copy the partly formed object from the end of the old 79: chunk to the beginning of the new larger chunk. We then carry on 80: accreting characters to the end of the object as we normally would. 81: 82: A special macro is provided to add a single char at a time to a 83: growing object. This allows the use of register variables, which 84: break the ordinary 'growth' macro. 85: 86: Summary: 87: We allocate large chunks. 88: We carve out one object at a time from the current chunk. 89: Once carved, an object never moves. 90: We are free to append data of any size to the currently 91: growing object. 92: Exactly one object is growing in an obstack at any one time. 93: You can run one obstack per control block. 94: You may have as many control blocks as you dare. 1.1.1.2 root 95: Because of the way we do it, you can `unwind' an obstack 1.1 root 96: back to a previous state. (You may remove objects much 97: as you would with a stack.) 98: */ 99: 100: 101: /* Don't do the contents of this file more than once. */ 102: 1.1.1.3 ! root 103: #ifndef __OBSTACK_H__ ! 104: #define __OBSTACK_H__ 1.1 root 105: 106: /* We use subtraction of (char *)0 instead of casting to int 107: because on word-addressable machines a simple cast to int 108: may ignore the byte-within-word field of the pointer. */ 109: 110: #ifndef __PTR_TO_INT 111: #define __PTR_TO_INT(P) ((P) - (char *)0) 112: #endif 113: 114: #ifndef __INT_TO_PTR 115: #define __INT_TO_PTR(P) ((P) + (char *)0) 116: #endif 117: 1.1.1.2 root 118: /* We need the type of the resulting object. In ANSI C it is ptrdiff_t 119: but in traditional C it is usually long. If we are in ANSI C and 120: don't already have ptrdiff_t get it. */ 121: 1.1.1.3 ! root 122: #if defined (__STDC__) && __STDC__ && ! defined (offsetof) 1.1.1.2 root 123: #if defined (__GNUC__) && defined (IN_GCC) 124: /* On Next machine, the system's stddef.h screws up if included 1.1.1.3 ! root 125: after we have defined just ptrdiff_t, so include all of stddef.h. 1.1.1.2 root 126: Otherwise, define just ptrdiff_t, which is all we need. */ 127: #ifndef __NeXT__ 128: #define __need_ptrdiff_t 129: #endif 1.1.1.3 ! root 130: #endif 1.1.1.2 root 131: 132: #include <stddef.h> 133: #endif 134: 1.1.1.3 ! root 135: #if defined (__STDC__) && __STDC__ 1.1.1.2 root 136: #define PTR_INT_TYPE ptrdiff_t 137: #else 138: #define PTR_INT_TYPE long 139: #endif 140: 1.1 root 141: struct _obstack_chunk /* Lives at front of each chunk. */ 142: { 143: char *limit; /* 1 past end of this chunk */ 144: struct _obstack_chunk *prev; /* address of prior chunk or NULL */ 145: char contents[4]; /* objects begin here */ 146: }; 147: 148: struct obstack /* control current object in current chunk */ 149: { 150: long chunk_size; /* preferred size to allocate chunks in */ 151: struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */ 152: char *object_base; /* address of object we are building */ 153: char *next_free; /* where to add next char to current object */ 154: char *chunk_limit; /* address of char after current chunk */ 1.1.1.2 root 155: PTR_INT_TYPE temp; /* Temporary for some macros. */ 1.1 root 156: int alignment_mask; /* Mask of alignment for each object. */ 157: struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ 158: void (*freefun) (); /* User's function to free a chunk. */ 1.1.1.2 root 159: char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ 160: unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ 161: unsigned maybe_empty_object:1;/* There is a possibility that the current 162: chunk contains a zero-length object. This 163: prevents freeing the chunk if we allocate 164: a bigger chunk to replace it. */ 1.1.1.3 ! root 165: unsigned alloc_failed:1; /* chunk alloc func returned 0 */ 1.1 root 166: }; 167: 168: /* Declare the external functions we use; they are in obstack.c. */ 169: 1.1.1.3 ! root 170: #if defined (__STDC__) && __STDC__ 1.1 root 171: extern void _obstack_newchunk (struct obstack *, int); 172: extern void _obstack_free (struct obstack *, void *); 1.1.1.3 ! root 173: extern int _obstack_begin (struct obstack *, int, int, 1.1 root 174: void *(*) (), void (*) ()); 1.1.1.3 ! root 175: extern int _obstack_begin_1 (struct obstack *, int, int, 1.1.1.2 root 176: void *(*) (), void (*) (), void *); 1.1 root 177: #else 178: extern void _obstack_newchunk (); 179: extern void _obstack_free (); 1.1.1.3 ! root 180: extern int _obstack_begin (); ! 181: extern int _obstack_begin_1 (); 1.1 root 182: #endif 183: 1.1.1.3 ! root 184: #if defined (__STDC__) && __STDC__ 1.1 root 185: 186: /* Do the function-declarations after the structs 187: but before defining the macros. */ 188: 189: void obstack_init (struct obstack *obstack); 190: 191: void * obstack_alloc (struct obstack *obstack, int size); 192: 193: void * obstack_copy (struct obstack *obstack, void *address, int size); 194: void * obstack_copy0 (struct obstack *obstack, void *address, int size); 195: 196: void obstack_free (struct obstack *obstack, void *block); 197: 198: void obstack_blank (struct obstack *obstack, int size); 199: 200: void obstack_grow (struct obstack *obstack, void *data, int size); 201: void obstack_grow0 (struct obstack *obstack, void *data, int size); 202: 203: void obstack_1grow (struct obstack *obstack, int data_char); 204: void obstack_ptr_grow (struct obstack *obstack, void *data); 205: void obstack_int_grow (struct obstack *obstack, int data); 206: 207: void * obstack_finish (struct obstack *obstack); 208: 209: int obstack_object_size (struct obstack *obstack); 210: 211: int obstack_room (struct obstack *obstack); 212: void obstack_1grow_fast (struct obstack *obstack, int data_char); 213: void obstack_ptr_grow_fast (struct obstack *obstack, void *data); 214: void obstack_int_grow_fast (struct obstack *obstack, int data); 215: void obstack_blank_fast (struct obstack *obstack, int size); 216: 217: void * obstack_base (struct obstack *obstack); 218: void * obstack_next_free (struct obstack *obstack); 219: int obstack_alignment_mask (struct obstack *obstack); 220: int obstack_chunk_size (struct obstack *obstack); 221: 222: #endif /* __STDC__ */ 223: 224: /* Non-ANSI C cannot really support alternative functions for these macros, 225: so we do not declare them. */ 226: 227: /* Pointer to beginning of object being allocated or to be allocated next. 228: Note that this might not be the final address of the object 229: because a new chunk might be needed to hold the final size. */ 230: 1.1.1.3 ! root 231: #define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base) 1.1 root 232: 233: /* Size for allocating ordinary chunks. */ 234: 235: #define obstack_chunk_size(h) ((h)->chunk_size) 236: 237: /* Pointer to next byte not yet allocated in current chunk. */ 238: 1.1.1.3 ! root 239: #define obstack_next_free(h) ((h)->alloc_failed ? 0 : (h)->next_free) 1.1 root 240: 241: /* Mask specifying low bits that should be clear in address of an object. */ 242: 243: #define obstack_alignment_mask(h) ((h)->alignment_mask) 244: 245: #define obstack_init(h) \ 246: _obstack_begin ((h), 0, 0, \ 1.1.1.2 root 247: (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) 1.1 root 248: 249: #define obstack_begin(h, size) \ 250: _obstack_begin ((h), (size), 0, \ 1.1.1.2 root 251: (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) 252: 253: #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ 254: _obstack_begin ((h), (size), (alignment), \ 255: (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) 256: 257: #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ 258: _obstack_begin_1 ((h), (size), (alignment), \ 259: (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) 1.1 root 260: 1.1.1.3 ! root 261: #define obstack_chunkfun(h, newchunkfun) \ ! 262: ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) ! 263: ! 264: #define obstack_freefun(h, newfreefun) \ ! 265: ((h) -> freefun = (void (*)()) (newfreefun)) ! 266: 1.1 root 267: #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) 268: 269: #define obstack_blank_fast(h,n) ((h)->next_free += (n)) 270: 1.1.1.3 ! root 271: #if defined (__GNUC__) && defined (__STDC__) && __STDC__ ! 272: /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and ! 273: does not implement __extension__. But that compiler doesn't define ! 274: __GNUC_MINOR__. */ ! 275: #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 1.1 root 276: #define __extension__ 277: #endif 278: 279: /* For GNU C, if not -traditional, 280: we can define these macros to compute all args only once 281: without using a global variable. 282: Also, we can avoid using the `temp' slot, to make faster code. */ 283: 284: #define obstack_object_size(OBSTACK) \ 285: __extension__ \ 286: ({ struct obstack *__o = (OBSTACK); \ 1.1.1.3 ! root 287: __o->alloc_failed ? 0 : \ 1.1 root 288: (unsigned) (__o->next_free - __o->object_base); }) 289: 290: #define obstack_room(OBSTACK) \ 291: __extension__ \ 292: ({ struct obstack *__o = (OBSTACK); \ 293: (unsigned) (__o->chunk_limit - __o->next_free); }) 294: 295: #define obstack_grow(OBSTACK,where,length) \ 296: __extension__ \ 297: ({ struct obstack *__o = (OBSTACK); \ 298: int __len = (length); \ 1.1.1.3 ! root 299: if (__o->next_free + __len > __o->chunk_limit) \ ! 300: _obstack_newchunk (__o, __len); \ ! 301: if (!__o->alloc_failed) \ ! 302: { \ ! 303: bcopy ((char *) (where), __o->next_free, __len); \ ! 304: __o->next_free += __len; \ ! 305: } \ 1.1 root 306: (void) 0; }) 307: 308: #define obstack_grow0(OBSTACK,where,length) \ 309: __extension__ \ 310: ({ struct obstack *__o = (OBSTACK); \ 311: int __len = (length); \ 1.1.1.3 ! root 312: if (__o->next_free + __len + 1 > __o->chunk_limit) \ ! 313: _obstack_newchunk (__o, __len + 1); \ ! 314: if (!__o->alloc_failed) \ ! 315: { \ ! 316: bcopy ((char *) (where), __o->next_free, __len); \ ! 317: __o->next_free += __len; \ ! 318: *(__o->next_free)++ = 0; \ ! 319: } \ 1.1 root 320: (void) 0; }) 321: 322: #define obstack_1grow(OBSTACK,datum) \ 323: __extension__ \ 324: ({ struct obstack *__o = (OBSTACK); \ 1.1.1.3 ! root 325: if (__o->next_free + 1 > __o->chunk_limit) \ ! 326: _obstack_newchunk (__o, 1); \ ! 327: if (!__o->alloc_failed) \ ! 328: *(__o->next_free)++ = (datum); \ 1.1 root 329: (void) 0; }) 330: 331: /* These assume that the obstack alignment is good enough for pointers or ints, 332: and that the data added so far to the current object 333: shares that much alignment. */ 334: 335: #define obstack_ptr_grow(OBSTACK,datum) \ 336: __extension__ \ 337: ({ struct obstack *__o = (OBSTACK); \ 1.1.1.3 ! root 338: if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ ! 339: _obstack_newchunk (__o, sizeof (void *)); \ ! 340: if (!__o->alloc_failed) \ ! 341: *((void **)__o->next_free)++ = ((void *)datum); \ 1.1 root 342: (void) 0; }) 343: 344: #define obstack_int_grow(OBSTACK,datum) \ 345: __extension__ \ 346: ({ struct obstack *__o = (OBSTACK); \ 1.1.1.3 ! root 347: if (__o->next_free + sizeof (int) > __o->chunk_limit) \ ! 348: _obstack_newchunk (__o, sizeof (int)); \ ! 349: if (!__o->alloc_failed) \ ! 350: *((int *)__o->next_free)++ = ((int)datum); \ 1.1 root 351: (void) 0; }) 352: 353: #define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr) 354: #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) 355: 356: #define obstack_blank(OBSTACK,length) \ 357: __extension__ \ 358: ({ struct obstack *__o = (OBSTACK); \ 359: int __len = (length); \ 1.1.1.3 ! root 360: if (__o->chunk_limit - __o->next_free < __len) \ ! 361: _obstack_newchunk (__o, __len); \ ! 362: if (!__o->alloc_failed) \ ! 363: __o->next_free += __len; \ 1.1 root 364: (void) 0; }) 365: 366: #define obstack_alloc(OBSTACK,length) \ 367: __extension__ \ 368: ({ struct obstack *__h = (OBSTACK); \ 369: obstack_blank (__h, (length)); \ 370: obstack_finish (__h); }) 371: 372: #define obstack_copy(OBSTACK,where,length) \ 373: __extension__ \ 374: ({ struct obstack *__h = (OBSTACK); \ 375: obstack_grow (__h, (where), (length)); \ 376: obstack_finish (__h); }) 377: 378: #define obstack_copy0(OBSTACK,where,length) \ 379: __extension__ \ 380: ({ struct obstack *__h = (OBSTACK); \ 381: obstack_grow0 (__h, (where), (length)); \ 382: obstack_finish (__h); }) 383: 384: /* The local variable is named __o1 to avoid a name conflict 385: when obstack_blank is called. */ 386: #define obstack_finish(OBSTACK) \ 387: __extension__ \ 388: ({ struct obstack *__o1 = (OBSTACK); \ 1.1.1.3 ! root 389: void *value; \ ! 390: if (__o1->alloc_failed) \ ! 391: value = 0; \ ! 392: else \ ! 393: { \ ! 394: value = (void *) __o1->object_base; \ ! 395: if (__o1->next_free == value) \ ! 396: __o1->maybe_empty_object = 1; \ ! 397: __o1->next_free \ ! 398: = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ ! 399: & ~ (__o1->alignment_mask)); \ ! 400: if (__o1->next_free - (char *)__o1->chunk \ ! 401: > __o1->chunk_limit - (char *)__o1->chunk) \ ! 402: __o1->next_free = __o1->chunk_limit; \ ! 403: __o1->object_base = __o1->next_free; \ ! 404: } \ 1.1 root 405: value; }) 406: 407: #define obstack_free(OBSTACK, OBJ) \ 408: __extension__ \ 409: ({ struct obstack *__o = (OBSTACK); \ 410: void *__obj = (OBJ); \ 411: if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ 412: __o->next_free = __o->object_base = __obj; \ 413: else (obstack_free) (__o, __obj); }) 414: 415: #else /* not __GNUC__ or not __STDC__ */ 416: 417: #define obstack_object_size(h) \ 1.1.1.3 ! root 418: (unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base) 1.1 root 419: 420: #define obstack_room(h) \ 421: (unsigned) ((h)->chunk_limit - (h)->next_free) 422: 1.1.1.3 ! root 423: /* Note that the call to _obstack_newchunk is enclosed in (..., 0) ! 424: so that we can avoid having void expressions ! 425: in the arms of the conditional expression. ! 426: Casting the third operand to void was tried before, ! 427: but some compilers won't accept it. */ ! 428: 1.1 root 429: #define obstack_grow(h,where,length) \ 430: ( (h)->temp = (length), \ 431: (((h)->next_free + (h)->temp > (h)->chunk_limit) \ 432: ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ 1.1.1.3 ! root 433: ((h)->alloc_failed ? 0 : \ ! 434: (bcopy ((char *) (where), (h)->next_free, (h)->temp), \ ! 435: (h)->next_free += (h)->temp))) 1.1 root 436: 437: #define obstack_grow0(h,where,length) \ 438: ( (h)->temp = (length), \ 439: (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ 440: ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ 1.1.1.3 ! root 441: ((h)->alloc_failed ? 0 : \ ! 442: (bcopy ((char *) (where), (h)->next_free, (h)->temp), \ 1.1 root 443: (h)->next_free += (h)->temp, \ 1.1.1.3 ! root 444: *((h)->next_free)++ = 0))) 1.1 root 445: 446: #define obstack_1grow(h,datum) \ 447: ( (((h)->next_free + 1 > (h)->chunk_limit) \ 448: ? (_obstack_newchunk ((h), 1), 0) : 0), \ 1.1.1.3 ! root 449: ((h)->alloc_failed ? 0 : \ ! 450: (*((h)->next_free)++ = (datum)))) 1.1 root 451: 452: #define obstack_ptr_grow(h,datum) \ 453: ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ 454: ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ 1.1.1.3 ! root 455: ((h)->alloc_failed ? 0 : \ ! 456: (*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum)))) 1.1 root 457: 458: #define obstack_int_grow(h,datum) \ 459: ( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ 460: ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ 1.1.1.3 ! root 461: ((h)->alloc_failed ? 0 : \ ! 462: (*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum)))) 1.1 root 463: 464: #define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr) 465: #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) 466: 467: #define obstack_blank(h,length) \ 468: ( (h)->temp = (length), \ 469: (((h)->chunk_limit - (h)->next_free < (h)->temp) \ 470: ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ 1.1.1.3 ! root 471: ((h)->alloc_failed ? 0 : \ ! 472: ((h)->next_free += (h)->temp))) 1.1 root 473: 474: #define obstack_alloc(h,length) \ 475: (obstack_blank ((h), (length)), obstack_finish ((h))) 476: 477: #define obstack_copy(h,where,length) \ 478: (obstack_grow ((h), (where), (length)), obstack_finish ((h))) 479: 480: #define obstack_copy0(h,where,length) \ 481: (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) 482: 483: #define obstack_finish(h) \ 1.1.1.3 ! root 484: ( (h)->alloc_failed ? 0 : \ ! 485: (((h)->next_free == (h)->object_base \ 1.1 root 486: ? (((h)->maybe_empty_object = 1), 0) \ 487: : 0), \ 488: (h)->temp = __PTR_TO_INT ((h)->object_base), \ 489: (h)->next_free \ 490: = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ 491: & ~ ((h)->alignment_mask)), \ 492: (((h)->next_free - (char *)(h)->chunk \ 493: > (h)->chunk_limit - (char *)(h)->chunk) \ 494: ? ((h)->next_free = (h)->chunk_limit) : 0), \ 495: (h)->object_base = (h)->next_free, \ 1.1.1.3 ! root 496: __INT_TO_PTR ((h)->temp))) 1.1 root 497: 1.1.1.3 ! root 498: #if defined (__STDC__) && __STDC__ 1.1 root 499: #define obstack_free(h,obj) \ 500: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ 501: (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ 502: ? (int) ((h)->next_free = (h)->object_base \ 503: = (h)->temp + (char *) (h)->chunk) \ 504: : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) 505: #else 506: #define obstack_free(h,obj) \ 507: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ 508: (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ 509: ? (int) ((h)->next_free = (h)->object_base \ 510: = (h)->temp + (char *) (h)->chunk) \ 511: : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) 512: #endif 513: 514: #endif /* not __GNUC__ or not __STDC__ */ 515: 1.1.1.3 ! root 516: #endif /* not __OBSTACK_H__ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.