objalloc.h revision 218822
133965Sjdp/* objalloc.h -- routines to allocate memory for objects 289857Sobrien Copyright 1997, 2001 Free Software Foundation, Inc. 333965Sjdp Written by Ian Lance Taylor, Cygnus Solutions. 433965Sjdp 533965SjdpThis program is free software; you can redistribute it and/or modify it 633965Sjdpunder the terms of the GNU General Public License as published by the 733965SjdpFree Software Foundation; either version 2, or (at your option) any 833965Sjdplater version. 933965Sjdp 1033965SjdpThis program is distributed in the hope that it will be useful, 1133965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1233965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1333965SjdpGNU General Public License for more details. 1433965Sjdp 1533965SjdpYou should have received a copy of the GNU General Public License 1633965Sjdpalong with this program; if not, write to the Free Software 17218822SdimFoundation, 51 Franklin Street - Fifth Floor, 18218822SdimBoston, MA 02110-1301, USA. */ 1933965Sjdp 2033965Sjdp#ifndef OBJALLOC_H 2133965Sjdp#define OBJALLOC_H 2233965Sjdp 2333965Sjdp#include "ansidecl.h" 2433965Sjdp 2533965Sjdp/* These routines allocate space for an object. The assumption is 2633965Sjdp that the object will want to allocate space as it goes along, but 2733965Sjdp will never want to free any particular block. There is a function 2833965Sjdp to free a block, which also frees all more recently allocated 2933965Sjdp blocks. There is also a function to free all the allocated space. 3033965Sjdp 3133965Sjdp This is essentially a specialization of obstacks. The main 3233965Sjdp difference is that a block may not be allocated a bit at a time. 3333965Sjdp Another difference is that these routines are always built on top 3433965Sjdp of malloc, and always pass an malloc failure back to the caller, 3533965Sjdp unlike more recent versions of obstacks. */ 3633965Sjdp 3733965Sjdp/* This is what an objalloc structure looks like. Callers should not 3833965Sjdp refer to these fields, nor should they allocate these structure 3933965Sjdp themselves. Instead, they should only create them via 4033965Sjdp objalloc_init, and only access them via the functions and macros 4133965Sjdp listed below. The structure is only defined here so that we can 4233965Sjdp access it via macros. */ 4333965Sjdp 4433965Sjdpstruct objalloc 4533965Sjdp{ 4633965Sjdp char *current_ptr; 4733965Sjdp unsigned int current_space; 48218822Sdim void *chunks; 4933965Sjdp}; 5033965Sjdp 5133965Sjdp/* Work out the required alignment. */ 5233965Sjdp 5333965Sjdpstruct objalloc_align { char x; double d; }; 5433965Sjdp 5533965Sjdp#if defined (__STDC__) && __STDC__ 5633965Sjdp#ifndef offsetof 5733965Sjdp#include <stddef.h> 5833965Sjdp#endif 5933965Sjdp#endif 6089857Sobrien#ifndef offsetof 6189857Sobrien#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) 6289857Sobrien#endif 6389857Sobrien#define OBJALLOC_ALIGN offsetof (struct objalloc_align, d) 6433965Sjdp 6533965Sjdp/* Create an objalloc structure. Returns NULL if malloc fails. */ 6633965Sjdp 67218822Sdimextern struct objalloc *objalloc_create (void); 6833965Sjdp 6933965Sjdp/* Allocate space from an objalloc structure. Returns NULL if malloc 7033965Sjdp fails. */ 7133965Sjdp 72218822Sdimextern void *_objalloc_alloc (struct objalloc *, unsigned long); 7333965Sjdp 7433965Sjdp/* The macro version of objalloc_alloc. We only define this if using 7533965Sjdp gcc, because otherwise we would have to evaluate the arguments 7633965Sjdp multiple times, or use a temporary field as obstack.h does. */ 7733965Sjdp 7833965Sjdp#if defined (__GNUC__) && defined (__STDC__) && __STDC__ 7933965Sjdp 8033965Sjdp/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 8133965Sjdp does not implement __extension__. But that compiler doesn't define 8233965Sjdp __GNUC_MINOR__. */ 8333965Sjdp#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 8433965Sjdp#define __extension__ 8533965Sjdp#endif 8633965Sjdp 8733965Sjdp#define objalloc_alloc(o, l) \ 8833965Sjdp __extension__ \ 8933965Sjdp ({ struct objalloc *__o = (o); \ 9033965Sjdp unsigned long __len = (l); \ 9133965Sjdp if (__len == 0) \ 9233965Sjdp __len = 1; \ 9333965Sjdp __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \ 9433965Sjdp (__len <= __o->current_space \ 9533965Sjdp ? (__o->current_ptr += __len, \ 9633965Sjdp __o->current_space -= __len, \ 97218822Sdim (void *) (__o->current_ptr - __len)) \ 9833965Sjdp : _objalloc_alloc (__o, __len)); }) 9933965Sjdp 10033965Sjdp#else /* ! __GNUC__ */ 10133965Sjdp 10233965Sjdp#define objalloc_alloc(o, l) _objalloc_alloc ((o), (l)) 10333965Sjdp 10433965Sjdp#endif /* ! __GNUC__ */ 10533965Sjdp 10633965Sjdp/* Free an entire objalloc structure. */ 10733965Sjdp 108218822Sdimextern void objalloc_free (struct objalloc *); 10933965Sjdp 11033965Sjdp/* Free a block allocated by objalloc_alloc. This also frees all more 11133965Sjdp recently allocated blocks. */ 11233965Sjdp 113218822Sdimextern void objalloc_free_block (struct objalloc *, void *); 11433965Sjdp 11533965Sjdp#endif /* OBJALLOC_H */ 116