# HG changeset patch # User Jim Meyering # Date 747510424 0 # Node ID 2323794dc2ce6ddfe3167552faafe93f660e1796 # Parent 8d09f0b9a26ef28b8ce18598c49b49a3aa284f6f GNU shell utilities diff --git a/lib/alloca.c b/lib/alloca.c --- 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 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 +#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 */ diff --git a/lib/error.c b/lib/error.c --- 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 #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 */ diff --git a/lib/getopt.c b/lib/getopt.c --- 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 -#else -#ifdef _AIX - #pragma alloca -#else -char *alloca (); +#ifdef HAVE_CONFIG_H +/* We use 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 #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 . */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif #include +/* 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 -#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 #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 +#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 diff --git a/lib/getopt.h b/lib/getopt.h --- 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 diff --git a/lib/getopt1.c b/lib/getopt1.c --- 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 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 +#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 + +/* 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 -#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 diff --git a/lib/xmalloc.c b/lib/xmalloc.c --- 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 #else -char *malloc (); -char *realloc (); +#include +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);