objalloc.h revision 33965
133965Sjdp/* objalloc.h -- routines to allocate memory for objects 233965Sjdp Copyright 1997 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 1733965SjdpFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 1833965Sjdp 1933965Sjdp#ifndef OBJALLOC_H 2033965Sjdp#define OBJALLOC_H 2133965Sjdp 2233965Sjdp#include "ansidecl.h" 2333965Sjdp 2433965Sjdp/* These routines allocate space for an object. The assumption is 2533965Sjdp that the object will want to allocate space as it goes along, but 2633965Sjdp will never want to free any particular block. There is a function 2733965Sjdp to free a block, which also frees all more recently allocated 2833965Sjdp blocks. There is also a function to free all the allocated space. 2933965Sjdp 3033965Sjdp This is essentially a specialization of obstacks. The main 3133965Sjdp difference is that a block may not be allocated a bit at a time. 3233965Sjdp Another difference is that these routines are always built on top 3333965Sjdp of malloc, and always pass an malloc failure back to the caller, 3433965Sjdp unlike more recent versions of obstacks. */ 3533965Sjdp 3633965Sjdp/* This is what an objalloc structure looks like. Callers should not 3733965Sjdp refer to these fields, nor should they allocate these structure 3833965Sjdp themselves. Instead, they should only create them via 3933965Sjdp objalloc_init, and only access them via the functions and macros 4033965Sjdp listed below. The structure is only defined here so that we can 4133965Sjdp access it via macros. */ 4233965Sjdp 4333965Sjdpstruct objalloc 4433965Sjdp{ 4533965Sjdp char *current_ptr; 4633965Sjdp unsigned int current_space; 4733965Sjdp PTR chunks; 4833965Sjdp}; 4933965Sjdp 5033965Sjdp/* Work out the required alignment. */ 5133965Sjdp 5233965Sjdpstruct objalloc_align { char x; double d; }; 5333965Sjdp 5433965Sjdp#if defined (__STDC__) && __STDC__ 5533965Sjdp#ifndef offsetof 5633965Sjdp#include <stddef.h> 5733965Sjdp#endif 5833965Sjdp#define OBJALLOC_ALIGN \ 5933965Sjdp ((ptrdiff_t) ((char *) &((struct objalloc_align *) 0)->d - (char *) 0)) 6033965Sjdp#else 6133965Sjdp#define OBJALLOC_ALIGN \ 6233965Sjdp ((long) ((char *) &((struct objalloc_align *) 0)->d - (char *) 0)) 6333965Sjdp#endif 6433965Sjdp 6533965Sjdp/* Create an objalloc structure. Returns NULL if malloc fails. */ 6633965Sjdp 6733965Sjdpextern struct objalloc *objalloc_create PARAMS ((void)); 6833965Sjdp 6933965Sjdp/* Allocate space from an objalloc structure. Returns NULL if malloc 7033965Sjdp fails. */ 7133965Sjdp 7233965Sjdpextern PTR _objalloc_alloc PARAMS ((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, \ 9733965Sjdp (PTR) (__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 10833965Sjdpextern void objalloc_free PARAMS ((struct objalloc *)); 10933965Sjdp 11033965Sjdp/* Free a block allocated by objalloc_alloc. This also frees all more 11133965Sjdp recently allocated blocks. */ 11233965Sjdp 11333965Sjdpextern void objalloc_free_block PARAMS ((struct objalloc *, PTR)); 11433965Sjdp 11533965Sjdp#endif /* OBJALLOC_H */ 116