|
|
1.1 ! root 1: /* obstack.c - subroutines used implicitly by 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: #include "obstack.h" ! 107: ! 108: #ifdef __STDC__ ! 109: #define POINTER void * ! 110: #else ! 111: #define POINTER char * ! 112: #endif ! 113: ! 114: /* Determine default alignment. */ ! 115: struct fooalign {char x; double d;}; ! 116: #define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0) ! 117: /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. ! 118: But in fact it might be less smart and round addresses to as much as ! 119: DEFAULT_ROUNDING. So we prepare for it to do that. */ ! 120: union fooround {long x; double d;}; ! 121: #define DEFAULT_ROUNDING (sizeof (union fooround)) ! 122: ! 123: /* When we copy a long block of data, this is the unit to do it with. ! 124: On some machines, copying successive ints does not work; ! 125: in such a case, redefine COPYING_UNIT to `long' (if that works) ! 126: or `char' as a last resort. */ ! 127: #ifndef COPYING_UNIT ! 128: #define COPYING_UNIT int ! 129: #endif ! 130: ! 131: /* The non-GNU-C macros copy the obstack into this global variable ! 132: to avoid multiple evaluation. */ ! 133: ! 134: struct obstack *_obstack; ! 135: ! 136: /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). ! 137: Objects start on multiples of ALIGNMENT (0 means use default). ! 138: CHUNKFUN is the function to use to allocate chunks, ! 139: and FREEFUN the function to free them. */ ! 140: ! 141: void ! 142: _obstack_begin (h, size, alignment, chunkfun, freefun) ! 143: struct obstack *h; ! 144: int size; ! 145: int alignment; ! 146: POINTER (*chunkfun) (); ! 147: void (*freefun) (); ! 148: { ! 149: register struct _obstack_chunk* chunk; /* points to new chunk */ ! 150: ! 151: if (alignment == 0) ! 152: alignment = DEFAULT_ALIGNMENT; ! 153: if (size == 0) ! 154: /* Default size is what GNU malloc can fit in a 4096-byte block. ! 155: Pick a number small enough that when rounded up to DEFAULT_ROUNDING ! 156: it is still smaller than 4096 - 4. */ ! 157: { ! 158: int extra = 4; ! 159: if (extra < DEFAULT_ROUNDING) ! 160: extra = DEFAULT_ROUNDING; ! 161: size = 4096 - extra; ! 162: } ! 163: ! 164: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; ! 165: h->freefun = freefun; ! 166: h->chunk_size = size; ! 167: h->alignment_mask = alignment - 1; ! 168: ! 169: chunk = h->chunk = (*h->chunkfun) (h->chunk_size); ! 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: } ! 175: ! 176: /* Allocate a new current chunk for the obstack *H ! 177: on the assumption that LENGTH bytes need to be added ! 178: to the current object, or a new object of length LENGTH allocated. ! 179: Copies any partial object from the end of the old chunk ! 180: to the beginning of the new one. */ ! 181: ! 182: void ! 183: _obstack_newchunk (h, length) ! 184: struct obstack *h; ! 185: int length; ! 186: { ! 187: register struct _obstack_chunk* old_chunk = h->chunk; ! 188: register struct _obstack_chunk* new_chunk; ! 189: register long new_size; ! 190: register int obj_size = h->next_free - h->object_base; ! 191: register int i; ! 192: ! 193: /* Compute size for new chunk. */ ! 194: new_size = (obj_size + length) << 1; ! 195: if (new_size < h->chunk_size) ! 196: new_size = h->chunk_size; ! 197: ! 198: /* Allocate and initialize the new chunk. */ ! 199: new_chunk = h->chunk = (*h->chunkfun) (new_size); ! 200: new_chunk->prev = old_chunk; ! 201: new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; ! 202: ! 203: /* Move the existing object to the new chunk. ! 204: Word at a time is fast and is safe because these ! 205: structures are aligned at least that much. */ ! 206: for (i = (obj_size + sizeof (COPYING_UNIT) - 1) / sizeof (COPYING_UNIT) - 1; ! 207: i >= 0; i--) ! 208: ((COPYING_UNIT *)new_chunk->contents)[i] ! 209: = ((COPYING_UNIT *)h->object_base)[i]; ! 210: ! 211: h->object_base = new_chunk->contents; ! 212: h->next_free = h->object_base + obj_size; ! 213: } ! 214: ! 215: /* Free objects in obstack H, including OBJ and everything allocate ! 216: more recently than OBJ. If OBJ is zero, free everything in H. */ ! 217: ! 218: void ! 219: #ifdef __STDC__ ! 220: #undef obstack_free ! 221: obstack_free (h, obj) ! 222: ! 223: #else ! 224: _obstack_free (h, obj) ! 225: #endif ! 226: struct obstack *h; ! 227: POINTER obj; ! 228: { ! 229: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ ! 230: register struct _obstack_chunk* plp; /* point to previous chunk if any */ ! 231: ! 232: lp = (h)->chunk; ! 233: while (lp != 0 && ((POINTER)lp > obj || (POINTER)(lp)->limit < obj)) ! 234: { ! 235: plp = lp -> prev; ! 236: (*h->freefun) (lp); ! 237: lp = plp; ! 238: } ! 239: if (lp) ! 240: { ! 241: (h)->object_base = (h)->next_free = (char *)(obj); ! 242: (h)->chunk_limit = lp->limit; ! 243: (h)->chunk = lp; ! 244: } ! 245: else if (obj != 0) ! 246: /* obj is not in any of the chunks! */ ! 247: abort (); ! 248: } ! 249: ! 250: #if 0 ! 251: /* These are now turned off because the applications do not use it ! 252: and it uses bcopy via obstack_grow, which causes trouble on sysV. */ ! 253: ! 254: /* Now define the functional versions of the obstack macros. ! 255: Define them to simply use the corresponding macros to do the job. */ ! 256: ! 257: #ifdef __STDC__ ! 258: /* These function definitions do not work with non-ANSI preprocessors; ! 259: they won't pass through the macro names in parentheses. */ ! 260: ! 261: /* The function names appear in parentheses in order to prevent ! 262: the macro-definitions of the names from being expanded there. */ ! 263: ! 264: POINTER (obstack_base) (obstack) ! 265: struct obstack *obstack; ! 266: { ! 267: return obstack_base (obstack); ! 268: } ! 269: ! 270: POINTER (obstack_next_free) (obstack) ! 271: struct obstack *obstack; ! 272: { ! 273: return obstack_next_free (obstack); ! 274: } ! 275: ! 276: int (obstack_object_size) (obstack) ! 277: struct obstack *obstack; ! 278: { ! 279: return obstack_object_size (obstack); ! 280: } ! 281: ! 282: int (obstack_room) (obstack) ! 283: struct obstack *obstack; ! 284: { ! 285: return obstack_room (obstack); ! 286: } ! 287: ! 288: void (obstack_grow) (obstack, pointer, length) ! 289: struct obstack *obstack; ! 290: POINTER pointer; ! 291: int length; ! 292: { ! 293: obstack_grow (obstack, pointer, length); ! 294: } ! 295: ! 296: void (obstack_grow0) (obstack, pointer, length) ! 297: struct obstack *obstack; ! 298: POINTER pointer; ! 299: int length; ! 300: { ! 301: obstack_grow0 (obstack, pointer, length); ! 302: } ! 303: ! 304: void (obstack_1grow) (obstack, character) ! 305: struct obstack *obstack; ! 306: int character; ! 307: { ! 308: obstack_1grow (obstack, character); ! 309: } ! 310: ! 311: void (obstack_blank) (obstack, length) ! 312: struct obstack *obstack; ! 313: int length; ! 314: { ! 315: obstack_blank (obstack, length); ! 316: } ! 317: ! 318: void (obstack_1grow_fast) (obstack, character) ! 319: struct obstack *obstack; ! 320: int character; ! 321: { ! 322: obstack_1grow_fast (obstack, character); ! 323: } ! 324: ! 325: void (obstack_blank_fast) (obstack, length) ! 326: struct obstack *obstack; ! 327: int length; ! 328: { ! 329: obstack_blank_fast (obstack, length); ! 330: } ! 331: ! 332: POINTER (obstack_finish) (obstack) ! 333: struct obstack *obstack; ! 334: { ! 335: return obstack_finish (obstack); ! 336: } ! 337: ! 338: POINTER (obstack_alloc) (obstack, length) ! 339: struct obstack *obstack; ! 340: int length; ! 341: { ! 342: return obstack_alloc (obstack, length); ! 343: } ! 344: ! 345: POINTER (obstack_copy) (obstack, pointer, length) ! 346: struct obstack *obstack; ! 347: POINTER pointer; ! 348: int length; ! 349: { ! 350: return obstack_copy (obstack, pointer, length); ! 351: } ! 352: ! 353: POINTER (obstack_copy0) (obstack, pointer, length) ! 354: struct obstack *obstack; ! 355: POINTER pointer; ! 356: int length; ! 357: { ! 358: return obstack_copy0 (obstack, pointer, length); ! 359: } ! 360: ! 361: #endif /* __STDC__ */ ! 362: ! 363: #endif /* 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.