Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

obstack.h

Go to the documentation of this file.
00001 /* obstack.h - object stack macros
00002    Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
00003 
00004 This program is free software; you can redistribute it and/or modify it
00005 under the terms of the GNU Library General Public License as published by the
00006 Free Software Foundation; either version 2, or (at your option) any
00007 later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU Library General Public License for more details.
00013 
00014 You should have received a copy of the GNU Library General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
00017 
00102 /* Don't do the contents of this file more than once.  */
00103 
00104 #ifndef __OBSTACK_H__
00105 #define __OBSTACK_H__
00106 
00107 
00108 #ifndef __PTR_TO_INT
00109 
00117 #define __PTR_TO_INT(P) ((P) - (char *)0)
00118 #endif
00119 
00120 #ifndef __INT_TO_PTR
00121 
00129 #define __INT_TO_PTR(P) ((P) + (char *)0)
00130 #endif
00131 
00132 /* CodeWarrior C++ does not define __STDC__ even though it should? */
00133 #if ( defined(__MWERKS__) && defined(__cplusplus) )
00134 #define __STDC__        TRUE    
00135 #endif
00136 
00137 /* We need the type of the resulting object.  In ANSI C it is ptrdiff_t
00138    but in traditional C it is usually long.  If we are in ANSI C and
00139    don't already have ptrdiff_t get it.  */
00140 
00141 #if defined (__STDC__) && ! defined (offsetof)
00142 #if defined (__GNUC__) && defined (IN_GCC)
00143 /* On Next machine, the system's stddef.h screws up if included
00144    after we have defined just ptrdiff_t, so include all of stddef.h.
00145    Otherwise, define just ptrdiff_t, which is all we need.  */
00146 #ifndef __NeXT__
00147 #define __need_ptrdiff_t
00148 #endif
00149 #endif
00150 
00151 #include <stddef.h>
00152 #endif
00153 
00154 #ifdef __STDC__
00155 #define PTR_INT_TYPE ptrdiff_t
00156 #else
00157 #define PTR_INT_TYPE long
00158 #endif
00159 
00163 struct _obstack_chunk           /* Lives at front of each chunk. */
00164 {
00165   char  *limit;                                 
00166   struct _obstack_chunk *prev;  
00167   char  contents[4];                    
00168 };
00169 
00173 struct obstack                                                  /* control current object in current chunk */
00174 {
00175   long  chunk_size;                                                     
00176   struct _obstack_chunk* chunk;                         
00177   char  *object_base;                                           
00178   char  *next_free;                                             
00179   char  *chunk_limit;                                   
00180   PTR_INT_TYPE temp;                                            
00181   int   alignment_mask;                                         
00182   struct _obstack_chunk *(*chunkfun) (int);     
00183   void (*freefun) (void *);                                     
00184   char *extra_arg;                                              
00185   unsigned use_extra_arg:1;                                     
00186   unsigned maybe_empty_object:1;                        
00190   unsigned alloc_failed:1;                                              
00191 };
00192 
00193 /* Declare the external functions we use; they are in obstack.c.  */
00194 
00195 #ifdef __STDC__
00196 
00197 extern void _obstack_newchunk (struct obstack *, int);
00198 extern void _obstack_free (struct obstack *, void *);
00199 extern int _obstack_begin (struct obstack *, int, int,
00200                             void *(*) (int), void (*) (void *));
00201 extern int _obstack_begin_1 (struct obstack *, int, int,
00202                               void *(*) (int), void (*) (void *), void *);
00203 extern int _obstack_memory_used (struct obstack *);
00204 #else
00205 extern void _obstack_newchunk ();
00206 extern void _obstack_free ();
00207 extern int _obstack_begin ();
00208 extern int _obstack_begin_1 ();
00209 extern int _obstack_memory_used ();
00210 #endif
00211 
00212 #ifdef __STDC__
00213 
00214 /* Do the function-declarations after the structs
00215    but before defining the macros.  */
00216 
00217 void obstack_init (struct obstack *obstack);
00218 
00219 void * obstack_alloc (struct obstack *obstack, int size);
00220 
00221 void * obstack_copy (struct obstack *obstack, void *address, int size);
00222 void * obstack_copy0 (struct obstack *obstack, void *address, int size);
00223 
00224 void obstack_free (struct obstack *obstack, void *block);
00225 
00226 void obstack_blank (struct obstack *obstack, int size);
00227 
00228 void obstack_grow (struct obstack *obstack, void *data, int size);
00229 void obstack_grow0 (struct obstack *obstack, void *data, int size);
00230 
00231 void obstack_1grow (struct obstack *obstack, int data_char);
00232 void obstack_ptr_grow (struct obstack *obstack, void *data);
00233 void obstack_int_grow (struct obstack *obstack, int data);
00234 
00235 void * obstack_finish (struct obstack *obstack);
00236 
00237 int obstack_object_size (struct obstack *obstack);
00238 
00239 int obstack_room (struct obstack *obstack);
00240 void obstack_1grow_fast (struct obstack *obstack, int data_char);
00241 void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
00242 void obstack_int_grow_fast (struct obstack *obstack, int data);
00243 void obstack_blank_fast (struct obstack *obstack, int size);
00244 
00245 void * obstack_base (struct obstack *obstack);
00246 void * obstack_next_free (struct obstack *obstack);
00247 int obstack_alignment_mask (struct obstack *obstack);
00248 int obstack_chunk_size (struct obstack *obstack);
00249 int obstack_memory_used (struct obstack *obstack);
00250 
00251 #endif /* __STDC__ */
00252 
00253 /* Non-ANSI C cannot really support alternative functions for these macros,
00254    so we do not declare them.  */
00255 
00264 #define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base)
00265 
00269 #define obstack_chunk_size(h) ((h)->chunk_size)
00270 
00276 #define obstack_next_free(h)    ((h)->alloc_failed ? 0 : (h)->next_free)
00277 
00283 #define obstack_alignment_mask(h) ((h)->alignment_mask)
00284 
00285 #define obstack_init(h) \
00286   _obstack_begin ((h), 0, 0, \
00287                   (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
00288 
00289 #define obstack_begin(h, size) \
00290   _obstack_begin ((h), (size), 0, \
00291                   (void *(*) (int)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
00292 
00293 #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
00294   _obstack_begin ((h), (size), (alignment), \
00295                     (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
00296 
00297 #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
00298   _obstack_begin_1 ((h), (size), (alignment), \
00299                     (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
00300 
00301 #define obstack_chunkfun(h, newchunkfun) \
00302   ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
00303 
00304 #define obstack_freefun(h, newfreefun) \
00305   ((h) -> freefun = (void (*)()) (newfreefun))
00306 
00307 #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
00308 
00309 #define obstack_blank_fast(h,n) ((h)->next_free += (n))
00310 
00311 #define obstack_memory_used(h) _obstack_memory_used (h)
00312 
00313 #if defined (__GNUC__) && defined (__STDC__)
00314 #if __GNUC__ < 2
00315 #define __extension__
00316 #endif
00317 
00318 /* For GNU C, if not -traditional,
00319    we can define these macros to compute all args only once
00320    without using a global variable.
00321    Also, we can avoid using the `temp' slot, to make faster code.  */
00322 
00323 #define obstack_object_size(OBSTACK)                                    \
00324   __extension__                                                         \
00325   ({ struct obstack *__o = (OBSTACK);                                   \
00326      __o->alloc_failed ? 0 :                                            \
00327      (unsigned) (__o->next_free - __o->object_base); })
00328 
00329 #define obstack_room(OBSTACK)                                           \
00330   __extension__                                                         \
00331   ({ struct obstack *__o = (OBSTACK);                                   \
00332      (unsigned) (__o->chunk_limit - __o->next_free); })
00333 
00334 #define obstack_grow(OBSTACK,where,length)                              \
00335 __extension__                                                           \
00336 ({ struct obstack *__o = (OBSTACK);                                     \
00337    int __len = (length);                                                \
00338    if (__o->next_free + __len > __o->chunk_limit)                       \
00339      _obstack_newchunk (__o, __len);                                    \
00340    if (!__o->alloc_failed)                                              \
00341      {                                                                  \
00342         bcopy (where, __o->next_free, __len);                           \
00343         __o->next_free += __len;                                        \
00344      }                                                                  \
00345    (void) 0; })
00346 
00347 #define obstack_grow0(OBSTACK,where,length)                             \
00348 __extension__                                                           \
00349 ({ struct obstack *__o = (OBSTACK);                                     \
00350    int __len = (length);                                                \
00351    if (__o->next_free + __len + 1 > __o->chunk_limit)                   \
00352      _obstack_newchunk (__o, __len + 1);                                \
00353    if (!__o->alloc_failed)                                              \
00354      {                                                                  \
00355        bcopy (where, __o->next_free, __len);                            \
00356        __o->next_free += __len;                                         \
00357        *(__o->next_free)++ = 0;                                         \
00358      }                                                                  \
00359    (void) 0; })
00360 
00361 #define obstack_1grow(OBSTACK,datum)                                    \
00362 __extension__                                                           \
00363 ({ struct obstack *__o = (OBSTACK);                                     \
00364    if (__o->next_free + 1 > __o->chunk_limit)                           \
00365      _obstack_newchunk (__o, 1);                                        \
00366    if (!__o->alloc_failed)                                              \
00367      *(__o->next_free)++ = (datum);                                     \
00368    (void) 0; })
00369 
00370 /* These assume that the obstack alignment is good enough for pointers or ints,
00371    and that the data added so far to the current object
00372    shares that much alignment.  */
00373    
00374 #define obstack_ptr_grow(OBSTACK,datum)                                 \
00375 __extension__                                                           \
00376 ({ struct obstack *__o = (OBSTACK);                                     \
00377    if (__o->next_free + sizeof (void *) > __o->chunk_limit)             \
00378      _obstack_newchunk (__o, sizeof (void *));                          \
00379    if (!__o->alloc_failed)                                              \
00380      *((void **)__o->next_free)++ = ((void *)datum);                    \
00381    (void) 0; })
00382 
00383 #define obstack_int_grow(OBSTACK,datum)                                 \
00384 __extension__                                                           \
00385 ({ struct obstack *__o = (OBSTACK);                                     \
00386    if (__o->next_free + sizeof (int) > __o->chunk_limit)                \
00387      _obstack_newchunk (__o, sizeof (int));                             \
00388    if (!__o->alloc_failed)                                              \
00389      *((int *)__o->next_free)++ = ((int)datum);                         \
00390    (void) 0; })
00391 
00392 #define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
00393 #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
00394 
00395 #define obstack_blank(OBSTACK,length)                                   \
00396 __extension__                                                           \
00397 ({ struct obstack *__o = (OBSTACK);                                     \
00398    int __len = (length);                                                \
00399    if (__o->chunk_limit - __o->next_free < __len)                       \
00400      _obstack_newchunk (__o, __len);                                    \
00401    if (!__o->alloc_failed)                                              \
00402      __o->next_free += __len;                                           \
00403    (void) 0; })
00404 
00405 #define obstack_alloc(OBSTACK,length)                                   \
00406 __extension__                                                           \
00407 ({ struct obstack *__h = (OBSTACK);                                     \
00408    obstack_blank (__h, (length));                                       \
00409    obstack_finish (__h); })
00410 
00411 #define obstack_copy(OBSTACK,where,length)                              \
00412 __extension__                                                           \
00413 ({ struct obstack *__h = (OBSTACK);                                     \
00414    obstack_grow (__h, (where), (length));                               \
00415    obstack_finish (__h); })
00416 
00417 #define obstack_copy0(OBSTACK,where,length)                             \
00418 __extension__                                                           \
00419 ({ struct obstack *__h = (OBSTACK);                                     \
00420    obstack_grow0 (__h, (where), (length));                              \
00421    obstack_finish (__h); })
00422 
00423 /* The local variable is named __o1 to avoid a name conflict
00424    when obstack_blank is called.  */
00425 #define obstack_finish(OBSTACK)                                         \
00426 __extension__                                                           \
00427 ({ struct obstack *__o1 = (OBSTACK);                                    \
00428    void *value;                                                         \
00429    if (__o1->alloc_failed)                                              \
00430      value = 0;                                                         \
00431    else                                                                 \
00432      {                                                                  \
00433        value = (void *) __o1->object_base;                              \
00434        if (__o1->next_free == value)                                    \
00435          __o1->maybe_empty_object = 1;                                  \
00436        __o1->next_free                                                  \
00437          = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
00438                          & ~ (__o1->alignment_mask));                   \
00439        if (__o1->next_free - (char *)__o1->chunk                        \
00440            > __o1->chunk_limit - (char *)__o1->chunk)                   \
00441          __o1->next_free = __o1->chunk_limit;                           \
00442        __o1->object_base = __o1->next_free;                             \
00443       }                                                                 \
00444    value; })
00445 
00446 #define obstack_free(OBSTACK, OBJ)                                      \
00447 __extension__                                                           \
00448 ({ struct obstack *__o = (OBSTACK);                                     \
00449    void *__obj = (OBJ);                                                 \
00450    if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit)  \
00451      __o->next_free = __o->object_base = (char *)__obj;                 \
00452    else (obstack_free) (__o, __obj); })
00453 
00454 #else /* not __GNUC__ or not __STDC__ */
00455 
00456 #define obstack_object_size(h) \
00457  (unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base)
00458 
00459 #define obstack_room(h)         \
00460  (unsigned) ((h)->chunk_limit - (h)->next_free)
00461 
00462 /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
00463    so that we can avoid having void expressions
00464    in the arms of the conditional expression.
00465    Casting the third operand to void was tried before,
00466    but some compilers won't accept it.  */
00467 
00468 #define obstack_grow(h,where,length)                                    \
00469 ( (h)->temp = (length),                                                 \
00470   (((h)->next_free + (h)->temp > (h)->chunk_limit)                      \
00471    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),                      \
00472   ((h)->alloc_failed ? 0 :                                              \
00473   (bcopy (where, (h)->next_free, (h)->temp),                            \
00474   (h)->next_free += (h)->temp)))
00475 
00476 #define obstack_grow0(h,where,length)                                   \
00477 ( (h)->temp = (length),                                                 \
00478   (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)                  \
00479    ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0),                  \
00480   ((h)->alloc_failed ? 0 :                                              \
00481   (bcopy (where, (h)->next_free, (h)->temp),                            \
00482   (h)->next_free += (h)->temp,                                          \
00483   *((h)->next_free)++ = 0)))
00484 
00485 #define obstack_1grow(h,datum)                                          \
00486 ( (((h)->next_free + 1 > (h)->chunk_limit)                              \
00487    ? (_obstack_newchunk ((h), 1), 0) : 0),                              \
00488  ((h)->alloc_failed ? 0 :                                               \
00489   (*((h)->next_free)++ = (datum))))
00490 
00491 #define obstack_ptr_grow(h,datum)                                       \
00492 ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)                \
00493    ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),                \
00494   ((h)->alloc_failed ? 0 :                                              \
00495   (*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum))))
00496 
00497 #define obstack_int_grow(h,datum)                                       \
00498 ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)                   \
00499    ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),                   \
00500   ((h)->alloc_failed ? 0 :                                              \
00501   (*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum))))
00502 
00503 #define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
00504 #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
00505 
00506 #define obstack_blank(h,length)                                         \
00507 ( (h)->temp = (length),                                                 \
00508   (((h)->chunk_limit - (h)->next_free < (h)->temp)                      \
00509    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),                      \
00510   ((h)->alloc_failed ? 0 :                                              \
00511   ((h)->next_free += (h)->temp)))
00512 
00513 #define obstack_alloc(h,length)                                         \
00514  (obstack_blank ((h), (length)), obstack_finish ((h)))
00515 
00516 #define obstack_copy(h,where,length)                                    \
00517  (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
00518 
00519 #define obstack_copy0(h,where,length)                                   \
00520  (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
00521 
00522 #define obstack_finish(h)                                               \
00523 ( (h)->alloc_failed ? 0 :                                               \
00524   (((h)->next_free == (h)->object_base                                  \
00525    ? (((h)->maybe_empty_object = 1), 0)                                 \
00526    : 0),                                                                \
00527   (h)->temp = __PTR_TO_INT ((h)->object_base),                          \
00528   (h)->next_free                                                        \
00529     = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
00530                     & ~ ((h)->alignment_mask)),                         \
00531   (((h)->next_free - (char *)(h)->chunk                                 \
00532     > (h)->chunk_limit - (char *)(h)->chunk)                            \
00533    ? ((h)->next_free = (h)->chunk_limit) : 0),                          \
00534   (h)->object_base = (h)->next_free,                                    \
00535   __INT_TO_PTR ((h)->temp)))
00536 
00537 #ifdef __STDC__
00538 #define obstack_free(h,obj)                                             \
00539 ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                      \
00540   (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
00541    ? (int) ((h)->next_free = (h)->object_base                           \
00542             = (h)->temp + (char *) (h)->chunk)                          \
00543    : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
00544 #else
00545 #define obstack_free(h,obj)                                             \
00546 ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                      \
00547   (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
00548    ? (int) ((h)->next_free = (h)->object_base                           \
00549             = (h)->temp + (char *) (h)->chunk)                          \
00550    : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
00551 #endif
00552 
00553 #endif /* not __GNUC__ or not __STDC__ */
00554 
00555 #endif /* not __OBSTACK_H__ */

Generated on Sat Sep 17 10:28:53 2005 for XconqKernel by doxygen 1.3.6