1a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* obstack.c - subroutines used implicitly by object stack macros 2a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 3a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 4a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software 5a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Foundation, Inc. 6a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 7a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner This program is free software: you can redistribute it and/or modify 8a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner it under the terms of the GNU General Public License as published by 9a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner the Free Software Foundation; either version 3 of the License, or 10a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (at your option) any later version. 11a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 12a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner This program is distributed in the hope that it will be useful, 13a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 14a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner GNU General Public License for more details. 16a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 17a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner You should have received a copy of the GNU General Public License 18a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 20a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#ifdef _LIBC 21a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <obstack.h> 22a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <shlib-compat.h> 23a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#else 24a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <config.h> 25a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include "obstack.h" 26a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif 27a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 28a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* NOTE BEFORE MODIFYING THIS FILE: This version number must be 29a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner incremented whenever callers compiled using an old obstack.h can no 30a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner longer properly call the functions in this obstack.c. */ 31a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#define OBSTACK_INTERFACE_VERSION 1 32a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 33a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Comment out all this code if we are using the GNU C Library, and are not 34a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner actually compiling the library itself, and the installed library 35a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner supports the same library interface we do. This code is part of the GNU 36a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner C Library, but also included in many other GNU distributions. Compiling 37a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner and linking in this code is a waste when using the GNU C library 38a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (especially if it is a shared library). Rather than having every GNU 39a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner program understand `configure --with-gnu-libc' and omit the object 40a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner files, it is simpler to just do this in the source for each such file. */ 41a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 42a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */ 43a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 44a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <gnu-versions.h> 45a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION 46a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define ELIDE_CODE 47a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 48a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif 49a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 50a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#include <stddef.h> 51a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 52a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#ifndef ELIDE_CODE 53a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 54a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <stdint.h> 55a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 56a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Determine default alignment. */ 57a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerunion fooround 58a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 59a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner uintmax_t i; 60a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner long double d; 61a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner void *p; 62a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner}; 63a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerstruct fooalign 64a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 65a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner char c; 66a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner union fooround u; 67a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner}; 68a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. 69a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner But in fact it might be less smart and round addresses to as much as 70a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner DEFAULT_ROUNDING. So we prepare for it to do that. */ 71a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerenum 72a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 73a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner DEFAULT_ALIGNMENT = offsetof (struct fooalign, u), 74a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner DEFAULT_ROUNDING = sizeof (union fooround) 75a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner }; 76a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 77a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* When we copy a long block of data, this is the unit to do it with. 78a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner On some machines, copying successive ints does not work; 79a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner in such a case, redefine COPYING_UNIT to `long' (if that works) 80a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner or `char' as a last resort. */ 81a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifndef COPYING_UNIT 82a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define COPYING_UNIT int 83a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 84a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 85a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 86a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* The functions allocating more room by calling `obstack_chunk_alloc' 87a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner jump to the handler pointed to by `obstack_alloc_failed_handler'. 88a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner This can be set to a user defined function which should either 89a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner abort gracefully or use longjump - but shouldn't return. This 90a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner variable by default points to the internal function 91a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner `print_and_abort'. */ 92a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerstatic void print_and_abort (void); 93a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnervoid (*obstack_alloc_failed_handler) (void) = print_and_abort; 94a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 95a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Exit value used when `print_and_abort' is used. */ 96a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <stdlib.h> 97a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef _LIBC 98a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerint obstack_exit_failure = EXIT_FAILURE; 99a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# else 100a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include "exitfail.h" 101a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define obstack_exit_failure exit_failure 102a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 103a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 104a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef _LIBC 105a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) 106a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* A looong time ago (before 1994, anyway; we're not sure) this global variable 107a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner was used by non-GNU-C macros to avoid multiple evaluation. The GNU C 108a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner library still exports it because somebody might use it. */ 109a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerstruct obstack *_obstack_compat; 110a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnercompat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); 111a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 112a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 113a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 114a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Define a macro that either calls functions with the traditional malloc/free 115a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner calling interface, or calls functions with the mmalloc/mfree interface 116a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (that adds an extra first argument), based on the state of use_extra_arg. 117a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner For free, do not use ?:, since some compilers, like the MIPS compilers, 118a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner do not allow (expr) ? void : void. */ 119a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 120a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define CALL_CHUNKFUN(h, size) \ 121a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (((h) -> use_extra_arg) \ 122a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ 123a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) 124a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 125a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define CALL_FREEFUN(h, old_chunk) \ 126a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner do { \ 127a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if ((h) -> use_extra_arg) \ 128a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ 129a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner else \ 130a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ 131a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } while (0) 132a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 133a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 134a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). 135a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Objects start on multiples of ALIGNMENT (0 means use default). 136a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner CHUNKFUN is the function to use to allocate chunks, 137a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner and FREEFUN the function to free them. 138a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 139a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Return nonzero if successful, calls obstack_alloc_failed_handler if 140a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner allocation fails. */ 141a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 142a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerint 143a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner_obstack_begin (struct obstack *h, 144a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner int size, int alignment, 145a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner void *(*chunkfun) (long), 146a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner void (*freefun) (void *)) 147a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 148a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *chunk; /* points to new chunk */ 149a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 150a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (alignment == 0) 151a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner alignment = DEFAULT_ALIGNMENT; 152a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (size == 0) 153a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Default size is what GNU malloc can fit in a 4096-byte block. */ 154a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 155a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. 156a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Use the values for range checking, because if range checking is off, 157a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner the extra bytes won't be missed terribly, but if range checking is on 158a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner and we used a larger request, a whole extra 4096 bytes would be 159a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner allocated. 160a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 161a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner These number are irrelevant to the new GNU malloc. I suspect it is 162a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner less sensitive to the size of the request. */ 163a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) 164a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner + 4 + DEFAULT_ROUNDING - 1) 165a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner & ~(DEFAULT_ROUNDING - 1)); 166a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner size = 4096 - extra; 167a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 168a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 169a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; 170a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; 171a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunk_size = size; 172a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->alignment_mask = alignment - 1; 173a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->use_extra_arg = 0; 174a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 175a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); 176a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (!chunk) 177a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (*obstack_alloc_failed_handler) (); 178a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, 179a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner alignment - 1); 180a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunk_limit = chunk->limit 181a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner = (char *) chunk + h->chunk_size; 182a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner chunk->prev = 0; 183a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* The initial chunk now contains no empty object. */ 184a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->maybe_empty_object = 0; 185a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->alloc_failed = 0; 186a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner return 1; 187a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner} 188a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 189a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerint 190a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner_obstack_begin_1 (struct obstack *h, int size, int alignment, 191a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner void *(*chunkfun) (void *, long), 192a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner void (*freefun) (void *, void *), 193a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner void *arg) 194a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 195a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *chunk; /* points to new chunk */ 196a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 197a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (alignment == 0) 198a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner alignment = DEFAULT_ALIGNMENT; 199a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (size == 0) 200a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Default size is what GNU malloc can fit in a 4096-byte block. */ 201a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 202a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. 203a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Use the values for range checking, because if range checking is off, 204a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner the extra bytes won't be missed terribly, but if range checking is on 205a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner and we used a larger request, a whole extra 4096 bytes would be 206a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner allocated. 207a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 208a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner These number are irrelevant to the new GNU malloc. I suspect it is 209a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner less sensitive to the size of the request. */ 210a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) 211a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner + 4 + DEFAULT_ROUNDING - 1) 212a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner & ~(DEFAULT_ROUNDING - 1)); 213a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner size = 4096 - extra; 214a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 215a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 216a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; 217a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; 218a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunk_size = size; 219a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->alignment_mask = alignment - 1; 220a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->extra_arg = arg; 221a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->use_extra_arg = 1; 222a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 223a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); 224a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (!chunk) 225a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (*obstack_alloc_failed_handler) (); 226a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, 227a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner alignment - 1); 228a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunk_limit = chunk->limit 229a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner = (char *) chunk + h->chunk_size; 230a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner chunk->prev = 0; 231a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* The initial chunk now contains no empty object. */ 232a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->maybe_empty_object = 0; 233a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->alloc_failed = 0; 234a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner return 1; 235a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner} 236a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 237a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Allocate a new current chunk for the obstack *H 238a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner on the assumption that LENGTH bytes need to be added 239a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner to the current object, or a new object of length LENGTH allocated. 240a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Copies any partial object from the end of the old chunk 241a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner to the beginning of the new one. */ 242a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 243a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnervoid 244a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner_obstack_newchunk (struct obstack *h, int length) 245a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 246a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *old_chunk = h->chunk; 247a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *new_chunk; 248a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register long new_size; 249a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register long obj_size = h->next_free - h->object_base; 250a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register long i; 251a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner long already; 252a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner char *object_base; 253a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 254a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Compute size for new chunk. */ 255a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100; 256a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (new_size < h->chunk_size) 257a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner new_size = h->chunk_size; 258a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 259a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Allocate and initialize the new chunk. */ 260a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner new_chunk = CALL_CHUNKFUN (h, new_size); 261a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (!new_chunk) 262a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (*obstack_alloc_failed_handler) (); 263a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunk = new_chunk; 264a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner new_chunk->prev = old_chunk; 265a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; 266a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 267a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Compute an aligned object_base in the new chunk */ 268a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner object_base = 269a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask); 270a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 271a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Move the existing object to the new chunk. 272a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner Word at a time is fast and is safe if the object 273a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner is sufficiently aligned. */ 274a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) 275a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 276a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner for (i = obj_size / sizeof (COPYING_UNIT) - 1; 277a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner i >= 0; i--) 278a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner ((COPYING_UNIT *)object_base)[i] 279a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner = ((COPYING_UNIT *)h->object_base)[i]; 280a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, 281a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner but that can cross a page boundary on a machine 282a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner which does not do strict alignment for COPYING_UNITS. */ 283a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); 284a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 285a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner else 286a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner already = 0; 287a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Copy remaining bytes one by one. */ 288a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner for (i = already; i < obj_size; i++) 289a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner object_base[i] = h->object_base[i]; 290a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 291a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* If the object just copied was the only data in OLD_CHUNK, 292a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner free that chunk and remove it from the chain. 293a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner But not if that chunk might contain an empty object. */ 294a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (! h->maybe_empty_object 295a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner && (h->object_base 296a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents, 297a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->alignment_mask))) 298a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 299a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner new_chunk->prev = old_chunk->prev; 300a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner CALL_FREEFUN (h, old_chunk); 301a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 302a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 303a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->object_base = object_base; 304a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->next_free = h->object_base + obj_size; 305a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* The new chunk certainly contains no empty object yet. */ 306a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->maybe_empty_object = 0; 307a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner} 308a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef _LIBC 309a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerlibc_hidden_def (_obstack_newchunk) 310a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 311a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 312a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Return nonzero if object OBJ has been allocated from obstack H. 313a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner This is here for debugging. 314a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner If you use it in a program, you are probably losing. */ 315a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 316a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Suppress -Wmissing-prototypes warning. We don't want to declare this in 317a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner obstack.h because it is just for debugging. */ 318a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerint _obstack_allocated_p (struct obstack *h, void *obj); 319a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 320a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerint 321a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner_obstack_allocated_p (struct obstack *h, void *obj) 322a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 323a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ 324a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *plp; /* point to previous chunk if any */ 325a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 326a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner lp = (h)->chunk; 327a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* We use >= rather than > since the object cannot be exactly at 328a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner the beginning of the chunk but might be an empty object exactly 329a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner at the end of an adjacent chunk. */ 330a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) 331a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 332a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner plp = lp->prev; 333a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner lp = plp; 334a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 335a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner return lp != 0; 336a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner} 337a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 338a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Free objects in obstack H, including OBJ and everything allocate 339a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner more recently than OBJ. If OBJ is zero, free everything in H. */ 340a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 341a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# undef obstack_free 342a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 343a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnervoid 344a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner__obstack_free (struct obstack *h, void *obj) 345a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 346a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ 347a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk *plp; /* point to previous chunk if any */ 348a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 349a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner lp = h->chunk; 350a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* We use >= because there cannot be an object at the beginning of a chunk. 351a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner But there can be an empty object at that address 352a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner at the end of another chunk. */ 353a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) 354a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 355a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner plp = lp->prev; 356a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner CALL_FREEFUN (h, lp); 357a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner lp = plp; 358a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* If we switch chunks, we can't tell whether the new current 359a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner chunk contains an empty object, so assume that it may. */ 360a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->maybe_empty_object = 1; 361a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 362a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner if (lp) 363a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 364a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->object_base = h->next_free = (char *) (obj); 365a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunk_limit = lp->limit; 366a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner h->chunk = lp; 367a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 368a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner else if (obj != 0) 369a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* obj is not in any of the chunks! */ 370a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner abort (); 371a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner} 372a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 373a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef _LIBC 374a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Older versions of libc used a function _obstack_free intended to be 375a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner called by non-GCC compilers. */ 376a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerstrong_alias (obstack_free, _obstack_free) 377a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 378a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 379a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerint 380a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner_obstack_memory_used (struct obstack *h) 381a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 382a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register struct _obstack_chunk* lp; 383a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner register int nbytes = 0; 384a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 385a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner for (lp = h->chunk; lp != 0; lp = lp->prev) 386a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner { 387a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner nbytes += lp->limit - (char *) lp; 388a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner } 389a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner return nbytes; 390a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner} 391a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 392a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* Define the error handler. */ 393a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef _LIBC 394a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <libintl.h> 395a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# else 396a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include "gettext.h" 397a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 398a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifndef _ 399a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define _(msgid) gettext (msgid) 400a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 401a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 402a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef _LIBC 403a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# include <libio/iolibio.h> 404a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 405a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 406a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifndef __attribute__ 407a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner/* This feature is available in gcc versions 2.5 and later. */ 408a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) 409a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# define __attribute__(Spec) /* empty */ 410a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 411a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 412a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 413a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerstatic void 414a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner__attribute__ ((noreturn)) 415a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turnerprint_and_abort (void) 416a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner{ 417a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner /* Don't change any of these strings. Yes, it would be possible to add 418a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner the newline to the string and use fputs or so. But this must not 419a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner happen because the "memory exhausted" message appears in other places 420a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner like this and the translation should be reused instead of creating 421a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner a very similar string which requires a separate translation. */ 422a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# ifdef _LIBC 423a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner (void) __fxprintf (NULL, "%s\n", _("memory exhausted")); 424a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# else 425a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner fprintf (stderr, "%s\n", _("memory exhausted")); 426a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner# endif 427a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner exit (obstack_exit_failure); 428a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner} 429a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner 430a6dfe5f70959a596290e1591579d26a288a1a2f9David 'Digit' Turner#endif /* !ELIDE_CODE */ 431