1130803Smarcel/* objalloc.h -- routines to allocate memory for objects 2130803Smarcel Copyright 1997, 2001 Free Software Foundation, Inc. 3130803Smarcel Written by Ian Lance Taylor, Cygnus Solutions. 4130803Smarcel 5130803SmarcelThis program is free software; you can redistribute it and/or modify it 6130803Smarcelunder the terms of the GNU General Public License as published by the 7130803SmarcelFree Software Foundation; either version 2, or (at your option) any 8130803Smarcellater version. 9130803Smarcel 10130803SmarcelThis program is distributed in the hope that it will be useful, 11130803Smarcelbut WITHOUT ANY WARRANTY; without even the implied warranty of 12130803SmarcelMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13130803SmarcelGNU General Public License for more details. 14130803Smarcel 15130803SmarcelYou should have received a copy of the GNU General Public License 16130803Smarcelalong with this program; if not, write to the Free Software 17130803SmarcelFoundation, 59 Temple Place - Suite 330, 18130803SmarcelBoston, MA 02111-1307, USA. */ 19130803Smarcel 20130803Smarcel#ifndef OBJALLOC_H 21130803Smarcel#define OBJALLOC_H 22130803Smarcel 23130803Smarcel#include "ansidecl.h" 24130803Smarcel 25130803Smarcel/* These routines allocate space for an object. The assumption is 26130803Smarcel that the object will want to allocate space as it goes along, but 27130803Smarcel will never want to free any particular block. There is a function 28130803Smarcel to free a block, which also frees all more recently allocated 29130803Smarcel blocks. There is also a function to free all the allocated space. 30130803Smarcel 31130803Smarcel This is essentially a specialization of obstacks. The main 32130803Smarcel difference is that a block may not be allocated a bit at a time. 33130803Smarcel Another difference is that these routines are always built on top 34130803Smarcel of malloc, and always pass an malloc failure back to the caller, 35130803Smarcel unlike more recent versions of obstacks. */ 36130803Smarcel 37130803Smarcel/* This is what an objalloc structure looks like. Callers should not 38130803Smarcel refer to these fields, nor should they allocate these structure 39130803Smarcel themselves. Instead, they should only create them via 40130803Smarcel objalloc_init, and only access them via the functions and macros 41130803Smarcel listed below. The structure is only defined here so that we can 42130803Smarcel access it via macros. */ 43130803Smarcel 44130803Smarcelstruct objalloc 45130803Smarcel{ 46130803Smarcel char *current_ptr; 47130803Smarcel unsigned int current_space; 48130803Smarcel PTR chunks; 49130803Smarcel}; 50130803Smarcel 51130803Smarcel/* Work out the required alignment. */ 52130803Smarcel 53130803Smarcelstruct objalloc_align { char x; double d; }; 54130803Smarcel 55130803Smarcel#if defined (__STDC__) && __STDC__ 56130803Smarcel#ifndef offsetof 57130803Smarcel#include <stddef.h> 58130803Smarcel#endif 59130803Smarcel#endif 60130803Smarcel#ifndef offsetof 61130803Smarcel#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) 62130803Smarcel#endif 63130803Smarcel#define OBJALLOC_ALIGN offsetof (struct objalloc_align, d) 64130803Smarcel 65130803Smarcel/* Create an objalloc structure. Returns NULL if malloc fails. */ 66130803Smarcel 67130803Smarcelextern struct objalloc *objalloc_create PARAMS ((void)); 68130803Smarcel 69130803Smarcel/* Allocate space from an objalloc structure. Returns NULL if malloc 70130803Smarcel fails. */ 71130803Smarcel 72130803Smarcelextern PTR _objalloc_alloc PARAMS ((struct objalloc *, unsigned long)); 73130803Smarcel 74130803Smarcel/* The macro version of objalloc_alloc. We only define this if using 75130803Smarcel gcc, because otherwise we would have to evaluate the arguments 76130803Smarcel multiple times, or use a temporary field as obstack.h does. */ 77130803Smarcel 78130803Smarcel#if defined (__GNUC__) && defined (__STDC__) && __STDC__ 79130803Smarcel 80130803Smarcel/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 81130803Smarcel does not implement __extension__. But that compiler doesn't define 82130803Smarcel __GNUC_MINOR__. */ 83130803Smarcel#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 84130803Smarcel#define __extension__ 85130803Smarcel#endif 86130803Smarcel 87130803Smarcel#define objalloc_alloc(o, l) \ 88130803Smarcel __extension__ \ 89130803Smarcel ({ struct objalloc *__o = (o); \ 90130803Smarcel unsigned long __len = (l); \ 91130803Smarcel if (__len == 0) \ 92130803Smarcel __len = 1; \ 93130803Smarcel __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \ 94130803Smarcel (__len <= __o->current_space \ 95130803Smarcel ? (__o->current_ptr += __len, \ 96130803Smarcel __o->current_space -= __len, \ 97130803Smarcel (PTR) (__o->current_ptr - __len)) \ 98130803Smarcel : _objalloc_alloc (__o, __len)); }) 99130803Smarcel 100130803Smarcel#else /* ! __GNUC__ */ 101130803Smarcel 102130803Smarcel#define objalloc_alloc(o, l) _objalloc_alloc ((o), (l)) 103130803Smarcel 104130803Smarcel#endif /* ! __GNUC__ */ 105130803Smarcel 106130803Smarcel/* Free an entire objalloc structure. */ 107130803Smarcel 108130803Smarcelextern void objalloc_free PARAMS ((struct objalloc *)); 109130803Smarcel 110130803Smarcel/* Free a block allocated by objalloc_alloc. This also frees all more 111130803Smarcel recently allocated blocks. */ 112130803Smarcel 113130803Smarcelextern void objalloc_free_block PARAMS ((struct objalloc *, PTR)); 114130803Smarcel 115130803Smarcel#endif /* OBJALLOC_H */ 116