diff options
author | 2008-05-27 18:46:00 +0000 | |
---|---|---|
committer | 2008-05-27 18:46:00 +0000 | |
commit | 20fce977aadac3358da45d5027d7d19cdc03b0fe (patch) | |
tree | e1acdd9f822949ee35a6e57d097d42a55be5a68e | |
parent | Don't fail to compile when not in debug mode. (diff) | |
download | wireguard-openbsd-20fce977aadac3358da45d5027d7d19cdc03b0fe.tar.xz wireguard-openbsd-20fce977aadac3358da45d5027d7d19cdc03b0fe.zip |
Update libiberty to the version found in binutils 2.17.1 (which still
identifies itself as the gcc 3 version...)
83 files changed, 6000 insertions, 1535 deletions
diff --git a/gnu/lib/libiberty/include/COPYING b/gnu/lib/libiberty/include/COPYING index d60c31a97a5..623b6258a13 100644 --- a/gnu/lib/libiberty/include/COPYING +++ b/gnu/lib/libiberty/include/COPYING @@ -2,7 +2,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. diff --git a/gnu/lib/libiberty/include/ansidecl.h b/gnu/lib/libiberty/include/ansidecl.h index f8f2d737bf0..a1a765d63f3 100644 --- a/gnu/lib/libiberty/include/ansidecl.h +++ b/gnu/lib/libiberty/include/ansidecl.h @@ -15,7 +15,7 @@ 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* ANSI and traditional C compatibility macros @@ -149,7 +149,12 @@ So instead we use the macro below and test it against specific values. */ #define PTRCONST void *const #define LONG_DOUBLE long double +/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in + a #ifndef. */ +#ifndef PARAMS #define PARAMS(ARGS) ARGS +#endif + #define VPARAMS(ARGS) ARGS #define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) @@ -253,17 +258,25 @@ So instead we use the macro below and test it against specific values. */ /* Attributes on labels were valid as of gcc 2.93. */ #ifndef ATTRIBUTE_UNUSED_LABEL -# if (GCC_VERSION >= 2093) +# if (!defined (__cplusplus) && GCC_VERSION >= 2093) # define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED # else # define ATTRIBUTE_UNUSED_LABEL -# endif /* GNUC >= 2.93 */ +# endif /* !__cplusplus && GNUC >= 2.93 */ #endif /* ATTRIBUTE_UNUSED_LABEL */ #ifndef ATTRIBUTE_UNUSED #define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) #endif /* ATTRIBUTE_UNUSED */ +/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the + identifier name. */ +#if ! defined(__cplusplus) || (GCC_VERSION >= 3004) +# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED +#else /* !__cplusplus || GNUC >= 3.4 */ +# define ARG_UNUSED(NAME) NAME +#endif /* !__cplusplus || GNUC >= 3.4 */ + #ifndef ATTRIBUTE_NORETURN #define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) #endif /* ATTRIBUTE_NORETURN */ @@ -277,6 +290,15 @@ So instead we use the macro below and test it against specific values. */ # endif /* GNUC >= 3.3 */ #endif /* ATTRIBUTE_NONNULL */ +/* Attribute `pure' was valid as of gcc 3.0. */ +#ifndef ATTRIBUTE_PURE +# if (GCC_VERSION >= 3000) +# define ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define ATTRIBUTE_PURE +# endif /* GNUC >= 3.0 */ +#endif /* ATTRIBUTE_PURE */ + /* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. This was the case for the `printf' format attribute by itself before GCC 3.3, but as of 3.3 we need to add the `nonnull' @@ -290,6 +312,22 @@ So instead we use the macro below and test it against specific values. */ #define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) #endif /* ATTRIBUTE_PRINTF */ +/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on + a function pointer. Format attributes were allowed on function + pointers as of gcc 3.1. */ +#ifndef ATTRIBUTE_FPTR_PRINTF +# if (GCC_VERSION >= 3001) +# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n) +# else +# define ATTRIBUTE_FPTR_PRINTF(m, n) +# endif /* GNUC >= 3.1 */ +# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2) +# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3) +# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4) +# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5) +# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6) +#endif /* ATTRIBUTE_FPTR_PRINTF */ + /* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A NULL format specifier was allowed as of gcc 3.3. */ #ifndef ATTRIBUTE_NULL_PRINTF @@ -305,6 +343,24 @@ So instead we use the macro below and test it against specific values. */ # define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) #endif /* ATTRIBUTE_NULL_PRINTF */ +/* Attribute `sentinel' was valid as of gcc 3.5. */ +#ifndef ATTRIBUTE_SENTINEL +# if (GCC_VERSION >= 3005) +# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) +# else +# define ATTRIBUTE_SENTINEL +# endif /* GNUC >= 3.5 */ +#endif /* ATTRIBUTE_SENTINEL */ + + +#ifndef ATTRIBUTE_ALIGNED_ALIGNOF +# if (GCC_VERSION >= 3000) +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m)))) +# else +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) +# endif /* GNUC >= 3.0 */ +#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */ + /* We use __extension__ in some places to suppress -pedantic warnings about GCC extensions. This feature didn't work properly before gcc 2.8. */ @@ -312,15 +368,4 @@ So instead we use the macro below and test it against specific values. */ #define __extension__ #endif -/* Bootstrap support: Adjust certain macros defined by Autoconf, - which are only valid for the stage1 compiler. If we detect - a modern version of GCC, we are probably in stage2 or beyond, - so unconditionally reset the values. Note that const, inline, - etc. have been dealt with above. */ -#if (GCC_VERSION >= 2007) -# ifndef HAVE_LONG_DOUBLE -# define HAVE_LONG_DOUBLE 1 -# endif -#endif /* GCC >= 2.7 */ - #endif /* ansidecl.h */ diff --git a/gnu/lib/libiberty/include/fibheap.h b/gnu/lib/libiberty/include/fibheap.h index fc37f9ef635..348c4ae2638 100644 --- a/gnu/lib/libiberty/include/fibheap.h +++ b/gnu/lib/libiberty/include/fibheap.h @@ -16,8 +16,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* Fibonacci heaps are somewhat complex, but, there's an article in DDJ that explains them pretty well: @@ -59,23 +59,28 @@ typedef struct fibnode struct fibnode *right; fibheapkey_t key; void *data; +#if defined (__GNUC__) && (!defined (SIZEOF_INT) || SIZEOF_INT < 4) + __extension__ unsigned long int degree : 31; + __extension__ unsigned long int mark : 1; +#else unsigned int degree : 31; unsigned int mark : 1; +#endif } *fibnode_t; -extern fibheap_t fibheap_new PARAMS ((void)); -extern fibnode_t fibheap_insert PARAMS ((fibheap_t, fibheapkey_t, void *)); -extern int fibheap_empty PARAMS ((fibheap_t)); -extern fibheapkey_t fibheap_min_key PARAMS ((fibheap_t)); -extern fibheapkey_t fibheap_replace_key PARAMS ((fibheap_t, fibnode_t, - fibheapkey_t)); -extern void *fibheap_replace_key_data PARAMS ((fibheap_t, fibnode_t, - fibheapkey_t, void *)); -extern void *fibheap_extract_min PARAMS ((fibheap_t)); -extern void *fibheap_min PARAMS ((fibheap_t)); -extern void *fibheap_replace_data PARAMS ((fibheap_t, fibnode_t, void *)); -extern void *fibheap_delete_node PARAMS ((fibheap_t, fibnode_t)); -extern void fibheap_delete PARAMS ((fibheap_t)); -extern fibheap_t fibheap_union PARAMS ((fibheap_t, fibheap_t)); +extern fibheap_t fibheap_new (void); +extern fibnode_t fibheap_insert (fibheap_t, fibheapkey_t, void *); +extern int fibheap_empty (fibheap_t); +extern fibheapkey_t fibheap_min_key (fibheap_t); +extern fibheapkey_t fibheap_replace_key (fibheap_t, fibnode_t, + fibheapkey_t); +extern void *fibheap_replace_key_data (fibheap_t, fibnode_t, + fibheapkey_t, void *); +extern void *fibheap_extract_min (fibheap_t); +extern void *fibheap_min (fibheap_t); +extern void *fibheap_replace_data (fibheap_t, fibnode_t, void *); +extern void *fibheap_delete_node (fibheap_t, fibnode_t); +extern void fibheap_delete (fibheap_t); +extern fibheap_t fibheap_union (fibheap_t, fibheap_t); #endif /* _FIBHEAP_H_ */ diff --git a/gnu/lib/libiberty/include/filenames.h b/gnu/lib/libiberty/include/filenames.h new file mode 100644 index 00000000000..6b72fd249b4 --- /dev/null +++ b/gnu/lib/libiberty/include/filenames.h @@ -0,0 +1,51 @@ +/* Macros for taking apart, interpreting and processing file names. + + These are here because some non-Posix (a.k.a. DOSish) systems have + drive letter brain-damage at the beginning of an absolute file name, + use forward- and back-slash in path names interchangeably, and + some of them have case-insensitive file names. + + Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +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 of the License, 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, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef FILENAMES_H +#define FILENAMES_H + +#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) + +#ifndef HAVE_DOS_BASED_FILE_SYSTEM +#define HAVE_DOS_BASED_FILE_SYSTEM 1 +#endif + +#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') +/* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is + only semi-absolute. This is because the users of IS_ABSOLUTE_PATH + want to know whether to prepend the current working directory to + a file name, which should not be done with a name like d:foo. */ +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':'))) +#define FILENAME_CMP(s1, s2) strcasecmp(s1, s2) + +#else /* not DOSish */ + +#define IS_DIR_SEPARATOR(c) ((c) == '/') +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0])) +#define FILENAME_CMP(s1, s2) strcmp(s1, s2) + +#endif /* not DOSish */ + +#endif /* FILENAMES_H */ diff --git a/gnu/lib/libiberty/include/fnmatch.h b/gnu/lib/libiberty/include/fnmatch.h index 37d23ee1b35..5b9953ca3f5 100644 --- a/gnu/lib/libiberty/include/fnmatch.h +++ b/gnu/lib/libiberty/include/fnmatch.h @@ -15,8 +15,8 @@ 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, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +Foundation, 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifndef _FNMATCH_H diff --git a/gnu/lib/libiberty/include/getopt.h b/gnu/lib/libiberty/include/getopt.h index a99a2290159..5421cabed82 100644 --- a/gnu/lib/libiberty/include/getopt.h +++ b/gnu/lib/libiberty/include/getopt.h @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _GETOPT_H diff --git a/gnu/lib/libiberty/include/objalloc.h b/gnu/lib/libiberty/include/objalloc.h index c7106478dca..36772d17b50 100644 --- a/gnu/lib/libiberty/include/objalloc.h +++ b/gnu/lib/libiberty/include/objalloc.h @@ -14,8 +14,8 @@ 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, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +Foundation, 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifndef OBJALLOC_H #define OBJALLOC_H @@ -45,7 +45,7 @@ struct objalloc { char *current_ptr; unsigned int current_space; - PTR chunks; + void *chunks; }; /* Work out the required alignment. */ @@ -64,12 +64,12 @@ struct objalloc_align { char x; double d; }; /* Create an objalloc structure. Returns NULL if malloc fails. */ -extern struct objalloc *objalloc_create PARAMS ((void)); +extern struct objalloc *objalloc_create (void); /* Allocate space from an objalloc structure. Returns NULL if malloc fails. */ -extern PTR _objalloc_alloc PARAMS ((struct objalloc *, unsigned long)); +extern void *_objalloc_alloc (struct objalloc *, unsigned long); /* The macro version of objalloc_alloc. We only define this if using gcc, because otherwise we would have to evaluate the arguments @@ -94,7 +94,7 @@ extern PTR _objalloc_alloc PARAMS ((struct objalloc *, unsigned long)); (__len <= __o->current_space \ ? (__o->current_ptr += __len, \ __o->current_space -= __len, \ - (PTR) (__o->current_ptr - __len)) \ + (void *) (__o->current_ptr - __len)) \ : _objalloc_alloc (__o, __len)); }) #else /* ! __GNUC__ */ @@ -105,11 +105,11 @@ extern PTR _objalloc_alloc PARAMS ((struct objalloc *, unsigned long)); /* Free an entire objalloc structure. */ -extern void objalloc_free PARAMS ((struct objalloc *)); +extern void objalloc_free (struct objalloc *); /* Free a block allocated by objalloc_alloc. This also frees all more recently allocated blocks. */ -extern void objalloc_free_block PARAMS ((struct objalloc *, PTR)); +extern void objalloc_free_block (struct objalloc *, void *); #endif /* OBJALLOC_H */ diff --git a/gnu/lib/libiberty/include/safe-ctype.h b/gnu/lib/libiberty/include/safe-ctype.h index b2ad8490bd0..e59b357ccfb 100644 --- a/gnu/lib/libiberty/include/safe-ctype.h +++ b/gnu/lib/libiberty/include/safe-ctype.h @@ -16,8 +16,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* This is a compatible replacement of the standard C library's <ctype.h> with the following properties: @@ -37,7 +37,24 @@ Boston, MA 02111-1307, USA. */ #ifdef isalpha #error "safe-ctype.h and ctype.h may not be used simultaneously" +#endif + +/* Determine host character set. */ +#define HOST_CHARSET_UNKNOWN 0 +#define HOST_CHARSET_ASCII 1 +#define HOST_CHARSET_EBCDIC 2 + +#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ + && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 +# define HOST_CHARSET HOST_CHARSET_ASCII #else +# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \ + && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A +# define HOST_CHARSET HOST_CHARSET_EBCDIC +# else +# define HOST_CHARSET HOST_CHARSET_UNKNOWN +# endif +#endif /* Categories. */ @@ -99,5 +116,4 @@ extern const unsigned char _sch_tolower[256]; #define TOUPPER(c) _sch_toupper[(c) & 0xff] #define TOLOWER(c) _sch_tolower[(c) & 0xff] -#endif /* no ctype.h */ #endif /* SAFE_CTYPE_H */ diff --git a/gnu/lib/libiberty/include/sort.h b/gnu/lib/libiberty/include/sort.h index 3f3a92f18f0..582af81623b 100644 --- a/gnu/lib/libiberty/include/sort.h +++ b/gnu/lib/libiberty/include/sort.h @@ -16,8 +16,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifndef SORT_H #define SORT_H @@ -35,7 +35,7 @@ extern "C" { /* Sort an array of pointers. */ -extern void sort_pointers PARAMS ((size_t, void **, void **)); +extern void sort_pointers (size_t, void **, void **); #ifdef __cplusplus } diff --git a/gnu/lib/libiberty/include/ternary.h b/gnu/lib/libiberty/include/ternary.h index 40d442e6223..31c1fcef6ad 100644 --- a/gnu/lib/libiberty/include/ternary.h +++ b/gnu/lib/libiberty/include/ternary.h @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef TERNARY_H_ #define TERNARY_H_ @@ -38,14 +38,14 @@ ternary_node; already there, and replace is 0. Otherwise, replaces if it it exists, inserts if it doesn't, and returns the data you passed in. */ -PTR ternary_insert PARAMS ((ternary_tree *p, const char *s, - PTR data, int replace)); +void *ternary_insert (ternary_tree *p, const char *s, + void *data, int replace); /* Delete the ternary search tree rooted at P. Does NOT delete the data you associated with the strings. */ -void ternary_cleanup PARAMS ((ternary_tree p)); +void ternary_cleanup (ternary_tree p); /* Search the ternary tree for string S, returning the data associated with it if found. */ -PTR ternary_search PARAMS ((const ternary_node *p, const char *s)); +void *ternary_search (const ternary_node *p, const char *s); #endif diff --git a/gnu/lib/libiberty/include/xregex2.h b/gnu/lib/libiberty/include/xregex2.h index 2991daf9bcf..d3d0da14a98 100644 --- a/gnu/lib/libiberty/include/xregex2.h +++ b/gnu/lib/libiberty/include/xregex2.h @@ -1,6 +1,9 @@ /* Definitions for data structures and routines for the regular expression library, version 0.12. - Copyright (C) 1985,1989-1993,1995-1998, 2000 Free Software Foundation, Inc. + + Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1997, + 1998, 2000, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. @@ -16,8 +19,8 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. */ #ifndef _REGEX_H #define _REGEX_H 1 @@ -434,32 +437,21 @@ typedef struct unfortunately clutters up the declarations a bit, but I think it's worth it. */ -#if __STDC__ - -# define _RE_ARGS(args) args - -#else /* not __STDC__ */ - -# define _RE_ARGS(args) () - -#endif /* not __STDC__ */ - /* Sets the current default syntax to SYNTAX, and return the old syntax. You can also simply assign to the `re_syntax_options' variable. */ -extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); +extern reg_syntax_t re_set_syntax (reg_syntax_t syntax); /* Compile the regular expression PATTERN, with length LENGTH and syntax given by the global `re_syntax_options', into the buffer BUFFER. Return NULL if successful, and an error string if not. */ -extern const char *re_compile_pattern - _RE_ARGS ((const char *pattern, size_t length, - struct re_pattern_buffer *buffer)); +extern const char *re_compile_pattern (const char *pattern, size_t length, + struct re_pattern_buffer *buffer); /* Compile a fastmap for the compiled pattern in BUFFER; used to accelerate searches. Return 0 if successful and -2 if was an internal error. */ -extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); +extern int re_compile_fastmap (struct re_pattern_buffer *buffer); /* Search in the string STRING (with length LENGTH) for the pattern @@ -467,31 +459,29 @@ extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); characters. Return the starting position of the match, -1 for no match, or -2 for an internal error. Also return register information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern int re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); +extern int re_search (struct re_pattern_buffer *buffer, const char *string, + int length, int start, int range, + struct re_registers *regs); /* Like `re_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ -extern int re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); +extern int re_search_2 (struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, int range, struct re_registers *regs, + int stop); /* Like `re_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ -extern int re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); +extern int re_match (struct re_pattern_buffer *buffer, const char *string, + int length, int start, struct re_registers *regs); /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern int re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); +extern int re_match_2 (struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, struct re_registers *regs, int stop); /* Set REGS to hold NUM_REGS registers, storing them in STARTS and @@ -506,15 +496,16 @@ extern int re_match_2 Unless this function is called, the first search or match using PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ -extern void re_set_registers - _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, - unsigned num_regs, regoff_t *starts, regoff_t *ends)); +extern void re_set_registers (struct re_pattern_buffer *buffer, + struct re_registers *regs, + unsigned num_regs, regoff_t *starts, + regoff_t *ends); #if defined _REGEX_RE_COMP || defined _LIBC # ifndef _CRAY /* 4.2 bsd compatibility. */ -extern char *re_comp _RE_ARGS ((const char *)); -extern int re_exec _RE_ARGS ((const char *)); +extern char *re_comp (const char *); +extern int re_exec (const char *); # endif #endif @@ -541,19 +532,22 @@ extern int re_exec _RE_ARGS ((const char *)); #endif /* POSIX compatibility. */ -extern int regcomp _RE_ARGS ((regex_t *__restrict __preg, - const char *__restrict __pattern, - int __cflags)); +extern int regcomp (regex_t *__restrict __preg, + const char *__restrict __pattern, + int __cflags); -extern int regexec _RE_ARGS ((const regex_t *__restrict __preg, - const char *__restrict __string, size_t __nmatch, - regmatch_t __pmatch[__restrict_arr], - int __eflags)); +#if (__GNUC__) +__extension__ +#endif +extern int regexec (const regex_t *__restrict __preg, + const char *__restrict __string, size_t __nmatch, + regmatch_t __pmatch[__restrict_arr], + int __eflags); -extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, - char *__errbuf, size_t __errbuf_size)); +extern size_t regerror (int __errcode, const regex_t *__preg, + char *__errbuf, size_t __errbuf_size); -extern void regfree _RE_ARGS ((regex_t *__preg)); +extern void regfree (regex_t *__preg); #ifdef __cplusplus diff --git a/gnu/lib/libiberty/move-if-change b/gnu/lib/libiberty/move-if-change index ee1b348beeb..ff74a556d2d 100644 --- a/gnu/lib/libiberty/move-if-change +++ b/gnu/lib/libiberty/move-if-change @@ -1,32 +1,22 @@ #!/bin/sh +# Like mv $1 $2, but if the files are the same, just delete $1. +# Status is zero if successful, nonzero otherwise. -# Copyright (C) 1996 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 of the License, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +usage="$0: usage: $0 SOURCE DEST" -if -test -r $2 -then -if -cmp $1 $2 > /dev/null -then -echo $2 is unchanged -rm -f $1 -else -mv -f $1 $2 -fi +case $# in +2) ;; +*) echo "$usage" >&2; exit 1;; +esac + +for arg in "$1" "$2"; do + case $arg in + -*) echo "$usage" >&2; exit 1;; + esac +done + +if test -r "$2" && cmp -s "$1" "$2"; then + rm -f "$1" else -mv -f $1 $2 + mv -f "$1" "$2" fi diff --git a/gnu/lib/libiberty/src/COPYING.LIB b/gnu/lib/libiberty/src/COPYING.LIB index b1e3f5a2638..ae23fcfda2d 100644 --- a/gnu/lib/libiberty/src/COPYING.LIB +++ b/gnu/lib/libiberty/src/COPYING.LIB @@ -2,7 +2,7 @@ Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -485,7 +485,7 @@ convey the exclusion of warranty; and each file should have at least the You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. diff --git a/gnu/lib/libiberty/src/README b/gnu/lib/libiberty/src/README index e8e9b338350..886bd67bc9d 100644 --- a/gnu/lib/libiberty/src/README +++ b/gnu/lib/libiberty/src/README @@ -34,7 +34,7 @@ name of the function must be the same as the name of the file. * Add the source file name to CFILES. * Add the function to name to the funcs shell variable in - configure.in. + configure.ac. * Add the function to the AC_CHECK_FUNCS lists just after the setting of the funcs shell variable. These AC_CHECK_FUNCS calls diff --git a/gnu/lib/libiberty/src/_doprnt.c b/gnu/lib/libiberty/src/_doprnt.c index 8ce14158c99..ca97bc8c5d4 100644 --- a/gnu/lib/libiberty/src/_doprnt.c +++ b/gnu/lib/libiberty/src/_doprnt.c @@ -14,18 +14,14 @@ 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "ansidecl.h" #include "safe-ctype.h" #include <stdio.h> -#ifdef ANSI_PROTOTYPES #include <stdarg.h> -#else -#include <varargs.h> -#endif #ifdef HAVE_STRING_H #include <string.h> #endif @@ -79,10 +75,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ } while (0) int -_doprnt (format, ap, stream) - const char * format; - va_list ap; - FILE * stream; +_doprnt (const char *format, va_list ap, FILE *stream) { const char * ptr = format; char specifier[128]; @@ -223,10 +216,10 @@ _doprnt (format, ap, stream) fflush(stdin); \ } while (0) -static int checkit PARAMS ((const char * format, ...)) ATTRIBUTE_PRINTF_1; +static int checkit (const char * format, ...) ATTRIBUTE_PRINTF_1; static int -checkit VPARAMS ((const char* format, ...)) +checkit (const char* format, ...) { int result; VA_OPEN (args, format); @@ -239,7 +232,7 @@ checkit VPARAMS ((const char* format, ...)) } int -main () +main (void) { RESULT(checkit ("<%d>\n", 0x12345678)); RESULT(printf ("<%d>\n", 0x12345678)); diff --git a/gnu/lib/libiberty/src/aclocal.m4 b/gnu/lib/libiberty/src/aclocal.m4 index 6c5dc6ac64b..0b49d032122 100644 --- a/gnu/lib/libiberty/src/aclocal.m4 +++ b/gnu/lib/libiberty/src/aclocal.m4 @@ -1,3 +1,6 @@ +sinclude(../config/acx.m4) +sinclude(../config/no-executables.m4) + dnl See whether strncmp reads past the end of its string parameters. dnl On some versions of SunOS4 at least, strncmp reads a word at a time dnl but erroneously reads past the end of strings. This can cause @@ -69,7 +72,7 @@ main () ac_cv_func_strncmp_works=no) rm -f core core.* *.core]) if test $ac_cv_func_strncmp_works = no ; then - LIBOBJS="$LIBOBJS strncmp.o" + AC_LIBOBJ([strncmp]) fi ]) @@ -116,57 +119,6 @@ if test $libiberty_cv_decl_needed_$1 = yes; then fi ])dnl -# FIXME: We temporarily define our own version of AC_PROG_CC. This is -# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We -# are probably using a cross compiler, which will not be able to fully -# link an executable. This should really be fixed in autoconf -# itself. - -AC_DEFUN(LIB_AC_PROG_CC, -[AC_BEFORE([$0], [AC_PROG_CPP])dnl -AC_PROVIDE([AC_PROG_CC]) -AC_CHECK_PROG(CC, gcc, gcc) -if test -z "$CC"; then - AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) - test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH]) -fi - -AC_PROG_CC_GNU - -if test $ac_cv_prog_gcc = yes; then - GCC=yes - ac_libiberty_warn_cflags='-W -Wall -Wtraditional -pedantic' -dnl Check whether -g works, even if CFLAGS is set, in case the package -dnl plays around with CFLAGS (such as to build both debugging and -dnl normal versions of a library), tasteless as that idea is. - ac_test_CFLAGS="${CFLAGS+set}" - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - AC_PROG_CC_G - if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" - elif test $ac_cv_prog_cc_g = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-O2" - fi -else - GCC= - ac_libiberty_warn_cflags= - test "${CFLAGS+set}" = set || CFLAGS="-g" -fi -AC_SUBST(ac_libiberty_warn_cflags) -]) - -# Work around a bug in autoheader. This can go away when we switch to -# autoconf >2.50. The use of define instead of AC_DEFUN is -# deliberate. -define(AC_DEFINE_NOAUTOHEADER, -[cat >> confdefs.h <<\EOF -[#define] $1 ifelse($#, 2, [$2], $#, 3, [$2], 1) -EOF -]) - # We always want a C version of alloca() compiled into libiberty, # because native-compiler support for the real alloca is so !@#$% # unreliable that GCC has decided to use it only when being compiled @@ -218,3 +170,52 @@ AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction, STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown]) ]) + +# AC_LANG_FUNC_LINK_TRY(C)(FUNCTION) +# ---------------------------------- +# Don't include <ctype.h> because on OSF/1 3.0 it includes +# <sys/types.h> which includes <sys/select.h> which contains a +# prototype for select. Similarly for bzero. +# +# This test used to merely assign f=$1 in main(), but that was +# optimized away by HP unbundled cc A.05.36 for ia64 under +O3, +# presumably on the basis that there's no need to do that store if the +# program is about to exit. Conversely, the AIX linker optimizes an +# unused external declaration that initializes f=$1. So this test +# program has both an external initialization of f, and a use of f in +# main that affects the exit status. +# +m4_define([AC_LANG_FUNC_LINK_TRY(C)], +[AC_LANG_PROGRAM( +[/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $1 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. Under hpux, + including <limits.h> includes <sys/time.h> and causes problems + checking for functions defined therein. */ +#if defined (__STDC__) && !defined (_HPUX_SOURCE) +# include <limits.h> +#else +# include <assert.h> +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $1 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$1) || defined (__stub___$1) +choke me +#else +char (*f) () = $1; +#endif +#ifdef __cplusplus +} +#endif +], [return f != $1;])]) + diff --git a/gnu/lib/libiberty/src/alloca.c b/gnu/lib/libiberty/src/alloca.c index 918235df465..9b2e9cb12b6 100644 --- a/gnu/lib/libiberty/src/alloca.c +++ b/gnu/lib/libiberty/src/alloca.c @@ -57,9 +57,15 @@ the possibility of a GCC built-in function. /* These variables are used by the ASTRDUP implementation that relies on C_alloca. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ const char *libiberty_optr; char *libiberty_nptr; unsigned long libiberty_len; +#ifdef __cplusplus +} +#endif /* __cplusplus */ /* If your stack is a linked list of frames, you have to provide an "address metric" ADDRESS_FUNCTION macro. */ @@ -97,7 +103,7 @@ static int stack_dir; /* 1 or -1 once known. */ #define STACK_DIR stack_dir static void -find_stack_direction () +find_stack_direction (void) { static char *addr = NULL; /* Address of first `dummy', once known. */ auto char dummy; /* To get stack address. */ @@ -153,8 +159,7 @@ static header *last_alloca_header = NULL; /* -> last alloca header. */ /* @undocumented C_alloca */ PTR -C_alloca (size) - size_t size; +C_alloca (size_t size) { auto char probe; /* Probes stack depth: */ register char *depth = ADDRESS_FUNCTION (probe); @@ -192,20 +197,20 @@ C_alloca (size) /* Allocate combined header + user data storage. */ { - register PTR new = xmalloc (sizeof (header) + size); + register void *new_storage = XNEWVEC (char, sizeof (header) + size); /* Address of header. */ - if (new == 0) + if (new_storage == 0) abort(); - ((header *) new)->h.next = last_alloca_header; - ((header *) new)->h.deep = depth; + ((header *) new_storage)->h.next = last_alloca_header; + ((header *) new_storage)->h.deep = depth; - last_alloca_header = (header *) new; + last_alloca_header = (header *) new_storage; /* User storage begins just after header. */ - return (PTR) ((char *) new + sizeof (header)); + return (PTR) ((char *) new_storage + sizeof (header)); } } diff --git a/gnu/lib/libiberty/src/asprintf.c b/gnu/lib/libiberty/src/asprintf.c index 5de775616d0..3cf50526609 100644 --- a/gnu/lib/libiberty/src/asprintf.c +++ b/gnu/lib/libiberty/src/asprintf.c @@ -1,6 +1,6 @@ /* Like sprintf but provides a pointer to malloc'd storage, which must be freed by the caller. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2003 Free Software Foundation, Inc. Contributed by Cygnus Solutions. This file is part of the libiberty library. @@ -16,17 +16,16 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "ansidecl.h" #include "libiberty.h" -#ifdef ANSI_PROTOTYPES #include <stdarg.h> -#else -#include <varargs.h> -#endif /* @@ -37,7 +36,7 @@ pass a pointer to a pointer. This function will compute the size of the buffer needed, allocate memory with @code{malloc}, and store a pointer to the allocated memory in @code{*@var{resptr}}. The value returned is the same as @code{sprintf} would return. If memory could -not be allocated, zero is returned and @code{NULL} is stored in +not be allocated, minus one is returned and @code{NULL} is stored in @code{*@var{resptr}}. @end deftypefn @@ -45,7 +44,7 @@ not be allocated, zero is returned and @code{NULL} is stored in */ int -asprintf VPARAMS ((char **buf, const char *fmt, ...)) +asprintf (char **buf, const char *fmt, ...) { int status; VA_OPEN (ap, fmt); diff --git a/gnu/lib/libiberty/src/at-file.texi b/gnu/lib/libiberty/src/at-file.texi new file mode 100644 index 00000000000..080d1951d62 --- /dev/null +++ b/gnu/lib/libiberty/src/at-file.texi @@ -0,0 +1,15 @@ +@c This file is designed to be included in manuals that use +@c expandargv. + +@item @@@var{file} +Read command-line options from @var{file}. The options read are +inserted in place of the original @@@var{file} option. If @var{file} +does not exist, or cannot be read, then the option will be treated +literally, and not removed. + +Options in @var{file} are separated by whitespace. A whitespace +character may be included in an option by surrounding the entire +option in either single or double quotes. Any character (including a +backslash) may be included by prefixing the character to be included +with a backslash. The @var{file} may itself contain additional +@@@var{file} options; any such options will be processed recursively. diff --git a/gnu/lib/libiberty/src/atexit.c b/gnu/lib/libiberty/src/atexit.c index e14de29ab1d..e091f0139ee 100644 --- a/gnu/lib/libiberty/src/atexit.c +++ b/gnu/lib/libiberty/src/atexit.c @@ -16,8 +16,7 @@ Causes function @var{f} to be called at exit. Returns 0. #ifdef HAVE_ON_EXIT int -atexit(f) - void (*f)(); +atexit(void (*f)(void)) { /* If the system doesn't provide a definition for atexit, use on_exit if the system provides that. */ diff --git a/gnu/lib/libiberty/src/bcmp.c b/gnu/lib/libiberty/src/bcmp.c index 1895773d52d..c639f9895bc 100644 --- a/gnu/lib/libiberty/src/bcmp.c +++ b/gnu/lib/libiberty/src/bcmp.c @@ -15,22 +15,13 @@ result mean @var{x} sorts before @var{y}). */ +#include <stddef.h> + +extern int memcmp(const void *, const void *, size_t); int -bcmp (from, to, count) - char *from, *to; - int count; +bcmp (const void *s1, const void *s2, size_t count) { - int rtnval = 0; - - while (count-- > 0) - { - if (*from++ != *to++) - { - rtnval = 1; - break; - } - } - return (rtnval); + return memcmp (s1, s2, count); } diff --git a/gnu/lib/libiberty/src/bcopy.c b/gnu/lib/libiberty/src/bcopy.c index 70fa7e328cc..1e2eca9c641 100644 --- a/gnu/lib/libiberty/src/bcopy.c +++ b/gnu/lib/libiberty/src/bcopy.c @@ -9,19 +9,23 @@ Copies @var{length} bytes from memory region @var{in} to region */ +#include <stddef.h> + void -bcopy (src, dest, len) - register char *src, *dest; - int len; +bcopy (const void *src, void *dest, size_t len) { if (dest < src) - while (len--) - *dest++ = *src++; + { + const char *firsts = src; + char *firstd = dest; + while (len--) + *firstd++ = *firsts++; + } else { - char *lasts = src + (len-1); - char *lastd = dest + (len-1); + const char *lasts = (const char *)src + (len-1); + char *lastd = (char *)dest + (len-1); while (len--) - *(char *)lastd-- = *(char *)lasts--; + *lastd-- = *lasts--; } } diff --git a/gnu/lib/libiberty/src/bsearch.c b/gnu/lib/libiberty/src/bsearch.c index b3283f9285f..771d5de7b12 100644 --- a/gnu/lib/libiberty/src/bsearch.c +++ b/gnu/lib/libiberty/src/bsearch.c @@ -67,24 +67,21 @@ is respectively less than, matching, or greater than the array member. * look at item 3. */ void * -bsearch(key, base0, nmemb, size, compar) - register void *key; - void *base0; - size_t nmemb; - register size_t size; - register int (*compar)(); +bsearch (register const void *key, const void *base0, + size_t nmemb, register size_t size, + register int (*compar)(const void *, const void *)) { - register char *base = base0; + register const char *base = (const char *) base0; register int lim, cmp; - register void *p; + register const void *p; for (lim = nmemb; lim != 0; lim >>= 1) { p = base + (lim >> 1) * size; cmp = (*compar)(key, p); if (cmp == 0) - return (p); + return (void *)p; if (cmp > 0) { /* key > p: move right */ - base = (char *)p + size; + base = (const char *)p + size; lim--; } /* else move left */ } diff --git a/gnu/lib/libiberty/src/bzero.c b/gnu/lib/libiberty/src/bzero.c index 8874118698e..44ad73da4d6 100644 --- a/gnu/lib/libiberty/src/bzero.c +++ b/gnu/lib/libiberty/src/bzero.c @@ -12,14 +12,12 @@ is deprecated in favor of @code{memset}. */ +#include <stddef.h> + +extern void *memset(void *, int, size_t); void -bzero (to, count) - char *to; - int count; +bzero (void *to, size_t count) { - while (count-- > 0) - { - *to++ = 0; - } + memset (to, 0, count); } diff --git a/gnu/lib/libiberty/src/clock.c b/gnu/lib/libiberty/src/clock.c index 3ea70c31c60..07d902e8a16 100644 --- a/gnu/lib/libiberty/src/clock.c +++ b/gnu/lib/libiberty/src/clock.c @@ -14,7 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause @@ -67,7 +67,7 @@ number of seconds used. /* FIXME: should be able to declare as clock_t. */ long -clock () +clock (void) { #ifdef HAVE_GETRUSAGE struct rusage rusage; diff --git a/gnu/lib/libiberty/src/concat.c b/gnu/lib/libiberty/src/concat.c index 98b20e16a11..1f329ea0e15 100644 --- a/gnu/lib/libiberty/src/concat.c +++ b/gnu/lib/libiberty/src/concat.c @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -51,11 +51,7 @@ NOTES #include "libiberty.h" #include <sys/types.h> /* size_t */ -#ifdef ANSI_PROTOTYPES #include <stdarg.h> -#else -#include <varargs.h> -#endif # if HAVE_STRING_H # include <string.h> @@ -69,11 +65,9 @@ NOTES #include <stdlib.h> #endif -static inline unsigned long vconcat_length PARAMS ((const char *, va_list)); +static inline unsigned long vconcat_length (const char *, va_list); static inline unsigned long -vconcat_length (first, args) - const char *first; - va_list args; +vconcat_length (const char *first, va_list args) { unsigned long length = 0; const char *arg; @@ -84,12 +78,8 @@ vconcat_length (first, args) return length; } -static inline char *vconcat_copy PARAMS ((char *, const char *, va_list)); static inline char * -vconcat_copy (dst, first, args) - char *dst; - const char *first; - va_list args; +vconcat_copy (char *dst, const char *first, va_list args) { char *end = dst; const char *arg; @@ -108,7 +98,7 @@ vconcat_copy (dst, first, args) /* @undocumented concat_length */ unsigned long -concat_length VPARAMS ((const char *first, ...)) +concat_length (const char *first, ...) { unsigned long length; @@ -123,7 +113,7 @@ concat_length VPARAMS ((const char *first, ...)) /* @undocumented concat_copy */ char * -concat_copy VPARAMS ((char *dst, const char *first, ...)) +concat_copy (char *dst, const char *first, ...) { char *save_dst; @@ -137,12 +127,18 @@ concat_copy VPARAMS ((char *dst, const char *first, ...)) return save_dst; } +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ char *libiberty_concat_ptr; +#ifdef __cplusplus +} +#endif /* __cplusplus */ /* @undocumented concat_copy2 */ char * -concat_copy2 VPARAMS ((const char *first, ...)) +concat_copy2 (const char *first, ...) { VA_OPEN (args, first); VA_FIXEDARG (args, const char *, first); @@ -153,14 +149,14 @@ concat_copy2 VPARAMS ((const char *first, ...)) } char * -concat VPARAMS ((const char *first, ...)) +concat (const char *first, ...) { char *newstr; /* First compute the size of the result and get sufficient memory. */ VA_OPEN (args, first); VA_FIXEDARG (args, const char *, first); - newstr = (char *) xmalloc (vconcat_length (first, args) + 1); + newstr = XNEWVEC (char, vconcat_length (first, args) + 1); VA_CLOSE (args); /* Now copy the individual pieces to the result string. */ @@ -190,7 +186,7 @@ loop: */ char * -reconcat VPARAMS ((char *optr, const char *first, ...)) +reconcat (char *optr, const char *first, ...) { char *newstr; @@ -198,7 +194,7 @@ reconcat VPARAMS ((char *optr, const char *first, ...)) VA_OPEN (args, first); VA_FIXEDARG (args, char *, optr); VA_FIXEDARG (args, const char *, first); - newstr = (char *) xmalloc (vconcat_length (first, args) + 1); + newstr = XNEWVEC (char, vconcat_length (first, args) + 1); VA_CLOSE (args); /* Now copy the individual pieces to the result string. */ @@ -221,7 +217,7 @@ reconcat VPARAMS ((char *optr, const char *first, ...)) #include <stdio.h> int -main () +main (void) { printf ("\"\" = \"%s\"\n", concat (NULLP)); printf ("\"a\" = \"%s\"\n", concat ("a", NULLP)); diff --git a/gnu/lib/libiberty/src/configure.ac b/gnu/lib/libiberty/src/configure.ac new file mode 100644 index 00000000000..76cf3d5333f --- /dev/null +++ b/gnu/lib/libiberty/src/configure.ac @@ -0,0 +1,669 @@ +dnl Process this file with autoconf to produce a configure script + +AC_PREREQ(2.59) +AC_INIT +AC_CONFIG_SRCDIR([xmalloc.c]) + +# This works around the fact that libtool configuration may change LD +# for this particular configuration, but some shells, instead of +# keeping the changes in LD private, export them just because LD is +# exported. We don't use libtool yet, but some day we might, so... +ORIGINAL_LD_FOR_MULTILIBS=$LD + +dnl We use these options to decide which functions to include. +AC_ARG_WITH(target-subdir, +[ --with-target-subdir=SUBDIR Configuring in a subdirectory for target]) +AC_ARG_WITH(build-subdir, +[ --with-build-subdir=SUBDIR Configuring in a subdirectory for build]) +AC_ARG_WITH(cross-host, +[ --with-cross-host=HOST Configuring with a cross compiler]) +AC_ARG_WITH(newlib, +[ --with-newlib Configuring with newlib]) + +if test "${srcdir}" = "."; then + if test -n "${with_build_subdir}"; then + libiberty_topdir="${srcdir}/../.." + with_target_subdir= + elif test -z "${with_target_subdir}"; then + libiberty_topdir="${srcdir}/.." + else + if test "${with_target_subdir}" != "."; then + libiberty_topdir="${srcdir}/${with_multisrctop}../.." + else + libiberty_topdir="${srcdir}/${with_multisrctop}.." + fi + fi +else + libiberty_topdir="${srcdir}/.." +fi +AC_SUBST(libiberty_topdir) +AC_CONFIG_AUX_DIR($libiberty_topdir) + +dnl Very limited version of automake's enable-maintainer-mode + +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode + enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + maintainer_mode=$enableval, + maintainer_mode=no) + +AC_MSG_RESULT($maintainer_mode) + +if test "$maintainer_mode" = "yes"; then + MAINT='' + NOTMAINT='#' +else + MAINT='#' + NOTMAINT='' +fi +AC_SUBST(MAINT)dnl +AC_SUBST(NOTMAINT)dnl + +# Do we have a single-tree copy of texinfo? Even if we do, we can't +# rely on it - libiberty is built before texinfo. +AC_CHECK_PROG(MAKEINFO, makeinfo, makeinfo, ) +if test "x$MAKEINFO" = "x"; then + MAKEINFO="@echo makeinfo missing; true" + BUILD_INFO= +else + BUILD_INFO=info + case "$MAKEINFO" in + */missing\ makeinfo*) + BUILD_INFO= + AC_MSG_WARN([ +*** Makeinfo is missing. Info documentation will not be built.]) + ;; + *) + case x"`$MAKEINFO --version | grep 'GNU texinfo'`" in + x*\ [[1-3]].* ) + MAKEINFO="@echo $MAKEINFO is too old, 4.0 or newer required; true" + BUILD_INFO= + AC_MSG_WARN([ +*** Makeinfo is too old. Info documentation will not be built.]) + ;; + esac + ;; + esac +fi +AC_SUBST(MAKEINFO) +AC_SUBST(BUILD_INFO) + +AC_CHECK_PROG(PERL, perl, perl, ) +if test x"$PERL" = x""; then + HAVE_PERL='#' +else + HAVE_PERL='' +fi +AC_SUBST(HAVE_PERL) + +AC_CANONICAL_HOST + +dnl When we start using automake: +dnl AM_INIT_AUTOMAKE(libiberty, 1.0) + +dnl These must be called before AM_PROG_LIBTOOL, because it may want +dnl to call AC_CHECK_PROG. +AC_CHECK_TOOL(AR, ar) +AC_CHECK_TOOL(RANLIB, ranlib, :) + +GCC_NO_EXECUTABLES +AC_PROG_CC +AC_PROG_CPP_WERROR + +# Warn C++ incompatibilities if supported. +AC_CACHE_CHECK( + [whether ${CC} accepts -Wc++-compat], + [ac_cv_prog_cc_w_cxx_compat], + [save_CFLAGS="$CFLAGS" + CFLAGS="-Wc++-compat" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])], + [ac_cv_prog_cc_w_cxx_compat=yes], + [ac_cv_prog_cc_w_cxx_compat=no]) + CFLAGS="$save_CFLAGS" + ]) + + +if test x$GCC = xyes; then + ac_libiberty_warn_cflags='-W -Wall -pedantic -Wwrite-strings -Wstrict-prototypes' +fi +if test $ac_cv_prog_cc_w_cxx_compat = yes ; then + ac_libiberty_warn_cflags="${ac_libiberty_warn_cflags} -Wc++-compat" +fi +AC_SUBST(ac_libiberty_warn_cflags) + +AC_PROG_CC_C_O +# autoconf is lame and doesn't give us any substitution variable for this. +if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then + NO_MINUS_C_MINUS_O=yes +else + OUTPUT_OPTION='-o $@' +fi +AC_SUBST(NO_MINUS_C_MINUS_O) +AC_SUBST(OUTPUT_OPTION) + +AC_C_CONST +AC_C_INLINE +AC_C_BIGENDIAN + +dnl When we start using libtool: +dnl Default to a non shared library. This may be overridden by the +dnl configure option --enable-shared. +dnl AM_DISABLE_SHARED + +dnl When we start using libtool: +dnl AM_PROG_LIBTOOL + +dnl When we start using automake: +dnl AM_CONFIG_HEADER(config.h:config.in) +AC_CONFIG_HEADER(config.h:config.in) + +dnl When we start using automake: +dnl AM_MAINTAINER_MODE +dnl AC_EXEEXT + +dnl When we start using automake: +dnl AM_PROG_INSTALL +AC_PROG_INSTALL + +# Don't build the shared library for build. +if [[ -n "${with_build_subdir}" ]]; then + enable_shared=no +fi + +frag= +case "${host}" in + rs6000-ibm-aix3.1 | rs6000-ibm-aix) + frag=mh-aix ;; + *-*-cxux7*) frag=mh-cxux7 ;; + *-*-freebsd2.1.*) frag=mh-fbsd21 ;; + *-*-freebsd2.2.[[012]]) frag=mh-fbsd21 ;; + i370-*-opened*) frag=mh-openedition ;; + i[[34567]]86-*-windows*) frag=mh-windows ;; +esac + +if [[ -n "${frag}" ]]; then + frags=${libiberty_topdir}/libiberty/config/$frag +else + frags= +fi + +# If they didn't specify --enable-shared, don't generate shared libs. +case "${enable_shared}" in + yes) shared=yes ;; + no) shared=no ;; + "") shared=no ;; + *) shared=yes ;; +esac +if [[ "${shared}" = "yes" ]]; then + frag= + case "${host}" in + *-*-cygwin*) ;; + alpha*-*-linux*) frag=mh-elfalphapic ;; + arm*-*-*) frag=mh-armpic ;; + hppa*-*-*) frag=mh-papic ;; + i[[34567]]86-*-* | x86_64-*-*) + frag=mh-x86pic ;; + powerpc*-*-aix*) ;; + powerpc*-*-*) frag=mh-ppcpic ;; + sparc*-*-*) frag=mh-sparcpic ;; + s390*-*-*) frag=mh-s390pic ;; + *) frag=mh-${host_cpu}pic ;; + esac + if [[ -n "${frag}" ]]; then + frags="${frags} ${libiberty_topdir}/config/${frag}" + fi +fi + +echo "# Warning: this fragment is automatically generated" > temp-frag + +for frag in ${frags}; do + if [[ -f ${frag} ]]; then + echo "Appending ${frag} to xhost-mkfrag" + echo "# Following fragment copied from ${frag}" >> temp-frag + cat ${frag} >> temp-frag + fi +done + +# record if we want to build shared libs. +if [[ "${shared}" = "yes" ]]; then + echo enable_shared = yes >> temp-frag +else + echo enable_shared = no >> temp-frag +fi + +frag=xhost-mkfrag +${CONFIG_SHELL-/bin/sh} ${libiberty_topdir}/move-if-change temp-frag xhost-mkfrag + +host_makefile_frag=${frag} +AC_SUBST_FILE(host_makefile_frag) + +# It's OK to check for header files. Although the compiler may not be +# able to link anything, it had better be able to at least compile +# something. +AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h) +AC_HEADER_SYS_WAIT +AC_HEADER_TIME + +libiberty_AC_DECLARE_ERRNO + +# Determine the size of an int for struct fibnode. +AC_CHECK_SIZEOF([int]) + +AC_CHECK_TYPE(uintptr_t, unsigned long) + +# Look for a 64-bit type. +AC_MSG_CHECKING([for a 64-bit type]) +AC_CACHE_VAL(liberty_cv_uint64, +[AC_TRY_COMPILE( +[#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif], +[extern uint64_t foo;], +liberty_cv_uint64=uint64_t, +[AC_TRY_COMPILE( +[#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif], +[extern char foo[sizeof(long) * CHAR_BIT >= 64 ? 1 : -1];], +liberty_cv_uint64="unsigned long", +[AC_TRY_COMPILE( +[#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif], +[extern char foo[sizeof(long long) * CHAR_BIT >= 64 ? 1 : -1];], +liberty_cv_uint64="unsigned long long", liberty_cv_uint64=none)])])]) +AC_MSG_RESULT($liberty_cv_uint64) +if test "$liberty_cv_uint64" != none; then + AC_DEFINE_UNQUOTED(UNSIGNED_64BIT_TYPE, $liberty_cv_uint64, + [Define to an unsigned 64-bit type available in the compiler.]) +fi + +# Given the above check, we always have uintptr_t or a fallback +# definition. So define HAVE_UINTPTR_T in case any imported code +# relies on it. +AC_DEFINE(HAVE_UINTPTR_T, 1, [Define if you have the \`uintptr_t' type.]) + +AC_TYPE_PID_T + +# This is the list of functions which libiberty will provide if they +# are not available on the host. + +funcs="asprintf" +funcs="$funcs atexit" +funcs="$funcs basename" +funcs="$funcs bcmp" +funcs="$funcs bcopy" +funcs="$funcs bsearch" +funcs="$funcs bzero" +funcs="$funcs calloc" +funcs="$funcs clock" +funcs="$funcs ffs" +funcs="$funcs getcwd" +funcs="$funcs getpagesize" +funcs="$funcs gettimeofday" +funcs="$funcs index" +funcs="$funcs insque" +funcs="$funcs memchr" +funcs="$funcs memcmp" +funcs="$funcs memcpy" +funcs="$funcs memmove" +funcs="$funcs mempcpy" +funcs="$funcs memset" +funcs="$funcs mkstemps" +funcs="$funcs putenv" +funcs="$funcs random" +funcs="$funcs rename" +funcs="$funcs rindex" +funcs="$funcs setenv" +funcs="$funcs snprintf" +funcs="$funcs sigsetmask" +funcs="$funcs stpcpy" +funcs="$funcs stpncpy" +funcs="$funcs strcasecmp" +funcs="$funcs strchr" +funcs="$funcs strdup" +funcs="$funcs strncasecmp" +funcs="$funcs strndup" +funcs="$funcs strrchr" +funcs="$funcs strstr" +funcs="$funcs strtod" +funcs="$funcs strtol" +funcs="$funcs strtoul" +funcs="$funcs strverscmp" +funcs="$funcs tmpnam" +funcs="$funcs vasprintf" +funcs="$funcs vfprintf" +funcs="$funcs vprintf" +funcs="$funcs vsnprintf" +funcs="$funcs vsprintf" +funcs="$funcs waitpid" + +# Also in the old function.def file: alloca, vfork, getopt. + +vars="sys_errlist sys_nerr sys_siglist" + +checkfuncs="getrusage on_exit psignal strerror strsignal sysconf times sbrk gettimeofday" +checkfuncs="$checkfuncs realpath canonicalize_file_name pstat_getstatic pstat_getdynamic sysmp" +checkfuncs="$checkfuncs getsysinfo table sysctl wait3 wait4 __fsetlocking" + +# These are neither executed nor required, but they help keep +# autoheader happy without adding a bunch of text to acconfig.h. +if test "x" = "y"; then + AC_CHECK_FUNCS(asprintf atexit basename bcmp bcopy bsearch bzero calloc clock \ + getcwd getpagesize gettimeofday index insque mkstemps memchr memcmp memcpy \ + memmove mempcpy memset putenv random rename rindex sigsetmask \ + strcasecmp setenv stpcpy stpncpy strchr strdup strncasecmp strndup strrchr strstr \ + strtod strtol strtoul strverscmp tmpnam vasprintf vfprintf vprintf \ + vsprintf waitpid getrusage on_exit psignal strerror strsignal \ + sysconf times sbrk gettimeofday ffs snprintf vsnprintf \ + pstat_getstatic pstat_getdynamic sysmp getsysinfo table sysctl wait3 wait4 \ + realpath canonicalize_file_name __fsetlocking) + AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf, snprintf, vsnprintf]) + AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.]) + AC_DEFINE(HAVE_SYS_NERR, 1, [Define if you have the sys_nerr variable.]) + AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.]) +fi + +# For each of these functions, if the host does not provide the +# function we want to put FN.o in LIBOBJS, and if the host does +# provide the function, we want to define HAVE_FN in config.h. + +setobjs= +CHECK= +target_header_dir= +if test -n "${with_target_subdir}"; then + + # We are being configured as a target library. AC_REPLACE_FUNCS + # may not work correctly, because the compiler may not be able to + # link executables. Note that we may still be being configured + # native. + + # If we are being configured for newlib, we know which functions + # newlib provide and which ones we will be expected to provide. + + if test "x${with_newlib}" = "xyes"; then + AC_LIBOBJ([asprintf]) + AC_LIBOBJ([basename]) + AC_LIBOBJ([insque]) + AC_LIBOBJ([random]) + AC_LIBOBJ([strdup]) + AC_LIBOBJ([vasprintf]) + + for f in $funcs; do + case "$f" in + asprintf | basename | insque | random | strdup | vasprintf) + ;; + *) + n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + AC_DEFINE_UNQUOTED($n) + ;; + esac + done + + # newlib doesnt provide any of the variables in $vars, so we + # dont have to check them here. + + # Of the functions in $checkfuncs, newlib only has strerror. + AC_DEFINE(HAVE_STRERROR) + + setobjs=yes + + fi + + # We may wish to install the target headers somewhere. + AC_ARG_ENABLE(install-libiberty, + [ --enable-install-libiberty Install headers for end users], + enable_install_libiberty=$enableval, + enable_install_libiberty=no)dnl + + # Option parsed, now set things appropriately. + case x"$enable_install_libiberty" in + xyes|x) + target_header_dir=libiberty + ;; + xno) + target_header_dir= + ;; + *) + # This could be sanity-checked in various ways... + target_header_dir="${enable_install_libiberty}" + ;; + esac + + +else + + # Not a target library, so we set things up to run the test suite. + CHECK=really-check + +fi + +AC_SUBST(CHECK) +AC_SUBST(target_header_dir) + +case "${host}" in + *-*-cygwin* | *-*-mingw*) + AC_DEFINE(HAVE_SYS_ERRLIST) + AC_DEFINE(HAVE_SYS_NERR) + ;; +esac + +if test -z "${setobjs}"; then + case "${host}" in + + *-*-vxworks*) + # Handle VxWorks configuration specially, since on VxWorks the + # libraries are actually on the target board, not in the file + # system. + AC_LIBOBJ([basename]) + AC_LIBOBJ([getpagesize]) + AC_LIBOBJ([insque]) + AC_LIBOBJ([random]) + AC_LIBOBJ([strcasecmp]) + AC_LIBOBJ([strncasecmp]) + AC_LIBOBJ([strdup]) + AC_LIBOBJ([vfork]) + AC_LIBOBJ([waitpid]) + AC_LIBOBJ([vasprintf]) + for f in $funcs; do + case "$f" in + basename | getpagesize | insque | random | strcasecmp) + ;; + strncasecmp | strdup | vfork | waitpid | vasprintf) + ;; + *) + n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + AC_DEFINE_UNQUOTED($n) + ;; + esac + done + + # VxWorks doesn't provide any of the variables in $vars, so we + # don't have to check them here. + + # Of the functions in $checkfuncs, VxWorks only has strerror. + AC_DEFINE(HAVE_STRERROR) + + setobjs=yes + ;; + + esac +fi + +if test -z "${setobjs}"; then + + case "${host}" in + + *-*-cygwin*) + # The Cygwin library actually uses a couple of files from + # libiberty when it is built. If we are building a native + # Cygwin, and we run the tests, we will appear to have these + # files. However, when we go on to build winsup, we will wind up + # with a library which does not have the files, since they should + # have come from libiberty. + + # We handle this by removing the functions the winsup library + # provides from our shell variables, so that they appear to be + # missing. + + # DJ - only if we're *building* cygwin, not just building *with* cygwin + + if test -n "${with_target_subdir}" + then + funcs="`echo $funcs | sed -e 's/random//'`" + AC_LIBOBJ([random]) + vars="`echo $vars | sed -e 's/sys_siglist//'`" + checkfuncs="`echo $checkfuncs | sed -e 's/strsignal//' -e 's/psignal//'`" + fi + ;; + + *-*-mingw32*) + # Under mingw32, sys_nerr and sys_errlist exist, but they are + # macros, so the test below won't find them. + libiberty_cv_var_sys_nerr=yes + libiberty_cv_var_sys_errlist=yes + ;; + + *-*-msdosdjgpp*) + # vfork and fork are stubs. + ac_cv_func_vfork_works=no + ;; + + *-*-uwin*) + # Under some versions of uwin, vfork is notoriously buggy and the test + # can hang configure; on other versions, vfork exists just as a stub. + # FIXME: This should be removed once vfork in uwin's runtime is fixed. + ac_cv_func_vfork_works=no + # Under uwin 2.0+, sys_nerr and sys_errlist exist, but they are + # macros (actually, these are imported from a DLL, but the end effect + # is the same), so the test below won't find them. + libiberty_cv_var_sys_nerr=yes + libiberty_cv_var_sys_errlist=yes + ;; + + *-*-*vms*) + # Under VMS, vfork works very different than on Unix. The standard test + # won't work, and it isn't easily adaptable. It makes more sense to + # just force it. + ac_cv_func_vfork_works=yes + ;; + + esac + + # We haven't set the list of objects yet. Use the standard autoconf + # tests. This will only work if the compiler works. + AC_ISC_POSIX + AC_REPLACE_FUNCS($funcs) + libiberty_AC_FUNC_C_ALLOCA + AC_FUNC_FORK + if test $ac_cv_func_vfork_works = no; then + AC_LIBOBJ([vfork]) + fi + # We only need _doprnt if we might use it to implement v*printf. + if test $ac_cv_func_vprintf != yes \ + || test $ac_cv_func_vfprintf != yes \ + || test $ac_cv_func_vsprintf != yes; then + AC_REPLACE_FUNCS(_doprnt) + else + AC_CHECK_FUNCS(_doprnt) + fi + + for v in $vars; do + AC_MSG_CHECKING([for $v]) + AC_CACHE_VAL(libiberty_cv_var_$v, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[int *p;]],[[extern int $v []; p = $v;]])], + [eval "libiberty_cv_var_$v=yes"], + [eval "libiberty_cv_var_$v=no"])]) + if eval "test \"`echo '$libiberty_cv_var_'$v`\" = yes"; then + AC_MSG_RESULT(yes) + n=HAVE_`echo $v | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + AC_DEFINE_UNQUOTED($n) + else + AC_MSG_RESULT(no) + fi + done + + # special check for _system_configuration because AIX <4.3.2 do not + # contain the `physmem' member. + AC_MSG_CHECKING([for external symbol _system_configuration]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/systemcfg.h>]], + [[double x = _system_configuration.physmem;]])], + [AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE__SYSTEM_CONFIGURATION, 1, + [Define if you have the _system_configuration variable.])], + [AC_MSG_RESULT([no])]) + + AC_CHECK_FUNCS($checkfuncs) + AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf, snprintf, vsnprintf]) + AC_CHECK_DECLS([calloc, getenv, getopt, malloc, realloc, sbrk]) + AC_CHECK_DECLS([strverscmp]) + libiberty_NEED_DECLARATION(canonicalize_file_name) +fi + +# Figure out which version of pexecute to use. +case "${host}" in + *-*-mingw* | *-*-winnt*) pexecute=./pex-win32.o ;; + *-*-msdosdjgpp*) pexecute=./pex-djgpp.o ;; + *-*-msdos*) pexecute=./pex-msdos.o ;; + *) pexecute=./pex-unix.o ;; +esac +AC_SUBST(pexecute) + +libiberty_AC_FUNC_STRNCMP + +# Install a library built with a cross compiler in $(tooldir) rather +# than $(libdir). +if test -z "${with_cross_host}"; then + INSTALL_DEST=libdir +else + INSTALL_DEST=tooldir +fi +AC_SUBST(INSTALL_DEST) + +m4_pattern_allow(LIBOBJS) +L="" +for l in x $LIBOBJS; do + case $l in + x) ;; + *) L="$L ./$l" ;; + esac +done +LIBOBJS="$L" + +dnl Required by html and install-html +AC_SUBST(datarootdir) +AC_SUBST(docdir) +AC_SUBST(htmldir) + +# We need multilib support, but only if configuring for the target. +AC_CONFIG_FILES([Makefile testsuite/Makefile]) +AC_CONFIG_COMMANDS([default], + [[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h +if test -n "$CONFIG_FILES"; then + if test -n "${with_target_subdir}"; then + # FIXME: We shouldn't need to set ac_file + ac_file=Makefile + LD="${ORIGINAL_LD_FOR_MULTILIBS}" + . ${libiberty_topdir}/config-ml.in + fi +fi]], +[[srcdir=${srcdir} +host=${host} +target=${target} +with_target_subdir=${with_target_subdir} +with_multisubdir=${with_multisubdir} +ac_configure_args="--enable-multilib ${ac_configure_args}" +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +ORIGINAL_LD_FOR_MULTILIBS="${ORIGINAL_LD_FOR_MULTILIBS}" +libiberty_topdir=${libiberty_topdir} +]]) +AC_OUTPUT diff --git a/gnu/lib/libiberty/src/copying-lib.texi b/gnu/lib/libiberty/src/copying-lib.texi index 940f70e0d63..79e1038783d 100644 --- a/gnu/lib/libiberty/src/copying-lib.texi +++ b/gnu/lib/libiberty/src/copying-lib.texi @@ -6,7 +6,7 @@ @display Copyright @copyright{} 1991, 1999 Free Software Foundation, Inc. -59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA +51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -544,7 +544,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @end smallexample diff --git a/gnu/lib/libiberty/src/cp-demangle.h b/gnu/lib/libiberty/src/cp-demangle.h new file mode 100644 index 00000000000..2517a57e69b --- /dev/null +++ b/gnu/lib/libiberty/src/cp-demangle.h @@ -0,0 +1,161 @@ +/* Internal demangler interface for g++ V3 ABI. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Written by Ian Lance Taylor <ian@wasabisystems.com>. + + This file is part of the libiberty library, which is part of GCC. + + This file 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 of the License, or + (at your option) any later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combined + executable.) + + 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, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* This file provides some definitions shared by cp-demangle.c and + cp-demint.c. It should not be included by any other files. */ + +/* Information we keep for operators. */ + +struct demangle_operator_info +{ + /* Mangled name. */ + const char *code; + /* Real name. */ + const char *name; + /* Length of real name. */ + int len; + /* Number of arguments. */ + int args; +}; + +/* How to print the value of a builtin type. */ + +enum d_builtin_type_print +{ + /* Print as (type)val. */ + D_PRINT_DEFAULT, + /* Print as integer. */ + D_PRINT_INT, + /* Print as unsigned integer, with trailing "u". */ + D_PRINT_UNSIGNED, + /* Print as long, with trailing "l". */ + D_PRINT_LONG, + /* Print as unsigned long, with trailing "ul". */ + D_PRINT_UNSIGNED_LONG, + /* Print as long long, with trailing "ll". */ + D_PRINT_LONG_LONG, + /* Print as unsigned long long, with trailing "ull". */ + D_PRINT_UNSIGNED_LONG_LONG, + /* Print as bool. */ + D_PRINT_BOOL, + /* Print as float--put value in square brackets. */ + D_PRINT_FLOAT, + /* Print in usual way, but here to detect void. */ + D_PRINT_VOID +}; + +/* Information we keep for a builtin type. */ + +struct demangle_builtin_type_info +{ + /* Type name. */ + const char *name; + /* Length of type name. */ + int len; + /* Type name when using Java. */ + const char *java_name; + /* Length of java name. */ + int java_len; + /* How to print a value of this type. */ + enum d_builtin_type_print print; +}; + +/* The information structure we pass around. */ + +struct d_info +{ + /* The string we are demangling. */ + const char *s; + /* The end of the string we are demangling. */ + const char *send; + /* The options passed to the demangler. */ + int options; + /* The next character in the string to consider. */ + const char *n; + /* The array of components. */ + struct demangle_component *comps; + /* The index of the next available component. */ + int next_comp; + /* The number of available component structures. */ + int num_comps; + /* The array of substitutions. */ + struct demangle_component **subs; + /* The index of the next substitution. */ + int next_sub; + /* The number of available entries in the subs array. */ + int num_subs; + /* The number of substitutions which we actually made from the subs + array, plus the number of template parameter references we + saw. */ + int did_subs; + /* The last name we saw, for constructors and destructors. */ + struct demangle_component *last_name; + /* A running total of the length of large expansions from the + mangled name to the demangled name, such as standard + substitutions and builtin types. */ + int expansion; +}; + +#define d_peek_char(di) (*((di)->n)) +#define d_peek_next_char(di) ((di)->n[1]) +#define d_advance(di, i) ((di)->n += (i)) +#define d_next_char(di) (*((di)->n++)) +#define d_str(di) ((di)->n) + +/* Functions and arrays in cp-demangle.c which are referenced by + functions in cp-demint.c. */ +#ifdef IN_GLIBCPP_V3 +#define CP_STATIC_IF_GLIBCPP_V3 static +#else +#define CP_STATIC_IF_GLIBCPP_V3 extern +#endif + +CP_STATIC_IF_GLIBCPP_V3 +const struct demangle_operator_info cplus_demangle_operators[]; + +#define D_BUILTIN_TYPE_COUNT (26) + +CP_STATIC_IF_GLIBCPP_V3 +const struct demangle_builtin_type_info +cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT]; + +CP_STATIC_IF_GLIBCPP_V3 +struct demangle_component * +cplus_demangle_mangled_name (struct d_info *, int); + +CP_STATIC_IF_GLIBCPP_V3 +struct demangle_component * +cplus_demangle_type (struct d_info *); + +extern void +cplus_demangle_init_info (const char *, int, size_t, struct d_info *); + +/* cp-demangle.c needs to define this a little differently */ +#undef CP_STATIC_IF_GLIBCPP_V3 diff --git a/gnu/lib/libiberty/src/cp-demint.c b/gnu/lib/libiberty/src/cp-demint.c new file mode 100644 index 00000000000..2e8f8d2d057 --- /dev/null +++ b/gnu/lib/libiberty/src/cp-demint.c @@ -0,0 +1,234 @@ +/* Demangler component interface functions. + Copyright (C) 2004 Free Software Foundation, Inc. + Written by Ian Lance Taylor <ian@wasabisystems.com>. + + This file is part of the libiberty library, which is part of GCC. + + This file 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 of the License, or + (at your option) any later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combined + executable.) + + 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, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* This file implements a few interface functions which are provided + for use with struct demangle_component trees. These functions are + declared in demangle.h. These functions are closely tied to the + demangler code in cp-demangle.c, and other interface functions can + be found in that file. We put these functions in a separate file + because they are not needed by the demangler, and so we avoid + having them pulled in by programs which only need the + demangler. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#include "ansidecl.h" +#include "libiberty.h" +#include "demangle.h" +#include "cp-demangle.h" + +/* Fill in most component types. */ + +int +cplus_demangle_fill_component (struct demangle_component *p, + enum demangle_component_type type, + struct demangle_component *left, + struct demangle_component *right) +{ + if (p == NULL) + return 0; + switch (type) + { + case DEMANGLE_COMPONENT_QUAL_NAME: + case DEMANGLE_COMPONENT_LOCAL_NAME: + case DEMANGLE_COMPONENT_TYPED_NAME: + case DEMANGLE_COMPONENT_TEMPLATE: + case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE: + case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: + case DEMANGLE_COMPONENT_FUNCTION_TYPE: + case DEMANGLE_COMPONENT_ARRAY_TYPE: + case DEMANGLE_COMPONENT_PTRMEM_TYPE: + case DEMANGLE_COMPONENT_ARGLIST: + case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: + case DEMANGLE_COMPONENT_UNARY: + case DEMANGLE_COMPONENT_BINARY: + case DEMANGLE_COMPONENT_BINARY_ARGS: + case DEMANGLE_COMPONENT_TRINARY: + case DEMANGLE_COMPONENT_TRINARY_ARG1: + case DEMANGLE_COMPONENT_TRINARY_ARG2: + case DEMANGLE_COMPONENT_LITERAL: + case DEMANGLE_COMPONENT_LITERAL_NEG: + break; + + /* These component types only have one subtree. */ + case DEMANGLE_COMPONENT_VTABLE: + case DEMANGLE_COMPONENT_VTT: + case DEMANGLE_COMPONENT_TYPEINFO: + case DEMANGLE_COMPONENT_TYPEINFO_NAME: + case DEMANGLE_COMPONENT_TYPEINFO_FN: + case DEMANGLE_COMPONENT_THUNK: + case DEMANGLE_COMPONENT_VIRTUAL_THUNK: + case DEMANGLE_COMPONENT_COVARIANT_THUNK: + case DEMANGLE_COMPONENT_JAVA_CLASS: + case DEMANGLE_COMPONENT_GUARD: + case DEMANGLE_COMPONENT_REFTEMP: + case DEMANGLE_COMPONENT_RESTRICT: + case DEMANGLE_COMPONENT_VOLATILE: + case DEMANGLE_COMPONENT_CONST: + case DEMANGLE_COMPONENT_RESTRICT_THIS: + case DEMANGLE_COMPONENT_VOLATILE_THIS: + case DEMANGLE_COMPONENT_CONST_THIS: + case DEMANGLE_COMPONENT_POINTER: + case DEMANGLE_COMPONENT_REFERENCE: + case DEMANGLE_COMPONENT_COMPLEX: + case DEMANGLE_COMPONENT_IMAGINARY: + case DEMANGLE_COMPONENT_VENDOR_TYPE: + case DEMANGLE_COMPONENT_CAST: + if (right != NULL) + return 0; + break; + + default: + /* Other types do not use subtrees. */ + return 0; + } + + p->type = type; + p->u.s_binary.left = left; + p->u.s_binary.right = right; + + return 1; +} + +/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE. */ + +int +cplus_demangle_fill_builtin_type (struct demangle_component *p, + const char *type_name) +{ + int len; + unsigned int i; + + if (p == NULL || type_name == NULL) + return 0; + len = strlen (type_name); + for (i = 0; i < D_BUILTIN_TYPE_COUNT; ++i) + { + if (len == cplus_demangle_builtin_types[i].len + && strcmp (type_name, cplus_demangle_builtin_types[i].name) == 0) + { + p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE; + p->u.s_builtin.type = &cplus_demangle_builtin_types[i]; + return 1; + } + } + return 0; +} + +/* Fill in a DEMANGLE_COMPONENT_OPERATOR. */ + +int +cplus_demangle_fill_operator (struct demangle_component *p, + const char *opname, int args) +{ + int len; + unsigned int i; + + if (p == NULL || opname == NULL) + return 0; + len = strlen (opname); + for (i = 0; cplus_demangle_operators[i].name != NULL; ++i) + { + if (len == cplus_demangle_operators[i].len + && args == cplus_demangle_operators[i].args + && strcmp (opname, cplus_demangle_operators[i].name) == 0) + { + p->type = DEMANGLE_COMPONENT_OPERATOR; + p->u.s_operator.op = &cplus_demangle_operators[i]; + return 1; + } + } + return 0; +} + +/* Translate a mangled name into components. */ + +struct demangle_component * +cplus_demangle_v3_components (const char *mangled, int options, void **mem) +{ + size_t len; + int type; + struct d_info di; + struct demangle_component *dc; + + len = strlen (mangled); + + if (mangled[0] == '_' && mangled[1] == 'Z') + type = 0; + else + { + if ((options & DMGL_TYPES) == 0) + return NULL; + type = 1; + } + + cplus_demangle_init_info (mangled, options, len, &di); + + di.comps = ((struct demangle_component *) + malloc (di.num_comps * sizeof (struct demangle_component))); + di.subs = ((struct demangle_component **) + malloc (di.num_subs * sizeof (struct demangle_component *))); + if (di.comps == NULL || di.subs == NULL) + { + if (di.comps != NULL) + free (di.comps); + if (di.subs != NULL) + free (di.subs); + return NULL; + } + + if (! type) + dc = cplus_demangle_mangled_name (&di, 1); + else + dc = cplus_demangle_type (&di); + + /* If DMGL_PARAMS is set, then if we didn't consume the entire + mangled string, then we didn't successfully demangle it. */ + if ((options & DMGL_PARAMS) != 0 && d_peek_char (&di) != '\0') + dc = NULL; + + free (di.subs); + + if (dc != NULL) + *mem = di.comps; + else + free (di.comps); + + return dc; +} diff --git a/gnu/lib/libiberty/src/fdmatch.c b/gnu/lib/libiberty/src/fdmatch.c index 979c214d5d4..f613cb3c01e 100644 --- a/gnu/lib/libiberty/src/fdmatch.c +++ b/gnu/lib/libiberty/src/fdmatch.c @@ -14,8 +14,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -41,14 +41,15 @@ BUGS */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "ansidecl.h" #include "libiberty.h" #include <sys/types.h> #include <sys/stat.h> -int fdmatch (fd1, fd2) - int fd1; - int fd2; +int fdmatch (int fd1, int fd2) { struct stat sbuf1; struct stat sbuf2; diff --git a/gnu/lib/libiberty/src/ffs.c b/gnu/lib/libiberty/src/ffs.c index de047e217eb..603cbe8ed99 100644 --- a/gnu/lib/libiberty/src/ffs.c +++ b/gnu/lib/libiberty/src/ffs.c @@ -11,8 +11,7 @@ value 1). If @var{valu} is zero, zero is returned. */ int -ffs (valu) - register int valu; +ffs (register int valu) { register int bit; diff --git a/gnu/lib/libiberty/src/fibheap.c b/gnu/lib/libiberty/src/fibheap.c index 36062d451a2..c032149c0c2 100644 --- a/gnu/lib/libiberty/src/fibheap.c +++ b/gnu/lib/libiberty/src/fibheap.c @@ -16,8 +16,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -37,32 +37,31 @@ Boston, MA 02111-1307, USA. */ #define FIBHEAPKEY_MIN LONG_MIN -static void fibheap_ins_root PARAMS ((fibheap_t, fibnode_t)); -static void fibheap_rem_root PARAMS ((fibheap_t, fibnode_t)); -static void fibheap_consolidate PARAMS ((fibheap_t)); -static void fibheap_link PARAMS ((fibheap_t, fibnode_t, fibnode_t)); -static void fibheap_cut PARAMS ((fibheap_t, fibnode_t, fibnode_t)); -static void fibheap_cascading_cut PARAMS ((fibheap_t, fibnode_t)); -static fibnode_t fibheap_extr_min_node PARAMS ((fibheap_t)); -static int fibheap_compare PARAMS ((fibheap_t, fibnode_t, fibnode_t)); -static int fibheap_comp_data PARAMS ((fibheap_t, fibheapkey_t, void *, - fibnode_t)); -static fibnode_t fibnode_new PARAMS ((void)); -static void fibnode_insert_after PARAMS ((fibnode_t, fibnode_t)); +static void fibheap_ins_root (fibheap_t, fibnode_t); +static void fibheap_rem_root (fibheap_t, fibnode_t); +static void fibheap_consolidate (fibheap_t); +static void fibheap_link (fibheap_t, fibnode_t, fibnode_t); +static void fibheap_cut (fibheap_t, fibnode_t, fibnode_t); +static void fibheap_cascading_cut (fibheap_t, fibnode_t); +static fibnode_t fibheap_extr_min_node (fibheap_t); +static int fibheap_compare (fibheap_t, fibnode_t, fibnode_t); +static int fibheap_comp_data (fibheap_t, fibheapkey_t, void *, fibnode_t); +static fibnode_t fibnode_new (void); +static void fibnode_insert_after (fibnode_t, fibnode_t); #define fibnode_insert_before(a, b) fibnode_insert_after (a->left, b) -static fibnode_t fibnode_remove PARAMS ((fibnode_t)); +static fibnode_t fibnode_remove (fibnode_t); /* Create a new fibonacci heap. */ fibheap_t -fibheap_new () +fibheap_new (void) { return (fibheap_t) xcalloc (1, sizeof (struct fibheap)); } /* Create a new fibonacci heap node. */ static fibnode_t -fibnode_new () +fibnode_new (void) { fibnode_t node; @@ -74,10 +73,7 @@ fibnode_new () } static inline int -fibheap_compare (heap, a, b) - fibheap_t heap ATTRIBUTE_UNUSED; - fibnode_t a; - fibnode_t b; +fibheap_compare (fibheap_t heap ATTRIBUTE_UNUSED, fibnode_t a, fibnode_t b) { if (a->key < b->key) return -1; @@ -87,11 +83,7 @@ fibheap_compare (heap, a, b) } static inline int -fibheap_comp_data (heap, key, data, b) - fibheap_t heap; - fibheapkey_t key; - void *data; - fibnode_t b; +fibheap_comp_data (fibheap_t heap, fibheapkey_t key, void *data, fibnode_t b) { struct fibnode a; @@ -103,10 +95,7 @@ fibheap_comp_data (heap, key, data, b) /* Insert DATA, with priority KEY, into HEAP. */ fibnode_t -fibheap_insert (heap, key, data) - fibheap_t heap; - fibheapkey_t key; - void *data; +fibheap_insert (fibheap_t heap, fibheapkey_t key, void *data) { fibnode_t node; @@ -132,8 +121,7 @@ fibheap_insert (heap, key, data) /* Return the data of the minimum node (if we know it). */ void * -fibheap_min (heap) - fibheap_t heap; +fibheap_min (fibheap_t heap) { /* If there is no min, we can't easily return it. */ if (heap->min == NULL) @@ -143,8 +131,7 @@ fibheap_min (heap) /* Return the key of the minimum node (if we know it). */ fibheapkey_t -fibheap_min_key (heap) - fibheap_t heap; +fibheap_min_key (fibheap_t heap) { /* If there is no min, we can't easily return it. */ if (heap->min == NULL) @@ -154,9 +141,7 @@ fibheap_min_key (heap) /* Union HEAPA and HEAPB into a new heap. */ fibheap_t -fibheap_union (heapa, heapb) - fibheap_t heapa; - fibheap_t heapb; +fibheap_union (fibheap_t heapa, fibheap_t heapb) { fibnode_t a_root, b_root, temp; @@ -190,8 +175,7 @@ fibheap_union (heapa, heapb) /* Extract the data of the minimum node from HEAP. */ void * -fibheap_extract_min (heap) - fibheap_t heap; +fibheap_extract_min (fibheap_t heap) { fibnode_t z; void *ret = NULL; @@ -211,14 +195,11 @@ fibheap_extract_min (heap) /* Replace both the KEY and the DATA associated with NODE. */ void * -fibheap_replace_key_data (heap, node, key, data) - fibheap_t heap; - fibnode_t node; - fibheapkey_t key; - void *data; +fibheap_replace_key_data (fibheap_t heap, fibnode_t node, + fibheapkey_t key, void *data) { void *odata; - int okey; + fibheapkey_t okey; fibnode_t y; /* If we wanted to, we could actually do a real increase by redeleting and @@ -253,20 +234,14 @@ fibheap_replace_key_data (heap, node, key, data) /* Replace the DATA associated with NODE. */ void * -fibheap_replace_data (heap, node, data) - fibheap_t heap; - fibnode_t node; - void *data; +fibheap_replace_data (fibheap_t heap, fibnode_t node, void *data) { return fibheap_replace_key_data (heap, node, node->key, data); } /* Replace the KEY associated with NODE. */ fibheapkey_t -fibheap_replace_key (heap, node, key) - fibheap_t heap; - fibnode_t node; - fibheapkey_t key; +fibheap_replace_key (fibheap_t heap, fibnode_t node, fibheapkey_t key) { int okey = node->key; fibheap_replace_key_data (heap, node, key, node->data); @@ -275,9 +250,7 @@ fibheap_replace_key (heap, node, key) /* Delete NODE from HEAP. */ void * -fibheap_delete_node (heap, node) - fibheap_t heap; - fibnode_t node; +fibheap_delete_node (fibheap_t heap, fibnode_t node) { void *ret = node->data; @@ -290,8 +263,7 @@ fibheap_delete_node (heap, node) /* Delete HEAP. */ void -fibheap_delete (heap) - fibheap_t heap; +fibheap_delete (fibheap_t heap) { while (heap->min != NULL) free (fibheap_extr_min_node (heap)); @@ -301,16 +273,14 @@ fibheap_delete (heap) /* Determine if HEAP is empty. */ int -fibheap_empty (heap) - fibheap_t heap; +fibheap_empty (fibheap_t heap) { return heap->nodes == 0; } /* Extract the minimum node of the heap. */ static fibnode_t -fibheap_extr_min_node (heap) - fibheap_t heap; +fibheap_extr_min_node (fibheap_t heap) { fibnode_t ret = heap->min; fibnode_t x, y, orig; @@ -346,9 +316,7 @@ fibheap_extr_min_node (heap) /* Insert NODE into the root list of HEAP. */ static void -fibheap_ins_root (heap, node) - fibheap_t heap; - fibnode_t node; +fibheap_ins_root (fibheap_t heap, fibnode_t node) { /* If the heap is currently empty, the new node becomes the singleton circular root list. */ @@ -367,9 +335,7 @@ fibheap_ins_root (heap, node) /* Remove NODE from the rootlist of HEAP. */ static void -fibheap_rem_root (heap, node) - fibheap_t heap; - fibnode_t node; +fibheap_rem_root (fibheap_t heap, fibnode_t node) { if (node->left == node) heap->root = NULL; @@ -379,8 +345,7 @@ fibheap_rem_root (heap, node) /* Consolidate the heap. */ static void -fibheap_consolidate (heap) - fibheap_t heap; +fibheap_consolidate (fibheap_t heap) { fibnode_t a[1 + 8 * sizeof (long)]; fibnode_t w; @@ -427,10 +392,8 @@ fibheap_consolidate (heap) /* Make NODE a child of PARENT. */ static void -fibheap_link (heap, node, parent) - fibheap_t heap ATTRIBUTE_UNUSED; - fibnode_t node; - fibnode_t parent; +fibheap_link (fibheap_t heap ATTRIBUTE_UNUSED, + fibnode_t node, fibnode_t parent) { if (parent->child == NULL) parent->child = node; @@ -443,10 +406,7 @@ fibheap_link (heap, node, parent) /* Remove NODE from PARENT's child list. */ static void -fibheap_cut (heap, node, parent) - fibheap_t heap; - fibnode_t node; - fibnode_t parent; +fibheap_cut (fibheap_t heap, fibnode_t node, fibnode_t parent) { fibnode_remove (node); parent->degree--; @@ -456,9 +416,7 @@ fibheap_cut (heap, node, parent) } static void -fibheap_cascading_cut (heap, y) - fibheap_t heap; - fibnode_t y; +fibheap_cascading_cut (fibheap_t heap, fibnode_t y) { fibnode_t z; @@ -478,9 +436,7 @@ fibheap_cascading_cut (heap, y) } static void -fibnode_insert_after (a, b) - fibnode_t a; - fibnode_t b; +fibnode_insert_after (fibnode_t a, fibnode_t b) { if (a == a->right) { @@ -499,8 +455,7 @@ fibnode_insert_after (a, b) } static fibnode_t -fibnode_remove (node) - fibnode_t node; +fibnode_remove (fibnode_t node) { fibnode_t ret; diff --git a/gnu/lib/libiberty/src/fopen_unlocked.c b/gnu/lib/libiberty/src/fopen_unlocked.c new file mode 100644 index 00000000000..3c3cefed76b --- /dev/null +++ b/gnu/lib/libiberty/src/fopen_unlocked.c @@ -0,0 +1,126 @@ +/* Implement fopen_unlocked and related functions. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* + +@deftypefn Extension void unlock_stream (FILE * @var{stream}) + +If the OS supports it, ensure that the supplied stream is setup to +avoid any multi-threaded locking. Otherwise leave the @code{FILE} +pointer unchanged. If the @var{stream} is @code{NULL} do nothing. + +@end deftypefn + +@deftypefn Extension void unlock_std_streams (void) + +If the OS supports it, ensure that the standard I/O streams, +@code{stdin}, @code{stdout} and @code{stderr} are setup to avoid any +multi-threaded locking. Otherwise do nothing. + +@end deftypefn + +@deftypefn Extension {FILE *} fopen_unlocked (const char *@var{path}, const char * @var{mode}) + +Opens and returns a @code{FILE} pointer via @code{fopen}. If the +operating system supports it, ensure that the stream is setup to avoid +any multi-threaded locking. Otherwise return the @code{FILE} pointer +unchanged. + +@end deftypefn + +@deftypefn Extension {FILE *} fdopen_unlocked (int @var{fildes}, const char * @var{mode}) + +Opens and returns a @code{FILE} pointer via @code{fdopen}. If the +operating system supports it, ensure that the stream is setup to avoid +any multi-threaded locking. Otherwise return the @code{FILE} pointer +unchanged. + +@end deftypefn + +@deftypefn Extension {FILE *} freopen_unlocked (const char * @var{path}, const char * @var{mode}, FILE * @var{stream}) + +Opens and returns a @code{FILE} pointer via @code{freopen}. If the +operating system supports it, ensure that the stream is setup to avoid +any multi-threaded locking. Otherwise return the @code{FILE} pointer +unchanged. + +@end deftypefn + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <stdio.h> +#ifdef HAVE_STDIO_EXT_H +#include <stdio_ext.h> +#endif + +#include "libiberty.h" + +/* This is an inline helper function to consolidate attempts to unlock + a stream. */ + +static inline void +unlock_1 (FILE *const fp ATTRIBUTE_UNUSED) +{ +#if defined(HAVE___FSETLOCKING) && defined(FSETLOCKING_BYCALLER) + if (fp) + __fsetlocking (fp, FSETLOCKING_BYCALLER); +#endif +} + +void +unlock_stream (FILE *fp) +{ + unlock_1 (fp); +} + +void +unlock_std_streams (void) +{ + unlock_1 (stdin); + unlock_1 (stdout); + unlock_1 (stderr); +} + +FILE * +fopen_unlocked (const char *path, const char *mode) +{ + FILE *const fp = fopen (path, mode); + unlock_1 (fp); + return fp; +} + +FILE * +fdopen_unlocked (int fildes, const char *mode) +{ + FILE *const fp = fdopen (fildes, mode); + unlock_1 (fp); + return fp; +} + +FILE * +freopen_unlocked (const char *path, const char *mode, FILE *stream) +{ + FILE *const fp = freopen (path, mode, stream); + unlock_1 (fp); + return fp; +} diff --git a/gnu/lib/libiberty/src/gather-docs b/gnu/lib/libiberty/src/gather-docs index b272c02ef2a..be4dbbfc1e2 100644 --- a/gnu/lib/libiberty/src/gather-docs +++ b/gnu/lib/libiberty/src/gather-docs @@ -17,8 +17,8 @@ # # You should have received a copy of the GNU Library General Public # License along with libiberty; see the file COPYING.LIB. If not, -# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. +# write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +# Boston, MA 02110-1301, USA. # # Originally written by DJ Delorie <dj@redhat.com> diff --git a/gnu/lib/libiberty/src/getopt.c b/gnu/lib/libiberty/src/getopt.c index a1e482763c1..d9c3532ce11 100644 --- a/gnu/lib/libiberty/src/getopt.c +++ b/gnu/lib/libiberty/src/getopt.c @@ -3,8 +3,8 @@ "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! - Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 - Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 2005 Free Software Foundation, Inc. NOTE: This source is derived from an old version taken from the GNU C Library (glibc). @@ -21,7 +21,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. @@ -42,6 +42,7 @@ # endif #endif +#include "ansidecl.h" #include <stdio.h> /* Comment out all this code if we are using the GNU C Library, and are not @@ -212,14 +213,20 @@ static char *posixly_correct; /* Avoid depending on library functions or files whose names are inconsistent. */ -#ifndef getenv -extern char *getenv (); +#if HAVE_STDLIB_H && HAVE_DECL_GETENV +# include <stdlib.h> +#elif !defined(getenv) +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ +extern char *getenv (const char *); +# ifdef __cplusplus +} +# endif /* __cplusplus */ #endif static char * -my_index (str, chr) - const char *str; - int chr; +my_index (const char *str, int chr) { while (*str) { @@ -307,8 +314,7 @@ static void exchange (char **); #endif static void -exchange (argv) - char **argv; +exchange (char **argv) { int bottom = first_nonopt; int middle = last_nonopt; @@ -328,7 +334,7 @@ exchange (argv) { /* We must extend the array. The user plays games with us and presents new arguments. */ - char *new_str = malloc (top + 1); + char *new_str = (char *) malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else @@ -392,10 +398,9 @@ exchange (argv) static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +_getopt_initialize (int argc ATTRIBUTE_UNUSED, + char *const *argv ATTRIBUTE_UNUSED, + const char *optstring) { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped @@ -514,13 +519,9 @@ _getopt_initialize (argc, argv, optstring) long-named options. */ int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; +_getopt_internal (int argc, char *const *argv, const char *optstring, + const struct option *longopts, + int *longind, int long_only) { optarg = NULL; @@ -970,10 +971,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) } int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +getopt (int argc, char *const *argv, const char *optstring) { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, @@ -989,9 +987,7 @@ getopt (argc, argv, optstring) the above definition of `getopt'. */ int -main (argc, argv) - int argc; - char **argv; +main (int argc, char **argv) { int c; int digit_optind = 0; diff --git a/gnu/lib/libiberty/src/getopt1.c b/gnu/lib/libiberty/src/getopt1.c index a3637c2d0e0..255b1445637 100644 --- a/gnu/lib/libiberty/src/getopt1.c +++ b/gnu/lib/libiberty/src/getopt1.c @@ -1,5 +1,5 @@ /* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2005 Free Software Foundation, Inc. NOTE: This source is derived from an old version taken from the GNU C @@ -17,15 +17,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include "getopt.h" - #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ @@ -36,6 +34,8 @@ #include <stdio.h> +#include "getopt.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 @@ -66,12 +66,8 @@ #endif int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } @@ -82,12 +78,8 @@ getopt_long (argc, argv, options, long_options, opt_index) instead. */ int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +getopt_long_only (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } @@ -100,9 +92,7 @@ getopt_long_only (argc, argv, options, long_options, opt_index) #include <stdio.h> int -main (argc, argv) - int argc; - char **argv; +main (int argc, char **argv) { int c; int digit_optind = 0; diff --git a/gnu/lib/libiberty/src/getpagesize.c b/gnu/lib/libiberty/src/getpagesize.c index eed9680378a..1c3a26304ea 100644 --- a/gnu/lib/libiberty/src/getpagesize.c +++ b/gnu/lib/libiberty/src/getpagesize.c @@ -61,7 +61,7 @@ BUGS #endif /* GNU_OUR_PAGESIZE */ int -getpagesize () +getpagesize (void) { return (GNU_OUR_PAGESIZE); } @@ -76,7 +76,7 @@ getpagesize () #endif extern unsigned long lib$getsyi(const unsigned short *,...); -int getpagesize () +int getpagesize (void) { long pagsiz = 0L; unsigned short itmcod = SYI$_PAGE_SIZE; diff --git a/gnu/lib/libiberty/src/getpwd.c b/gnu/lib/libiberty/src/getpwd.c index f508b1e21e5..fa5c132fd6b 100644 --- a/gnu/lib/libiberty/src/getpwd.c +++ b/gnu/lib/libiberty/src/getpwd.c @@ -35,10 +35,9 @@ extern int errno; #if HAVE_SYS_STAT_H #include <sys/stat.h> #endif - -/* Prototype these in case the system headers don't provide them. */ -extern char *getpwd (); -extern char *getwd (); +#if HAVE_LIMITS_H +#include <limits.h> +#endif #include "libiberty.h" @@ -47,6 +46,8 @@ extern char *getwd (); the few exceptions to the general rule here. */ #if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) +/* Prototype in case the system headers doesn't provide it. */ +extern char *getwd (); #define getcwd(buf,len) getwd(buf) #endif @@ -64,7 +65,7 @@ extern char *getwd (); yield 0 and set errno. */ char * -getpwd () +getpwd (void) { static char *pwd; static int failure_errno; @@ -83,7 +84,7 @@ getpwd () && dotstat.st_dev == pwdstat.st_dev)) /* The shortcut didn't work. Try the slow, ``sure'' way. */ - for (s = GUESSPATHLEN; ! getcwd (p = xmalloc (s), s); s *= 2) + for (s = GUESSPATHLEN; !getcwd (p = XNEWVEC (char, s), s); s *= 2) { int e = errno; free (p); @@ -111,12 +112,12 @@ getpwd () #endif char * -getpwd () +getpwd (void) { static char *pwd = 0; if (!pwd) - pwd = getcwd (xmalloc (MAXPATHLEN + 1), MAXPATHLEN + 1 + pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1 #ifdef VMS , 0 #endif diff --git a/gnu/lib/libiberty/src/gettimeofday.c b/gnu/lib/libiberty/src/gettimeofday.c new file mode 100644 index 00000000000..fca16794028 --- /dev/null +++ b/gnu/lib/libiberty/src/gettimeofday.c @@ -0,0 +1,30 @@ +#include "config.h" +#include "libiberty.h" +#ifdef HAVE_TIME_H +#include <time.h> +#endif +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +/* + +@deftypefn Supplemental int gettimeofday (struct timeval *@var{tp}, void *@var{tz}) + +Writes the current time to @var{tp}. This implementation requires +that @var{tz} be NULL. Returns 0 on success, -1 on failure. + +@end deftypefn + +*/ + +int +gettimeofday (struct timeval *tp, void *tz) +{ + if (tz) + abort (); + tp->tv_usec = 0; + if (time (&tp->tv_sec) == (time_t) -1) + return -1; + return 0; +} diff --git a/gnu/lib/libiberty/src/hex.c b/gnu/lib/libiberty/src/hex.c index 5f822925349..86ba0b5b872 100644 --- a/gnu/lib/libiberty/src/hex.c +++ b/gnu/lib/libiberty/src/hex.c @@ -14,11 +14,19 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #include <stdio.h> /* for EOF */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "libiberty.h" +#include "safe-ctype.h" /* for HOST_CHARSET_ASCII */ + +#if EOF != -1 + #error "hex.c requires EOF == -1" +#endif /* @@ -39,13 +47,19 @@ or zero if it is not. Note that the value you pass will be cast to @end deftypefn -@deftypefn Extension int hex_value (int @var{c}) +@deftypefn Extension {unsigned int} hex_value (int @var{c}) Returns the numeric equivalent of the given character when interpreted as a hexidecimal digit. The result is undefined if you pass an invalid hex digit. Note that the value you pass will be cast to @code{unsigned char} within the macro. +The @code{hex_value} macro returns @code{unsigned int}, rather than +signed @code{int}, to make it easier to use in parsing addresses from +hex dump files: a signed @code{int} would be sign-extended when +converted to a wider unsigned type --- like @code{bfd_vma}, on some +systems. + @end deftypefn @undocumented _hex_array_size @@ -56,11 +70,9 @@ invalid hex digit. Note that the value you pass will be cast to /* Are we ASCII? */ -#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ - && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 \ - && EOF == -1 +#if HOST_CHARSET == HOST_CHARSET_ASCII -const char _hex_value[_hex_array_size] = +const unsigned char _hex_value[_hex_array_size] = { _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* NUL SOH STX ETX */ _hex_bad, _hex_bad, _hex_bad, _hex_bad, /* EOT ENQ ACK BEL */ @@ -139,12 +151,12 @@ const char _hex_value[_hex_array_size] = #else -char _hex_value[_hex_array_size]; +unsigned char _hex_value[_hex_array_size]; #endif /* not ASCII */ void -hex_init () +hex_init (void) { #ifndef HEX_TABLE_INITIALIZED int i; diff --git a/gnu/lib/libiberty/src/index.c b/gnu/lib/libiberty/src/index.c index a2e272783b9..acd0a45fc02 100644 --- a/gnu/lib/libiberty/src/index.c +++ b/gnu/lib/libiberty/src/index.c @@ -12,12 +12,10 @@ deprecated in new programs in favor of @code{strchr}. */ -extern char * strchr(); +extern char * strchr(const char *, int); char * -index (s, c) - char *s; - int c; +index (const char *s, int c) { return strchr (s, c); } diff --git a/gnu/lib/libiberty/src/insque.c b/gnu/lib/libiberty/src/insque.c index c0c1180d421..3473bb92b31 100644 --- a/gnu/lib/libiberty/src/insque.c +++ b/gnu/lib/libiberty/src/insque.c @@ -33,9 +33,7 @@ struct qelem { void -insque (elem, pred) - struct qelem *elem; - struct qelem *pred; +insque (struct qelem *elem, struct qelem *pred) { elem -> q_forw = pred -> q_forw; pred -> q_forw -> q_back = elem; @@ -45,8 +43,7 @@ insque (elem, pred) void -remque (elem) - struct qelem *elem; +remque (struct qelem *elem) { elem -> q_forw -> q_back = elem -> q_back; elem -> q_back -> q_forw = elem -> q_forw; diff --git a/gnu/lib/libiberty/src/lbasename.c b/gnu/lib/libiberty/src/lbasename.c index 43cb73f0a1d..56fcd625072 100644 --- a/gnu/lib/libiberty/src/lbasename.c +++ b/gnu/lib/libiberty/src/lbasename.c @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -37,32 +37,16 @@ and a path ending in @code{/} returns the empty string after it. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "ansidecl.h" #include "libiberty.h" #include "safe-ctype.h" - -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) \ - || defined (__DJGPP__) || defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif +#include "filenames.h" const char * -lbasename (name) - const char *name; +lbasename (const char *name) { const char *base; diff --git a/gnu/lib/libiberty/src/libiberty.texi b/gnu/lib/libiberty/src/libiberty.texi index b57e3c530e1..d3701e69dfa 100644 --- a/gnu/lib/libiberty/src/libiberty.texi +++ b/gnu/lib/libiberty/src/libiberty.texi @@ -315,7 +315,7 @@ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -@node Index +@node Index @unnumbered Index @printindex cp diff --git a/gnu/lib/libiberty/src/lrealpath.c b/gnu/lib/libiberty/src/lrealpath.c index b001b38ef66..b27c8de990e 100644 --- a/gnu/lib/libiberty/src/lrealpath.c +++ b/gnu/lib/libiberty/src/lrealpath.c @@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ /* @@ -64,11 +64,16 @@ extern char *canonicalize_file_name (const char *); # define REALPATH_LIMIT MAXPATHLEN # endif # endif +#else + /* cygwin has realpath, so it won't get here. */ +# if defined (_WIN32) +# define WIN32_LEAN_AND_MEAN +# include <windows.h> /* for GetFullPathName */ +# endif #endif char * -lrealpath (filename) - const char *filename; +lrealpath (const char *filename) { /* Method 1: The system has a compile time upper bound on a filename path. Use that and realpath() to canonicalize the name. This is @@ -112,7 +117,7 @@ lrealpath (filename) { /* PATH_MAX is bounded. */ char *buf, *rp, *ret; - buf = malloc (path_max); + buf = (char *) malloc (path_max); if (buf == NULL) return NULL; rp = realpath (filename, buf); @@ -123,6 +128,30 @@ lrealpath (filename) } #endif + /* The MS Windows method. If we don't have realpath, we assume we + don't have symlinks and just canonicalize to a Windows absolute + path. GetFullPath converts ../ and ./ in relative paths to + absolute paths, filling in current drive if one is not given + or using the current directory of a specified drive (eg, "E:foo"). + It also converts all forward slashes to back slashes. */ +#if defined (_WIN32) + { + char buf[MAX_PATH]; + char* basename; + DWORD len = GetFullPathName (filename, MAX_PATH, buf, &basename); + if (len == 0 || len > MAX_PATH - 1) + return strdup (filename); + else + { + /* The file system is case-preserving but case-insensitive, + Canonicalize to lowercase, using the codepage associated + with the process locale. */ + CharLowerBuff (buf, len); + return strdup (buf); + } + } +#endif + /* This system is a lost cause, just duplicate the filename. */ return strdup (filename); } diff --git a/gnu/lib/libiberty/src/make-relative-prefix.c b/gnu/lib/libiberty/src/make-relative-prefix.c index dc4f8d5259d..66ddcaa471b 100644 --- a/gnu/lib/libiberty/src/make-relative-prefix.c +++ b/gnu/lib/libiberty/src/make-relative-prefix.c @@ -16,8 +16,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA +02110-1301, USA. */ /* @@ -95,16 +95,14 @@ relative prefix can be found, return @code{NULL}. #define DIR_UP ".." -static char *save_string PARAMS ((const char *, int)); -static char **split_directories PARAMS ((const char *, int *)); -static void free_split_directories PARAMS ((char **)); +static char *save_string (const char *, int); +static char **split_directories (const char *, int *); +static void free_split_directories (char **); static char * -save_string (s, len) - const char *s; - int len; +save_string (const char *s, int len) { - char *result = malloc (len + 1); + char *result = (char *) malloc (len + 1); memcpy (result, s, len); result[len] = 0; @@ -114,9 +112,7 @@ save_string (s, len) /* Split a filename into component directories. */ static char ** -split_directories (name, ptr_num_dirs) - const char *name; - int *ptr_num_dirs; +split_directories (const char *name, int *ptr_num_dirs) { int num_dirs = 0; char **dirs; @@ -201,8 +197,7 @@ split_directories (name, ptr_num_dirs) /* Release storage held by split directories. */ static void -free_split_directories (dirs) - char **dirs; +free_split_directories (char **dirs) { int i = 0; @@ -223,10 +218,8 @@ free_split_directories (dirs) If no relative prefix can be found, return NULL. */ char * -make_relative_prefix (progname, bin_prefix, prefix) - const char *progname; - const char *bin_prefix; - const char *prefix; +make_relative_prefix (const char *progname, + const char *bin_prefix, const char *prefix) { char **prog_dirs, **bin_dirs, **prefix_dirs; int prog_num, bin_num, prefix_num; diff --git a/gnu/lib/libiberty/src/make-temp-file.c b/gnu/lib/libiberty/src/make-temp-file.c index 883350479fc..5e21414ad8e 100644 --- a/gnu/lib/libiberty/src/make-temp-file.c +++ b/gnu/lib/libiberty/src/make-temp-file.c @@ -14,8 +14,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -43,7 +43,7 @@ Boston, MA 02111-1307, USA. */ #endif #include "libiberty.h" -extern int mkstemps PARAMS ((char *, int)); +extern int mkstemps (char *, int); /* '/' works just fine on MS-DOS based systems. */ #ifndef DIR_SEPARATOR @@ -61,11 +61,10 @@ extern int mkstemps PARAMS ((char *, int)); If success, DIR is returned. Otherwise NULL is returned. */ -static inline const char *try PARAMS ((const char *, const char *)); +static inline const char *try_dir (const char *, const char *); static inline const char * -try (dir, base) - const char *dir, *base; +try_dir (const char *dir, const char *base) { if (base != 0) return base; @@ -95,7 +94,7 @@ files in. */ char * -choose_tmpdir () +choose_tmpdir (void) { const char *base = 0; char *tmpdir; @@ -104,18 +103,18 @@ choose_tmpdir () if (memoized_tmpdir) return memoized_tmpdir; - base = try (getenv ("TMPDIR"), base); - base = try (getenv ("TMP"), base); - base = try (getenv ("TEMP"), base); + base = try_dir (getenv ("TMPDIR"), base); + base = try_dir (getenv ("TMP"), base); + base = try_dir (getenv ("TEMP"), base); #ifdef P_tmpdir - base = try (P_tmpdir, base); + base = try_dir (P_tmpdir, base); #endif /* Try /var/tmp, /usr/tmp, then /tmp. */ - base = try (vartmp, base); - base = try (usrtmp, base); - base = try (tmp, base); + base = try_dir (vartmp, base); + base = try_dir (usrtmp, base); + base = try_dir (tmp, base); /* If all else fails, use the current directory! */ if (base == 0) @@ -124,7 +123,7 @@ choose_tmpdir () /* Append DIR_SEPARATOR to the directory we've chosen and return it. */ len = strlen (base); - tmpdir = xmalloc (len + 2); + tmpdir = XNEWVEC (char, len + 2); strcpy (tmpdir, base); tmpdir[len] = DIR_SEPARATOR; tmpdir[len+1] = '\0'; @@ -146,8 +145,7 @@ string is @code{malloc}ed, and the temporary file has been created. */ char * -make_temp_file (suffix) - const char *suffix; +make_temp_file (const char *suffix) { const char *base = choose_tmpdir (); char *temp_filename; @@ -160,7 +158,7 @@ make_temp_file (suffix) base_len = strlen (base); suffix_len = strlen (suffix); - temp_filename = xmalloc (base_len + temp_filename = XNEWVEC (char, base_len + TEMP_FILE_LEN + suffix_len + 1); strcpy (temp_filename, base); diff --git a/gnu/lib/libiberty/src/md5.c b/gnu/lib/libiberty/src/md5.c index e458f2a6a64..83e0beb339f 100644 --- a/gnu/lib/libiberty/src/md5.c +++ b/gnu/lib/libiberty/src/md5.c @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ @@ -62,8 +62,7 @@ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; /* Initialize structure containing state of computation. (RFC 1321, 3.3: Step 3) */ void -md5_init_ctx (ctx) - struct md5_ctx *ctx; +md5_init_ctx (struct md5_ctx *ctx) { ctx->A = (md5_uint32) 0x67452301; ctx->B = (md5_uint32) 0xefcdab89; @@ -80,9 +79,7 @@ md5_init_ctx (ctx) IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void * -md5_read_ctx (ctx, resbuf) - const struct md5_ctx *ctx; - void *resbuf; +md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) { ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); @@ -98,9 +95,7 @@ md5_read_ctx (ctx, resbuf) IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void * -md5_finish_ctx (ctx, resbuf) - struct md5_ctx *ctx; - void *resbuf; +md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) { /* Take yet unprocessed bytes into account. */ md5_uint32 bytes = ctx->buflen; @@ -129,9 +124,7 @@ md5_finish_ctx (ctx, resbuf) resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ int -md5_stream (stream, resblock) - FILE *stream; - void *resblock; +md5_stream (FILE *stream, void *resblock) { /* Important: BLOCKSIZE must be a multiple of 64. */ #define BLOCKSIZE 4096 @@ -186,10 +179,7 @@ md5_stream (stream, resblock) output yields to the wanted ASCII representation of the message digest. */ void * -md5_buffer (buffer, len, resblock) - const char *buffer; - size_t len; - void *resblock; +md5_buffer (const char *buffer, size_t len, void *resblock) { struct md5_ctx ctx; @@ -205,10 +195,7 @@ md5_buffer (buffer, len, resblock) void -md5_process_bytes (buffer, len, ctx) - const void *buffer; - size_t len; - struct md5_ctx *ctx; +md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) { /* When we already have some bits in our internal buffer concatenate both inputs first. */ @@ -236,6 +223,23 @@ md5_process_bytes (buffer, len, ctx) /* Process available complete blocks. */ if (len > 64) { +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0) +# else +# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 64) + { + md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif md5_process_block (buffer, len & ~63, ctx); buffer = (const void *) ((const char *) buffer + (len & ~63)); len &= 63; @@ -263,10 +267,7 @@ md5_process_bytes (buffer, len, ctx) It is assumed that LEN % 64 == 0. */ void -md5_process_block (buffer, len, ctx) - const void *buffer; - size_t len; - struct md5_ctx *ctx; +md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) { md5_uint32 correct_words[16]; const md5_uint32 *words = (const md5_uint32 *) buffer; diff --git a/gnu/lib/libiberty/src/mempcpy.c b/gnu/lib/libiberty/src/mempcpy.c index b0dccfa6167..beda7dfc982 100644 --- a/gnu/lib/libiberty/src/mempcpy.c +++ b/gnu/lib/libiberty/src/mempcpy.c @@ -1,5 +1,5 @@ /* Implement the mempcpy function. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>. This file is part of the libiberty library. @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -30,19 +30,12 @@ Copies @var{length} bytes from memory region @var{in} to region */ #include <ansidecl.h> -#ifdef ANSI_PROTOTYPES #include <stddef.h> -#else -#define size_t unsigned long -#endif -extern PTR memcpy PARAMS ((PTR, const PTR, size_t)); +extern PTR memcpy (PTR, const PTR, size_t); PTR -mempcpy (dst, src, len) - PTR dst; - const PTR src; - size_t len; +mempcpy (PTR dst, const PTR src, size_t len) { return (char *) memcpy (dst, src, len) + len; } diff --git a/gnu/lib/libiberty/src/obstack.c b/gnu/lib/libiberty/src/obstack.c index 02560c9e032..a6dbaf095df 100644 --- a/gnu/lib/libiberty/src/obstack.c +++ b/gnu/lib/libiberty/src/obstack.c @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H @@ -52,11 +52,7 @@ #ifndef ELIDE_CODE -#if defined (__STDC__) && __STDC__ #define POINTER void * -#else -#define POINTER char * -#endif /* Determine default alignment. */ struct fooalign {char x; double d;}; @@ -81,13 +77,8 @@ union fooround {long x; double d;}; jump to the handler pointed to by `obstack_alloc_failed_handler'. This variable by default points to the internal function `print_and_abort'. */ -#if defined (__STDC__) && __STDC__ static void print_and_abort (void); void (*obstack_alloc_failed_handler) (void) = print_and_abort; -#else -static void print_and_abort (); -void (*obstack_alloc_failed_handler) () = print_and_abort; -#endif /* Exit value used when `print_and_abort' is used. */ #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H @@ -148,17 +139,8 @@ struct obstack *_obstack; free up some memory, then call this again. */ int -_obstack_begin (h, size, alignment, chunkfun, freefun) - struct obstack *h; - int size; - int alignment; -#if defined (__STDC__) && __STDC__ - POINTER (*chunkfun) (long); - void (*freefun) (void *); -#else - POINTER (*chunkfun) (); - void (*freefun) (); -#endif +_obstack_begin (struct obstack *h, int size, int alignment, + POINTER (*chunkfun) (long), void (*freefun) (void *)) { register struct _obstack_chunk *chunk; /* points to new chunk */ @@ -181,13 +163,8 @@ _obstack_begin (h, size, alignment, chunkfun, freefun) size = 4096 - extra; } -#if defined (__STDC__) && __STDC__ h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; -#else - h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; - h->freefun = freefun; -#endif h->chunk_size = size; h->alignment_mask = alignment - 1; h->use_extra_arg = 0; @@ -206,18 +183,9 @@ _obstack_begin (h, size, alignment, chunkfun, freefun) } int -_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) - struct obstack *h; - int size; - int alignment; -#if defined (__STDC__) && __STDC__ - POINTER (*chunkfun) (POINTER, long); - void (*freefun) (POINTER, POINTER); -#else - POINTER (*chunkfun) (); - void (*freefun) (); -#endif - POINTER arg; +_obstack_begin_1 (struct obstack *h, int size, int alignment, + POINTER (*chunkfun) (POINTER, long), + void (*freefun) (POINTER, POINTER), POINTER arg) { register struct _obstack_chunk *chunk; /* points to new chunk */ @@ -240,13 +208,8 @@ _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) size = 4096 - extra; } -#if defined(__STDC__) && __STDC__ h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; -#else - h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; - h->freefun = freefun; -#endif h->chunk_size = size; h->alignment_mask = alignment - 1; h->extra_arg = arg; @@ -272,9 +235,7 @@ _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) to the beginning of the new one. */ void -_obstack_newchunk (h, length) - struct obstack *h; - int length; +_obstack_newchunk (struct obstack *h, int length) { register struct _obstack_chunk *old_chunk = h->chunk; register struct _obstack_chunk *new_chunk; @@ -335,16 +296,12 @@ _obstack_newchunk (h, length) This is here for debugging. If you use it in a program, you are probably losing. */ -#if defined (__STDC__) && __STDC__ /* Suppress -Wmissing-prototypes warning. We don't want to declare this in obstack.h because it is just for debugging. */ int _obstack_allocated_p (struct obstack *h, POINTER obj); -#endif int -_obstack_allocated_p (h, obj) - struct obstack *h; - POINTER obj; +_obstack_allocated_p (struct obstack *h, POINTER obj) { register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ register struct _obstack_chunk *plp; /* point to previous chunk if any */ @@ -370,9 +327,7 @@ _obstack_allocated_p (h, obj) This is the first one, called from non-ANSI code. */ void -_obstack_free (h, obj) - struct obstack *h; - POINTER obj; +_obstack_free (struct obstack *h, POINTER obj) { register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ register struct _obstack_chunk *plp; /* point to previous chunk if any */ @@ -404,9 +359,7 @@ _obstack_free (h, obj) /* This function is used from ANSI code. */ void -obstack_free (h, obj) - struct obstack *h; - POINTER obj; +obstack_free (struct obstack *h, POINTER obj) { register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ register struct _obstack_chunk *plp; /* point to previous chunk if any */ @@ -436,8 +389,7 @@ obstack_free (h, obj) } int -_obstack_memory_used (h) - struct obstack *h; +_obstack_memory_used (struct obstack *h) { register struct _obstack_chunk* lp; register int nbytes = 0; @@ -462,7 +414,7 @@ _obstack_memory_used (h) #endif static void -print_and_abort () +print_and_abort (void) { fputs (_("memory exhausted\n"), stderr); exit (obstack_exit_failure); @@ -475,119 +427,84 @@ print_and_abort () /* Now define the functional versions of the obstack macros. Define them to simply use the corresponding macros to do the job. */ -#if defined (__STDC__) && __STDC__ -/* These function definitions do not work with non-ANSI preprocessors; - they won't pass through the macro names in parentheses. */ - /* The function names appear in parentheses in order to prevent the macro-definitions of the names from being expanded there. */ -POINTER (obstack_base) (obstack) - struct obstack *obstack; +POINTER (obstack_base) (struct obstack *obstack) { return obstack_base (obstack); } -POINTER (obstack_next_free) (obstack) - struct obstack *obstack; +POINTER (obstack_next_free) (struct obstack *obstack) { return obstack_next_free (obstack); } -int (obstack_object_size) (obstack) - struct obstack *obstack; +int (obstack_object_size) (struct obstack *obstack) { return obstack_object_size (obstack); } -int (obstack_room) (obstack) - struct obstack *obstack; +int (obstack_room) (struct obstack *obstack) { return obstack_room (obstack); } -int (obstack_make_room) (obstack, length) - struct obstack *obstack; - int length; +int (obstack_make_room) (struct obstack *obstack, int length) { return obstack_make_room (obstack, length); } -void (obstack_grow) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; +void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length) { obstack_grow (obstack, pointer, length); } -void (obstack_grow0) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; +void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length) { obstack_grow0 (obstack, pointer, length); } -void (obstack_1grow) (obstack, character) - struct obstack *obstack; - int character; +void (obstack_1grow) (struct obstack *obstack, int character) { obstack_1grow (obstack, character); } -void (obstack_blank) (obstack, length) - struct obstack *obstack; - int length; +void (obstack_blank) (struct obstack *obstack, int length) { obstack_blank (obstack, length); } -void (obstack_1grow_fast) (obstack, character) - struct obstack *obstack; - int character; +void (obstack_1grow_fast) (struct obstack *obstack, int character) { obstack_1grow_fast (obstack, character); } -void (obstack_blank_fast) (obstack, length) - struct obstack *obstack; - int length; +void (obstack_blank_fast) (struct obstack *obstack, int length) { obstack_blank_fast (obstack, length); } -POINTER (obstack_finish) (obstack) - struct obstack *obstack; +POINTER (obstack_finish) (struct obstack *obstack) { return obstack_finish (obstack); } -POINTER (obstack_alloc) (obstack, length) - struct obstack *obstack; - int length; +POINTER (obstack_alloc) (struct obstack *obstack, int length) { return obstack_alloc (obstack, length); } -POINTER (obstack_copy) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; +POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length) { return obstack_copy (obstack, pointer, length); } -POINTER (obstack_copy0) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; +POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length) { return obstack_copy0 (obstack, pointer, length); } -#endif /* __STDC__ */ - #endif /* 0 */ #endif /* !ELIDE_CODE */ diff --git a/gnu/lib/libiberty/src/pex-common.c b/gnu/lib/libiberty/src/pex-common.c new file mode 100644 index 00000000000..ebe8c437590 --- /dev/null +++ b/gnu/lib/libiberty/src/pex-common.c @@ -0,0 +1,575 @@ +/* Common code for executing a program in a sub-process. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Ian Lance Taylor <ian@airs.com>. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If not, +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include "libiberty.h" +#include "pex-common.h" + +#include <stdio.h> +#include <errno.h> +#ifdef NEED_DECLARATION_ERRNO +extern int errno; +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +extern int mkstemps (char *, int); + +/* This file contains subroutines for the program execution routines + (pex_init, pex_run, etc.). This file is compiled on all + systems. */ + +static void pex_add_remove (struct pex_obj *, const char *, int); +static int pex_get_status_and_time (struct pex_obj *, int, const char **, + int *); + +/* Initialize a pex_obj structure. */ + +struct pex_obj * +pex_init_common (int flags, const char *pname, const char *tempbase, + const struct pex_funcs *funcs) +{ + struct pex_obj *obj; + + obj = XNEW (struct pex_obj); + obj->flags = flags; + obj->pname = pname; + obj->tempbase = tempbase; + obj->next_input = STDIN_FILE_NO; + obj->next_input_name = NULL; + obj->next_input_name_allocated = 0; + obj->count = 0; + obj->children = NULL; + obj->status = NULL; + obj->time = NULL; + obj->number_waited = 0; + obj->input_file = NULL; + obj->read_output = NULL; + obj->remove_count = 0; + obj->remove = NULL; + obj->funcs = funcs; + obj->sysdep = NULL; + return obj; +} + +/* Add a file to be removed when we are done. */ + +static void +pex_add_remove (struct pex_obj *obj, const char *name, int allocated) +{ + char *add; + + ++obj->remove_count; + obj->remove = XRESIZEVEC (char *, obj->remove, obj->remove_count); + if (allocated) + add = (char *) name; + else + add = xstrdup (name); + obj->remove[obj->remove_count - 1] = add; +} + +/* Generate a temporary file name based on OBJ, FLAGS, and NAME. + Return NULL if we were unable to reserve a temporary filename. + + If non-NULL, the result is either allocated with malloc, or the + same pointer as NAME. */ +static char * +temp_file (struct pex_obj *obj, int flags, char *name) +{ + if (name == NULL) + { + if (obj->tempbase == NULL) + { + name = make_temp_file (NULL); + } + else + { + int len = strlen (obj->tempbase); + int out; + + if (len >= 6 + && strcmp (obj->tempbase + len - 6, "XXXXXX") == 0) + name = xstrdup (obj->tempbase); + else + name = concat (obj->tempbase, "XXXXXX", NULL); + + out = mkstemps (name, 0); + if (out < 0) + { + free (name); + return NULL; + } + + /* This isn't obj->funcs->close because we got the + descriptor from mkstemps, not from a function in + obj->funcs. Calling close here is just like what + make_temp_file does. */ + close (out); + } + } + else if ((flags & PEX_SUFFIX) != 0) + { + if (obj->tempbase == NULL) + name = make_temp_file (name); + else + name = concat (obj->tempbase, name, NULL); + } + + return name; +} + +/* Run a program. */ + +const char * +pex_run (struct pex_obj *obj, int flags, const char *executable, + char * const * argv, const char *orig_outname, const char *errname, + int *err) +{ + const char *errmsg; + int in, out, errdes; + char *outname; + int outname_allocated; + int p[2]; + long pid; + + in = -1; + out = -1; + errdes = -1; + outname = (char *) orig_outname; + outname_allocated = 0; + + /* If the user called pex_input_file, close the file now. */ + if (obj->input_file) + { + if (fclose (obj->input_file) == EOF) + { + errmsg = "closing pipeline input file"; + goto error_exit; + } + obj->input_file = NULL; + } + + /* Set IN. */ + + if (obj->next_input_name != NULL) + { + /* We have to make sure that the previous process has completed + before we try to read the file. */ + if (!pex_get_status_and_time (obj, 0, &errmsg, err)) + goto error_exit; + + in = obj->funcs->open_read (obj, obj->next_input_name, + (flags & PEX_BINARY_INPUT) != 0); + if (in < 0) + { + *err = errno; + errmsg = "open temporary file"; + goto error_exit; + } + if (obj->next_input_name_allocated) + { + free (obj->next_input_name); + obj->next_input_name_allocated = 0; + } + obj->next_input_name = NULL; + } + else + { + in = obj->next_input; + if (in < 0) + { + *err = 0; + errmsg = "pipeline already complete"; + goto error_exit; + } + } + + /* Set OUT and OBJ->NEXT_INPUT/OBJ->NEXT_INPUT_NAME. */ + + if ((flags & PEX_LAST) != 0) + { + if (outname == NULL) + out = STDOUT_FILE_NO; + else if ((flags & PEX_SUFFIX) != 0) + { + outname = concat (obj->tempbase, outname, NULL); + outname_allocated = 1; + } + obj->next_input = -1; + } + else if ((obj->flags & PEX_USE_PIPES) == 0) + { + outname = temp_file (obj, flags, outname); + if (! outname) + { + *err = 0; + errmsg = "could not create temporary file"; + goto error_exit; + } + + if (outname != orig_outname) + outname_allocated = 1; + + if ((obj->flags & PEX_SAVE_TEMPS) == 0) + { + pex_add_remove (obj, outname, outname_allocated); + outname_allocated = 0; + } + + /* Hand off ownership of outname to the next stage. */ + obj->next_input_name = outname; + obj->next_input_name_allocated = outname_allocated; + outname_allocated = 0; + } + else + { + if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_OUTPUT) != 0) < 0) + { + *err = errno; + errmsg = "pipe"; + goto error_exit; + } + + out = p[WRITE_PORT]; + obj->next_input = p[READ_PORT]; + } + + if (out < 0) + { + out = obj->funcs->open_write (obj, outname, + (flags & PEX_BINARY_OUTPUT) != 0); + if (out < 0) + { + *err = errno; + errmsg = "open temporary output file"; + goto error_exit; + } + } + + if (outname_allocated) + { + free (outname); + outname_allocated = 0; + } + + /* Set ERRDES. */ + + if (errname == NULL) + errdes = STDERR_FILE_NO; + else + { + /* We assume that stderr is in text mode--it certainly shouldn't + be controlled by PEX_BINARY_OUTPUT. If necessary, we can add + a PEX_BINARY_STDERR flag. */ + errdes = obj->funcs->open_write (obj, errname, 0); + if (errdes < 0) + { + *err = errno; + errmsg = "open error file"; + goto error_exit; + } + } + + /* Run the program. */ + + pid = obj->funcs->exec_child (obj, flags, executable, argv, in, out, errdes, + &errmsg, err); + if (pid < 0) + goto error_exit; + + ++obj->count; + obj->children = XRESIZEVEC (long, obj->children, obj->count); + obj->children[obj->count - 1] = pid; + + return NULL; + + error_exit: + if (in >= 0 && in != STDIN_FILE_NO) + obj->funcs->close (obj, in); + if (out >= 0 && out != STDOUT_FILE_NO) + obj->funcs->close (obj, out); + if (errdes >= 0 && errdes != STDERR_FILE_NO) + obj->funcs->close (obj, errdes); + if (outname_allocated) + free (outname); + return errmsg; +} + +/* Return a FILE pointer for a temporary file to fill with input for + the pipeline. */ +FILE * +pex_input_file (struct pex_obj *obj, int flags, const char *in_name) +{ + char *name = (char *) in_name; + FILE *f; + + /* This must be called before the first pipeline stage is run, and + there must not have been any other input selected. */ + if (obj->count != 0 + || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) + || obj->next_input_name) + { + errno = EINVAL; + return NULL; + } + + name = temp_file (obj, flags, name); + if (! name) + return NULL; + + f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w"); + if (! f) + { + free (name); + return NULL; + } + + obj->input_file = f; + obj->next_input_name = name; + obj->next_input_name_allocated = (name != in_name); + + return f; +} + +/* Return a stream for a pipe connected to the standard input of the + first stage of the pipeline. */ +FILE * +pex_input_pipe (struct pex_obj *obj, int binary) +{ + int p[2]; + FILE *f; + + /* You must call pex_input_pipe before the first pex_run or pex_one. */ + if (obj->count > 0) + goto usage_error; + + /* You must be using pipes. Implementations that don't support + pipes clear this flag before calling pex_init_common. */ + if (! (obj->flags & PEX_USE_PIPES)) + goto usage_error; + + /* If we have somehow already selected other input, that's a + mistake. */ + if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) + || obj->next_input_name) + goto usage_error; + + if (obj->funcs->pipe (obj, p, binary != 0) < 0) + return NULL; + + f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0); + if (! f) + { + int saved_errno = errno; + obj->funcs->close (obj, p[READ_PORT]); + obj->funcs->close (obj, p[WRITE_PORT]); + errno = saved_errno; + return NULL; + } + + obj->next_input = p[READ_PORT]; + + return f; + + usage_error: + errno = EINVAL; + return NULL; +} + +/* Return a FILE pointer for the output of the last program + executed. */ + +FILE * +pex_read_output (struct pex_obj *obj, int binary) +{ + if (obj->next_input_name != NULL) + { + const char *errmsg; + int err; + + /* We have to make sure that the process has completed before we + try to read the file. */ + if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) + { + errno = err; + return NULL; + } + + obj->read_output = fopen (obj->next_input_name, binary ? "rb" : "r"); + + if (obj->next_input_name_allocated) + { + free (obj->next_input_name); + obj->next_input_name_allocated = 0; + } + obj->next_input_name = NULL; + } + else + { + int o; + + o = obj->next_input; + if (o < 0 || o == STDIN_FILE_NO) + return NULL; + obj->read_output = obj->funcs->fdopenr (obj, o, binary); + obj->next_input = -1; + } + + return obj->read_output; +} + +/* Get the exit status and, if requested, the resource time for all + the child processes. Return 0 on failure, 1 on success. */ + +static int +pex_get_status_and_time (struct pex_obj *obj, int done, const char **errmsg, + int *err) +{ + int ret; + int i; + + if (obj->number_waited == obj->count) + return 1; + + obj->status = XRESIZEVEC (int, obj->status, obj->count); + if ((obj->flags & PEX_RECORD_TIMES) != 0) + obj->time = XRESIZEVEC (struct pex_time, obj->time, obj->count); + + ret = 1; + for (i = obj->number_waited; i < obj->count; ++i) + { + if (obj->funcs->wait (obj, obj->children[i], &obj->status[i], + obj->time == NULL ? NULL : &obj->time[i], + done, errmsg, err) < 0) + ret = 0; + } + obj->number_waited = i; + + return ret; +} + +/* Get exit status of executed programs. */ + +int +pex_get_status (struct pex_obj *obj, int count, int *vector) +{ + if (obj->status == NULL) + { + const char *errmsg; + int err; + + if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) + return 0; + } + + if (count > obj->count) + { + memset (vector + obj->count, 0, (count - obj->count) * sizeof (int)); + count = obj->count; + } + + memcpy (vector, obj->status, count * sizeof (int)); + + return 1; +} + +/* Get process times of executed programs. */ + +int +pex_get_times (struct pex_obj *obj, int count, struct pex_time *vector) +{ + if (obj->status == NULL) + { + const char *errmsg; + int err; + + if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) + return 0; + } + + if (obj->time == NULL) + return 0; + + if (count > obj->count) + { + memset (vector + obj->count, 0, + (count - obj->count) * sizeof (struct pex_time)); + count = obj->count; + } + + memcpy (vector, obj->time, count * sizeof (struct pex_time)); + + return 1; +} + +/* Free a pex_obj structure. */ + +void +pex_free (struct pex_obj *obj) +{ + if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) + obj->funcs->close (obj, obj->next_input); + + /* If the caller forgot to wait for the children, we do it here, to + avoid zombies. */ + if (obj->status == NULL) + { + const char *errmsg; + int err; + + obj->flags &= ~ PEX_RECORD_TIMES; + pex_get_status_and_time (obj, 1, &errmsg, &err); + } + + if (obj->next_input_name_allocated) + free (obj->next_input_name); + if (obj->children != NULL) + free (obj->children); + if (obj->status != NULL) + free (obj->status); + if (obj->time != NULL) + free (obj->time); + if (obj->read_output != NULL) + fclose (obj->read_output); + + if (obj->remove_count > 0) + { + int i; + + for (i = 0; i < obj->remove_count; ++i) + { + remove (obj->remove[i]); + free (obj->remove[i]); + } + free (obj->remove); + } + + if (obj->funcs->cleanup != NULL) + obj->funcs->cleanup (obj); + + free (obj); +} diff --git a/gnu/lib/libiberty/src/pex-common.h b/gnu/lib/libiberty/src/pex-common.h index da2f71e1247..8ded138148c 100644 --- a/gnu/lib/libiberty/src/pex-common.h +++ b/gnu/lib/libiberty/src/pex-common.h @@ -1,6 +1,6 @@ /* Utilities to execute a program in a subprocess (possibly linked by pipes with other subprocesses), and wait for it. Shared logic. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. This file is part of the libiberty library. @@ -16,14 +16,15 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifndef PEX_COMMON_H #define PEX_COMMON_H #include "config.h" #include "libiberty.h" +#include <stdio.h> #define install_error_msg "installation problem, cannot exec `%s'" @@ -33,10 +34,106 @@ Boston, MA 02111-1307, USA. */ /* stdout file number. */ #define STDOUT_FILE_NO 1 +/* stderr file number. */ +#define STDERR_FILE_NO 2 + /* value of `pipe': port index for reading. */ #define READ_PORT 0 /* value of `pipe': port index for writing. */ #define WRITE_PORT 1 +/* The structure used by pex_init and friends. */ + +struct pex_obj +{ + /* Flags. */ + int flags; + /* Name of calling program, for error messages. */ + const char *pname; + /* Base name to use for temporary files. */ + const char *tempbase; + /* Pipe to use as stdin for next process. */ + int next_input; + /* File name to use as stdin for next process. */ + char *next_input_name; + /* Whether next_input_name was allocated using malloc. */ + int next_input_name_allocated; + /* Number of child processes. */ + int count; + /* PIDs of child processes; array allocated using malloc. */ + long *children; + /* Exit statuses of child processes; array allocated using malloc. */ + int *status; + /* Time used by child processes; array allocated using malloc. */ + struct pex_time *time; + /* Number of children we have already waited for. */ + int number_waited; + /* FILE created by pex_input_file. */ + FILE *input_file; + /* FILE created by pex_read_output. */ + FILE *read_output; + /* Number of temporary files to remove. */ + int remove_count; + /* List of temporary files to remove; array allocated using malloc + of strings allocated using malloc. */ + char **remove; + /* Pointers to system dependent functions. */ + const struct pex_funcs *funcs; + /* For use by system dependent code. */ + void *sysdep; +}; + +/* Functions passed to pex_run_common. */ + +struct pex_funcs +{ + /* Open file NAME for reading. If BINARY is non-zero, open in + binary mode. Return >= 0 on success, -1 on error. */ + int (*open_read) (struct pex_obj *, const char */* name */, int /* binary */); + /* Open file NAME for writing. If BINARY is non-zero, open in + binary mode. Return >= 0 on success, -1 on error. */ + int (*open_write) (struct pex_obj *, const char */* name */, + int /* binary */); + /* Execute a child process. FLAGS, EXECUTABLE, ARGV, ERR are from + pex_run. IN, OUT, ERRDES are each a descriptor, from open_read, + open_write, or pipe, or they are one of STDIN_FILE_NO, + STDOUT_FILE_NO or STDERR_FILE_NO; if not STD*_FILE_NO, they + should be closed. The function should handle the + PEX_STDERR_TO_STDOUT flag. Return >= 0 on success, or -1 on + error and set *ERRMSG and *ERR. */ + long (*exec_child) (struct pex_obj *, int /* flags */, + const char */* executable */, char * const * /* argv */, + int /* in */, int /* out */, int /* errdes */, + const char **/* errmsg */, int */* err */); + /* Close a descriptor. Return 0 on success, -1 on error. */ + int (*close) (struct pex_obj *, int); + /* Wait for a child to complete, returning exit status in *STATUS + and time in *TIME (if it is not null). CHILD is from fork. DONE + is 1 if this is called via pex_free. ERRMSG and ERR are as in + fork. Return 0 on success, -1 on error. */ + int (*wait) (struct pex_obj *, long /* child */, int * /* status */, + struct pex_time * /* time */, int /* done */, + const char ** /* errmsg */, int * /* err */); + /* Create a pipe (only called if PEX_USE_PIPES is set) storing two + descriptors in P[0] and P[1]. If BINARY is non-zero, open in + binary mode. Return 0 on success, -1 on error. */ + int (*pipe) (struct pex_obj *, int * /* p */, int /* binary */); + /* Get a FILE pointer to read from a file descriptor (only called if + PEX_USE_PIPES is set). If BINARY is non-zero, open in binary + mode. Return pointer on success, NULL on error. */ + FILE * (*fdopenr) (struct pex_obj *, int /* fd */, int /* binary */); + /* Get a FILE pointer to write to the file descriptor FD (only + called if PEX_USE_PIPES is set). If BINARY is non-zero, open in + binary mode. Arrange for FD not to be inherited by the child + processes. Return pointer on success, NULL on error. */ + FILE * (*fdopenw) (struct pex_obj *, int /* fd */, int /* binary */); + /* Free any system dependent data associated with OBJ. May be + NULL if there is nothing to do. */ + void (*cleanup) (struct pex_obj *); +}; + +extern struct pex_obj *pex_init_common (int, const char *, const char *, + const struct pex_funcs *); + #endif diff --git a/gnu/lib/libiberty/src/pex-djgpp.c b/gnu/lib/libiberty/src/pex-djgpp.c index 968e7841215..17fbf2cc7e4 100644 --- a/gnu/lib/libiberty/src/pex-djgpp.c +++ b/gnu/lib/libiberty/src/pex-djgpp.c @@ -1,6 +1,6 @@ /* Utilities to execute a program in a subprocess (possibly linked by pipes with other subprocesses), and wait for it. DJGPP specialization. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc. This file is part of the libiberty library. @@ -16,8 +16,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #include "pex-common.h" @@ -29,6 +29,10 @@ extern int errno; #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> #include <process.h> /* Use ECHILD if available, otherwise use EINVAL. */ @@ -38,66 +42,246 @@ extern int errno; #define PWAIT_ERROR EINVAL #endif -/* MSDOS doesn't multitask, but for the sake of a consistent interface - the code behaves like it does. pexecute runs the program, tucks the - exit code away, and returns a "pid". pwait must be called to fetch the - exit code. */ - -/* For communicating information from pexecute to pwait. */ -static int last_pid = 0; -static int last_status = 0; -static int last_reaped = 0; - -int -pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) - const char *program; - char * const *argv; - const char *this_pname; - const char *temp_base; - char **errmsg_fmt, **errmsg_arg; - int flags; +static int pex_djgpp_open_read (struct pex_obj *, const char *, int); +static int pex_djgpp_open_write (struct pex_obj *, const char *, int); +static long pex_djgpp_exec_child (struct pex_obj *, int, const char *, + char * const *, int, int, int, + const char **, int *); +static int pex_djgpp_close (struct pex_obj *, int); +static int pex_djgpp_wait (struct pex_obj *, long, int *, struct pex_time *, + int, const char **, int *); + +/* The list of functions we pass to the common routines. */ + +const struct pex_funcs funcs = { - int rc; + pex_djgpp_open_read, + pex_djgpp_open_write, + pex_djgpp_exec_child, + pex_djgpp_close, + pex_djgpp_wait, + NULL, /* pipe */ + NULL, /* fdopenr */ + NULL, /* fdopenw */ + NULL /* cleanup */ +}; - last_pid++; - if (last_pid < 0) - last_pid = 1; +/* Return a newly initialized pex_obj structure. */ - if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE) - abort (); +struct pex_obj * +pex_init (int flags, const char *pname, const char *tempbase) +{ + /* DJGPP does not support pipes. */ + flags &= ~ PEX_USE_PIPES; + return pex_init_common (flags, pname, tempbase, &funcs); +} - /* ??? What are the possible return values from spawnv? */ - rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (P_WAIT, program, argv); +/* Open a file for reading. */ - if (rc == -1) - { - *errmsg_fmt = install_error_msg; - *errmsg_arg = (char *)program; - return -1; - } +static int +pex_djgpp_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, + const char *name, int binary) +{ + return open (name, O_RDONLY | (binary ? O_BINARY : O_TEXT)); +} + +/* Open a file for writing. */ - /* Tuck the status away for pwait, and return a "pid". */ - last_status = rc << 8; - return last_pid; +static int +pex_djgpp_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, + const char *name, int binary) +{ + /* Note that we can't use O_EXCL here because gcc may have already + created the temporary file via make_temp_file. */ + return open (name, + (O_WRONLY | O_CREAT | O_TRUNC + | (binary ? O_BINARY : O_TEXT)), + S_IRUSR | S_IWUSR); } -int -pwait (pid, status, flags) - int pid; - int *status; - int flags; +/* Close a file. */ + +static int +pex_djgpp_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) { - /* On MSDOS each pexecute must be followed by its associated pwait. */ - if (pid != last_pid - /* Called twice for the same child? */ - || pid == last_reaped) + return close (fd); +} + +/* Execute a child. */ + +static long +pex_djgpp_exec_child (struct pex_obj *obj, int flags, const char *executable, + char * const * argv, int in, int out, int errdes, + const char **errmsg, int *err) +{ + int org_in, org_out, org_errdes; + int status; + int *statuses; + + org_in = -1; + org_out = -1; + org_errdes = -1; + + if (in != STDIN_FILE_NO) + { + org_in = dup (STDIN_FILE_NO); + if (org_in < 0) + { + *err = errno; + *errmsg = "dup"; + return -1; + } + if (dup2 (in, STDIN_FILE_NO) < 0) + { + *err = errno; + *errmsg = "dup2"; + return -1; + } + if (close (in) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + + if (out != STDOUT_FILE_NO) + { + org_out = dup (STDOUT_FILE_NO); + if (org_out < 0) + { + *err = errno; + *errmsg = "dup"; + return -1; + } + if (dup2 (out, STDOUT_FILE_NO) < 0) + { + *err = errno; + *errmsg = "dup2"; + return -1; + } + if (close (out) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + + if (errdes != STDERR_FILE_NO + || (flags & PEX_STDERR_TO_STDOUT) != 0) { - errno = PWAIT_ERROR; - return -1; + org_errdes = dup (STDERR_FILE_NO); + if (org_errdes < 0) + { + *err = errno; + *errmsg = "dup"; + return -1; + } + if (dup2 ((flags & PEX_STDERR_TO_STDOUT) != 0 ? STDOUT_FILE_NO : errdes, + STDERR_FILE_NO) < 0) + { + *err = errno; + *errmsg = "dup2"; + return -1; + } + if (errdes != STDERR_FILE_NO) + { + if (close (errdes) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } } - /* ??? Here's an opportunity to canonicalize the values in STATUS. - Needed? */ - *status = (last_status >> 8); - last_reaped = last_pid; - return last_pid; + + status = (((flags & PEX_SEARCH) != 0 ? spawnvp : spawnv) + (P_WAIT, executable, (char * const *) argv)); + + if (status == -1) + { + *err = errno; + *errmsg = ((flags & PEX_SEARCH) != 0) ? "spawnvp" : "spawnv"; + } + + if (in != STDIN_FILE_NO) + { + if (dup2 (org_in, STDIN_FILE_NO) < 0) + { + *err = errno; + *errmsg = "dup2"; + return -1; + } + if (close (org_in) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + + if (out != STDOUT_FILE_NO) + { + if (dup2 (org_out, STDOUT_FILE_NO) < 0) + { + *err = errno; + *errmsg = "dup2"; + return -1; + } + if (close (org_out) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + + if (errdes != STDERR_FILE_NO + || (flags & PEX_STDERR_TO_STDOUT) != 0) + { + if (dup2 (org_errdes, STDERR_FILE_NO) < 0) + { + *err = errno; + *errmsg = "dup2"; + return -1; + } + if (close (org_errdes) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + + /* Save the exit status for later. When we are called, obj->count + is the number of children which have executed before this + one. */ + statuses = (int *) obj->sysdep; + statuses = XRESIZEVEC (int, statuses, obj->count + 1); + statuses[obj->count] = status; + obj->sysdep = (void *) statuses; + + return obj->count; +} + +/* Wait for a child process to complete. Actually the child process + has already completed, and we just need to return the exit + status. */ + +static int +pex_djgpp_wait (struct pex_obj *obj, long pid, int *status, + struct pex_time *time, int done ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED, + int *err ATTRIBUTE_UNUSED) +{ + int *statuses; + + if (time != NULL) + memset (time, 0, sizeof *time); + + statuses = (int *) obj->sysdep; + *status = statuses[pid]; + + return 0; } diff --git a/gnu/lib/libiberty/src/pex-msdos.c b/gnu/lib/libiberty/src/pex-msdos.c index d61c129b97f..db22337aa2a 100644 --- a/gnu/lib/libiberty/src/pex-msdos.c +++ b/gnu/lib/libiberty/src/pex-msdos.c @@ -1,6 +1,6 @@ /* Utilities to execute a program in a subprocess (possibly linked by pipes with other subprocesses), and wait for it. Generic MSDOS specialization. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc. This file is part of the libiberty library. @@ -16,8 +16,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #include "pex-common.h" @@ -36,112 +36,282 @@ extern int errno; #include "safe-ctype.h" #include <process.h> -/* MSDOS doesn't multitask, but for the sake of a consistent interface - the code behaves like it does. pexecute runs the program, tucks the - exit code away, and returns a "pid". pwait must be called to fetch the - exit code. */ - -/* For communicating information from pexecute to pwait. */ -static int last_pid = 0; -static int last_status = 0; -static int last_reaped = 0; - -int -pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) - const char *program; - char * const *argv; - const char *this_pname; - const char *temp_base; - char **errmsg_fmt, **errmsg_arg; - int flags; +/* The structure we keep in obj->sysdep. */ + +#define PEX_MSDOS_FILE_COUNT 3 + +#define PEX_MSDOS_FD_OFFSET 10 + +struct pex_msdos { - int rc; - char *scmd, *rf; - FILE *argfile; - int i, el = flags & PEXECUTE_SEARCH ? 4 : 0; + /* An array of file names. We refer to these using file descriptors + of 10 + array index. */ + const char *files[PEX_MSDOS_FILE_COUNT]; + /* Exit statuses of programs which have been run. */ + int *statuses; +}; + +static int pex_msdos_open (struct pex_obj *, const char *, int); +static int pex_msdos_open (struct pex_obj *, const char *, int); +static int pex_msdos_fdindex (struct pex_msdos *, int); +static long pex_msdos_exec_child (struct pex_obj *, int, const char *, + char * const *, int, int, int, + const char **, int *); +static int pex_msdos_close (struct pex_obj *, int); +static int pex_msdos_wait (struct pex_obj *, long, int *, struct pex_time *, + int, const char **, int *); +static void pex_msdos_cleanup (struct pex_obj *); + +/* The list of functions we pass to the common routines. */ + +const struct pex_funcs funcs = +{ + pex_msdos_open, + pex_msdos_open, + pex_msdos_exec_child, + pex_msdos_close, + pex_msdos_wait, + NULL, /* pipe */ + NULL, /* fdopenr */ + NULL, /* fdopenw */ + pex_msdos_cleanup +}; + +/* Return a newly initialized pex_obj structure. */ + +struct pex_obj * +pex_init (int flags, const char *pname, const char *tempbase) +{ + struct pex_obj *ret; + int i; + + /* MSDOS does not support pipes. */ + flags &= ~ PEX_USE_PIPES; + + ret = pex_init_common (flags, pname, tempbase, funcs); + + ret->sysdep = XNEW (struct pex_msdos); + for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i) + ret->files[i] = NULL; + ret->statuses = NULL; + + return ret; +} + +/* Open a file. FIXME: We ignore the binary argument, since we have + no way to handle it. */ + +static int +pex_msdos_open (struct pex_obj *obj, const char *name, + int binary ATTRIBUTE_UNUSED) +{ + struct pex_msdos *ms; + int i; - last_pid++; - if (last_pid < 0) - last_pid = 1; + ms = (struct pex_msdos *) obj->sysdep; - if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE) + for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i) + { + if (ms->files[i] == NULL) + { + ms->files[i] = xstrdup (name); + return i + PEX_MSDOS_FD_OFFSET; + } + } + + abort (); +} + +/* Get the index into msdos->files associated with an open file + descriptor. */ + +static int +pex_msdos_fdindex (struct pex_msdos *ms, int fd) +{ + fd -= PEX_MSDOS_FD_OFFSET; + if (fd < 0 || fd >= PEX_MSDOS_FILE_COUNT || ms->files[fd] == NULL) abort (); + return fd; +} + + +/* Close a file. */ + +static int +pex_msdos_close (struct pex_obj *obj, int fd) +{ + struct pex_msdos *ms; + int fdinex; + + ms = (struct pex_msdos *) obj->sysdep; + fdindex = pe_msdos_fdindex (ms, fd); + free (ms->files[fdindex]); + ms->files[fdindex] = NULL; +} + +/* Execute a child. */ + +static long +pex_msdos_exec_child (struct pex_obj *obj, int flags, const char *executable, + char * const * argv, int in, int out, + int errdes ATTRIBUTE_UNUSED, const char **errmsg, + int *err) +{ + struct pex_msdos *ms; + char *temp_base; + int temp_base_allocated; + char *rf; + int inindex; + char *infile; + int outindex; + char *outfile; + char *scmd; + FILE *argfile; + int i; + int status; + + ms = (struct pex_msdos *) obj->sysdep; + + /* FIXME: I don't know how to redirect stderr, so we ignore ERRDES + and PEX_STDERR_TO_STDOUT. */ + + temp_base = obj->temp_base; + if (temp_base != NULL) + temp_base_allocated = 0; + else + { + temp_base = choose_temp_base (); + temp_base_allocated = 1; + } + + rf = concat (temp_base, ".gp", NULL); + + if (temp_base_allocated) + free (temp_base); + + if (in == STDIN_FILE_NO) + { + inindex = -1; + infile = ""; + } + else + { + inindex = pex_msdos_fdindex (ms, in); + infile = ms->files[inindex]; + } + + if (out == STDOUT_FILE_NO) + { + outindex = -1; + outfile = ""; + } + else + { + outindex = pex_msdos_fdindex (ms, out); + outfile = ms->files[outindex]; + } + + scmd = XNEWVEC (char, strlen (program) + + ((flags & PEXECUTE_SEARCH) != 0 ? 4 : 0) + + strlen (rf) + + strlen (infile) + + strlen (outfile) + + 10); + sprintf (scmd, "%s%s @%s%s%s%s%s", + program, + (flags & PEXECUTE_SEARCH) != 0 ? ".exe" : "", + rf, + inindex != -1 ? " <" : "", + infile, + outindex != -1 ? " >" : "", + outfile); - if (temp_base == 0) - temp_base = choose_temp_base (); - scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el); - rf = scmd + strlen(program) + 2 + el; - sprintf (scmd, "%s%s @%s.gp", program, - (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base); argfile = fopen (rf, "w"); - if (argfile == 0) + if (argfile == NULL) { - int errno_save = errno; + *err = errno; free (scmd); - errno = errno_save; - *errmsg_fmt = "cannot open `%s.gp'"; - *errmsg_arg = temp_base; + free (rf); + *errmsg = "cannot open temporary command file"; return -1; } - for (i=1; argv[i]; i++) + for (i = 1; argv[i] != NULL; ++i) { - char *cp; - for (cp = argv[i]; *cp; cp++) + char *p; + + for (p = argv[i]; *p != '\0'; ++p) { - if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp)) - fputc ('\\', argfile); - fputc (*cp, argfile); + if (*p == '"' || *p == '\'' || *p == '\\' || ISSPACE (*p)) + putc ('\\', argfile); + putc (*p, argfile); } - fputc ('\n', argfile); + putc ('\n', argfile); } - fclose (argfile); - rc = system (scmd); + fclose (argfile); - { - int errno_save = errno; - remove (rf); - free (scmd); - errno = errno_save; - } + status = system (scmd); - if (rc == -1) + if (status == -1) { - *errmsg_fmt = install_error_msg; - *errmsg_arg = (char *)program; + *err = errno; + remove (rf); + free (scmd); + free (rf); + *errmsg = "system"; return -1; } - /* Tuck the status away for pwait, and return a "pid". */ - last_status = rc << 8; - return last_pid; + remove (rf); + free (scmd); + free (rf); + + /* Save the exit status for later. When we are called, obj->count + is the number of children which have executed before this + one. */ + ms->statuses = XRESIZEVEC(int, ms->statuses, obj->count + 1); + ms->statuses[obj->count] = status; + + return obj->count; } -/* Use ECHILD if available, otherwise use EINVAL. */ -#ifdef ECHILD -#define PWAIT_ERROR ECHILD -#else -#define PWAIT_ERROR EINVAL -#endif +/* Wait for a child process to complete. Actually the child process + has already completed, and we just need to return the exit + status. */ -int -pwait (pid, status, flags) - int pid; - int *status; - int flags; +static int +pex_msdos_wait (struct pex_obj *obj, long pid, int *status, + struct pex_time *time, int done ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED, + int *err ATTRIBUTE_UNUSED) { - /* On MSDOS each pexecute must be followed by its associated pwait. */ - if (pid != last_pid - /* Called twice for the same child? */ - || pid == last_reaped) - { - errno = PWAIT_ERROR; - return -1; - } - /* ??? Here's an opportunity to canonicalize the values in STATUS. - Needed? */ - *status = last_status; - last_reaped = last_pid; - return last_pid; + struct pex_msdos *ms; + + ms = (struct pex_msdos *) obj->sysdep; + + if (time != NULL) + memset (time, 0, sizeof *time); + + *status = ms->statuses[pid]; + + return 0; +} + +/* Clean up the pex_msdos structure. */ + +static void +pex_msdos_cleanup (struct pex_obj *obj) +{ + struct pex_msdos *ms; + int i; + + ms = (struct pex_msdos *) obj->sysdep; + for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i) + if (msdos->files[i] != NULL) + free (msdos->files[i]); + if (msdos->statuses != NULL) + free (msdos->statuses); + free (msdos); + obj->sysdep = NULL; } diff --git a/gnu/lib/libiberty/src/pex-one.c b/gnu/lib/libiberty/src/pex-one.c new file mode 100644 index 00000000000..696b8bcc62a --- /dev/null +++ b/gnu/lib/libiberty/src/pex-one.c @@ -0,0 +1,43 @@ +/* Execute a program and wait for a result. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If not, +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include "libiberty.h" + +const char * +pex_one (int flags, const char *executable, char * const *argv, + const char *pname, const char *outname, const char *errname, + int *status, int *err) +{ + struct pex_obj *obj; + const char *errmsg; + + obj = pex_init (0, pname, NULL); + errmsg = pex_run (obj, flags, executable, argv, outname, errname, err); + if (errmsg == NULL) + { + if (!pex_get_status (obj, 1, status)) + { + *err = 0; + errmsg = "pex_get_status failed"; + } + } + pex_free (obj); + return errmsg; +} diff --git a/gnu/lib/libiberty/src/pex-unix.c b/gnu/lib/libiberty/src/pex-unix.c index 14fe71ed09c..c92a4297971 100644 --- a/gnu/lib/libiberty/src/pex-unix.c +++ b/gnu/lib/libiberty/src/pex-unix.c @@ -1,7 +1,7 @@ /* Utilities to execute a program in a subprocess (possibly linked by pipes with other subprocesses), and wait for it. Generic Unix version (also used for UWIN and VMS). - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the libiberty library. @@ -17,87 +17,357 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ +#include "config.h" +#include "libiberty.h" #include "pex-common.h" #include <stdio.h> +#include <signal.h> #include <errno.h> #ifdef NEED_DECLARATION_ERRNO extern int errno; #endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> + +#include <sys/types.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> #endif #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif +#ifdef HAVE_GETRUSAGE +#include <sys/time.h> +#include <sys/resource.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif -#ifndef HAVE_WAITPID -#define waitpid(pid, status, flags) wait(status) + +#ifdef vfork /* Autoconf may define this to fork for us. */ +# define VFORK_STRING "fork" +#else +# define VFORK_STRING "vfork" +#endif +#ifdef HAVE_VFORK_H +#include <vfork.h> #endif +#ifdef VMS +#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ + lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) +#endif /* VMS */ + -extern int execv (); -extern int execvp (); +/* File mode to use for private and world-readable files. */ + +#if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH) +#define PUBLIC_MODE \ + (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) +#else +#define PUBLIC_MODE 0666 +#endif -int -pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) - const char *program; - char * const *argv; - const char *this_pname; - const char *temp_base ATTRIBUTE_UNUSED; - char **errmsg_fmt, **errmsg_arg; - int flags; +/* Get the exit status of a particular process, and optionally get the + time that it took. This is simple if we have wait4, slightly + harder if we have waitpid, and is a pain if we only have wait. */ + +static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *); + +#ifdef HAVE_WAIT4 + +static pid_t +pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, + struct pex_time *time) { - int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv); - int pid; - int pdes[2]; - int input_desc, output_desc; - int retries, sleep_interval; - /* Pipe waiting from last process, to be used as input for the next one. - Value is STDIN_FILE_NO if no pipe is waiting - (i.e. the next command is the first of a group). */ - static int last_pipe_input; + pid_t ret; + struct rusage r; + +#ifdef HAVE_WAITPID + if (time == NULL) + return waitpid (pid, status, 0); +#endif + + ret = wait4 (pid, status, 0, &r); + + if (time != NULL) + { + time->user_seconds = r.ru_utime.tv_sec; + time->user_microseconds= r.ru_utime.tv_usec; + time->system_seconds = r.ru_stime.tv_sec; + time->system_microseconds= r.ru_stime.tv_usec; + } + + return ret; +} + +#else /* ! defined (HAVE_WAIT4) */ + +#ifdef HAVE_WAITPID + +#ifndef HAVE_GETRUSAGE + +static pid_t +pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, + struct pex_time *time) +{ + if (time != NULL) + memset (time, 0, sizeof (struct pex_time)); + return waitpid (pid, status, 0); +} + +#else /* defined (HAVE_GETRUSAGE) */ + +static pid_t +pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, + struct pex_time *time) +{ + struct rusage r1, r2; + pid_t ret; + + if (time == NULL) + return waitpid (pid, status, 0); - /* If this is the first process, initialize. */ - if (flags & PEXECUTE_FIRST) - last_pipe_input = STDIN_FILE_NO; + getrusage (RUSAGE_CHILDREN, &r1); - input_desc = last_pipe_input; + ret = waitpid (pid, status, 0); + if (ret < 0) + return ret; - /* If this isn't the last process, make a pipe for its output, - and record it as waiting to be the input to the next process. */ - if (! (flags & PEXECUTE_LAST)) + getrusage (RUSAGE_CHILDREN, &r2); + + time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; + time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; + if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec) + { + --time->user_seconds; + time->user_microseconds += 1000000; + } + + time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; + time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; + if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec) + { + --time->system_seconds; + time->system_microseconds += 1000000; + } + + return ret; +} + +#endif /* defined (HAVE_GETRUSAGE) */ + +#else /* ! defined (HAVE_WAITPID) */ + +struct status_list +{ + struct status_list *next; + pid_t pid; + int status; + struct pex_time time; +}; + +static pid_t +pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time) +{ + struct status_list **pp; + + for (pp = (struct status_list **) &obj->sysdep; + *pp != NULL; + pp = &(*pp)->next) { - if (pipe (pdes) < 0) + if ((*pp)->pid == pid) { - *errmsg_fmt = "pipe"; - *errmsg_arg = NULL; - return -1; + struct status_list *p; + + p = *pp; + *status = p->status; + if (time != NULL) + *time = p->time; + *pp = p->next; + free (p); + return pid; } - output_desc = pdes[WRITE_PORT]; - last_pipe_input = pdes[READ_PORT]; } - else + + while (1) { - /* Last process. */ - output_desc = STDOUT_FILE_NO; - last_pipe_input = STDIN_FILE_NO; + pid_t cpid; + struct status_list *psl; + struct pex_time pt; +#ifdef HAVE_GETRUSAGE + struct rusage r1, r2; +#endif + + if (time != NULL) + { +#ifdef HAVE_GETRUSAGE + getrusage (RUSAGE_CHILDREN, &r1); +#else + memset (&pt, 0, sizeof (struct pex_time)); +#endif + } + + cpid = wait (status); + +#ifdef HAVE_GETRUSAGE + if (time != NULL && cpid >= 0) + { + getrusage (RUSAGE_CHILDREN, &r2); + + pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; + pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; + if (pt.user_microseconds < 0) + { + --pt.user_seconds; + pt.user_microseconds += 1000000; + } + + pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; + pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; + if (pt.system_microseconds < 0) + { + --pt.system_seconds; + pt.system_microseconds += 1000000; + } + } +#endif + + if (cpid < 0 || cpid == pid) + { + if (time != NULL) + *time = pt; + return cpid; + } + + psl = XNEW (struct status_list); + psl->pid = cpid; + psl->status = *status; + if (time != NULL) + psl->time = pt; + psl->next = (struct status_list *) obj->sysdep; + obj->sysdep = (void *) psl; } +} + +#endif /* ! defined (HAVE_WAITPID) */ +#endif /* ! defined (HAVE_WAIT4) */ + +static void pex_child_error (struct pex_obj *, const char *, const char *, int) + ATTRIBUTE_NORETURN; +static int pex_unix_open_read (struct pex_obj *, const char *, int); +static int pex_unix_open_write (struct pex_obj *, const char *, int); +static long pex_unix_exec_child (struct pex_obj *, int, const char *, + char * const *, int, int, int, + const char **, int *); +static int pex_unix_close (struct pex_obj *, int); +static int pex_unix_wait (struct pex_obj *, long, int *, struct pex_time *, + int, const char **, int *); +static int pex_unix_pipe (struct pex_obj *, int *, int); +static FILE *pex_unix_fdopenr (struct pex_obj *, int, int); +static FILE *pex_unix_fdopenw (struct pex_obj *, int, int); +static void pex_unix_cleanup (struct pex_obj *); + +/* The list of functions we pass to the common routines. */ + +const struct pex_funcs funcs = +{ + pex_unix_open_read, + pex_unix_open_write, + pex_unix_exec_child, + pex_unix_close, + pex_unix_wait, + pex_unix_pipe, + pex_unix_fdopenr, + pex_unix_fdopenw, + pex_unix_cleanup +}; + +/* Return a newly initialized pex_obj structure. */ + +struct pex_obj * +pex_init (int flags, const char *pname, const char *tempbase) +{ + return pex_init_common (flags, pname, tempbase, &funcs); +} + +/* Open a file for reading. */ + +static int +pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, + int binary ATTRIBUTE_UNUSED) +{ + return open (name, O_RDONLY); +} + +/* Open a file for writing. */ + +static int +pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, + int binary ATTRIBUTE_UNUSED) +{ + /* Note that we can't use O_EXCL here because gcc may have already + created the temporary file via make_temp_file. */ + return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE); +} + +/* Close a file. */ + +static int +pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) +{ + return close (fd); +} + +/* Report an error from a child process. We don't use stdio routines, + because we might be here due to a vfork call. */ + +static void +pex_child_error (struct pex_obj *obj, const char *executable, + const char *errmsg, int err) +{ +#define writeerr(s) write (STDERR_FILE_NO, s, strlen (s)) + writeerr (obj->pname); + writeerr (": error trying to exec '"); + writeerr (executable); + writeerr ("': "); + writeerr (errmsg); + writeerr (": "); + writeerr (xstrerror (err)); + writeerr ("\n"); + _exit (-1); +} + +/* Execute a child. */ + +static long +pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, + char * const * argv, int in, int out, int errdes, + const char **errmsg, int *err) +{ + pid_t pid; + /* We declare these to be volatile to avoid warnings from gcc about + them being clobbered by vfork. */ + volatile int sleep_interval; + volatile int retries; - /* Fork a subprocess; wait and retry if it fails. */ sleep_interval = 1; pid = -1; - for (retries = 0; retries < 4; retries++) + for (retries = 0; retries < 4; ++retries) { - pid = fork (); + pid = vfork (); if (pid >= 0) break; sleep (sleep_interval); @@ -107,60 +377,148 @@ pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) switch (pid) { case -1: - *errmsg_fmt = "fork"; - *errmsg_arg = NULL; + *err = errno; + *errmsg = VFORK_STRING; return -1; - case 0: /* child */ - /* Move the input and output pipes into place, if necessary. */ - if (input_desc != STDIN_FILE_NO) + case 0: + /* Child process. */ + if (in != STDIN_FILE_NO) { - close (STDIN_FILE_NO); - dup (input_desc); - close (input_desc); + if (dup2 (in, STDIN_FILE_NO) < 0) + pex_child_error (obj, executable, "dup2", errno); + if (close (in) < 0) + pex_child_error (obj, executable, "close", errno); } - if (output_desc != STDOUT_FILE_NO) + if (out != STDOUT_FILE_NO) { - close (STDOUT_FILE_NO); - dup (output_desc); - close (output_desc); + if (dup2 (out, STDOUT_FILE_NO) < 0) + pex_child_error (obj, executable, "dup2", errno); + if (close (out) < 0) + pex_child_error (obj, executable, "close", errno); + } + if (errdes != STDERR_FILE_NO) + { + if (dup2 (errdes, STDERR_FILE_NO) < 0) + pex_child_error (obj, executable, "dup2", errno); + if (close (errdes) < 0) + pex_child_error (obj, executable, "close", errno); + } + if ((flags & PEX_STDERR_TO_STDOUT) != 0) + { + if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0) + pex_child_error (obj, executable, "dup2", errno); + } + if ((flags & PEX_SEARCH) != 0) + { + execvp (executable, argv); + pex_child_error (obj, executable, "execvp", errno); + } + else + { + execv (executable, argv); + pex_child_error (obj, executable, "execv", errno); } - /* Close the parent's descs that aren't wanted here. */ - if (last_pipe_input != STDIN_FILE_NO) - close (last_pipe_input); - - /* Exec the program. */ - (*func) (program, argv); - - fprintf (stderr, "%s: ", this_pname); - fprintf (stderr, install_error_msg, program); - fprintf (stderr, ": %s\n", xstrerror (errno)); - exit (-1); /* NOTREACHED */ - return 0; + return -1; default: - /* In the parent, after forking. - Close the descriptors that we made for this child. */ - if (input_desc != STDIN_FILE_NO) - close (input_desc); - if (output_desc != STDOUT_FILE_NO) - close (output_desc); - - /* Return child's process number. */ - return pid; + /* Parent process. */ + if (in != STDIN_FILE_NO) + { + if (close (in) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + if (out != STDOUT_FILE_NO) + { + if (close (out) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + if (errdes != STDERR_FILE_NO) + { + if (close (errdes) < 0) + { + *err = errno; + *errmsg = "close"; + return -1; + } + } + + return (long) pid; + } +} + +/* Wait for a child process to complete. */ + +static int +pex_unix_wait (struct pex_obj *obj, long pid, int *status, + struct pex_time *time, int done, const char **errmsg, + int *err) +{ + /* If we are cleaning up when the caller didn't retrieve process + status for some reason, encourage the process to go away. */ + if (done) + kill (pid, SIGTERM); + + if (pex_wait (obj, pid, status, time) < 0) + { + *err = errno; + *errmsg = "wait"; + return -1; } + + return 0; } -int -pwait (pid, status, flags) - int pid; - int *status; - int flags ATTRIBUTE_UNUSED; +/* Create a pipe. */ + +static int +pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, + int binary ATTRIBUTE_UNUSED) { - /* ??? Here's an opportunity to canonicalize the values in STATUS. - Needed? */ - pid = waitpid (pid, status, 0); - return pid; + return pipe (p); +} + +/* Get a FILE pointer to read from a file descriptor. */ + +static FILE * +pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, + int binary ATTRIBUTE_UNUSED) +{ + return fdopen (fd, "r"); +} + +static FILE * +pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, + int binary ATTRIBUTE_UNUSED) +{ + if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) + return NULL; + return fdopen (fd, "w"); +} + +static void +pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED) +{ +#if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID) + while (obj->sysdep != NULL) + { + struct status_list *this; + struct status_list *next; + + this = (struct status_list *) obj->sysdep; + next = this->next; + free (this); + obj->sysdep = (void *) next; + } +#endif } diff --git a/gnu/lib/libiberty/src/pex-win32.c b/gnu/lib/libiberty/src/pex-win32.c index bd097a4bb05..046f393c6d9 100644 --- a/gnu/lib/libiberty/src/pex-win32.c +++ b/gnu/lib/libiberty/src/pex-win32.c @@ -1,6 +1,6 @@ /* Utilities to execute a program in a subprocess (possibly linked by pipes with other subprocesses), and wait for it. Generic Win32 specialization. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the libiberty library. @@ -16,11 +16,16 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #include "pex-common.h" +#include <windows.h> + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif #ifdef HAVE_STRING_H #include <string.h> #endif @@ -35,6 +40,8 @@ Boston, MA 02111-1307, USA. */ #include <io.h> #include <fcntl.h> #include <signal.h> +#include <sys/stat.h> +#include <errno.h> /* mingw32 headers may not define the following. */ @@ -49,195 +56,740 @@ Boston, MA 02111-1307, USA. */ # define WAIT_GRANDCHILD 1 #endif -/* This is a kludge to get around the Microsoft C spawn functions' propensity - to remove the outermost set of double quotes from all arguments. */ - -static const char * const * -fix_argv (argvec) - char **argvec; -{ - int i; - - for (i = 1; argvec[i] != 0; i++) - { - int len, j; - char *temp, *newtemp; - - temp = argvec[i]; - len = strlen (temp); - for (j = 0; j < len; j++) - { - if (temp[j] == '"') - { - newtemp = xmalloc (len + 2); - strncpy (newtemp, temp, j); - newtemp [j] = '\\'; - strncpy (&newtemp [j+1], &temp [j], len-j); - newtemp [len+1] = 0; - temp = newtemp; - len++; - j++; - } - } - - argvec[i] = temp; - } - - for (i = 0; argvec[i] != 0; i++) - { - if (strpbrk (argvec[i], " \t")) - { - int len, trailing_backslash; - char *temp; - - len = strlen (argvec[i]); - trailing_backslash = 0; - - /* There is an added complication when an arg with embedded white - space ends in a backslash (such as in the case of -iprefix arg - passed to cpp). The resulting quoted strings gets misinterpreted - by the command interpreter -- it thinks that the ending quote - is escaped by the trailing backslash and things get confused. - We handle this case by escaping the trailing backslash, provided - it was not escaped in the first place. */ - if (len > 1 - && argvec[i][len-1] == '\\' - && argvec[i][len-2] != '\\') - { - trailing_backslash = 1; - ++len; /* to escape the final backslash. */ - } +#define MINGW_NAME "Minimalist GNU for Windows" +#define MINGW_NAME_LEN (sizeof(MINGW_NAME) - 1) + +/* Ensure that the executable pathname uses Win32 backslashes. This + is not necessary on NT, but on W9x, forward slashes causes + failure of spawn* and exec* functions (and probably any function + that calls CreateProcess) *iff* the executable pathname (argv[0]) + is a quoted string. And quoting is necessary in case a pathname + contains embedded white space. You can't win. */ +static void +backslashify (char *s) +{ + while ((s = strchr (s, '/')) != NULL) + *s = '\\'; + return; +} - len += 2; /* and for the enclosing quotes. */ +static int pex_win32_open_read (struct pex_obj *, const char *, int); +static int pex_win32_open_write (struct pex_obj *, const char *, int); +static long pex_win32_exec_child (struct pex_obj *, int, const char *, + char * const *, int, int, int, + const char **, int *); +static int pex_win32_close (struct pex_obj *, int); +static int pex_win32_wait (struct pex_obj *, long, int *, + struct pex_time *, int, const char **, int *); +static int pex_win32_pipe (struct pex_obj *, int *, int); +static FILE *pex_win32_fdopenr (struct pex_obj *, int, int); +static FILE *pex_win32_fdopenw (struct pex_obj *, int, int); + +/* The list of functions we pass to the common routines. */ + +const struct pex_funcs funcs = +{ + pex_win32_open_read, + pex_win32_open_write, + pex_win32_exec_child, + pex_win32_close, + pex_win32_wait, + pex_win32_pipe, + pex_win32_fdopenr, + pex_win32_fdopenw, + NULL /* cleanup */ +}; + +/* Return a newly initialized pex_obj structure. */ + +struct pex_obj * +pex_init (int flags, const char *pname, const char *tempbase) +{ + return pex_init_common (flags, pname, tempbase, &funcs); +} + +/* Open a file for reading. */ + +static int +pex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, + int binary) +{ + return _open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT)); +} + +/* Open a file for writing. */ + +static int +pex_win32_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, + int binary) +{ + /* Note that we can't use O_EXCL here because gcc may have already + created the temporary file via make_temp_file. */ + return _open (name, + (_O_WRONLY | _O_CREAT | _O_TRUNC + | (binary ? _O_BINARY : _O_TEXT)), + _S_IREAD | _S_IWRITE); +} - temp = xmalloc (len + 1); - temp[0] = '"'; - strcpy (temp + 1, argvec[i]); - if (trailing_backslash) - temp[len-2] = '\\'; - temp[len-1] = '"'; - temp[len] = '\0'; +/* Close a file. */ - argvec[i] = temp; +static int +pex_win32_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) +{ + return _close (fd); +} + +#ifdef USE_MINGW_MSYS +static const char *mingw_keys[] = {"SOFTWARE", "Microsoft", "Windows", "CurrentVersion", "Uninstall", NULL}; + +/* Tack the executable on the end of a (possibly slash terminated) buffer + and convert everything to \. */ +static const char * +tack_on_executable (char *buf, const char *executable) +{ + char *p = strchr (buf, '\0'); + if (p > buf && (p[-1] == '\\' || p[-1] == '/')) + p[-1] = '\0'; + backslashify (strcat (buf, executable)); + return buf; +} + +/* Walk down a registry hierarchy until the end. Return the key. */ +static HKEY +openkey (HKEY hStart, const char *keys[]) +{ + HKEY hKey, hTmp; + for (hKey = hStart; *keys; keys++) + { + LONG res; + hTmp = hKey; + res = RegOpenKey (hTmp, *keys, &hKey); + + if (hTmp != HKEY_LOCAL_MACHINE) + RegCloseKey (hTmp); + + if (res != ERROR_SUCCESS) + return NULL; + } + return hKey; +} + +/* Return the "mingw root" as derived from the mingw uninstall information. */ +static const char * +mingw_rootify (const char *executable) +{ + HKEY hKey, hTmp; + DWORD maxlen; + char *namebuf, *foundbuf; + DWORD i; + LONG res; + + /* Open the uninstall "directory". */ + hKey = openkey (HKEY_LOCAL_MACHINE, mingw_keys); + + /* Not found. */ + if (!hKey) + return executable; + + /* Need to enumerate all of the keys here looking for one the most recent + one for MinGW. */ + if (RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, &maxlen, NULL, NULL, + NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + RegCloseKey (hKey); + return executable; + } + namebuf = XNEWVEC (char, ++maxlen); + foundbuf = XNEWVEC (char, maxlen); + foundbuf[0] = '\0'; + if (!namebuf || !foundbuf) + { + RegCloseKey (hKey); + if (namebuf) + free (namebuf); + if (foundbuf) + free (foundbuf); + return executable; + } + + /* Look through all of the keys for one that begins with Minimal GNU... + Try to get the latest version by doing a string compare although that + string never really works with version number sorting. */ + for (i = 0; RegEnumKey (hKey, i, namebuf, maxlen) == ERROR_SUCCESS; i++) + { + int match = strcasecmp (namebuf, MINGW_NAME); + if (match < 0) + continue; + if (match > 0 && strncasecmp (namebuf, MINGW_NAME, MINGW_NAME_LEN) > 0) + continue; + if (strcasecmp (namebuf, foundbuf) > 0) + strcpy (foundbuf, namebuf); + } + free (namebuf); + + /* If foundbuf is empty, we didn't find anything. Punt. */ + if (!foundbuf[0]) + { + free (foundbuf); + RegCloseKey (hKey); + return executable; + } + + /* Open the key that we wanted */ + res = RegOpenKey (hKey, foundbuf, &hTmp); + RegCloseKey (hKey); + free (foundbuf); + + /* Don't know why this would fail, but you gotta check */ + if (res != ERROR_SUCCESS) + return executable; + + maxlen = 0; + /* Get the length of the value pointed to by InstallLocation */ + if (RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, NULL, + &maxlen) != ERROR_SUCCESS || maxlen == 0) + { + RegCloseKey (hTmp); + return executable; + } + + /* Allocate space for the install location */ + foundbuf = XNEWVEC (char, maxlen + strlen (executable)); + if (!foundbuf) + { + free (foundbuf); + RegCloseKey (hTmp); + } + + /* Read the install location into the buffer */ + res = RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, (LPBYTE) foundbuf, + &maxlen); + RegCloseKey (hTmp); + if (res != ERROR_SUCCESS) + { + free (foundbuf); + return executable; + } + + /* Concatenate the install location and the executable, turn all slashes + to backslashes, and return that. */ + return tack_on_executable (foundbuf, executable); +} + +/* Read the install location of msys from it's installation file and + rootify the executable based on that. */ +static const char * +msys_rootify (const char *executable) +{ + size_t bufsize = 64; + size_t execlen = strlen (executable) + 1; + char *buf; + DWORD res = 0; + for (;;) + { + buf = XNEWVEC (char, bufsize + execlen); + if (!buf) + break; + res = GetPrivateProfileString ("InstallSettings", "InstallPath", NULL, + buf, bufsize, "msys.ini"); + if (!res) + break; + if (strlen (buf) < bufsize) + break; + res = 0; + free (buf); + bufsize *= 2; + if (bufsize > 65536) + { + buf = NULL; + break; } } - return (const char * const *) argvec; + if (res) + return tack_on_executable (buf, executable); + + /* failed */ + if (buf) + free (buf); + return executable; } +#endif -/* Win32 supports pipes */ -int -pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) - const char *program; - char * const *argv; - const char *this_pname; - const char *temp_base; - char **errmsg_fmt, **errmsg_arg; - int flags; -{ - int pid; - int pdes[2], org_stdin, org_stdout; - int input_desc, output_desc; - int retries, sleep_interval; - - /* Pipe waiting from last process, to be used as input for the next one. - Value is STDIN_FILE_NO if no pipe is waiting - (i.e. the next command is the first of a group). */ - static int last_pipe_input; - - /* If this is the first process, initialize. */ - if (flags & PEXECUTE_FIRST) - last_pipe_input = STDIN_FILE_NO; - - input_desc = last_pipe_input; - - /* If this isn't the last process, make a pipe for its output, - and record it as waiting to be the input to the next process. */ - if (! (flags & PEXECUTE_LAST)) - { - if (_pipe (pdes, 256, O_BINARY) < 0) +/* Return a Windows command-line from ARGV. It is the caller's + responsibility to free the string returned. */ + +static char * +argv_to_cmdline (char *const *argv) +{ + char *cmdline; + char *p; + size_t cmdline_len; + int i, j, k; + + cmdline_len = 0; + for (i = 0; argv[i]; i++) + { + /* We quote every last argument. This simplifies the problem; + we need only escape embedded double-quotes and immediately + preceeding backslash characters. A sequence of backslach characters + that is not follwed by a double quote character will not be + escaped. */ + for (j = 0; argv[i][j]; j++) { - *errmsg_fmt = "pipe"; - *errmsg_arg = NULL; - return -1; + if (argv[i][j] == '"') + { + /* Escape preceeding backslashes. */ + for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) + cmdline_len++; + /* Escape the qote character. */ + cmdline_len++; + } } - output_desc = pdes[WRITE_PORT]; - last_pipe_input = pdes[READ_PORT]; + /* Trailing backslashes also need to be escaped because they will be + followed by the terminating quote. */ + for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) + cmdline_len++; + cmdline_len += j; + cmdline_len += 3; /* for leading and trailing quotes and space */ } - else + cmdline = xmalloc (cmdline_len); + p = cmdline; + for (i = 0; argv[i]; i++) { - /* Last process. */ - output_desc = STDOUT_FILE_NO; - last_pipe_input = STDIN_FILE_NO; + *p++ = '"'; + for (j = 0; argv[i][j]; j++) + { + if (argv[i][j] == '"') + { + for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) + *p++ = '\\'; + *p++ = '\\'; + } + *p++ = argv[i][j]; + } + for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) + *p++ = '\\'; + *p++ = '"'; + *p++ = ' '; } + p[-1] = '\0'; + return cmdline; +} - if (input_desc != STDIN_FILE_NO) +static const char *const +std_suffixes[] = { + ".com", + ".exe", + ".bat", + ".cmd", + 0 +}; +static const char *const +no_suffixes[] = { + "", + 0 +}; + +/* Returns the full path to PROGRAM. If SEARCH is true, look for + PROGRAM in each directory in PATH. */ + +static char * +find_executable (const char *program, BOOL search) +{ + char *full_executable; + char *e; + size_t fe_len; + const char *path = 0; + const char *const *ext; + const char *p, *q; + size_t proglen = strlen (program); + int has_extension = !!strchr (program, '.'); + int has_slash = (strchr (program, '/') || strchr (program, '\\')); + HANDLE h; + + if (has_slash) + search = FALSE; + + if (search) + path = getenv ("PATH"); + if (!path) + path = ""; + + fe_len = 0; + for (p = path; *p; p = q) { - org_stdin = dup (STDIN_FILE_NO); - dup2 (input_desc, STDIN_FILE_NO); - close (input_desc); + q = p; + while (*q != ';' && *q != '\0') + q++; + if ((size_t)(q - p) > fe_len) + fe_len = q - p; + if (*q == ';') + q++; } + fe_len = fe_len + 1 + proglen + (has_extension ? 1 : 5); + full_executable = xmalloc (fe_len); - if (output_desc != STDOUT_FILE_NO) + p = path; + do { - org_stdout = dup (STDOUT_FILE_NO); - dup2 (output_desc, STDOUT_FILE_NO); - close (output_desc); + q = p; + while (*q != ';' && *q != '\0') + q++; + + e = full_executable; + memcpy (e, p, q - p); + e += (q - p); + if (q - p) + *e++ = '\\'; + strcpy (e, program); + + if (*q == ';') + q++; + + for (e = full_executable; *e; e++) + if (*e == '/') + *e = '\\'; + + /* At this point, e points to the terminating NUL character for + full_executable. */ + for (ext = has_extension ? no_suffixes : std_suffixes; *ext; ext++) + { + /* Remove any current extension. */ + *e = '\0'; + /* Add the new one. */ + strcat (full_executable, *ext); + + /* Attempt to open this file. */ + h = CreateFile (full_executable, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (h != INVALID_HANDLE_VALUE) + goto found; + } + p = q; } + while (*p); + free (full_executable); + return 0; + + found: + CloseHandle (h); + return full_executable; +} - pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv) - (_P_NOWAIT, program, fix_argv(argv)); +/* Low-level process creation function. */ - if (input_desc != STDIN_FILE_NO) +static long +win32_spawn (const char *executable, + BOOL search, + char *const *argv, + DWORD dwCreationFlags, + LPSTARTUPINFO si, + LPPROCESS_INFORMATION pi) +{ + char *full_executable; + char *cmdline; + + full_executable = NULL; + cmdline = NULL; + + full_executable = find_executable (executable, search); + if (!full_executable) + goto error; + cmdline = argv_to_cmdline (argv); + if (!cmdline) + goto error; + + /* Create the child process. */ + if (!CreateProcess (full_executable, cmdline, + /*lpProcessAttributes=*/NULL, + /*lpThreadAttributes=*/NULL, + /*bInheritHandles=*/TRUE, + dwCreationFlags, + /*lpEnvironment=*/NULL, + /*lpCurrentDirectory=*/NULL, + si, + pi)) { - dup2 (org_stdin, STDIN_FILE_NO); - close (org_stdin); + free (full_executable); + return -1; } - if (output_desc != STDOUT_FILE_NO) + /* Clean up. */ + CloseHandle (pi->hThread); + free (full_executable); + + return (long) pi->hProcess; + + error: + if (cmdline) + free (cmdline); + if (full_executable) + free (full_executable); + return -1; +} + +static long +spawn_script (const char *executable, char *const *argv, + DWORD dwCreationFlags, + LPSTARTUPINFO si, + LPPROCESS_INFORMATION pi) +{ + int pid = -1; + int save_errno = errno; + int fd = _open (executable, _O_RDONLY); + + if (fd >= 0) { - dup2 (org_stdout, STDOUT_FILE_NO); - close (org_stdout); + char buf[MAX_PATH + 5]; + int len = _read (fd, buf, sizeof (buf) - 1); + _close (fd); + if (len > 3) + { + char *eol; + buf[len] = '\0'; + eol = strchr (buf, '\n'); + if (eol && strncmp (buf, "#!", 2) == 0) + { + char *executable1; + const char ** avhere = (const char **) --argv; + do + *eol = '\0'; + while (*--eol == '\r' || *eol == ' ' || *eol == '\t'); + for (executable1 = buf + 2; *executable1 == ' ' || *executable1 == '\t'; executable1++) + continue; + + backslashify (executable1); + *avhere = executable1; +#ifndef USE_MINGW_MSYS + executable = strrchr (executable1, '\\') + 1; + if (!executable) + executable = executable1; + pid = win32_spawn (executable, TRUE, argv, + dwCreationFlags, si, pi); +#else + if (strchr (executable1, '\\') == NULL) + pid = win32_spawn (executable1, TRUE, argv, + dwCreationFlags, si, pi); + else if (executable1[0] != '\\') + pid = win32_spawn (executable1, FALSE, argv, + dwCreationFlags, si, pi); + else + { + const char *newex = mingw_rootify (executable1); + *avhere = newex; + pid = win32_spawn (newex, FALSE, argv, + dwCreationFlags, si, pi); + if (executable1 != newex) + free ((char *) newex); + if (pid < 0) + { + newex = msys_rootify (executable1); + if (newex != executable1) + { + *avhere = newex; + pid = win32_spawn (newex, FALSE, argv, + dwCreationFlags, si, pi); + free ((char *) newex); + } + } + } +#endif + } + } } + if (pid < 0) + errno = save_errno; + return pid; +} +/* Execute a child. */ + +static long +pex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags, + const char *executable, char * const * argv, + int in, int out, int errdes, const char **errmsg, + int *err) +{ + long pid; + HANDLE stdin_handle; + HANDLE stdout_handle; + HANDLE stderr_handle; + DWORD dwCreationFlags; + OSVERSIONINFO version_info; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + stdin_handle = INVALID_HANDLE_VALUE; + stdout_handle = INVALID_HANDLE_VALUE; + stderr_handle = INVALID_HANDLE_VALUE; + + stdin_handle = (HANDLE) _get_osfhandle (in); + stdout_handle = (HANDLE) _get_osfhandle (out); + if (!(flags & PEX_STDERR_TO_STDOUT)) + stderr_handle = (HANDLE) _get_osfhandle (errdes); + else + stderr_handle = stdout_handle; + + /* Determine the version of Windows we are running on. */ + version_info.dwOSVersionInfoSize = sizeof (version_info); + GetVersionEx (&version_info); + if (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) + /* On Windows 95/98/ME the CREATE_NO_WINDOW flag is not + supported, so we cannot avoid creating a console window. */ + dwCreationFlags = 0; + else + { + HANDLE conout_handle; + + /* Determine whether or not we have an associated console. */ + conout_handle = CreateFile("CONOUT$", + GENERIC_WRITE, + FILE_SHARE_WRITE, + /*lpSecurityAttributes=*/NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + /*hTemplateFile=*/NULL); + if (conout_handle == INVALID_HANDLE_VALUE) + /* There is no console associated with this process. Since + the child is a console process, the OS would normally + create a new console Window for the child. Since we'll be + redirecting the child's standard streams, we do not need + the console window. */ + dwCreationFlags = CREATE_NO_WINDOW; + else + { + /* There is a console associated with the process, so the OS + will not create a new console. And, if we use + CREATE_NO_WINDOW in this situation, the child will have + no associated console. Therefore, if the child's + standard streams are connected to the console, the output + will be discarded. */ + CloseHandle(conout_handle); + dwCreationFlags = 0; + } + } + + /* Since the child will be a console process, it will, by default, + connect standard input/output to its console. However, we want + the child to use the handles specifically designated above. In + addition, if there is no console (such as when we are running in + a Cygwin X window), then we must redirect the child's + input/output, as there is no console for the child to use. */ + memset (&si, 0, sizeof (si)); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = stdin_handle; + si.hStdOutput = stdout_handle; + si.hStdError = stderr_handle; + + /* Create the child process. */ + pid = win32_spawn (executable, (flags & PEX_SEARCH) != 0, + argv, dwCreationFlags, &si, &pi); + if (pid == -1) + pid = spawn_script (executable, argv, dwCreationFlags, &si, &pi); if (pid == -1) { - *errmsg_fmt = install_error_msg; - *errmsg_arg = program; - return -1; + *err = ENOENT; + *errmsg = "CreateProcess"; } + /* Close the standard output and standard error handles in the + parent. */ + if (out != STDOUT_FILENO) + obj->funcs->close (obj, out); + if (errdes != STDERR_FILENO) + obj->funcs->close (obj, errdes); + return pid; } -/* MS CRTDLL doesn't return enough information in status to decide if the - child exited due to a signal or not, rather it simply returns an - integer with the exit code of the child; eg., if the child exited with - an abort() call and didn't have a handler for SIGABRT, it simply returns - with status = 3. We fix the status code to conform to the usual WIF* - macros. Note that WIFSIGNALED will never be true under CRTDLL. */ - -int -pwait (pid, status, flags) - int pid; - int *status; - int flags; +/* Wait for a child process to complete. MS CRTDLL doesn't return + enough information in status to decide if the child exited due to a + signal or not, rather it simply returns an integer with the exit + code of the child; eg., if the child exited with an abort() call + and didn't have a handler for SIGABRT, it simply returns with + status == 3. We fix the status code to conform to the usual WIF* + macros. Note that WIFSIGNALED will never be true under CRTDLL. */ + +static int +pex_win32_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, long pid, + int *status, struct pex_time *time, int done ATTRIBUTE_UNUSED, + const char **errmsg, int *err) { - int termstat; + DWORD termstat; + HANDLE h; - pid = _cwait (&termstat, pid, WAIT_CHILD); + if (time != NULL) + memset (time, 0, sizeof *time); - /* ??? Here's an opportunity to canonicalize the values in STATUS. - Needed? */ + h = (HANDLE) pid; + + /* FIXME: If done is non-zero, we should probably try to kill the + process. */ + if (WaitForSingleObject (h, INFINITE) != WAIT_OBJECT_0) + { + CloseHandle (h); + *err = ECHILD; + *errmsg = "WaitForSingleObject"; + return -1; + } - /* cwait returns the child process exit code in termstat. - A value of 3 indicates that the child caught a signal, but not + GetExitCodeProcess (h, &termstat); + CloseHandle (h); + + /* A value of 3 indicates that the child caught a signal, but not which one. Since only SIGABRT, SIGFPE and SIGINT do anything, we report SIGABRT. */ if (termstat == 3) *status = SIGABRT; else - *status = (((termstat) & 0xff) << 8); + *status = (termstat & 0xff) << 8; - return pid; + return 0; +} + +/* Create a pipe. */ + +static int +pex_win32_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, + int binary) +{ + return _pipe (p, 256, binary ? _O_BINARY : _O_TEXT); +} + +/* Get a FILE pointer to read from a file descriptor. */ + +static FILE * +pex_win32_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, + int binary) +{ + return fdopen (fd, binary ? "rb" : "r"); +} + +static FILE * +pex_win32_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, + int binary) +{ + HANDLE h = (HANDLE) _get_osfhandle (fd); + if (h == INVALID_HANDLE_VALUE) + return NULL; + if (! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0)) + return NULL; + return fdopen (fd, binary ? "wb" : "w"); +} + +#ifdef MAIN +#include <stdio.h> + +int +main (int argc ATTRIBUTE_UNUSED, char **argv) +{ + char const *errmsg; + int err; + argv++; + printf ("%ld\n", pex_win32_exec_child (NULL, PEX_SEARCH, argv[0], argv, 0, 1, 2, &errmsg, &err)); + exit (0); } +#endif diff --git a/gnu/lib/libiberty/src/pexecute.txh b/gnu/lib/libiberty/src/pexecute.txh index 269f031cc72..7d45576eece 100644 --- a/gnu/lib/libiberty/src/pexecute.txh +++ b/gnu/lib/libiberty/src/pexecute.txh @@ -1,63 +1,261 @@ -@deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int flags) +@c -*- mode: texinfo -*- +@deftypefn Extension {struct pex_obj *} pex_init (int @var{flags}, const char *@var{pname}, const char *@var{tempbase}) -Executes a program. +Prepare to execute one or more programs, with standard output of each +program fed to standard input of the next. This is a system +independent interface to execute a pipeline. -@var{program} and @var{argv} are the arguments to -@code{execv}/@code{execvp}. +@var{flags} is a bitwise combination of the following: -@var{this_pname} is name of the calling program (i.e., @code{argv[0]}). +@table @code -@var{temp_base} is the path name, sans suffix, of a temporary file to -use if needed. This is currently only needed for MS-DOS ports that -don't use @code{go32} (do any still exist?). Ports that don't need it -can pass @code{NULL}. +@vindex PEX_RECORD_TIMES +@item PEX_RECORD_TIMES +Record subprocess times if possible. -(@code{@var{flags} & PEXECUTE_SEARCH}) is non-zero if @env{PATH} -should be searched (??? It's not clear that GCC passes this flag -correctly). (@code{@var{flags} & PEXECUTE_FIRST}) is nonzero for the -first process in chain. (@code{@var{flags} & PEXECUTE_FIRST}) is -nonzero for the last process in chain. The first/last flags could be -simplified to only mark the last of a chain of processes but that -requires the caller to always mark the last one (and not give up -early if some error occurs). It's more robust to require the caller -to mark both ends of the chain. +@vindex PEX_USE_PIPES +@item PEX_USE_PIPES +Use pipes for communication between processes, if possible. -The result is the pid on systems like Unix where we -@code{fork}/@code{exec} and on systems like WIN32 and OS/2 where we -use @code{spawn}. It is up to the caller to wait for the child. +@vindex PEX_SAVE_TEMPS +@item PEX_SAVE_TEMPS +Don't delete temporary files used for communication between +processes. -The result is the @code{WEXITSTATUS} on systems like MS-DOS where we -@code{spawn} and wait for the child here. +@end table -Upon failure, @var{errmsg_fmt} and @var{errmsg_arg} are set to the -text of the error message with an optional argument (if not needed, -@var{errmsg_arg} is set to @code{NULL}), and @minus{}1 is returned. -@code{errno} is available to the caller to use. +@var{pname} is the name of program to be executed, used in error +messages. @var{tempbase} is a base name to use for any required +temporary files; it may be @code{NULL} to use a randomly chosen name. @end deftypefn -@deftypefn Extension int pwait (int @var{pid}, int *@var{status}, int @var{flags}) +@deftypefn Extension {const char *} pex_run (struct pex_obj *@var{obj}, int @var{flags}, const char *@var{executable}, char * const *@var{argv}, const char *@var{outname}, const char *@var{errname}, int *@var{err}) + +Execute one program in a pipeline. On success this returns +@code{NULL}. On failure it returns an error message, a statically +allocated string. + +@var{obj} is returned by a previous call to @code{pex_init}. + +@var{flags} is a bitwise combination of the following: + +@table @code + +@vindex PEX_LAST +@item PEX_LAST +This must be set on the last program in the pipeline. In particular, +it should be set when executing a single program. The standard output +of the program will be sent to @var{outname}, or, if @var{outname} is +@code{NULL}, to the standard output of the calling program. Do @emph{not} +set this bit if you want to call @code{pex_read_output} +(described below). After a call to @code{pex_run} with this bit set, +@var{pex_run} may no longer be called with the same @var{obj}. + +@vindex PEX_SEARCH +@item PEX_SEARCH +Search for the program using the user's executable search path. + +@vindex PEX_SUFFIX +@item PEX_SUFFIX +@var{outname} is a suffix. See the description of @var{outname}, +below. + +@vindex PEX_STDERR_TO_STDOUT +@item PEX_STDERR_TO_STDOUT +Send the program's standard error to standard output, if possible. + +@vindex PEX_BINARY_INPUT +@vindex PEX_BINARY_OUTPUT +@item PEX_BINARY_INPUT +@itemx PEX_BINARY_OUTPUT +The standard input (output) of the program should be read (written) in +binary mode rather than text mode. These flags are ignored on systems +which do not distinguish binary mode and text mode, such as Unix. For +proper behavior these flags should match appropriately---a call to +@code{pex_run} using @code{PEX_BINARY_OUTPUT} should be followed by a +call using @code{PEX_BINARY_INPUT}. +@end table + +@var{executable} is the program to execute. @var{argv} is the set of +arguments to pass to the program; normally @code{@var{argv}[0]} will +be a copy of @var{executable}. + +@var{outname} is used to set the name of the file to use for standard +output. There are two cases in which no output file will be used: + +@enumerate +@item +if @code{PEX_LAST} is not set in @var{flags}, and @code{PEX_USE_PIPES} +was set in the call to @code{pex_init}, and the system supports pipes + +@item +if @code{PEX_LAST} is set in @var{flags}, and @var{outname} is +@code{NULL} +@end enumerate + +@noindent +Otherwise the code will use a file to hold standard +output. If @code{PEX_LAST} is not set, this file is considered to be +a temporary file, and it will be removed when no longer needed, unless +@code{PEX_SAVE_TEMPS} was set in the call to @code{pex_init}. + +There are two cases to consider when setting the name of the file to +hold standard output. + +@enumerate +@item +@code{PEX_SUFFIX} is set in @var{flags}. In this case +@var{outname} may not be @code{NULL}. If the @var{tempbase} parameter +to @code{pex_init} was not @code{NULL}, then the output file name is +the concatenation of @var{tempbase} and @var{outname}. If +@var{tempbase} was @code{NULL}, then the output file name is a random +file name ending in @var{outname}. + +@item +@code{PEX_SUFFIX} was not set in @var{flags}. In this +case, if @var{outname} is not @code{NULL}, it is used as the output +file name. If @var{outname} is @code{NULL}, and @var{tempbase} was +not NULL, the output file name is randomly chosen using +@var{tempbase}. Otherwise the output file name is chosen completely +at random. +@end enumerate + +@var{errname} is the file name to use for standard error output. If +it is @code{NULL}, standard error is the same as the caller's. +Otherwise, standard error is written to the named file. + +On an error return, the code sets @code{*@var{err}} to an @code{errno} +value, or to 0 if there is no relevant @code{errno}. + +@end deftypefn + +@deftypefn Extension {FILE *} pex_input_file (struct pex_obj *@var{obj}, int @var{flags}, const char *@var{in_name}) + +Return a stream for a temporary file to pass to the first program in +the pipeline as input. + +The name of the input file is chosen according to the same rules +@code{pex_run} uses to choose output file names, based on +@var{in_name}, @var{obj} and the @code{PEX_SUFFIX} bit in @var{flags}. + +Don't call @code{fclose} on the returned stream; the first call to +@code{pex_run} closes it automatically. + +If @var{flags} includes @code{PEX_BINARY_OUTPUT}, open the stream in +binary mode; otherwise, open it in the default mode. Including +@code{PEX_BINARY_OUTPUT} in @var{flags} has no effect on Unix. +@end deftypefn + +@deftypefn Extension {FILE *} pex_input_pipe (struct pex_obj *@var{obj}, int @var{binary}) + +Return a stream @var{fp} for a pipe connected to the standard input of +the first program in the pipeline; @var{fp} is opened for writing. +You must have passed @code{PEX_USE_PIPES} to the @code{pex_init} call +that returned @var{obj}. -Waits for a program started by @code{pexecute} to finish. +You must close @var{fp} using @code{fclose} yourself when you have +finished writing data to the pipeline. -@var{pid} is the process id of the task to wait for. @var{status} is -the `status' argument to wait. @var{flags} is currently unused -(allows future enhancement without breaking upward compatibility). -Pass 0 for now. +The file descriptor underlying @var{fp} is marked not to be inherited +by child processes. -The result is the pid of the child reaped, or -1 for failure -(@code{errno} says why). +On systems that do not support pipes, this function returns +@code{NULL}, and sets @code{errno} to @code{EINVAL}. If you would +like to write code that is portable to all systems the @code{pex} +functions support, consider using @code{pex_input_file} instead. -On systems that don't support waiting for a particular child, -@var{pid} is ignored. On systems like MS-DOS that don't really -multitask @code{pwait} is just a mechanism to provide a consistent -interface for the caller. +There are two opportunities for deadlock using +@code{pex_input_pipe}: + +@itemize @bullet +@item +Most systems' pipes can buffer only a fixed amount of data; a process +that writes to a full pipe blocks. Thus, if you write to @file{fp} +before starting the first process, you run the risk of blocking when +there is no child process yet to read the data and allow you to +continue. @code{pex_input_pipe} makes no promises about the +size of the pipe's buffer, so if you need to write any data at all +before starting the first process in the pipeline, consider using +@code{pex_input_file} instead. + +@item +Using @code{pex_input_pipe} and @code{pex_read_output} together +may also cause deadlock. If the output pipe fills up, so that each +program in the pipeline is waiting for the next to read more data, and +you fill the input pipe by writing more data to @var{fp}, then there +is no way to make progress: the only process that could read data from +the output pipe is you, but you are blocked on the input pipe. + +@end itemize + +@end deftypefn + +@deftypefn Extension {FILE *} pex_read_output (struct pex_obj *@var{obj}, int @var{binary}) + +Returns a @code{FILE} pointer which may be used to read the standard +output of the last program in the pipeline. When this is used, +@code{PEX_LAST} should not be used in a call to @code{pex_run}. After +this is called, @code{pex_run} may no longer be called with the same +@var{obj}. @var{binary} should be non-zero if the file should be +opened in binary mode. Don't call @code{fclose} on the returned file; +it will be closed by @code{pex_free}. + +@end deftypefn + +@deftypefn Extension int pex_get_status (struct pex_obj *@var{obj}, int @var{count}, int *@var{vector}) + +Returns the exit status of all programs run using @var{obj}. +@var{count} is the number of results expected. The results will be +placed into @var{vector}. The results are in the order of the calls +to @code{pex_run}. Returns 0 on error, 1 on success. + +@end deftypefn + +@deftypefn Extension int pex_get_times (struct pex_obj *@var{obj}, int @var{count}, struct pex_time *@var{vector}) + +Returns the process execution times of all programs run using +@var{obj}. @var{count} is the number of results expected. The +results will be placed into @var{vector}. The results are in the +order of the calls to @code{pex_run}. Returns 0 on error, 1 on +success. + +@code{struct pex_time} has the following fields of the type +@code{unsigned long}: @code{user_seconds}, +@code{user_microseconds}, @code{system_seconds}, +@code{system_microseconds}. On systems which do not support reporting +process times, all the fields will be set to @code{0}. @end deftypefn -@undocumented pfinish +@deftypefn Extension void pex_free (struct pex_obj @var{obj}) -pfinish: finish generation of script +Clean up and free all data associated with @var{obj}. -pfinish is necessary for systems like MPW where a script is generated -that runs the requested programs. +@end deftypefn + +@deftypefn Extension {const char *} pex_one (int @var{flags}, const char *@var{executable}, char * const *@var{argv}, const char *@var{pname}, const char *@var{outname}, const char *@var{errname}, int *@var{status}, int *@var{err}) + +An interface to permit the easy execution of a +single program. The return value and most of the parameters are as +for a call to @code{pex_run}. @var{flags} is restricted to a +combination of @code{PEX_SEARCH}, @code{PEX_STDERR_TO_STDOUT}, and +@code{PEX_BINARY_OUTPUT}. @var{outname} is interpreted as if +@code{PEX_LAST} were set. On a successful return, @code{*@var{status}} will +be set to the exit status of the program. + +@end deftypefn + +@deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int flags) + +This is the old interface to execute one or more programs. It is +still supported for compatibility purposes, but is no longer +documented. + +@end deftypefn + +@deftypefn Extension int pwait (int @var{pid}, int *@var{status}, int @var{flags}) + +Another part of the old execution interface. + +@end deftypefn diff --git a/gnu/lib/libiberty/src/putenv.c b/gnu/lib/libiberty/src/putenv.c index 6d027dc5aaa..248f50e9203 100644 --- a/gnu/lib/libiberty/src/putenv.c +++ b/gnu/lib/libiberty/src/putenv.c @@ -13,8 +13,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ /* @@ -67,8 +67,7 @@ extern char *alloca (); /* Put STRING, which is of the form "NAME=VALUE", in the environment. */ int -putenv (string) - const char *string; +putenv (const char *string) { const char *const name_end = strchr (string, '='); diff --git a/gnu/lib/libiberty/src/random.c b/gnu/lib/libiberty/src/random.c index 48035f0821f..c306698a538 100644 --- a/gnu/lib/libiberty/src/random.c +++ b/gnu/lib/libiberty/src/random.c @@ -80,7 +80,7 @@ control over the state of the random number generator. #endif -long int random (); +long int random (void); /* An improved random number generation package. In addition to the standard rand()/srand() like interface, this package also has a special state info @@ -227,8 +227,7 @@ static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])]; introduced by the L.C.R.N.G. Note that the initialization of randtbl[] for default usage relies on values produced by this routine. */ void -srandom (x) - unsigned int x; +srandom (unsigned int x) { state[0] = x; if (rand_type != TYPE_0) @@ -255,10 +254,7 @@ srandom (x) setstate so that it doesn't matter when initstate is called. Returns a pointer to the old state. */ PTR -initstate (seed, arg_state, n) - unsigned int seed; - PTR arg_state; - unsigned long n; +initstate (unsigned int seed, PTR arg_state, unsigned long n) { PTR ostate = (PTR) &state[-1]; @@ -324,8 +320,7 @@ initstate (seed, arg_state, n) Returns a pointer to the old state information. */ PTR -setstate (arg_state) - PTR arg_state; +setstate (PTR arg_state) { register long int *new_state = (long int *) arg_state; register int type = new_state[0] % MAX_TYPES; @@ -378,7 +373,7 @@ setstate (arg_state) pointer if the front one has wrapped. Returns a 31-bit random number. */ long int -random () +random (void) { if (rand_type == TYPE_0) { diff --git a/gnu/lib/libiberty/src/regex.c b/gnu/lib/libiberty/src/regex.c index e3439b2ff63..fa1df197ce9 100644 --- a/gnu/lib/libiberty/src/regex.c +++ b/gnu/lib/libiberty/src/regex.c @@ -2,7 +2,9 @@ version 0.12. (Implements POSIX draft P1003.2/D11.2, except for some of the internationalization features.) - Copyright (C) 1993-1999, 2000, 2001, 2002 Free Software Foundation, Inc. + + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,8 +19,8 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. */ /* This file has been modified for usage in libiberty. It includes "xregex.h" instead of <regex.h>. The "xregex.h" header file renames all external @@ -32,17 +34,13 @@ #undef _GNU_SOURCE #define _GNU_SOURCE -#ifdef HAVE_CONFIG_H -# include <config.h> +#ifndef INSIDE_RECURSION +# ifdef HAVE_CONFIG_H +# include <config.h> +# endif #endif -#ifndef PARAMS -# if defined __GNUC__ || (defined __STDC__ && __STDC__) -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif /* GCC. */ -#endif /* Not PARAMS. */ +#include <ansidecl.h> #ifndef INSIDE_RECURSION @@ -273,10 +271,10 @@ extern char *re_syntax_table; static char re_syntax_table[CHAR_SET_SIZE]; -static void init_syntax_once PARAMS ((void)); +static void init_syntax_once (void); static void -init_syntax_once () +init_syntax_once (void) { register int c; static int done = 0; @@ -407,44 +405,44 @@ typedef char boolean; # define false 0 # define true 1 -static reg_errcode_t byte_regex_compile _RE_ARGS ((const char *pattern, size_t size, - reg_syntax_t syntax, - struct re_pattern_buffer *bufp)); - -static int byte_re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp, - const char *string1, int size1, - const char *string2, int size2, - int pos, - struct re_registers *regs, - int stop)); -static int byte_re_search_2 PARAMS ((struct re_pattern_buffer *bufp, - const char *string1, int size1, - const char *string2, int size2, - int startpos, int range, - struct re_registers *regs, int stop)); -static int byte_re_compile_fastmap PARAMS ((struct re_pattern_buffer *bufp)); +static reg_errcode_t byte_regex_compile (const char *pattern, size_t size, + reg_syntax_t syntax, + struct re_pattern_buffer *bufp); + +static int byte_re_match_2_internal (struct re_pattern_buffer *bufp, + const char *string1, int size1, + const char *string2, int size2, + int pos, + struct re_registers *regs, + int stop); +static int byte_re_search_2 (struct re_pattern_buffer *bufp, + const char *string1, int size1, + const char *string2, int size2, + int startpos, int range, + struct re_registers *regs, int stop); +static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp); #ifdef MBS_SUPPORT -static reg_errcode_t wcs_regex_compile _RE_ARGS ((const char *pattern, size_t size, - reg_syntax_t syntax, - struct re_pattern_buffer *bufp)); - - -static int wcs_re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp, - const char *cstring1, int csize1, - const char *cstring2, int csize2, - int pos, - struct re_registers *regs, - int stop, - wchar_t *string1, int size1, - wchar_t *string2, int size2, - int *mbs_offset1, int *mbs_offset2)); -static int wcs_re_search_2 PARAMS ((struct re_pattern_buffer *bufp, - const char *string1, int size1, - const char *string2, int size2, - int startpos, int range, - struct re_registers *regs, int stop)); -static int wcs_re_compile_fastmap PARAMS ((struct re_pattern_buffer *bufp)); +static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size, + reg_syntax_t syntax, + struct re_pattern_buffer *bufp); + + +static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp, + const char *cstring1, int csize1, + const char *cstring2, int csize2, + int pos, + struct re_registers *regs, + int stop, + wchar_t *string1, int size1, + wchar_t *string2, int size2, + int *mbs_offset1, int *mbs_offset2); +static int wcs_re_search_2 (struct re_pattern_buffer *bufp, + const char *string1, int size1, + const char *string2, int size2, + int startpos, int range, + struct re_registers *regs, int stop); +static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp); #endif /* These are the command codes that appear in compiled regular @@ -612,11 +610,7 @@ typedef enum # define UCHAR_T unsigned char # define COMPILED_BUFFER_VAR bufp->buffer # define OFFSET_ADDRESS_SIZE 2 -# if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) -# define PREFIX(name) byte_##name -# else -# define PREFIX(name) byte_/**/name -# endif +# define PREFIX(name) byte_##name # define ARG_PREFIX(name) name # define PUT_CHAR(c) putchar (c) #else @@ -626,13 +620,8 @@ typedef enum # define COMPILED_BUFFER_VAR wc_buffer # define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */ # define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1) -# if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) -# define PREFIX(name) wcs_##name -# define ARG_PREFIX(name) c##name -# else -# define PREFIX(name) wcs_/**/name -# define ARG_PREFIX(name) c/**/name -# endif +# define PREFIX(name) wcs_##name +# define ARG_PREFIX(name) c##name /* Should we use wide stream?? */ # define PUT_CHAR(c) printf ("%C", c); # define TRUE 1 @@ -699,11 +688,9 @@ typedef enum # endif # ifdef DEBUG -static void PREFIX(extract_number) _RE_ARGS ((int *dest, UCHAR_T *source)); +static void PREFIX(extract_number) (int *dest, UCHAR_T *source); static void -PREFIX(extract_number) (dest, source) - int *dest; - UCHAR_T *source; +PREFIX(extract_number) (int *dest, UCHAR_T *source) { # ifdef WCHAR *dest = *source; @@ -731,12 +718,10 @@ PREFIX(extract_number) (dest, source) } while (0) # ifdef DEBUG -static void PREFIX(extract_number_and_incr) _RE_ARGS ((int *destination, - UCHAR_T **source)); +static void PREFIX(extract_number_and_incr) (int *destination, + UCHAR_T **source); static void -PREFIX(extract_number_and_incr) (destination, source) - int *destination; - UCHAR_T **source; +PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source) { PREFIX(extract_number) (destination, *source); *source += OFFSET_ADDRESS_SIZE; @@ -787,8 +772,7 @@ static int debug; # ifndef DEFINED_ONCE void -print_fastmap (fastmap) - char *fastmap; +print_fastmap (char *fastmap) { unsigned was_a_range = 0; unsigned i = 0; @@ -820,9 +804,7 @@ print_fastmap (fastmap) the START pointer into it and ending just before the pointer END. */ void -PREFIX(print_partial_compiled_pattern) (start, end) - UCHAR_T *start; - UCHAR_T *end; +PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end) { int mcnt, mcnt2; UCHAR_T *p1; @@ -1155,8 +1137,7 @@ PREFIX(print_partial_compiled_pattern) (start, end) void -PREFIX(print_compiled_pattern) (bufp) - struct re_pattern_buffer *bufp; +PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp) { UCHAR_T *buffer = (UCHAR_T*) bufp->buffer; @@ -1188,12 +1169,8 @@ PREFIX(print_compiled_pattern) (bufp) void -PREFIX(print_double_string) (where, string1, size1, string2, size2) - const CHAR_T *where; - const CHAR_T *string1; - const CHAR_T *string2; - int size1; - int size2; +PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1, + int size1, const CHAR_T *string2, int size2) { int this_char; @@ -1226,8 +1203,7 @@ PREFIX(print_double_string) (where, string1, size1, string2, size2) # ifndef DEFINED_ONCE void -printchar (c) - int c; +printchar (int c) { putc (c, stderr); } @@ -1264,11 +1240,8 @@ static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src, size_t len, int *offset_buffer, char *is_binary); static size_t -convert_mbs_to_wcs (dest, src, len, offset_buffer, is_binary) - CHAR_T *dest; - const unsigned char* src; - size_t len; /* the length of multibyte string. */ - +convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len, + int *offset_buffer, char *is_binary) /* It hold correspondances between src(char string) and dest(wchar_t string) for optimization. e.g. src = "xxxyzz" @@ -1278,8 +1251,6 @@ convert_mbs_to_wcs (dest, src, len, offset_buffer, is_binary) offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")} = {0, 3, 4, 6} */ - int *offset_buffer; - char *is_binary; { wchar_t *pdest = dest; const unsigned char *psrc = src; @@ -1350,8 +1321,7 @@ reg_syntax_t re_syntax_options; defined in regex.h. We return the old syntax. */ reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; +re_set_syntax (reg_syntax_t syntax) { reg_syntax_t ret = re_syntax_options; @@ -1870,35 +1840,35 @@ static CHAR_T PREFIX(reg_unset_dummy); # define REG_UNSET(e) ((e) == REG_UNSET_VALUE) /* Subroutine declarations and macros for regex_compile. */ -static void PREFIX(store_op1) _RE_ARGS ((re_opcode_t op, UCHAR_T *loc, int arg)); -static void PREFIX(store_op2) _RE_ARGS ((re_opcode_t op, UCHAR_T *loc, - int arg1, int arg2)); -static void PREFIX(insert_op1) _RE_ARGS ((re_opcode_t op, UCHAR_T *loc, - int arg, UCHAR_T *end)); -static void PREFIX(insert_op2) _RE_ARGS ((re_opcode_t op, UCHAR_T *loc, - int arg1, int arg2, UCHAR_T *end)); -static boolean PREFIX(at_begline_loc_p) _RE_ARGS ((const CHAR_T *pattern, - const CHAR_T *p, - reg_syntax_t syntax)); -static boolean PREFIX(at_endline_loc_p) _RE_ARGS ((const CHAR_T *p, - const CHAR_T *pend, - reg_syntax_t syntax)); +static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg); +static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, + int arg1, int arg2); +static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, + int arg, UCHAR_T *end); +static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, + int arg1, int arg2, UCHAR_T *end); +static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern, + const CHAR_T *p, + reg_syntax_t syntax); +static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p, + const CHAR_T *pend, + reg_syntax_t syntax); # ifdef WCHAR -static reg_errcode_t wcs_compile_range _RE_ARGS ((CHAR_T range_start, - const CHAR_T **p_ptr, - const CHAR_T *pend, - char *translate, - reg_syntax_t syntax, - UCHAR_T *b, - CHAR_T *char_set)); -static void insert_space _RE_ARGS ((int num, CHAR_T *loc, CHAR_T *end)); +static reg_errcode_t wcs_compile_range (CHAR_T range_start, + const CHAR_T **p_ptr, + const CHAR_T *pend, + char *translate, + reg_syntax_t syntax, + UCHAR_T *b, + CHAR_T *char_set); +static void insert_space (int num, CHAR_T *loc, CHAR_T *end); # else /* BYTE */ -static reg_errcode_t byte_compile_range _RE_ARGS ((unsigned int range_start, - const char **p_ptr, - const char *pend, - char *translate, - reg_syntax_t syntax, - unsigned char *b)); +static reg_errcode_t byte_compile_range (unsigned int range_start, + const char **p_ptr, + const char *pend, + char *translate, + reg_syntax_t syntax, + unsigned char *b); # endif /* WCHAR */ /* Fetch the next character in the uncompiled pattern---translating it @@ -1950,7 +1920,7 @@ static reg_errcode_t byte_compile_range _RE_ARGS ((unsigned int range_start, ? (char) translate[(unsigned char) (d)] : (d)) # else /* BYTE */ # define TRANSLATE(d) \ - (translate ? (char) translate[(unsigned char) (d)] : (d)) + (translate ? (char) translate[(unsigned char) (d)] : (char) (d)) # endif /* WCHAR */ # endif @@ -2256,8 +2226,7 @@ static PREFIX(register_info_type) *PREFIX(reg_info_dummy); but don't make them smaller. */ static void -PREFIX(regex_grow_registers) (num_regs) - int num_regs; +PREFIX(regex_grow_registers) (int num_regs) { if (num_regs > regs_allocated_size) { @@ -2278,9 +2247,8 @@ PREFIX(regex_grow_registers) (num_regs) # endif /* not MATCH_MAY_ALLOCATE */ # ifndef DEFINED_ONCE -static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type - compile_stack, - regnum_t regnum)); +static boolean group_in_compile_stack (compile_stack_type compile_stack, + regnum_t regnum); # endif /* not DEFINED_ONCE */ /* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. @@ -2311,11 +2279,9 @@ static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type # endif /* WCHAR */ static reg_errcode_t -PREFIX(regex_compile) (ARG_PREFIX(pattern), ARG_PREFIX(size), syntax, bufp) - const char *ARG_PREFIX(pattern); - size_t ARG_PREFIX(size); - reg_syntax_t syntax; - struct re_pattern_buffer *bufp; +PREFIX(regex_compile) (const char *ARG_PREFIX(pattern), + size_t ARG_PREFIX(size), reg_syntax_t syntax, + struct re_pattern_buffer *bufp) { /* We fetch characters from PATTERN here. Even though PATTERN is `char *' (i.e., signed), we declare these variables as unsigned, so @@ -4260,10 +4226,7 @@ PREFIX(regex_compile) (ARG_PREFIX(pattern), ARG_PREFIX(size), syntax, bufp) /* ifdef WCHAR, integer parameter is 1 wchar_t. */ static void -PREFIX(store_op1) (op, loc, arg) - re_opcode_t op; - UCHAR_T *loc; - int arg; +PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg) { *loc = (UCHAR_T) op; STORE_NUMBER (loc + 1, arg); @@ -4274,10 +4237,7 @@ PREFIX(store_op1) (op, loc, arg) /* ifdef WCHAR, integer parameter is 1 wchar_t. */ static void -PREFIX(store_op2) (op, loc, arg1, arg2) - re_opcode_t op; - UCHAR_T *loc; - int arg1, arg2; +PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2) { *loc = (UCHAR_T) op; STORE_NUMBER (loc + 1, arg1); @@ -4290,11 +4250,7 @@ PREFIX(store_op2) (op, loc, arg1, arg2) /* ifdef WCHAR, integer parameter is 1 wchar_t. */ static void -PREFIX(insert_op1) (op, loc, arg, end) - re_opcode_t op; - UCHAR_T *loc; - int arg; - UCHAR_T *end; +PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end) { register UCHAR_T *pfrom = end; register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE; @@ -4310,11 +4266,8 @@ PREFIX(insert_op1) (op, loc, arg, end) /* ifdef WCHAR, integer parameter is 1 wchar_t. */ static void -PREFIX(insert_op2) (op, loc, arg1, arg2, end) - re_opcode_t op; - UCHAR_T *loc; - int arg1, arg2; - UCHAR_T *end; +PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, + int arg2, UCHAR_T *end) { register UCHAR_T *pfrom = end; register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE; @@ -4331,9 +4284,8 @@ PREFIX(insert_op2) (op, loc, arg1, arg2, end) least one character before the ^. */ static boolean -PREFIX(at_begline_loc_p) (pattern, p, syntax) - const CHAR_T *pattern, *p; - reg_syntax_t syntax; +PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p, + reg_syntax_t syntax) { const CHAR_T *prev = p - 2; boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; @@ -4350,9 +4302,8 @@ PREFIX(at_begline_loc_p) (pattern, p, syntax) at least one character after the $, i.e., `P < PEND'. */ static boolean -PREFIX(at_endline_loc_p) (p, pend, syntax) - const CHAR_T *p, *pend; - reg_syntax_t syntax; +PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend, + reg_syntax_t syntax) { const CHAR_T *next = p; boolean next_backslash = *next == '\\'; @@ -4373,9 +4324,7 @@ PREFIX(at_endline_loc_p) (p, pend, syntax) false if it's not. */ static boolean -group_in_compile_stack (compile_stack, regnum) - compile_stack_type compile_stack; - regnum_t regnum; +group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum) { int this_element; @@ -4395,10 +4344,7 @@ group_in_compile_stack (compile_stack, regnum) /* This insert space, which size is "num", into the pattern at "loc". "end" must point the end of the allocated buffer. */ static void -insert_space (num, loc, end) - int num; - CHAR_T *loc; - CHAR_T *end; +insert_space (int num, CHAR_T *loc, CHAR_T *end) { register CHAR_T *pto = end; register CHAR_T *pfrom = end - num; @@ -4410,13 +4356,9 @@ insert_space (num, loc, end) #ifdef WCHAR static reg_errcode_t -wcs_compile_range (range_start_char, p_ptr, pend, translate, syntax, b, - char_set) - CHAR_T range_start_char; - const CHAR_T **p_ptr, *pend; - CHAR_T *char_set, *b; - RE_TRANSLATE_TYPE translate; - reg_syntax_t syntax; +wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr, + const CHAR_T *pend, RE_TRANSLATE_TYPE translate, + reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set) { const CHAR_T *p = *p_ptr; CHAR_T range_start, range_end; @@ -4497,12 +4439,9 @@ wcs_compile_range (range_start_char, p_ptr, pend, translate, syntax, b, `regex_compile' itself. */ static reg_errcode_t -byte_compile_range (range_start_char, p_ptr, pend, translate, syntax, b) - unsigned int range_start_char; - const char **p_ptr, *pend; - RE_TRANSLATE_TYPE translate; - reg_syntax_t syntax; - unsigned char *b; +byte_compile_range (unsigned int range_start_char, const char **p_ptr, + const char *pend, RE_TRANSLATE_TYPE translate, + reg_syntax_t syntax, unsigned char *b) { unsigned this_char; const char *p = *p_ptr; @@ -4583,8 +4522,7 @@ byte_compile_range (range_start_char, p_ptr, pend, translate, syntax, b) static unsigned char truncate_wchar (CHAR_T c); static unsigned char -truncate_wchar (c) - CHAR_T c; +truncate_wchar (CHAR_T c) { unsigned char buf[MB_CUR_MAX]; mbstate_t state; @@ -4600,8 +4538,7 @@ truncate_wchar (c) #endif /* WCHAR */ static int -PREFIX(re_compile_fastmap) (bufp) - struct re_pattern_buffer *bufp; +PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp) { int j, k; #ifdef MATCH_MAY_ALLOCATE @@ -4920,8 +4857,7 @@ PREFIX(re_compile_fastmap) (bufp) #else /* not INSIDE_RECURSION */ int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; +re_compile_fastmap (struct re_pattern_buffer *bufp) { # ifdef MBS_SUPPORT if (MB_CUR_MAX != 1) @@ -4949,11 +4885,9 @@ weak_alias (__re_compile_fastmap, re_compile_fastmap) freeing the old data. */ void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - unsigned num_regs; - regoff_t *starts, *ends; +re_set_registers (struct re_pattern_buffer *bufp, + struct re_registers *regs, unsigned num_regs, + regoff_t *starts, regoff_t *ends) { if (num_regs) { @@ -4979,11 +4913,8 @@ weak_alias (__re_set_registers, re_set_registers) doesn't let you say where to stop matching. */ int -re_search (bufp, string, size, startpos, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, startpos, range; - struct re_registers *regs; +re_search (struct re_pattern_buffer *bufp, const char *string, int size, + int startpos, int range, struct re_registers *regs) { return re_search_2 (bufp, NULL, 0, string, size, startpos, range, regs, size); @@ -5015,14 +4946,9 @@ weak_alias (__re_search, re_search) stack overflow). */ int -re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int startpos; - int range; - struct re_registers *regs; - int stop; +re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1, + const char *string2, int size2, int startpos, int range, + struct re_registers *regs, int stop) { # ifdef MBS_SUPPORT if (MB_CUR_MAX != 1) @@ -5078,15 +5004,10 @@ weak_alias (__re_search_2, re_search_2) static int -PREFIX(re_search_2) (bufp, string1, size1, string2, size2, startpos, range, - regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int startpos; - int range; - struct re_registers *regs; - int stop; +PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1, + int size1, const char *string2, int size2, + int startpos, int range, + struct re_registers *regs, int stop) { int val; register char *fastmap = bufp->fastmap; @@ -5469,11 +5390,8 @@ PREFIX(re_search_2) (bufp, string1, size1, string2, size2, startpos, range, /* re_match is like re_match_2 except it takes only a single string. */ int -re_match (bufp, string, size, pos, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, pos; - struct re_registers *regs; +re_match (struct re_pattern_buffer *bufp, const char *string, + int size, int pos, struct re_registers *regs) { int result; # ifdef MBS_SUPPORT @@ -5500,17 +5418,17 @@ weak_alias (__re_match, re_match) #endif /* not INSIDE_RECURSION */ #ifdef INSIDE_RECURSION -static boolean PREFIX(group_match_null_string_p) _RE_ARGS ((UCHAR_T **p, - UCHAR_T *end, - PREFIX(register_info_type) *reg_info)); -static boolean PREFIX(alt_match_null_string_p) _RE_ARGS ((UCHAR_T *p, - UCHAR_T *end, - PREFIX(register_info_type) *reg_info)); -static boolean PREFIX(common_op_match_null_string_p) _RE_ARGS ((UCHAR_T **p, - UCHAR_T *end, - PREFIX(register_info_type) *reg_info)); -static int PREFIX(bcmp_translate) _RE_ARGS ((const CHAR_T *s1, const CHAR_T *s2, - int len, char *translate)); +static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p, + UCHAR_T *end, + PREFIX(register_info_type) *reg_info); +static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p, + UCHAR_T *end, + PREFIX(register_info_type) *reg_info); +static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p, + UCHAR_T *end, + PREFIX(register_info_type) *reg_info); +static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, + int len, char *translate); #else /* not INSIDE_RECURSION */ /* re_match_2 matches the compiled pattern in BUFP against the @@ -5527,13 +5445,9 @@ static int PREFIX(bcmp_translate) _RE_ARGS ((const CHAR_T *s1, const CHAR_T *s2, matched substring. */ int -re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int pos; - struct re_registers *regs; - int stop; +re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1, + const char *string2, int size2, int pos, + struct re_registers *regs, int stop) { int result; # ifdef MBS_SUPPORT @@ -5562,7 +5476,7 @@ weak_alias (__re_match_2, re_match_2) #ifdef INSIDE_RECURSION #ifdef WCHAR -static int count_mbs_length PARAMS ((int *, int)); +static int count_mbs_length (int *, int); /* This check the substring (from 0, to length) of the multibyte string, to which offset_buffer correspond. And count how many wchar_t_characters @@ -5570,9 +5484,7 @@ static int count_mbs_length PARAMS ((int *, int)); See convert_mbs_to_wcs. */ static int -count_mbs_length(offset_buffer, length) - int *offset_buffer; - int length; +count_mbs_length(int *offset_buffer, int length) { int upper, lower; @@ -5613,33 +5525,26 @@ count_mbs_length(offset_buffer, length) afterwards. */ #ifdef WCHAR static int -wcs_re_match_2_internal (bufp, cstring1, csize1, cstring2, csize2, pos, - regs, stop, string1, size1, string2, size2, - mbs_offset1, mbs_offset2) - struct re_pattern_buffer *bufp; - const char *cstring1, *cstring2; - int csize1, csize2; - int pos; - struct re_registers *regs; - int stop; +wcs_re_match_2_internal (struct re_pattern_buffer *bufp, + const char *cstring1, int csize1, + const char *cstring2, int csize2, + int pos, + struct re_registers *regs, + int stop, /* string1 == string2 == NULL means string1/2, size1/2 and mbs_offset1/2 need seting up in this function. */ /* We need wchar_t* buffers correspond to cstring1, cstring2. */ - wchar_t *string1, *string2; - /* We need the size of wchar_t buffers correspond to csize1, csize2. */ - int size1, size2; + wchar_t *string1, int size1, + wchar_t *string2, int size2, /* offset buffer for optimizatoin. See convert_mbs_to_wc. */ - int *mbs_offset1, *mbs_offset2; + int *mbs_offset1, int *mbs_offset2) #else /* BYTE */ static int -byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos, - regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int pos; - struct re_registers *regs; - int stop; +byte_re_match_2_internal (struct re_pattern_buffer *bufp, + const char *string1, int size1, + const char *string2, int size2, + int pos, + struct re_registers *regs, int stop) #endif /* BYTE */ { /* General temporaries. */ @@ -6269,9 +6174,9 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos, uint32_t nrules; # endif /* _LIBC */ #endif /* WCHAR */ - boolean not = (re_opcode_t) *(p - 1) == charset_not; + boolean negate = (re_opcode_t) *(p - 1) == charset_not; - DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); + DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : ""); PREFETCH (); c = TRANSLATE (*d); /* The character to match. */ #ifdef WCHAR @@ -6638,20 +6543,20 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos, if (c == *workp) goto char_set_matched; - not = !not; + negate = !negate; char_set_matched: - if (not) goto fail; + if (negate) goto fail; #else /* Cast to `unsigned' instead of `unsigned char' in case the bit list is a full 32 bytes long. */ if (c < (unsigned) (*p * BYTEWIDTH) && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; + negate = !negate; p += 1 + *p; - if (!not) goto fail; + if (!negate) goto fail; #undef WORK_BUFFER_SIZE #endif /* WCHAR */ SET_REGS_MATCHED (); @@ -7141,15 +7046,15 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos, else if ((re_opcode_t) p1[3] == charset || (re_opcode_t) p1[3] == charset_not) { - int not = (re_opcode_t) p1[3] == charset_not; + int negate = (re_opcode_t) p1[3] == charset_not; if (c < (unsigned) (p1[4] * BYTEWIDTH) && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; + negate = !negate; - /* `not' is equal to 1 if c would match, which means + /* `negate' is equal to 1 if c would match, which means that we can't change to pop_failure_jump. */ - if (!not) + if (!negate) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); @@ -7589,9 +7494,8 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos, We don't handle duplicates properly (yet). */ static boolean -PREFIX(group_match_null_string_p) (p, end, reg_info) - UCHAR_T **p, *end; - PREFIX(register_info_type) *reg_info; +PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end, + PREFIX(register_info_type) *reg_info) { int mcnt; /* Point to after the args to the start_memory. */ @@ -7701,9 +7605,8 @@ PREFIX(group_match_null_string_p) (p, end, reg_info) byte past the last. The alternative can contain groups. */ static boolean -PREFIX(alt_match_null_string_p) (p, end, reg_info) - UCHAR_T *p, *end; - PREFIX(register_info_type) *reg_info; +PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end, + PREFIX(register_info_type) *reg_info) { int mcnt; UCHAR_T *p1 = p; @@ -7738,9 +7641,8 @@ PREFIX(alt_match_null_string_p) (p, end, reg_info) Sets P to one after the op and its arguments, if any. */ static boolean -PREFIX(common_op_match_null_string_p) (p, end, reg_info) - UCHAR_T **p, *end; - PREFIX(register_info_type) *reg_info; +PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end, + PREFIX(register_info_type) *reg_info) { int mcnt; boolean ret; @@ -7826,10 +7728,8 @@ PREFIX(common_op_match_null_string_p) (p, end, reg_info) bytes; nonzero otherwise. */ static int -PREFIX(bcmp_translate) (s1, s2, len, translate) - const CHAR_T *s1, *s2; - register int len; - RE_TRANSLATE_TYPE translate; +PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len, + RE_TRANSLATE_TYPE translate) { register const UCHAR_T *p1 = (const UCHAR_T *) s1; register const UCHAR_T *p2 = (const UCHAR_T *) s2; @@ -7862,10 +7762,8 @@ PREFIX(bcmp_translate) (s1, s2, len, translate) We call regex_compile to do the actual compilation. */ const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - size_t length; - struct re_pattern_buffer *bufp; +re_compile_pattern (const char *pattern, size_t length, + struct re_pattern_buffer *bufp) { reg_errcode_t ret; @@ -7911,15 +7809,14 @@ char * regcomp/regexec below without link errors. */ weak_function #endif -re_comp (s) - const char *s; +re_comp (const char *s) { reg_errcode_t ret; if (!s) { if (!re_comp_buf.buffer) - return gettext ("No previous regular expression"); + return (char *) gettext ("No previous regular expression"); return 0; } @@ -7960,8 +7857,7 @@ int #ifdef _LIBC weak_function #endif -re_exec (s) - const char *s; +re_exec (const char *s) { const int len = strlen (s); return @@ -8010,10 +7906,7 @@ re_exec (s) the return codes and their meanings.) */ int -regcomp (preg, pattern, cflags) - regex_t *preg; - const char *pattern; - int cflags; +regcomp (regex_t *preg, const char *pattern, int cflags) { reg_errcode_t ret; reg_syntax_t syntax @@ -8030,7 +7923,7 @@ regcomp (preg, pattern, cflags) if (cflags & REG_ICASE) { - unsigned i; + int i; preg->translate = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE @@ -8106,12 +7999,8 @@ weak_alias (__regcomp, regcomp) We return 0 if we find a match and REG_NOMATCH if not. */ int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *preg; - const char *string; - size_t nmatch; - regmatch_t pmatch[]; - int eflags; +regexec (const regex_t *preg, const char *string, size_t nmatch, + regmatch_t pmatch[], int eflags) { int ret; struct re_registers regs; @@ -8173,11 +8062,8 @@ weak_alias (__regexec, regexec) from either regcomp or regexec. We don't use PREG here. */ size_t -regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *preg; - char *errbuf; - size_t errbuf_size; +regerror (int errcode, const regex_t *preg ATTRIBUTE_UNUSED, + char *errbuf, size_t errbuf_size) { const char *msg; size_t msg_size; @@ -8220,8 +8106,7 @@ weak_alias (__regerror, regerror) /* Free dynamically allocated space used by PREG. */ void -regfree (preg) - regex_t *preg; +regfree (regex_t *preg) { if (preg->buffer != NULL) free (preg->buffer); diff --git a/gnu/lib/libiberty/src/rindex.c b/gnu/lib/libiberty/src/rindex.c index ef9cdc59877..194ef9fad78 100644 --- a/gnu/lib/libiberty/src/rindex.c +++ b/gnu/lib/libiberty/src/rindex.c @@ -12,12 +12,10 @@ deprecated in new programs in favor of @code{strrchr}. */ -extern char *strrchr (); +extern char *strrchr (const char *, int); char * -rindex (s, c) - char *s; - int c; +rindex (const char *s, int c) { return strrchr (s, c); } diff --git a/gnu/lib/libiberty/src/safe-ctype.c b/gnu/lib/libiberty/src/safe-ctype.c index 3bac84bf68a..0972b4b354f 100644 --- a/gnu/lib/libiberty/src/safe-ctype.c +++ b/gnu/lib/libiberty/src/safe-ctype.c @@ -1,6 +1,7 @@ /* <ctype.h> replacement macros. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, + 2005 Free Software Foundation, Inc. Contributed by Zack Weinberg <zackw@stanford.edu>. This file is part of the libiberty library. @@ -16,23 +17,112 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is a compatible replacement of the standard C library's <ctype.h> - with the following properties: - - - Implements all isxxx() macros required by C99. - - Also implements some character classes useful when - parsing C-like languages. - - Does not change behavior depending on the current locale. - - Behaves properly for all values in the range of a signed or - unsigned char. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* + +@defvr Extension HOST_CHARSET +This macro indicates the basic character set and encoding used by the +host: more precisely, the encoding used for character constants in +preprocessor @samp{#if} statements (the C "execution character set"). +It is defined by @file{safe-ctype.h}, and will be an integer constant +with one of the following values: + +@ftable @code +@item HOST_CHARSET_UNKNOWN +The host character set is unknown - that is, not one of the next two +possibilities. + +@item HOST_CHARSET_ASCII +The host character set is ASCII. + +@item HOST_CHARSET_EBCDIC +The host character set is some variant of EBCDIC. (Only one of the +nineteen EBCDIC varying characters is tested; exercise caution.) +@end ftable +@end defvr + +@deffn Extension ISALPHA (@var{c}) +@deffnx Extension ISALNUM (@var{c}) +@deffnx Extension ISBLANK (@var{c}) +@deffnx Extension ISCNTRL (@var{c}) +@deffnx Extension ISDIGIT (@var{c}) +@deffnx Extension ISGRAPH (@var{c}) +@deffnx Extension ISLOWER (@var{c}) +@deffnx Extension ISPRINT (@var{c}) +@deffnx Extension ISPUNCT (@var{c}) +@deffnx Extension ISSPACE (@var{c}) +@deffnx Extension ISUPPER (@var{c}) +@deffnx Extension ISXDIGIT (@var{c}) + +These twelve macros are defined by @file{safe-ctype.h}. Each has the +same meaning as the corresponding macro (with name in lowercase) +defined by the standard header @file{ctype.h}. For example, +@code{ISALPHA} returns true for alphabetic characters and false for +others. However, there are two differences between these macros and +those provided by @file{ctype.h}: + +@itemize @bullet +@item These macros are guaranteed to have well-defined behavior for all +values representable by @code{signed char} and @code{unsigned char}, and +for @code{EOF}. + +@item These macros ignore the current locale; they are true for these +fixed sets of characters: +@multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada} +@item @code{ALPHA} @tab @kbd{A-Za-z} +@item @code{ALNUM} @tab @kbd{A-Za-z0-9} +@item @code{BLANK} @tab @kbd{space tab} +@item @code{CNTRL} @tab @code{!PRINT} +@item @code{DIGIT} @tab @kbd{0-9} +@item @code{GRAPH} @tab @code{ALNUM || PUNCT} +@item @code{LOWER} @tab @kbd{a-z} +@item @code{PRINT} @tab @code{GRAPH ||} @kbd{space} +@item @code{PUNCT} @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?} +@item @code{SPACE} @tab @kbd{space tab \n \r \f \v} +@item @code{UPPER} @tab @kbd{A-Z} +@item @code{XDIGIT} @tab @kbd{0-9A-Fa-f} +@end multitable + +Note that, if the host character set is ASCII or a superset thereof, +all these macros will return false for all values of @code{char} outside +the range of 7-bit ASCII. In particular, both ISPRINT and ISCNTRL return +false for characters with numeric values from 128 to 255. +@end itemize +@end deffn + +@deffn Extension ISIDNUM (@var{c}) +@deffnx Extension ISIDST (@var{c}) +@deffnx Extension IS_VSPACE (@var{c}) +@deffnx Extension IS_NVSPACE (@var{c}) +@deffnx Extension IS_SPACE_OR_NUL (@var{c}) +@deffnx Extension IS_ISOBASIC (@var{c}) +These six macros are defined by @file{safe-ctype.h} and provide +additional character classes which are useful when doing lexical +analysis of C or similar languages. They are true for the following +sets of characters: + +@multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada} +@item @code{IDNUM} @tab @kbd{A-Za-z0-9_} +@item @code{IDST} @tab @kbd{A-Za-z_} +@item @code{VSPACE} @tab @kbd{\r \n} +@item @code{NVSPACE} @tab @kbd{space tab \f \v \0} +@item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE} +@item @code{ISOBASIC} @tab @code{VSPACE || NVSPACE || PRINT} +@end multitable +@end deffn + +*/ #include "ansidecl.h" #include <safe-ctype.h> #include <stdio.h> /* for EOF */ +#if EOF != -1 + #error "<safe-ctype.h> requires EOF == -1" +#endif + /* Shorthand */ #define bl _sch_isblank #define cn _sch_iscntrl @@ -64,9 +154,7 @@ Boston, MA 02111-1307, USA. */ #define S (const unsigned short) (nv|sp|bl|pr) /* space */ /* Are we ASCII? */ -#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ - && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 \ - && EOF == -1 +#if HOST_CHARSET == HOST_CHARSET_ASCII const unsigned short _sch_istable[256] = { @@ -159,5 +247,9 @@ const unsigned char _sch_toupper[256] = }; #else - #error "Unsupported host character set" -#endif /* not ASCII */ +# if HOST_CHARSET == HOST_CHARSET_EBCDIC + #error "FIXME: write tables for EBCDIC" +# else + #error "Unrecognized host character set" +# endif +#endif diff --git a/gnu/lib/libiberty/src/snprintf.c b/gnu/lib/libiberty/src/snprintf.c index 89164695b50..f1ba49f980f 100644 --- a/gnu/lib/libiberty/src/snprintf.c +++ b/gnu/lib/libiberty/src/snprintf.c @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause @@ -41,18 +41,13 @@ this function is used. #include "ansidecl.h" -#ifdef ANSI_PROTOTYPES #include <stdarg.h> #include <stddef.h> -#else -#include <varargs.h> -#define size_t unsigned long -#endif -int vsnprintf PARAMS ((char *, size_t, const char *, va_list)); +int vsnprintf (char *, size_t, const char *, va_list); int -snprintf VPARAMS ((char *s, size_t n, const char *format, ...)) +snprintf (char *s, size_t n, const char *format, ...) { int result; VA_OPEN (ap, format); diff --git a/gnu/lib/libiberty/src/sort.c b/gnu/lib/libiberty/src/sort.c index 90c97e04e07..3738dd733e5 100644 --- a/gnu/lib/libiberty/src/sort.c +++ b/gnu/lib/libiberty/src/sort.c @@ -16,8 +16,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -44,10 +44,7 @@ Boston, MA 02111-1307, USA. */ /* POINTERS and WORK are both arrays of N pointers. When this function returns POINTERS will be sorted in ascending order. */ -void sort_pointers (n, pointers, work) - size_t n; - void **pointers; - void **work; +void sort_pointers (size_t n, void **pointers, void **work) { /* The type of a single digit. This can be any unsigned integral type. When changing this, DIGIT_MAX should be changed as @@ -140,8 +137,7 @@ void sort_pointers (n, pointers, work) #include <stdio.h> -void *xmalloc (n) - size_t n; +void *xmalloc (size_t n) { return malloc (n); } @@ -159,8 +155,8 @@ int main (int argc, char **argv) else k = 10; - pointers = xmalloc (k * sizeof (void *)); - work = xmalloc (k * sizeof (void *)); + pointers = XNEWVEC (void*, k); + work = XNEWVEC (void*, k); for (i = 0; i < k; ++i) { diff --git a/gnu/lib/libiberty/src/spaces.c b/gnu/lib/libiberty/src/spaces.c index bfead7ed7a4..67481c9bcd8 100644 --- a/gnu/lib/libiberty/src/spaces.c +++ b/gnu/lib/libiberty/src/spaces.c @@ -14,8 +14,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -29,6 +29,9 @@ valid until at least the next call. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "ansidecl.h" #include "libiberty.h" @@ -37,13 +40,12 @@ valid until at least the next call. #include <unixlib.h> #else /* For systems with larger pointers than ints, these must be declared. */ -extern PTR malloc PARAMS ((size_t)); -extern void free PARAMS ((PTR)); +extern PTR malloc (size_t); +extern void free (PTR); #endif const char * -spaces (count) - int count; +spaces (int count) { register char *t; static char *buf; @@ -55,7 +57,7 @@ spaces (count) { free (buf); } - buf = malloc (count + 1); + buf = (char *) malloc (count + 1); if (buf == (char *) 0) return 0; for (t = buf + count ; t != buf ; ) diff --git a/gnu/lib/libiberty/src/stpcpy.c b/gnu/lib/libiberty/src/stpcpy.c index a589642fd88..57b32d1c841 100644 --- a/gnu/lib/libiberty/src/stpcpy.c +++ b/gnu/lib/libiberty/src/stpcpy.c @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -30,19 +30,13 @@ Copies the string @var{src} into @var{dst}. Returns a pointer to */ #include <ansidecl.h> -#ifdef ANSI_PROTOTYPES #include <stddef.h> -#else -#define size_t unsigned long -#endif -extern size_t strlen PARAMS ((const char *)); -extern PTR memcpy PARAMS ((PTR, const PTR, size_t)); +extern size_t strlen (const char *); +extern PTR memcpy (PTR, const PTR, size_t); char * -stpcpy (dst, src) - char *dst; - const char *src; +stpcpy (char *dst, const char *src) { const size_t len = strlen (src); return (char *) memcpy (dst, src, len + 1) + len; diff --git a/gnu/lib/libiberty/src/stpncpy.c b/gnu/lib/libiberty/src/stpncpy.c index cb67b4dbab1..f97206a09e6 100644 --- a/gnu/lib/libiberty/src/stpncpy.c +++ b/gnu/lib/libiberty/src/stpncpy.c @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -32,20 +32,13 @@ strlen(@var{src}). */ #include <ansidecl.h> -#ifdef ANSI_PROTOTYPES #include <stddef.h> -#else -#define size_t unsigned long -#endif -extern size_t strlen PARAMS ((const char *)); -extern char *strncpy PARAMS ((char *, const char *, size_t)); +extern size_t strlen (const char *); +extern char *strncpy (char *, const char *, size_t); char * -stpncpy (dst, src, len) - char *dst; - const char *src; - size_t len; +stpncpy (char *dst, const char *src, size_t len) { size_t n = strlen (src); if (n > len) diff --git a/gnu/lib/libiberty/src/strchr.c b/gnu/lib/libiberty/src/strchr.c index 1f71c5143d0..935805ef4f4 100644 --- a/gnu/lib/libiberty/src/strchr.c +++ b/gnu/lib/libiberty/src/strchr.c @@ -16,9 +16,7 @@ null character, the results are undefined. #include <ansidecl.h> char * -strchr (s, c) - register const char *s; - int c; +strchr (register const char *s, int c) { do { if (*s == c) diff --git a/gnu/lib/libiberty/src/strndup.c b/gnu/lib/libiberty/src/strndup.c new file mode 100644 index 00000000000..9e9b4e2991f --- /dev/null +++ b/gnu/lib/libiberty/src/strndup.c @@ -0,0 +1,55 @@ +/* Implement the strndup function. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* + +@deftypefn Extension char* strndup (const char *@var{s}, size_t @var{n}) + +Returns a pointer to a copy of @var{s} with at most @var{n} characters +in memory obtained from @code{malloc}, or @code{NULL} if insufficient +memory was available. The result is always NUL terminated. + +@end deftypefn + +*/ + +#include "ansidecl.h" +#include <stddef.h> + +extern size_t strlen (const char*); +extern PTR malloc (size_t); +extern PTR memcpy (PTR, const PTR, size_t); + +char * +strndup (const char *s, size_t n) +{ + char *result; + size_t len = strlen (s); + + if (n < len) + len = n; + + result = (char *) malloc (len + 1); + if (!result) + return 0; + + result[len] = '\0'; + return (char *) memcpy (result, s, len); +} diff --git a/gnu/lib/libiberty/src/strrchr.c b/gnu/lib/libiberty/src/strrchr.c index bc380c4c5d3..5cf7c14d8b7 100644 --- a/gnu/lib/libiberty/src/strrchr.c +++ b/gnu/lib/libiberty/src/strrchr.c @@ -16,9 +16,7 @@ null character, the results are undefined. #include <ansidecl.h> char * -strrchr (s, c) - register const char *s; - int c; +strrchr (register const char *s, int c) { char *rtnval = 0; diff --git a/gnu/lib/libiberty/src/strverscmp.c b/gnu/lib/libiberty/src/strverscmp.c new file mode 100644 index 00000000000..04e1e4ae99e --- /dev/null +++ b/gnu/lib/libiberty/src/strverscmp.c @@ -0,0 +1,157 @@ +/* Compare strings while treating digits characters numerically. + Copyright (C) 1997, 2002, 2005 Free Software Foundation, Inc. + This file is part of the libiberty library. + Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997. + + Libiberty is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Libiberty 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. */ + +#include "libiberty.h" +#include "safe-ctype.h" + +/* +@deftypefun int strverscmp (const char *@var{s1}, const char *@var{s2}) +The @code{strverscmp} function compares the string @var{s1} against +@var{s2}, considering them as holding indices/version numbers. Return +value follows the same conventions as found in the @code{strverscmp} +function. In fact, if @var{s1} and @var{s2} contain no digits, +@code{strverscmp} behaves like @code{strcmp}. + +Basically, we compare strings normally (character by character), until +we find a digit in each string - then we enter a special comparison +mode, where each sequence of digits is taken as a whole. If we reach the +end of these two parts without noticing a difference, we return to the +standard comparison mode. There are two types of numeric parts: +"integral" and "fractional" (those begin with a '0'). The types +of the numeric parts affect the way we sort them: + +@itemize @bullet +@item +integral/integral: we compare values as you would expect. + +@item +fractional/integral: the fractional part is less than the integral one. +Again, no surprise. + +@item +fractional/fractional: the things become a bit more complex. +If the common prefix contains only leading zeroes, the longest part is less +than the other one; else the comparison behaves normally. +@end itemize + +@smallexample +strverscmp ("no digit", "no digit") + @result{} 0 // @r{same behavior as strcmp.} +strverscmp ("item#99", "item#100") + @result{} <0 // @r{same prefix, but 99 < 100.} +strverscmp ("alpha1", "alpha001") + @result{} >0 // @r{fractional part inferior to integral one.} +strverscmp ("part1_f012", "part1_f01") + @result{} >0 // @r{two fractional parts.} +strverscmp ("foo.009", "foo.0") + @result{} <0 // @r{idem, but with leading zeroes only.} +@end smallexample + +This function is especially useful when dealing with filename sorting, +because filenames frequently hold indices/version numbers. +@end deftypefun + +*/ + +/* states: S_N: normal, S_I: comparing integral part, S_F: comparing + fractional parts, S_Z: idem but with leading Zeroes only */ +#define S_N 0x0 +#define S_I 0x4 +#define S_F 0x8 +#define S_Z 0xC + +/* result_type: CMP: return diff; LEN: compare using len_diff/diff */ +#define CMP 2 +#define LEN 3 + + +/* Compare S1 and S2 as strings holding indices/version numbers, + returning less than, equal to or greater than zero if S1 is less than, + equal to or greater than S2 (for more info, see the Glibc texinfo doc). */ + +int +strverscmp (const char *s1, const char *s2) +{ + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + int state; + int diff; + + /* Symbol(s) 0 [1-9] others (padding) + Transition (10) 0 (01) d (00) x (11) - */ + static const unsigned int next_state[] = + { + /* state x d 0 - */ + /* S_N */ S_N, S_I, S_Z, S_N, + /* S_I */ S_N, S_I, S_I, S_I, + /* S_F */ S_N, S_F, S_F, S_F, + /* S_Z */ S_N, S_F, S_Z, S_Z + }; + + static const int result_type[] = + { + /* state x/x x/d x/0 x/- d/x d/d d/0 d/- + 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */ + + /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, + /* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP, + +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, + /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, + /* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP, + -1, CMP, CMP, CMP + }; + + if (p1 == p2) + return 0; + + c1 = *p1++; + c2 = *p2++; + /* Hint: '0' is a digit too. */ + state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0)); + + while ((diff = c1 - c2) == 0 && c1 != '\0') + { + state = next_state[state]; + c1 = *p1++; + c2 = *p2++; + state |= (c1 == '0') + (ISDIGIT (c1) != 0); + } + + state = result_type[state << 2 | (((c2 == '0') + (ISDIGIT (c2) != 0)))]; + + switch (state) + { + case CMP: + return diff; + + case LEN: + while (ISDIGIT (*p1++)) + if (!ISDIGIT (*p2++)) + return 1; + + return ISDIGIT (*p2) ? -1 : diff; + + default: + return state; + } +} diff --git a/gnu/lib/libiberty/src/ternary.c b/gnu/lib/libiberty/src/ternary.c index 056d2cee11e..8fc561a4531 100644 --- a/gnu/lib/libiberty/src/ternary.c +++ b/gnu/lib/libiberty/src/ternary.c @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -34,11 +34,7 @@ insertions. */ PTR -ternary_insert (root, s, data, replace) - ternary_tree *root; - const char *s; - PTR data; - int replace; +ternary_insert (ternary_tree *root, const char *s, PTR data, int replace) { int diff; ternary_tree curr, *pcurr; @@ -78,7 +74,7 @@ ternary_insert (root, s, data, replace) for (;;) { /* Allocate the memory for the node, and fill it in */ - *pcurr = (ternary_tree) xmalloc (sizeof (ternary_node)); + *pcurr = XNEW (ternary_node); curr = *pcurr; curr->splitchar = *s; curr->lokid = curr->hikid = curr->eqkid = 0; @@ -98,8 +94,7 @@ ternary_insert (root, s, data, replace) /* Free the ternary search tree rooted at p. */ void -ternary_cleanup (p) - ternary_tree p; +ternary_cleanup (ternary_tree p) { if (p) { @@ -113,9 +108,7 @@ ternary_cleanup (p) /* Non-recursive find of a string in the ternary tree */ PTR -ternary_search (p, s) - const ternary_node *p; - const char *s; +ternary_search (const ternary_node *p, const char *s) { const ternary_node *curr; int diff, spchar; @@ -147,9 +140,7 @@ ternary_search (p, s) /* For those who care, the recursive version of the search. Useful if you want a starting point for pmsearch or nearsearch. */ static PTR -ternary_recursivesearch (p, s) - const ternary_node *p; - const char *s; +ternary_recursivesearch (const ternary_node *p, const char *s) { if (!p) return 0; diff --git a/gnu/lib/libiberty/src/testsuite/Makefile.in b/gnu/lib/libiberty/src/testsuite/Makefile.in index 515dcd56b7e..534626e952d 100644 --- a/gnu/lib/libiberty/src/testsuite/Makefile.in +++ b/gnu/lib/libiberty/src/testsuite/Makefile.in @@ -1,6 +1,6 @@ # # Makefile -# Copyright (C) 1999, 2002 +# Copyright (C) 1999, 2002, 2006 # Free Software Foundation # # This file is part of the libiberty library. @@ -16,8 +16,8 @@ # # You should have received a copy of the GNU Library General Public # License along with libiberty; see the file COPYING.LIB. If not, -# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. +# write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. # # This file was written by Tom Tromey <tromey@cygnus.com>. @@ -42,23 +42,44 @@ INCDIR=$(srcdir)/../$(MULTISRCTOP)../include all: +# CHECK is set to "really_check" or the empty string by configure. check: @CHECK@ +really-check: check-cplus-dem check-pexecute check-expandargv + # Run some tests of the demangler. check-cplus-dem: test-demangle $(srcdir)/demangle-expected ./test-demangle < $(srcdir)/demangle-expected +# Check the pexecute code. +check-pexecute: test-pexecute + ./test-pexecute + +# Check the expandargv functionality +check-expandargv: test-expandargv + ./test-expandargv + TEST_COMPILE = $(CC) @DEFS@ $(LIBCFLAGS) -I.. -I$(INCDIR) $(HDEFINES) -test-demangle: $(srcdir)/test-demangle.c +test-demangle: $(srcdir)/test-demangle.c ../libiberty.a $(TEST_COMPILE) -o test-demangle \ $(srcdir)/test-demangle.c ../libiberty.a +test-pexecute: $(srcdir)/test-pexecute.c ../libiberty.a + $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-pexecute \ + $(srcdir)/test-pexecute.c ../libiberty.a + +test-expandargv: $(srcdir)/test-expandargv.c ../libiberty.a + $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-expandargv \ + $(srcdir)/test-expandargv.c ../libiberty.a + # Standard (either GNU or Cygnus) rules we don't use. -info install-info clean-info dvi install etags tags installcheck: +html install-html info install-info clean-info dvi install etags tags installcheck: # The standard clean rules. mostlyclean: rm -f test-demangle + rm -f test-pexecute + rm -f test-expandargv clean: mostlyclean distclean: clean rm -f Makefile diff --git a/gnu/lib/libiberty/src/testsuite/test-expandargv.c b/gnu/lib/libiberty/src/testsuite/test-expandargv.c new file mode 100644 index 00000000000..9d1af014545 --- /dev/null +++ b/gnu/lib/libiberty/src/testsuite/test-expandargv.c @@ -0,0 +1,296 @@ +/* expandargv test program, + Copyright (C) 2006 Free Software Foundation, Inc. + Written by Carlos O'Donell <carlos@codesourcery.com> + + This file is part of the libiberty library, which is part of GCC. + + This file 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 of the License, or + (at your option) any later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combined + executable.) + + 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, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "libiberty.h" +#include <stdio.h> +#include <errno.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN; +void writeout_test (int, const char *); +void run_replaces (char *); +void hook_char_replace (char *, size_t, char, char); +int run_tests (const char **); +void erase_test (int); + +/* Test input data, argv before, and argv after: + + The \n is an important part of test_data since expandargv + may have to work in environments where \n is translated + as \r\n. Thus \n is included in the test data for the file. + + We use \b to indicate that the test data is the null character. + This is because we use \0 normally to represent the end of the + file data, so we need something else for this. */ + +#define FILENAME_PATTERN "test-expandargv-%d.lst" +#define ARGV0 "test-expandargv" + +const char *test_data[] = { + /* Test 0 - Check for expansion with \r\n */ + "a\r\nb", /* Test 0 data */ + ARGV0, + "@test-expandargv-0.lst", + 0, /* End of argv[] before expansion */ + ARGV0, + "a", + "b", + 0, /* End of argv[] after expansion */ + + /* Test 1 - Check for expansion with \n */ + "a\nb", /* Test 1 data */ + ARGV0, + "@test-expandargv-1.lst", + 0, + ARGV0, + "a", + "b", + 0, + + /* Test 2 - Check for expansion with \0 */ + "a\bb", /* Test 2 data */ + ARGV0, + "@test-expandargv-2.lst", + 0, + ARGV0, + "a", + 0, + + /* Test 3 - Check for expansion with only \0 */ + "\b", /* Test 3 data */ + ARGV0, + "@test-expandargv-3.lst", + 0, + ARGV0, + 0, + + 0 /* Test done marker, don't remove. */ +}; + +/* Print a fatal error and exit. LINE is the line number where we + detected the error, ERRMSG is the error message to print, and ERR + is 0 or an errno value to print. */ + +static void +fatal_error (int line, const char *errmsg, int err) +{ + fprintf (stderr, "test-expandargv:%d: %s", line, errmsg); + if (errno != 0) + fprintf (stderr, ": %s", xstrerror (err)); + fprintf (stderr, "\n"); + exit (EXIT_FAILURE); +} + +/* hook_char_replace: + Replace 'replacethis' with 'withthis' */ + +void +hook_char_replace (char *string, size_t len, char replacethis, char withthis) +{ + int i = 0; + for (i = 0; i < len; i++) + if (string[i] == replacethis) + string[i] = withthis; +} + +/* run_replaces: + Hook here all the character for character replaces. + Be warned that expanding the string or contracting the string + should be handled with care. */ + +void +run_replaces (char * string) +{ + /* Store original string size */ + size_t len = strlen (string); + hook_char_replace (string, len, '\b', '\0'); +} + +/* write_test: + Write test datafile */ + +void +writeout_test (int test, const char * test_data) +{ + char filename[256]; + FILE *fd; + size_t len; + char * parse; + + /* Unique filename per test */ + sprintf (filename, FILENAME_PATTERN, test); + fd = fopen (filename, "w"); + if (fd == NULL) + fatal_error (__LINE__, "Failed to create test file.", errno); + + /* Generate RW copy of data for replaces */ + len = strlen (test_data); + parse = malloc (sizeof (char) * (len + 1)); + if (parse == NULL) + fatal_error (__LINE__, "Failed to malloc parse.", errno); + + memcpy (parse, test_data, sizeof (char) * len); + /* Run all possible replaces */ + run_replaces (parse); + + fwrite (parse, len, sizeof (char), fd); + free (parse); + fclose (fd); +} + +/* erase_test: + Erase the test file */ + +void +erase_test (int test) +{ + char filename[256]; + sprintf (filename, FILENAME_PATTERN, test); + if (unlink (filename) != 0) + fatal_error (__LINE__, "Failed to erase test file.", errno); +} + + +/* run_tests: + Run expandargv + Compare argv before and after. + Return number of fails */ + +int +run_tests (const char **test_data) +{ + int argc_after, argc_before; + char ** argv_before, ** argv_after; + int i, j, k, fails, failed; + + i = j = fails = 0; + /* Loop over all the tests */ + while (test_data[j]) + { + /* Write test data */ + writeout_test (i, test_data[j++]); + /* Copy argv before */ + argv_before = dupargv ((char **) &test_data[j]); + + /* Count argc before/after */ + argc_before = 0; + argc_after = 0; + while (test_data[j + argc_before]) + argc_before++; + j += argc_before + 1; /* Skip null */ + while (test_data[j + argc_after]) + argc_after++; + + /* Copy argv after */ + argv_after = dupargv ((char **) &test_data[j]); + + /* Run all possible replaces */ + for (k = 0; k < argc_before; k++) + run_replaces (argv_before[k]); + for (k = 0; k < argc_after; k++) + run_replaces (argv_after[k]); + + /* Run test: Expand arguments */ + expandargv (&argc_before, &argv_before); + + failed = 0; + /* Compare size first */ + if (argc_before != argc_after) + { + printf ("FAIL: test-expandargv-%d. Number of arguments don't match.\n", i); + failed++; + } + /* Compare each of the argv's ... */ + else + for (k = 0; k < argc_after; k++) + if (strncmp (argv_before[k], argv_after[k], strlen(argv_after[k])) != 0) + { + printf ("FAIL: test-expandargv-%d. Arguments don't match.\n", i); + failed++; + } + + if (!failed) + printf ("PASS: test-expandargv-%d.\n", i); + else + fails++; + + freeargv (argv_before); + freeargv (argv_after); + /* Advance to next test */ + j += argc_after + 1; + /* Erase test file */ + erase_test (i); + i++; + } + return fails; +} + +/* main: + Run tests. + Check result and exit with appropriate code. */ + +int +main(int argc, char **argv) +{ + int fails; + /* Repeat for all the tests: + - Parse data array and write into file. + - Run replace hooks before writing to file. + - Parse data array and build argv before/after. + - Run replace hooks on argv before/after + - Run expandargv. + - Compare output of expandargv argv to after argv. + - If they compare the same then test passes + else the test fails. + - Erase test file. */ + + fails = run_tests (test_data); + if (!fails) + exit (EXIT_SUCCESS); + else + exit (EXIT_FAILURE); +} + diff --git a/gnu/lib/libiberty/src/testsuite/test-pexecute.c b/gnu/lib/libiberty/src/testsuite/test-pexecute.c new file mode 100644 index 00000000000..8e01fda479a --- /dev/null +++ b/gnu/lib/libiberty/src/testsuite/test-pexecute.c @@ -0,0 +1,522 @@ +/* Pexecute test program, + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Ian Lance Taylor <ian@airs.com>. + + This file is part of GNU libiberty. + + 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 of the License, 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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "ansidecl.h" +#include "libiberty.h" +#include <stdio.h> +#include <signal.h> +#include <errno.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#include <sys/types.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif + +#ifndef WIFSIGNALED +#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f) +#endif +#ifndef WTERMSIG +#define WTERMSIG(S) ((S) & 0x7f) +#endif +#ifndef WIFEXITED +#define WIFEXITED(S) (((S) & 0xff) == 0) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(S) (((S) & 0xff00) >> 8) +#endif +#ifndef WSTOPSIG +#define WSTOPSIG WEXITSTATUS +#endif +#ifndef WCOREDUMP +#define WCOREDUMP(S) ((S) & WCOREFLG) +#endif +#ifndef WCOREFLG +#define WCOREFLG 0200 +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +/* When this program is run with no arguments, it runs some tests of + the libiberty pexecute functions. As a test program, it simply + invokes itself with various arguments. + + argv[1]: + *empty string* Run tests, exit with success status + exit Exit success + error Exit error + abort Abort + echo Echo remaining arguments, exit success + echoerr Echo next arg to stdout, next to stderr, repeat + copy Copy stdin to stdout + write Write stdin to file named in next argument +*/ + +static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN; +static void error (int, const char *); +static void check_line (int, FILE *, const char *); +static void do_cmd (int, char **) ATTRIBUTE_NORETURN; + +/* The number of errors we have seen. */ + +static int error_count; + +/* Print a fatal error and exit. LINE is the line number where we + detected the error, ERRMSG is the error message to print, and ERR + is 0 or an errno value to print. */ + +static void +fatal_error (int line, const char *errmsg, int err) +{ + fprintf (stderr, "test-pexecute:%d: %s", line, errmsg); + if (errno != 0) + fprintf (stderr, ": %s", xstrerror (err)); + fprintf (stderr, "\n"); + exit (EXIT_FAILURE); +} + +#define FATAL_ERROR(ERRMSG, ERR) fatal_error (__LINE__, ERRMSG, ERR) + +/* Print an error message and bump the error count. LINE is the line + number where we detected the error, ERRMSG is the error to + print. */ + +static void +error (int line, const char *errmsg) +{ + fprintf (stderr, "test-pexecute:%d: %s\n", line, errmsg); + ++error_count; +} + +#define ERROR(ERRMSG) error (__LINE__, ERRMSG) + +/* Check a line in a file. */ + +static void +check_line (int line, FILE *e, const char *str) +{ + const char *p; + int c; + char buf[1000]; + + p = str; + while (1) + { + c = getc (e); + + if (*p == '\0') + { + if (c != '\n') + { + snprintf (buf, sizeof buf, "got '%c' when expecting newline", c); + fatal_error (line, buf, 0); + } + c = getc (e); + if (c != EOF) + { + snprintf (buf, sizeof buf, "got '%c' when expecting EOF", c); + fatal_error (line, buf, 0); + } + return; + } + + if (c != *p) + { + snprintf (buf, sizeof buf, "expected '%c', got '%c'", *p, c); + fatal_error (line, buf, 0); + } + + ++p; + } +} + +#define CHECK_LINE(E, STR) check_line (__LINE__, E, STR) + +/* Main function for the pexecute tester. Run the tests. */ + +int +main (int argc, char **argv) +{ + int trace; + struct pex_obj *test_pex_tmp; + int test_pex_status; + FILE *test_pex_file; + struct pex_obj *pex1; + char *subargv[10]; + int status; + FILE *e; + int statuses[10]; + + trace = 0; + if (argc > 1 && strcmp (argv[1], "-t") == 0) + { + trace = 1; + --argc; + ++argv; + } + + if (argc > 1) + do_cmd (argc, argv); + +#define TEST_PEX_INIT(FLAGS, TEMPBASE) \ + (((test_pex_tmp = pex_init (FLAGS, "test-pexecute", TEMPBASE)) \ + != NULL) \ + ? test_pex_tmp \ + : (FATAL_ERROR ("pex_init failed", 0), NULL)) + +#define TEST_PEX_RUN(PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, ERRNAME) \ + do \ + { \ + int err; \ + const char *pex_run_err; \ + if (trace) \ + fprintf (stderr, "Line %d: running %s %s\n", \ + __LINE__, EXECUTABLE, ARGV[0]); \ + pex_run_err = pex_run (PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, \ + ERRNAME, &err); \ + if (pex_run_err != NULL) \ + FATAL_ERROR (pex_run_err, err); \ + } \ + while (0) + +#define TEST_PEX_GET_STATUS_1(PEXOBJ) \ + (pex_get_status (PEXOBJ, 1, &test_pex_status) \ + ? test_pex_status \ + : (FATAL_ERROR ("pex_get_status failed", errno), 1)) + +#define TEST_PEX_GET_STATUS(PEXOBJ, COUNT, VECTOR) \ + do \ + { \ + if (!pex_get_status (PEXOBJ, COUNT, VECTOR)) \ + FATAL_ERROR ("pex_get_status failed", errno); \ + } \ + while (0) + +#define TEST_PEX_READ_OUTPUT(PEXOBJ) \ + ((test_pex_file = pex_read_output (PEXOBJ, 0)) != NULL \ + ? test_pex_file \ + : (FATAL_ERROR ("pex_read_output failed", errno), NULL)) + + remove ("temp.x"); + remove ("temp.y"); + + memset (subargv, 0, sizeof subargv); + + subargv[0] = "./test-pexecute"; + + pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL); + subargv[1] = "exit"; + subargv[2] = NULL; + TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL); + status = TEST_PEX_GET_STATUS_1 (pex1); + if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) + ERROR ("exit failed"); + pex_free (pex1); + + pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL); + subargv[1] = "error"; + subargv[2] = NULL; + TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL); + status = TEST_PEX_GET_STATUS_1 (pex1); + if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_FAILURE) + ERROR ("error test failed"); + pex_free (pex1); + + /* We redirect stderr to a file to avoid an error message which is + printed on mingw32 when the child calls abort. */ + pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL); + subargv[1] = "abort"; + subargv[2] = NULL; + TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, "temp.z"); + status = TEST_PEX_GET_STATUS_1 (pex1); + if (!WIFSIGNALED (status) || WTERMSIG (status) != SIGABRT) + ERROR ("abort failed"); + pex_free (pex1); + remove ("temp.z"); + + pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp"); + subargv[1] = "echo"; + subargv[2] = "foo"; + subargv[3] = NULL; + TEST_PEX_RUN (pex1, 0, "./test-pexecute", subargv, NULL, NULL); + e = TEST_PEX_READ_OUTPUT (pex1); + CHECK_LINE (e, "foo"); + if (TEST_PEX_GET_STATUS_1 (pex1) != 0) + ERROR ("echo exit status failed"); + pex_free (pex1); + + pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp"); + subargv[1] = "echo"; + subargv[2] = "bar"; + subargv[3] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL); + subargv[1] = "copy"; + subargv[2] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); + e = TEST_PEX_READ_OUTPUT (pex1); + CHECK_LINE (e, "bar"); + TEST_PEX_GET_STATUS (pex1, 2, statuses); + if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS + || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) + ERROR ("copy exit status failed"); + pex_free (pex1); + if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL) + ERROR ("temporary files exist"); + + pex1 = TEST_PEX_INIT (0, "temp"); + subargv[1] = "echo"; + subargv[2] = "bar"; + subargv[3] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL); + subargv[1] = "copy"; + subargv[2] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); + e = TEST_PEX_READ_OUTPUT (pex1); + CHECK_LINE (e, "bar"); + TEST_PEX_GET_STATUS (pex1, 2, statuses); + if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS + || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) + ERROR ("copy exit status failed"); + pex_free (pex1); + if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL) + ERROR ("temporary files exist"); + + pex1 = TEST_PEX_INIT (PEX_SAVE_TEMPS, "temp"); + subargv[1] = "echo"; + subargv[2] = "quux"; + subargv[3] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL); + subargv[1] = "copy"; + subargv[2] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); + e = TEST_PEX_READ_OUTPUT (pex1); + CHECK_LINE (e, "quux"); + TEST_PEX_GET_STATUS (pex1, 2, statuses); + if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS + || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) + ERROR ("copy temp exit status failed"); + e = fopen ("temp.x", "r"); + if (e == NULL) + FATAL_ERROR ("fopen temp.x failed in copy temp", errno); + CHECK_LINE (e, "quux"); + fclose (e); + e = fopen ("temp.y", "r"); + if (e == NULL) + FATAL_ERROR ("fopen temp.y failed in copy temp", errno); + CHECK_LINE (e, "quux"); + fclose (e); + pex_free (pex1); + remove ("temp.x"); + remove ("temp.y"); + + pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp"); + subargv[1] = "echoerr"; + subargv[2] = "one"; + subargv[3] = "two"; + subargv[4] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", "temp2.x"); + subargv[1] = "write"; + subargv[2] = "temp2.y"; + subargv[3] = NULL; + TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); + TEST_PEX_GET_STATUS (pex1, 2, statuses); + if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS + || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) + ERROR ("echoerr exit status failed"); + pex_free (pex1); + if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL) + ERROR ("temporary files exist"); + e = fopen ("temp2.x", "r"); + if (e == NULL) + FATAL_ERROR ("fopen temp2.x failed in echoerr", errno); + CHECK_LINE (e, "two"); + fclose (e); + e = fopen ("temp2.y", "r"); + if (e == NULL) + FATAL_ERROR ("fopen temp2.y failed in echoerr", errno); + CHECK_LINE (e, "one"); + fclose (e); + remove ("temp2.x"); + remove ("temp2.y"); + + /* Test the old pexecute interface. */ + { + int pid1, pid2; + char *errmsg_fmt; + char *errmsg_arg; + char errbuf1[1000]; + char errbuf2[1000]; + + subargv[1] = "echo"; + subargv[2] = "oldpexecute"; + subargv[3] = NULL; + pid1 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp", + &errmsg_fmt, &errmsg_arg, PEXECUTE_FIRST); + if (pid1 < 0) + { + snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg); + snprintf (errbuf2, sizeof errbuf2, "pexecute 1 failed: %s", errbuf1); + FATAL_ERROR (errbuf2, 0); + } + + subargv[1] = "write"; + subargv[2] = "temp.y"; + subargv[3] = NULL; + pid2 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp", + &errmsg_fmt, &errmsg_arg, PEXECUTE_LAST); + if (pid2 < 0) + { + snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg); + snprintf (errbuf2, sizeof errbuf2, "pexecute 2 failed: %s", errbuf1); + FATAL_ERROR (errbuf2, 0); + } + + if (pwait (pid1, &status, 0) < 0) + FATAL_ERROR ("write pwait 1 failed", errno); + if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) + ERROR ("write exit status 1 failed"); + + if (pwait (pid2, &status, 0) < 0) + FATAL_ERROR ("write pwait 1 failed", errno); + if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) + ERROR ("write exit status 2 failed"); + + e = fopen ("temp.y", "r"); + if (e == NULL) + FATAL_ERROR ("fopen temp.y failed in copy temp", errno); + CHECK_LINE (e, "oldpexecute"); + fclose (e); + + remove ("temp.y"); + } + + if (trace) + fprintf (stderr, "Exiting with status %d\n", error_count); + + return error_count; +} + +/* Execute one of the special testing commands. */ + +static void +do_cmd (int argc, char **argv) +{ + const char *s; + + /* Try to prevent generating a core dump. */ +#ifdef RLIMIT_CORE + { + struct rlimit r; + + r.rlim_cur = 0; + r.rlim_max = 0; + setrlimit (RLIMIT_CORE, &r); + } +#endif + + s = argv[1]; + if (strcmp (s, "exit") == 0) + exit (EXIT_SUCCESS); + else if (strcmp (s, "echo") == 0) + { + int i; + + for (i = 2; i < argc; ++i) + { + if (i > 2) + putchar (' '); + fputs (argv[i], stdout); + } + putchar ('\n'); + exit (EXIT_SUCCESS); + } + else if (strcmp (s, "echoerr") == 0) + { + int i; + + for (i = 2; i < argc; ++i) + { + if (i > 3) + putc (' ', (i & 1) == 0 ? stdout : stderr); + fputs (argv[i], (i & 1) == 0 ? stdout : stderr); + } + putc ('\n', stdout); + putc ('\n', stderr); + exit (EXIT_SUCCESS); + } + else if (strcmp (s, "error") == 0) + exit (EXIT_FAILURE); + else if (strcmp (s, "abort") == 0) + abort (); + else if (strcmp (s, "copy") == 0) + { + int c; + + while ((c = getchar ()) != EOF) + putchar (c); + exit (EXIT_SUCCESS); + } + else if (strcmp (s, "write") == 0) + { + FILE *e; + int c; + + e = fopen (argv[2], "w"); + if (e == NULL) + FATAL_ERROR ("fopen for write failed", errno); + while ((c = getchar ()) != EOF) + putc (c, e); + if (fclose (e) != 0) + FATAL_ERROR ("fclose for write failed", errno); + exit (EXIT_SUCCESS); + } + else + { + char buf[1000]; + + snprintf (buf, sizeof buf, "unrecognized command %s", argv[1]); + FATAL_ERROR (buf, 0); + } + + exit (EXIT_FAILURE); +} diff --git a/gnu/lib/libiberty/src/tmpnam.c b/gnu/lib/libiberty/src/tmpnam.c index 406878c49a3..cc343336642 100644 --- a/gnu/lib/libiberty/src/tmpnam.c +++ b/gnu/lib/libiberty/src/tmpnam.c @@ -24,11 +24,10 @@ not be used in new projects. Use @code{mkstemp} instead. static char tmpnam_buffer[L_tmpnam]; static int tmpnam_counter; -extern int getpid (); +extern int getpid (void); char * -tmpnam (s) - char *s; +tmpnam (char *s) { int pid = getpid (); diff --git a/gnu/lib/libiberty/src/unlink-if-ordinary.c b/gnu/lib/libiberty/src/unlink-if-ordinary.c new file mode 100644 index 00000000000..c03b4dd7c70 --- /dev/null +++ b/gnu/lib/libiberty/src/unlink-if-ordinary.c @@ -0,0 +1,72 @@ +/* unlink-if-ordinary.c - remove link to a file unless it is special + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of the libiberty library. This library 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 library 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* + +@deftypefn Supplemental int unlink_if_ordinary (const char*) + +Unlinks the named file, unless it is special (e.g. a device file). +Returns 0 when the file was unlinked, a negative value (and errno set) when +there was an error deleting the file, and a positive value if no attempt +was made to unlink the file because it is special. + +@end deftypefn + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#if HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#include "libiberty.h" + +#ifndef S_ISLNK +#ifdef S_IFLNK +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#else +#define S_ISLNK(m) 0 +#define lstat stat +#endif +#endif + +int +unlink_if_ordinary (const char *name) +{ + struct stat st; + + if (lstat (name, &st) == 0 + && (S_ISREG (st.st_mode) || S_ISLNK (st.st_mode))) + return unlink (name); + + return 1; +} diff --git a/gnu/lib/libiberty/src/vsnprintf.c b/gnu/lib/libiberty/src/vsnprintf.c index fd3dd18a91c..7df5bd88e52 100644 --- a/gnu/lib/libiberty/src/vsnprintf.c +++ b/gnu/lib/libiberty/src/vsnprintf.c @@ -1,5 +1,5 @@ /* Implement the vsnprintf function. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>. This file is part of the libiberty library. This library is free @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause @@ -42,11 +42,7 @@ system version of this function is used. #include "config.h" #include "ansidecl.h" -#ifdef ANSI_PROTOTYPES #include <stdarg.h> -#else -#include <varargs.h> -#endif #ifdef HAVE_STRING_H #include <string.h> #endif @@ -58,11 +54,7 @@ system version of this function is used. /* This implementation relies on a working vasprintf. */ int -vsnprintf (s, n, format, ap) - char * s; - size_t n; - const char *format; - va_list ap; +vsnprintf (char *s, size_t n, const char *format, va_list ap) { char *buf = 0; int result = vasprintf (&buf, format, ap); @@ -97,7 +89,7 @@ vsnprintf (s, n, format, ap) #define VERIFY(P) do { if (!(P)) abort(); } while (0) static int ATTRIBUTE_PRINTF_3 -checkit VPARAMS ((char *s, size_t n, const char *format, ...)) +checkit (char *s, size_t n, const char *format, ...) { int result; VA_OPEN (ap, format); @@ -109,9 +101,9 @@ checkit VPARAMS ((char *s, size_t n, const char *format, ...)) return result; } -extern int main PARAMS ((void)); +extern int main (void); int -main () +main (void) { char buf[128]; int status; diff --git a/gnu/lib/libiberty/src/vsprintf.c b/gnu/lib/libiberty/src/vsprintf.c index 9f09d7e2758..99e704493f5 100644 --- a/gnu/lib/libiberty/src/vsprintf.c +++ b/gnu/lib/libiberty/src/vsprintf.c @@ -18,7 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause @@ -27,21 +27,14 @@ This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include <ansidecl.h> -#ifdef ANSI_PROTOTYPES #include <stdarg.h> -#else -#include <varargs.h> -#endif #include <stdio.h> #undef vsprintf #if defined _IOSTRG && defined _IOWRT int -vsprintf (buf, format, ap) - char *buf; - const char *format; - va_list ap; +vsprintf (char *buf, const char *format, va_list ap) { FILE b; int ret; diff --git a/gnu/lib/libiberty/src/xstrdup.c b/gnu/lib/libiberty/src/xstrdup.c index 5aa084a7687..9ac2ea038f3 100644 --- a/gnu/lib/libiberty/src/xstrdup.c +++ b/gnu/lib/libiberty/src/xstrdup.c @@ -19,16 +19,18 @@ obtain memory. #endif #ifdef HAVE_STRING_H #include <string.h> +#else +# ifdef HAVE_STRINGS_H +# include <strings.h> +# endif #endif #include "ansidecl.h" #include "libiberty.h" char * -xstrdup (s) - const char *s; +xstrdup (const char *s) { register size_t len = strlen (s) + 1; - register char *ret = xmalloc (len); - memcpy (ret, s, len); - return ret; + register char *ret = XNEWVEC (char, len); + return (char *) memcpy (ret, s, len); } diff --git a/gnu/lib/libiberty/src/xstrndup.c b/gnu/lib/libiberty/src/xstrndup.c new file mode 100644 index 00000000000..0a41f608ec0 --- /dev/null +++ b/gnu/lib/libiberty/src/xstrndup.c @@ -0,0 +1,60 @@ +/* Implement the xstrndup function. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* + +@deftypefn Replacement char* xstrndup (const char *@var{s}, size_t @var{n}) + +Returns a pointer to a copy of @var{s} with at most @var{n} characters +without fail, using @code{xmalloc} to obtain memory. The result is +always NUL terminated. + +@end deftypefn + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <sys/types.h> +#ifdef HAVE_STRING_H +#include <string.h> +#else +# ifdef HAVE_STRINGS_H +# include <strings.h> +# endif +#endif +#include "ansidecl.h" +#include "libiberty.h" + +char * +xstrndup (const char *s, size_t n) +{ + char *result; + size_t len = strlen (s); + + if (n < len) + len = n; + + result = XNEWVEC (char, len + 1); + + result[len] = '\0'; + return (char *) memcpy (result, s, len); +} |