doc: use ASCII in .texi files where UTF-8 isn't needed
[gnulib.git] / lib / alloca.c
index fd95a34..ee0f018 100644 (file)
    allocating any.  It is a good idea to use alloca(0) in
    your main control loop, etc. to force garbage collection.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
 
-#if HAVE_STRING_H
-# include <string.h>
-#endif
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
+#include <alloca.h>
+
+#include <string.h>
+#include <stdlib.h>
 
 #ifdef emacs
 # include "lisp.h"
 # include "blockinput.h"
-# define xalloc_die() memory_full ()
 # ifdef EMACS_FREE
 #  undef free
 #  define free EMACS_FREE
 # endif
 #else
-# include <xalloc.h>
+# define memory_full() abort ()
 #endif
 
 /* If compiling with GCC 2, this file's not needed.  */
@@ -77,19 +72,6 @@ long i00afunc ();
 #   define ADDRESS_FUNCTION(arg) &(arg)
 #  endif
 
-#  ifndef POINTER_TYPE
-#   ifdef __STDC__
-#    define POINTER_TYPE void
-#   else
-#    define POINTER_TYPE char
-#   endif
-#  endif
-typedef POINTER_TYPE *pointer;
-
-#  ifndef NULL
-#   define NULL 0
-#  endif
-
 /* Define STACK_DIRECTION if you know the direction of stack
    growth for your system; otherwise it will be automatically
    deduced at run-time.
@@ -99,38 +81,27 @@ typedef POINTER_TYPE *pointer;
    STACK_DIRECTION = 0 => direction of growth unknown  */
 
 #  ifndef STACK_DIRECTION
-#   define STACK_DIRECTION     0       /* Direction unknown.  */
+#   define STACK_DIRECTION      0       /* Direction unknown.  */
 #  endif
 
 #  if STACK_DIRECTION != 0
 
-#   define STACK_DIR   STACK_DIRECTION /* Known at compile-time.  */
+#   define STACK_DIR    STACK_DIRECTION /* Known at compile-time.  */
 
 #  else /* STACK_DIRECTION == 0; need run-time code.  */
 
-static int stack_dir;          /* 1 or -1 once known.  */
-#   define STACK_DIR   stack_dir
+static int stack_dir;           /* 1 or -1 once known.  */
+#   define STACK_DIR    stack_dir
 
-static void
-find_stack_direction ()
+static int
+find_stack_direction (int *addr, int depth)
 {
-  static char *addr = NULL;    /* Address of first `dummy', once known.  */
-  auto char dummy;             /* To get stack address.  */
-
-  if (addr == NULL)
-    {                          /* Initial entry.  */
-      addr = ADDRESS_FUNCTION (dummy);
-
-      find_stack_direction (); /* Recurse once.  */
-    }
-  else
-    {
-      /* Second entry.  */
-      if (ADDRESS_FUNCTION (dummy) > addr)
-       stack_dir = 1;          /* Stack grew upward.  */
-      else
-       stack_dir = -1;         /* Stack grew downward.  */
-    }
+  int dir, dummy = 0;
+  if (! addr)
+    addr = &dummy;
+  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+  return dir + dummy;
 }
 
 #  endif /* STACK_DIRECTION == 0 */
@@ -142,21 +113,21 @@ find_stack_direction ()
    It is very important that sizeof(header) agree with malloc
    alignment chunk size.  The following default should work okay.  */
 
-#  ifndef      ALIGN_SIZE
-#   define ALIGN_SIZE  sizeof(double)
+#  ifndef       ALIGN_SIZE
+#   define ALIGN_SIZE   sizeof(double)
 #  endif
 
 typedef union hdr
 {
-  char align[ALIGN_SIZE];      /* To force sizeof(header).  */
+  char align[ALIGN_SIZE];       /* To force sizeof(header).  */
   struct
     {
-      union hdr *next;         /* For chaining headers.  */
-      char *deep;              /* For stack depth measure.  */
+      union hdr *next;          /* For chaining headers.  */
+      char *deep;               /* For stack depth measure.  */
     } h;
 } header;
 
-static header *last_alloca_header = NULL;      /* -> last alloca header.  */
+static header *last_alloca_header = NULL;       /* -> last alloca header.  */
 
 /* Return a pointer to at least SIZE bytes of storage,
    which will be automatically reclaimed upon exit from
@@ -165,23 +136,22 @@ static header *last_alloca_header = NULL; /* -> last alloca header.  */
    caller, but that method cannot be made to work for some
    implementations of C, for example under Gould's UTX/32.  */
 
-pointer
-alloca (size)
-     size_t size;
+void *
+alloca (size_t size)
 {
-  auto char probe;             /* Probes stack depth: */
+  auto char probe;              /* Probes stack depth: */
   register char *depth = ADDRESS_FUNCTION (probe);
 
 #  if STACK_DIRECTION == 0
-  if (STACK_DIR == 0)          /* Unknown growth direction.  */
-    find_stack_direction ();
+  if (STACK_DIR == 0)           /* Unknown growth direction.  */
+    STACK_DIR = find_stack_direction (NULL, (size & 1) + 20);
 #  endif
 
   /* Reclaim garbage, defined as all alloca'd storage that
      was allocated from deeper in the stack than currently.  */
 
   {
-    register header *hp;       /* Traverses linked list.  */
+    register header *hp;        /* Traverses linked list.  */
 
 #  ifdef emacs
     BLOCK_INPUT;
@@ -189,18 +159,18 @@ alloca (size)
 
     for (hp = last_alloca_header; hp != NULL;)
       if ((STACK_DIR > 0 && hp->h.deep > depth)
-         || (STACK_DIR < 0 && hp->h.deep < depth))
-       {
-         register header *np = hp->h.next;
+          || (STACK_DIR < 0 && hp->h.deep < depth))
+        {
+          register header *np = hp->h.next;
 
-         free ((pointer) hp);  /* Collect garbage.  */
+          free (hp);            /* Collect garbage.  */
 
-         hp = np;              /* -> next header.  */
-       }
+          hp = np;              /* -> next header.  */
+        }
       else
-       break;                  /* Rest are not deeper.  */
+        break;                  /* Rest are not deeper.  */
 
-    last_alloca_header = hp;   /* -> last valid storage.  */
+    last_alloca_header = hp;    /* -> last valid storage.  */
 
 #  ifdef emacs
     UNBLOCK_INPUT;
@@ -208,31 +178,31 @@ alloca (size)
   }
 
   if (size == 0)
-    return NULL;               /* No allocation required.  */
+    return NULL;                /* No allocation required.  */
 
   /* Allocate combined header + user data storage.  */
 
   {
     /* Address of header.  */
-    register pointer new;
+    register header *new;
 
     size_t combined_size = sizeof (header) + size;
     if (combined_size < sizeof (header))
-      xalloc_die ();
+      memory_full ();
 
-    new = xmalloc (combined_size);
+    new = malloc (combined_size);
 
-    if (new == 0)
-      abort();
+    if (! new)
+      memory_full ();
 
-    ((header *) new)->h.next = last_alloca_header;
-    ((header *) new)->h.deep = depth;
+    new->h.next = last_alloca_header;
+    new->h.deep = depth;
 
-    last_alloca_header = (header *) new;
+    last_alloca_header = new;
 
     /* User storage begins just after header.  */
 
-    return (pointer) ((char *) new + sizeof (header));
+    return (void *) (new + 1);
   }
 }
 
@@ -248,10 +218,10 @@ alloca (size)
 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
 struct stack_control_header
   {
-    long shgrow:32;            /* Number of times stack has grown.  */
-    long shaseg:32;            /* Size of increments to stack.  */
-    long shhwm:32;             /* High water mark of stack.  */
-    long shsize:32;            /* Current size of stack (all segments).  */
+    long shgrow:32;             /* Number of times stack has grown.  */
+    long shaseg:32;             /* Size of increments to stack.  */
+    long shhwm:32;              /* High water mark of stack.  */
+    long shsize:32;             /* Current size of stack (all segments).  */
   };
 
 /* The stack segment linkage control information occurs at
@@ -263,21 +233,21 @@ struct stack_control_header
 
 struct stack_segment_linkage
   {
-    long ss[0200];             /* 0200 overflow words.  */
-    long sssize:32;            /* Number of words in this segment.  */
-    long ssbase:32;            /* Offset to stack base.  */
+    long ss[0200];              /* 0200 overflow words.  */
+    long sssize:32;             /* Number of words in this segment.  */
+    long ssbase:32;             /* Offset to stack base.  */
     long:32;
-    long sspseg:32;            /* Offset to linkage control of previous
-                                  segment of stack.  */
+    long sspseg:32;             /* Offset to linkage control of previous
+                                   segment of stack.  */
     long:32;
-    long sstcpt:32;            /* Pointer to task common address block.  */
-    long sscsnm;               /* Private control structure number for
-                                  microtasking.  */
-    long ssusr1;               /* Reserved for user.  */
-    long ssusr2;               /* Reserved for user.  */
-    long sstpid;               /* Process ID for pid based multi-tasking.  */
-    long ssgvup;               /* Pointer to multitasking thread giveup.  */
-    long sscray[7];            /* Reserved for Cray Research.  */
+    long sstcpt:32;             /* Pointer to task common address block.  */
+    long sscsnm;                /* Private control structure number for
+                                   microtasking.  */
+    long ssusr1;                /* Reserved for user.  */
+    long ssusr2;                /* Reserved for user.  */
+    long sstpid;                /* Process ID for pid based multi-tasking.  */
+    long ssgvup;                /* Pointer to multitasking thread giveup.  */
+    long sscray[7];             /* Reserved for Cray Research.  */
     long ssa0;
     long ssa1;
     long ssa2;
@@ -301,27 +271,27 @@ struct stack_segment_linkage
    returned by the STKSTAT library routine.  */
 struct stk_stat
   {
-    long now;                  /* Current total stack size.  */
-    long maxc;                 /* Amount of contiguous space which would
-                                  be required to satisfy the maximum
-                                  stack demand to date.  */
-    long high_water;           /* Stack high-water mark.  */
-    long overflows;            /* Number of stack overflow ($STKOFEN) calls.  */
-    long hits;                 /* Number of internal buffer hits.  */
-    long extends;              /* Number of block extensions.  */
-    long stko_mallocs;         /* Block allocations by $STKOFEN.  */
-    long underflows;           /* Number of stack underflow calls ($STKRETN).  */
-    long stko_free;            /* Number of deallocations by $STKRETN.  */
-    long stkm_free;            /* Number of deallocations by $STKMRET.  */
-    long segments;             /* Current number of stack segments.  */
-    long maxs;                 /* Maximum number of stack segments so far.  */
-    long pad_size;             /* Stack pad size.  */
-    long current_address;      /* Current stack segment address.  */
-    long current_size;         /* Current stack segment size.  This
-                                  number is actually corrupted by STKSTAT to
-                                  include the fifteen word trailer area.  */
-    long initial_address;      /* Address of initial segment.  */
-    long initial_size;         /* Size of initial segment.  */
+    long now;                   /* Current total stack size.  */
+    long maxc;                  /* Amount of contiguous space which would
+                                   be required to satisfy the maximum
+                                   stack demand to date.  */
+    long high_water;            /* Stack high-water mark.  */
+    long overflows;             /* Number of stack overflow ($STKOFEN) calls.  */
+    long hits;                  /* Number of internal buffer hits.  */
+    long extends;               /* Number of block extensions.  */
+    long stko_mallocs;          /* Block allocations by $STKOFEN.  */
+    long underflows;            /* Number of stack underflow calls ($STKRETN).  */
+    long stko_free;             /* Number of deallocations by $STKRETN.  */
+    long stkm_free;             /* Number of deallocations by $STKMRET.  */
+    long segments;              /* Current number of stack segments.  */
+    long maxs;                  /* Maximum number of stack segments so far.  */
+    long pad_size;              /* Stack pad size.  */
+    long current_address;       /* Current stack segment address.  */
+    long current_size;          /* Current stack segment size.  This
+                                   number is actually corrupted by STKSTAT to
+                                   include the fifteen word trailer area.  */
+    long initial_address;       /* Address of initial segment.  */
+    long initial_size;          /* Size of initial segment.  */
   };
 
 /* The following structure describes the data structure which trails
@@ -330,13 +300,13 @@ struct stk_stat
 
 struct stk_trailer
   {
-    long this_address;         /* Address of this block.  */
-    long this_size;            /* Size of this block (does not include
-                                  this trailer).  */
+    long this_address;          /* Address of this block.  */
+    long this_size;             /* Size of this block (does not include
+                                   this trailer).  */
     long unknown2;
     long unknown3;
-    long link;                 /* Address of trailer block of previous
-                                  segment.  */
+    long link;                  /* Address of trailer block of previous
+                                   segment.  */
     long unknown5;
     long unknown6;
     long unknown7;
@@ -374,8 +344,8 @@ i00afunc (long *address)
   /* Set up the iteration.  */
 
   trailer = (struct stk_trailer *) (status.current_address
-                                   + status.current_size
-                                   - 15);
+                                    + status.current_size
+                                    - 15);
 
   /* There must be at least one stack segment.  Therefore it is
      a fatal error if "trailer" is null.  */
@@ -390,10 +360,10 @@ i00afunc (long *address)
       block = (long *) trailer->this_address;
       size = trailer->this_size;
       if (block == 0 || size == 0)
-       abort ();
+        abort ();
       trailer = (struct stk_trailer *) trailer->link;
       if ((block <= address) && (address < (block + size)))
-       break;
+        break;
     }
 
   /* Set the result to the offset in this segment and add the sizes
@@ -409,7 +379,7 @@ i00afunc (long *address)
   do
     {
       if (trailer->this_size <= 0)
-       abort ();
+        abort ();
       result += trailer->this_size;
       trailer = (struct stk_trailer *) trailer->link;
     }
@@ -472,7 +442,7 @@ i00afunc (long address)
       fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
 #    endif
       if (pseg == 0)
-       break;
+        break;
       stkl = stkl - pseg;
       ssptr = (struct stack_segment_linkage *) stkl;
       size = ssptr->sssize;
@@ -505,4 +475,4 @@ i00afunc (long address)
 #  endif /* CRAY */
 
 # endif /* no alloca */
-#endif /* not GCC version 2 */
+#endif /* not GCC 2 */