changeset 72:2323794dc2ce

GNU shell utilities
author Jim Meyering <jim@meyering.net>
date Wed, 08 Sep 1993 17:47:04 +0000
parents 8d09f0b9a26e
children d24aeffde572
files lib/alloca.c lib/error.c lib/getopt.c lib/getopt.h lib/getopt1.c lib/xmalloc.c
diffstat 6 files changed, 589 insertions(+), 175 deletions(-) [+]
line wrap: on
line diff
--- a/lib/alloca.c
+++ b/lib/alloca.c
@@ -1,37 +1,38 @@
-/*
-	alloca -- (mostly) portable public-domain implementation -- D A Gwyn
+/* alloca.c -- allocate automatically reclaimed memory
+   (Mostly) portable public-domain implementation -- D A Gwyn
 
-	last edit:	86/05/30	rms
-	   include config.h, since on VMS it renames some symbols.
-	   Use xmalloc instead of malloc.
+   This implementation of the PWB library alloca function,
+   which is used to allocate space off the run-time stack so
+   that it is automatically reclaimed upon procedure exit,
+   was inspired by discussions with J. Q. Johnson of Cornell.
+   J.Otto Tennant <jot@cray.com> contributed the Cray support.
 
-	This implementation of the PWB library alloca() function,
-	which is used to allocate space off the run-time stack so
-	that it is automatically reclaimed upon procedure exit, 
-	was inspired by discussions with J. Q. Johnson of Cornell.
+   There are some preprocessor constants that can
+   be defined when compiling for your specific system, for
+   improved efficiency; however, the defaults should be okay.
 
-	It should work under any C implementation that uses an
-	actual procedure stack (as opposed to a linked list of
-	frames).  There are some preprocessor constants that can
-	be defined when compiling for your specific system, for
-	improved efficiency; however, the defaults should be okay.
+   The general concept of this implementation is to keep
+   track of all alloca-allocated blocks, and reclaim any
+   that are found to be deeper in the stack than the current
+   invocation.  This heuristic does not reclaim storage as
+   soon as it becomes invalid, but it will do so eventually.
 
-	The general concept of this implementation is to keep
-	track of all alloca()-allocated blocks, and reclaim any
-	that are found to be deeper in the stack than the current
-	invocation.  This heuristic does not reclaim storage as
-	soon as it becomes invalid, but it will do so eventually.
+   As a special case, alloca(0) reclaims storage without
+   allocating any.  It is a good idea to use alloca(0) in
+   your main control loop, etc. to force garbage collection.  */
 
-	As a special case, alloca(0) reclaims storage without
-	allocating any.  It is a good idea to use alloca(0) in
-	your main control loop, etc. to force garbage collection.
-*/
-#ifndef lint
-static char	SCCSid[] = "@(#)alloca.c	1.1";	/* for the "what" utility */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
+/* If compiling with GCC 2, this file's not needed.  */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+   there must be some other way alloca is supposed to work.  */
+#ifndef alloca
+
 #ifdef emacs
-#include "config.h"
 #ifdef static
 /* actually, only want this if static is defined as ""
    -- this is for usg, in which emacs must undefine static
@@ -45,72 +46,90 @@
 #endif /* static */
 #endif /* emacs */
 
-#ifndef alloca  /* If compiling with GCC, this file's not needed.  */
+/* If your stack is a linked list of frames, you have to
+   provide an "address metric" ADDRESS_FUNCTION macro.  */
 
-#ifdef __STDC__
-typedef void	*pointer;		/* generic pointer type */
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
 #else
-typedef char	*pointer;		/* generic pointer type */
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
 #endif
 
-#define	NULL	0			/* null pointer constant */
+#define	NULL	0
 
-extern void	free();
-extern pointer	xmalloc();
+/* Different portions of Emacs need to call different versions of
+   malloc.  The Emacs executable needs alloca to call xmalloc, because
+   ordinary malloc isn't protected from input signals.  On the other
+   hand, the utilities in lib-src need alloca to call malloc; some of
+   them are very simple, and don't have an xmalloc routine.
+
+   Non-Emacs programs expect this to call use xmalloc.
+
+   Callers below should use malloc.  */
 
-/*
-	Define STACK_DIRECTION if you know the direction of stack
-	growth for your system; otherwise it will be automatically
-	deduced at run-time.
+#ifndef emacs
+#define malloc xmalloc
+#endif
+extern pointer malloc ();
 
-	STACK_DIRECTION > 0 => grows toward higher addresses
-	STACK_DIRECTION < 0 => grows toward lower addresses
-	STACK_DIRECTION = 0 => direction of growth unknown
-*/
+/* Define STACK_DIRECTION if you know the direction of stack
+   growth for your system; otherwise it will be automatically
+   deduced at run-time.
+
+   STACK_DIRECTION > 0 => grows toward higher addresses
+   STACK_DIRECTION < 0 => grows toward lower addresses
+   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 */
+#else /* STACK_DIRECTION == 0; need run-time code.  */
 
-static int	stack_dir;		/* 1 or -1 once known */
+static int stack_dir;		/* 1 or -1 once known.  */
 #define	STACK_DIR	stack_dir
 
 static void
-find_stack_direction (/* void */)
+find_stack_direction ()
 {
-  static char	*addr = NULL;	/* address of first
-				   `dummy', once known */
-  auto char	dummy;		/* to get stack address */
+  static char *addr = NULL;	/* Address of first `dummy', once known.  */
+  auto char dummy;		/* To get stack address.  */
 
   if (addr == NULL)
-    {				/* initial entry */
-      addr = &dummy;
+    {				/* Initial entry.  */
+      addr = ADDRESS_FUNCTION (dummy);
 
-      find_stack_direction ();	/* recurse once */
+      find_stack_direction ();	/* Recurse once.  */
     }
-  else				/* second entry */
-    if (&dummy > addr)
-      stack_dir = 1;		/* stack grew upward */
-    else
-      stack_dir = -1;		/* stack grew downward */
+  else
+    {
+      /* Second entry.  */
+      if (ADDRESS_FUNCTION (dummy) > addr)
+	stack_dir = 1;		/* Stack grew upward.  */
+      else
+	stack_dir = -1;		/* Stack grew downward.  */
+    }
 }
 
-#endif	/* STACK_DIRECTION == 0 */
+#endif /* STACK_DIRECTION == 0 */
 
-/*
-	An "alloca header" is used to:
-	(a) chain together all alloca()ed blocks;
-	(b) keep track of stack depth.
+/* An "alloca header" is used to:
+   (a) chain together all alloca'ed blocks;
+   (b) keep track of stack depth.
 
-	It is very important that sizeof(header) agree with malloc()
-	alignment chunk size.  The following default should work okay.
-*/
+   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)
@@ -118,77 +137,344 @@
 
 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;
 
-/*
-	alloca( size ) returns a pointer to at least `size' bytes of
-	storage which will be automatically reclaimed upon exit from
-	the procedure that called alloca().  Originally, this space
-	was supposed to be taken from the current stack frame of the
-	caller, but that method cannot be made to work for some
-	implementations of C, for example under Gould's UTX/32.
-*/
+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
+   the procedure that called alloca.  Originally, this space
+   was supposed to be taken from the current stack frame of the
+   caller, but that method cannot be made to work for some
+   implementations of C, for example under Gould's UTX/32.  */
 
 pointer
-alloca (size)			/* returns pointer to storage */
-     unsigned	size;		/* # bytes to allocate */
+alloca (size)
+     unsigned size;
 {
-  auto char	probe;		/* probes stack depth: */
-  register char	*depth = &probe;
+  auto char probe;		/* Probes stack depth: */
+  register char *depth = ADDRESS_FUNCTION (probe);
 
 #if STACK_DIRECTION == 0
-  if (STACK_DIR == 0)		/* unknown growth direction */
+  if (STACK_DIR == 0)		/* Unknown growth direction.  */
     find_stack_direction ();
 #endif
 
-				/* Reclaim garbage, defined as all alloca()ed storage that
-				   was allocated from deeper in the stack than currently. */
+  /* 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.  */
 
     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;
+	  register header *np = hp->h.next;
 
-	  free ((pointer) hp);	/* collect garbage */
+	  free ((pointer) 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.  */
   }
 
   if (size == 0)
-    return NULL;		/* no allocation required */
+    return NULL;		/* No allocation required.  */
 
-  /* Allocate combined header + user data storage. */
+  /* Allocate combined header + user data storage.  */
 
   {
-    register pointer	new = xmalloc (sizeof (header) + size);
-    /* address of header */
+    register pointer new = malloc (sizeof (header) + size);
+    /* Address of header.  */
 
-    ((header *)new)->h.next = last_alloca_header;
-    ((header *)new)->h.deep = depth;
+    ((header *) new)->h.next = last_alloca_header;
+    ((header *) new)->h.deep = depth;
 
-    last_alloca_header = (header *)new;
+    last_alloca_header = (header *) new;
 
-    /* User storage begins just after header. */
+    /* User storage begins just after header.  */
 
-    return (pointer)((char *)new + sizeof(header));
+    return (pointer) ((char *) new + sizeof (header));
   }
 }
 
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* 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).  */
+  };
+
+/* The stack segment linkage control information occurs at
+   the high-address end of a stack segment.  (The stack
+   grows from low addresses to high addresses.)  The initial
+   part of the stack segment linkage control information is
+   0200 (octal) words.  This provides for register storage
+   for the routine which overflows the stack.  */
+
+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:32;
+    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 ssa0;
+    long ssa1;
+    long ssa2;
+    long ssa3;
+    long ssa4;
+    long ssa5;
+    long ssa6;
+    long ssa7;
+    long sss0;
+    long sss1;
+    long sss2;
+    long sss3;
+    long sss4;
+    long sss5;
+    long sss6;
+    long sss7;
+  };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+   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.  */
+  };
+
+/* The following structure describes the data structure which trails
+   any stack segment.  I think that the description in 'asdef' is
+   out of date.  I only describe the parts that I am sure about.  */
+
+struct stk_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 unknown5;
+    long unknown6;
+    long unknown7;
+    long unknown8;
+    long unknown9;
+    long unknown10;
+    long unknown11;
+    long unknown12;
+    long unknown13;
+    long unknown14;
+  };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+   I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+  struct stk_stat status;
+  struct stk_trailer *trailer;
+  long *block, size;
+  long result = 0;
+
+  /* We want to iterate through all of the segments.  The first
+     step is to get the stack status structure.  We could do this
+     more quickly and more directly, perhaps, by referencing the
+     $LM00 common block, but I know that this works.  */
+
+  STKSTAT (&status);
+
+  /* Set up the iteration.  */
+
+  trailer = (struct stk_trailer *) (status.current_address
+				    + status.current_size
+				    - 15);
+
+  /* There must be at least one stack segment.  Therefore it is
+     a fatal error if "trailer" is null.  */
+
+  if (trailer == 0)
+    abort ();
+
+  /* Discard segments that do not contain our argument address.  */
+
+  while (trailer != 0)
+    {
+      block = (long *) trailer->this_address;
+      size = trailer->this_size;
+      if (block == 0 || size == 0)
+	abort ();
+      trailer = (struct stk_trailer *) trailer->link;
+      if ((block <= address) && (address < (block + size)))
+	break;
+    }
+
+  /* Set the result to the offset in this segment and add the sizes
+     of all predecessor segments.  */
+
+  result = address - block;
+
+  if (trailer == 0)
+    {
+      return result;
+    }
+
+  do
+    {
+      if (trailer->this_size <= 0)
+	abort ();
+      result += trailer->this_size;
+      trailer = (struct stk_trailer *) trailer->link;
+    }
+  while (trailer != 0);
+
+  /* We are done.  Note that if you present a bogus address (one
+     not in any segment), you will get a different number back, formed
+     from subtracting the address of the first block.  This is probably
+     not what you want.  */
+
+  return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+   Determine the number of the cell within the stack,
+   given the address of the cell.  The purpose of this
+   routine is to linearize, in some sense, stack addresses
+   for alloca.  */
+
+static long
+i00afunc (long address)
+{
+  long stkl = 0;
+
+  long size, pseg, this_segment, stack;
+  long result = 0;
+
+  struct stack_segment_linkage *ssptr;
+
+  /* Register B67 contains the address of the end of the
+     current stack segment.  If you (as a subprogram) store
+     your registers on the stack and find that you are past
+     the contents of B67, you have overflowed the segment.
+
+     B67 also points to the stack segment linkage control
+     area, which is what we are really interested in.  */
+
+  stkl = CRAY_STACKSEG_END ();
+  ssptr = (struct stack_segment_linkage *) stkl;
+
+  /* If one subtracts 'size' from the end of the segment,
+     one has the address of the first word of the segment.
+
+     If this is not the first segment, 'pseg' will be
+     nonzero.  */
+
+  pseg = ssptr->sspseg;
+  size = ssptr->sssize;
+
+  this_segment = stkl - size;
+
+  /* It is possible that calling this routine itself caused
+     a stack overflow.  Discard stack segments which do not
+     contain the target address.  */
+
+  while (!(this_segment <= address && address <= stkl))
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+      if (pseg == 0)
+	break;
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      this_segment = stkl - size;
+    }
+
+  result = address - this_segment;
+
+  /* If you subtract pseg from the current end of the stack,
+     you get the address of the previous stack segment's end.
+     This seems a little convoluted to me, but I'll bet you save
+     a cycle somewhere.  */
+
+  while (pseg != 0)
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      result += size;
+    }
+  return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
 #endif /* no alloca */
+#endif /* not GCC version 2 */
--- a/lib/error.c
+++ b/lib/error.c
@@ -1,5 +1,5 @@
 /* error.c -- error handler for noninteractive utilities
-   Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -17,6 +17,10 @@
 
 /* Written by David MacKenzie.  */
 
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 
 #ifdef HAVE_VPRINTF
@@ -48,6 +52,8 @@
 void exit ();
 #endif /* !STDC_HEADERS */
 
+extern char *program_name;
+
 #ifndef HAVE_STRERROR
 static char *
 private_strerror (errnum)
@@ -79,7 +85,6 @@
      va_dcl
 #endif /* !HAVE_VPRINTF or !__STDC__ */
 {
-  extern char *program_name;
 #ifdef HAVE_VPRINTF
   va_list args;
 #endif /* HAVE_VPRINTF */
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -3,58 +3,68 @@
    "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
    before changing it!
 
-   Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+   	Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* AIX requires this to be the first thing in the file.  */
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else /* not __GNUC__ */
-#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
-#include <alloca.h>
-#else
-#ifdef _AIX
- #pragma alloca
-#else
-char *alloca ();
+#ifdef HAVE_CONFIG_H
+/* We use <config.h> instead of "config.h" so that a compilation
+   using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+   (which it would do because getopt.c was found in $srcdir).  */
+#include <config.h>
 #endif
-#endif /* alloca.h */
-#endif /* not __GNUC__ */
+
+#ifndef __STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
 
 #include <stdio.h>
 
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
 /* This needs to come after some library #include
    to get __GNU_LIBRARY__ defined.  */
 #ifdef	__GNU_LIBRARY__
-#undef	alloca
 /* Don't include stdlib.h for non-GNU C libraries because some of them
    contain conflicting prototypes for getopt.  */
 #include <stdlib.h>
-#else	/* Not GNU C library.  */
-#define	__alloca	alloca
 #endif	/* GNU C library.  */
 
-#if !__STDC__
-#define const
-#endif
-
 /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
    long-named option.  Because this is not POSIX.2 compliant, it is
    being phased out.  */
-#define GETOPT_COMPAT
+/* #define GETOPT_COMPAT */
 
 /* This version of `getopt' appears to the caller like standard Unix `getopt'
    but it behaves differently for the user, since it allows the user
@@ -92,6 +102,7 @@
    Otherwise, `optind' communicates from one call to the next
    how much of ARGV has been scanned so far.  */
 
+/* XXX 1003.2 says this must be 1 before any call.  */
 int optind = 0;
 
 /* The next char to be scanned in the option-element
@@ -108,6 +119,12 @@
 
 int opterr = 1;
 
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
 /* Describe how to deal with options that follow non-option ARGV-elements.
 
    If the caller did not specify anything,
@@ -149,7 +166,6 @@
    in GCC.  */
 #include <string.h>
 #define	my_index	strchr
-#define	my_bcopy(src, dst, n)	memcpy ((dst), (src), (n))
 #else
 
 /* Avoid depending on library functions or files
@@ -158,28 +174,32 @@
 char *getenv ();
 
 static char *
-my_index (string, chr)
-     char *string;
+my_index (str, chr)
+     const char *str;
      int chr;
 {
-  while (*string)
+  while (*str)
     {
-      if (*string == chr)
-	return string;
-      string++;
+      if (*str == chr)
+	return (char *) str;
+      str++;
     }
   return 0;
 }
 
-static void
-my_bcopy (from, to, size)
-     char *from, *to;
-     int size;
-{
-  int i;
-  for (i = 0; i < size; i++)
-    to[i] = from[i];
-}
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.
+   (Supposedly there are some machines where it might get a warning,
+   but changing this conditional to __STDC__ is too risky.)  */
+#ifdef __GNUC__
+#ifdef IN_GCC
+#include "gstddef.h"
+#else
+#include <stddef.h>
+#endif
+extern size_t strlen (const char *);
+#endif
+
 #endif				/* GNU C library.  */
 
 /* Handle permutation of arguments.  */
@@ -204,17 +224,51 @@
 exchange (argv)
      char **argv;
 {
-  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
-  char **temp = (char **) __alloca (nonopts_size);
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
 
-  /* Interchange the two blocks of data in ARGV.  */
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+	{
+	  /* Bottom segment is the short one.  */
+	  int len = middle - bottom;
+	  register int i;
 
-  my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
-  my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
-	    (optind - last_nonopt) * sizeof (char *));
-  my_bcopy ((char *) temp,
-	    (char *) &argv[first_nonopt + optind - last_nonopt],
-	    nonopts_size);
+	  /* Swap it with the top part of the top segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[top - (middle - bottom) + i];
+	      argv[top - (middle - bottom) + i] = tem;
+	    }
+	  /* Exclude the moved bottom segment from further swapping.  */
+	  top -= len;
+	}
+      else
+	{
+	  /* Top segment is the short one.  */
+	  int len = top - middle;
+	  register int i;
+
+	  /* Swap it with the bottom part of the bottom segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[middle + i];
+	      argv[middle + i] = tem;
+	    }
+	  /* Exclude the moved top segment from further swapping.  */
+	  bottom += len;
+	}
+    }
 
   /* Update records for the slots the non-options now occupy.  */
 
@@ -490,7 +544,7 @@
 		    fprintf (stderr, "%s: option `%s' requires an argument\n",
 			     argv[0], argv[optind - 1]);
 		  nextchar += strlen (nextchar);
-		  return '?';
+		  return optstring[0] == ':' ? ':' : '?';
 		}
 	    }
 	  nextchar += strlen (nextchar);
@@ -544,12 +598,18 @@
       {
 	if (opterr)
 	  {
+#if 0
 	    if (c < 040 || c >= 0177)
 	      fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
 		       argv[0], c);
 	    else
 	      fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+	    /* 1003.2 specifies the format of this message.  */
+	    fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
 	  }
+	optopt = c;
 	return '?';
       }
     if (temp[1] == ':')
@@ -579,9 +639,21 @@
 	    else if (optind == argc)
 	      {
 		if (opterr)
-		  fprintf (stderr, "%s: option `-%c' requires an argument\n",
-			   argv[0], c);
-		c = '?';
+		  {
+#if 0
+		    fprintf (stderr, "%s: option `-%c' requires an argument\n",
+			     argv[0], c);
+#else
+		    /* 1003.2 specifies the format of this message.  */
+		    fprintf (stderr, "%s: option requires an argument -- %c\n",
+			     argv[0], c);
+#endif
+		  }
+		optopt = c;
+		if (optstring[0] == ':')
+		  c = ':';
+		else
+		  c = '?';
 	      }
 	    else
 	      /* We already incremented `optind' once;
@@ -605,6 +677,8 @@
 			   (int *) 0,
 			   0);
 }
+
+#endif	/* _LIBC or not __GNU_LIBRARY__.  */
 
 #ifdef TEST
 
--- a/lib/getopt.h
+++ b/lib/getopt.h
@@ -1,16 +1,16 @@
 /* Declarations for getopt.
-   Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
@@ -49,6 +49,10 @@
 
 extern int opterr;
 
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
 /* Describe the long-named options requested by the application.
    The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
    of `struct option' terminated by an element containing a name which is
--- a/lib/getopt1.c
+++ b/lib/getopt1.c
@@ -1,31 +1,58 @@
-/* Getopt for GNU.
-   Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+	Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+#ifdef HAVE_CONFIG_H
+/* We use <config.h> instead of "config.h" so that a compilation
+   using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+   (which it would do because getopt1.c was found in $srcdir).  */
+#include <config.h>
+#endif
+
 #include "getopt.h"
 
 #ifndef __STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
 #define const
 #endif
+#endif
 
-#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__) || defined (LIBC)
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
 #include <stdlib.h>
-#else /* STDC_HEADERS or __GNU_LIBRARY__ */
+#else
 char *getenv ();
-#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
+#endif
 
 #ifndef	NULL
 #define NULL 0
@@ -47,7 +74,7 @@
    but does match a short option, it is parsed as a short option
    instead.  */
 
-int 
+int
 getopt_long_only (argc, argv, options, long_options, opt_index)
      int argc;
      char *const *argv;
@@ -57,6 +84,9 @@
 {
   return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
 }
+
+
+#endif	/* _LIBC or not __GNU_LIBRARY__.  */
 
 #ifdef TEST
 
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -1,5 +1,5 @@
 /* xmalloc.c -- malloc with out of memory checking
-   Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1993 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,23 +15,38 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#ifdef STDC_HEADERS
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if __STDC__
+#define VOID void
+#else
+#define VOID char
+#endif
+
+#if STDC_HEADERS
 #include <stdlib.h>
 #else
-char *malloc ();
-char *realloc ();
+#include <sys/types.h>
+VOID *malloc ();
+VOID *realloc ();
 void free ();
 #endif
 
+#if __STDC__ && defined (HAVE_VPRINTF)
+void error (int, int, char const *, ...);
+#else
 void error ();
+#endif
 
 /* Allocate N bytes of memory dynamically, with error checking.  */
 
-char *
+VOID *
 xmalloc (n)
-     unsigned n;
+     size_t n;
 {
-  char *p;
+  VOID *p;
 
   p = malloc (n);
   if (p == 0)
@@ -45,10 +60,10 @@
    If P is NULL, run xmalloc.
    If N is 0, run free and return NULL.  */
 
-char *
+VOID *
 xrealloc (p, n)
-     char *p;
-     unsigned n;
+     VOID *p;
+     size_t n;
 {
   if (p == 0)
     return xmalloc (n);