source: vendor/diffutils/2.8.1/lib/alloca.c@ 3506

Last change on this file since 3506 was 2556, checked in by bird, 20 years ago

diffutils 2.8.1

File size: 14.0 KB
Line 
1/* alloca.c -- allocate automatically reclaimed memory
2 (Mostly) portable public-domain implementation -- D A Gwyn
3
4 This implementation of the PWB library alloca function,
5 which is used to allocate space off the run-time stack so
6 that it is automatically reclaimed upon procedure exit,
7 was inspired by discussions with J. Q. Johnson of Cornell.
8 J.Otto Tennant <[email protected]> contributed the Cray support.
9
10 There are some preprocessor constants that can
11 be defined when compiling for your specific system, for
12 improved efficiency; however, the defaults should be okay.
13
14 The general concept of this implementation is to keep
15 track of all alloca-allocated blocks, and reclaim any
16 that are found to be deeper in the stack than the current
17 invocation. This heuristic does not reclaim storage as
18 soon as it becomes invalid, but it will do so eventually.
19
20 As a special case, alloca(0) reclaims storage without
21 allocating any. It is a good idea to use alloca(0) in
22 your main control loop, etc. to force garbage collection. */
23
24#ifdef HAVE_CONFIG_H
25# include <config.h>
26#endif
27
28#if HAVE_STRING_H
29# include <string.h>
30#endif
31#if HAVE_STDLIB_H
32# include <stdlib.h>
33#endif
34
35#ifdef emacs
36# include "blockinput.h"
37#endif
38
39/* If compiling with GCC 2, this file's not needed. */
40#if !defined (__GNUC__) || __GNUC__ < 2
41
42/* If someone has defined alloca as a macro,
43 there must be some other way alloca is supposed to work. */
44# ifndef alloca
45
46# ifdef emacs
47# ifdef static
48/* actually, only want this if static is defined as ""
49 -- this is for usg, in which emacs must undefine static
50 in order to make unexec workable
51 */
52# ifndef STACK_DIRECTION
53you
54lose
55-- must know STACK_DIRECTION at compile-time
56# endif /* STACK_DIRECTION undefined */
57# endif /* static */
58# endif /* emacs */
59
60/* If your stack is a linked list of frames, you have to
61 provide an "address metric" ADDRESS_FUNCTION macro. */
62
63# if defined (CRAY) && defined (CRAY_STACKSEG_END)
64long i00afunc ();
65# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
66# else
67# define ADDRESS_FUNCTION(arg) &(arg)
68# endif
69
70# if __STDC__
71typedef void *pointer;
72# else
73typedef char *pointer;
74# endif
75
76# ifndef NULL
77# define NULL 0
78# endif
79
80/* Different portions of Emacs need to call different versions of
81 malloc. The Emacs executable needs alloca to call xmalloc, because
82 ordinary malloc isn't protected from input signals. On the other
83 hand, the utilities in lib-src need alloca to call malloc; some of
84 them are very simple, and don't have an xmalloc routine.
85
86 Non-Emacs programs expect this to call xmalloc.
87
88 Callers below should use malloc. */
89
90# ifndef emacs
91# undef malloc
92# define malloc xmalloc
93# endif
94extern pointer malloc ();
95
96/* Define STACK_DIRECTION if you know the direction of stack
97 growth for your system; otherwise it will be automatically
98 deduced at run-time.
99
100 STACK_DIRECTION > 0 => grows toward higher addresses
101 STACK_DIRECTION < 0 => grows toward lower addresses
102 STACK_DIRECTION = 0 => direction of growth unknown */
103
104# ifndef STACK_DIRECTION
105# define STACK_DIRECTION 0 /* Direction unknown. */
106# endif
107
108# if STACK_DIRECTION != 0
109
110# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
111
112# else /* STACK_DIRECTION == 0; need run-time code. */
113
114static int stack_dir; /* 1 or -1 once known. */
115# define STACK_DIR stack_dir
116
117static void
118find_stack_direction ()
119{
120 static char *addr = NULL; /* Address of first `dummy', once known. */
121 auto char dummy; /* To get stack address. */
122
123 if (addr == NULL)
124 { /* Initial entry. */
125 addr = ADDRESS_FUNCTION (dummy);
126
127 find_stack_direction (); /* Recurse once. */
128 }
129 else
130 {