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