aboutsummaryrefslogtreecommitdiff
path: root/libiberty
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2000-06-15 20:56:25 +0000
committerH.J. Lu <hjl.tools@gmail.com>2000-06-15 20:56:25 +0000
commiteb383413c242546f266f9694071e0480806649b3 (patch)
tree95b240bd0c181ac81463ba1f0e6b97f06e973638 /libiberty
parentb91280077a7ea882b26a1dfb84b1f314e84c6a86 (diff)
downloadfsf-binutils-gdb-eb383413c242546f266f9694071e0480806649b3.zip
fsf-binutils-gdb-eb383413c242546f266f9694071e0480806649b3.tar.gz
fsf-binutils-gdb-eb383413c242546f266f9694071e0480806649b3.tar.bz2
Synced with libiberty in the gcc repository.
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog193
-rw-r--r--libiberty/Makefile.in50
-rw-r--r--libiberty/aclocal.m471
-rw-r--r--libiberty/choose-temp.c10
-rw-r--r--libiberty/config.in9
-rw-r--r--libiberty/config.table1
-rwxr-xr-xlibiberty/configure585
-rw-r--r--libiberty/configure.in25
-rw-r--r--libiberty/cp-demangle.c3015
-rw-r--r--libiberty/cplus-dem.c186
-rw-r--r--libiberty/dyn-string.c333
-rw-r--r--libiberty/hashtab.c169
-rw-r--r--libiberty/memcmp.c4
-rw-r--r--libiberty/mkstemps.c2
-rw-r--r--libiberty/partition.c8
-rw-r--r--libiberty/setenv.c12
-rw-r--r--libiberty/strncmp.c28
-rw-r--r--libiberty/xmalloc.c3
18 files changed, 4421 insertions, 283 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index c375430..e7bac6d 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,11 +1,83 @@
-2000-06-06 DJ Delorie <dj@cygnus.com>
+2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
- * Makefile.in: add EXTRA_INCS
- * configure.in: if with-newlib, point to it for includes
- rather than using the installed includes, for target builds.
- If cygwin, override function list only for target builds.
- * configure: regenerate
+ * cp-demangle.c (demangle_operator_name): Add spaces before
+ names beginning with a letter: delete, delete[], new, new[],
+ sizeof.
+ (demangle_special_name): Handle TF <type> and TJ <type>.
+
+Thu Jun 8 18:52:24 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * cp-demangle.c (template_arg_list_new): Revert previous PARAMS patch.
+
+Thu Jun 8 09:25:54 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * cp-demangle.c (stdio.h): File included unconditionaly.
+ (template_arg_list_new): Parameter list is PARAMS ((void)), not ().
+ * dyn-string.c (stdio.h): File included.
+ * partition.c (partition_print): No `&' needed to take the address of
+ a function.
+
+2000-06-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in (ac_libiberty_warn_cflags): Add -pedantic.
+
+ * choose-temp.c (try, choose_temp_base, make_temp_file): Constify.
+
+ * cp-demangle.c (demangle_char): Change parameter from char to int.
+ (demangle_expression, demangle_expr_primary): Remove extra
+ semi-colon in prototype.
+
+ * dyn-string.c (dyn_string_append_char): Change parameter from
+ char to int.
+
+ * memcmp.c (memcmp): Constify.
+
+ * mkstemps.c (gcc_uint64_t): Mark GNUC `long long' case with
+ __extension__.
+
+ * partition.c (elem_compare): Prototype. Don't cast away
+ const-ness.
+
+ * setenv.c (setenv): Use braces to avoid ambiguous `else'.
+
+2000-06-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ * Makefile.in (cp-demangle.o): Depend on $(INCDIR)/demangle.h.
+
+ * cp-demangle.c: Include demangle.h.
+ (template_arg_list_new): DeANSIfy.
+ (cp_demangle): Make static and add prototype.
+ (operator_code, operators): Constify.
+ (demangle_operator_name): Likewise for variables `p1', `p2' and `p'.
+
+2000-06-05 Alex Samuel <samuel@codesourcery.com>
+
+ * cp-demangle.c (demangle_prefix): Cast argument to isdigit to
+ unsigned char.
+ (demangle_unqualified_name): Likewise.
+ (demangle_number_literally): Likewise.
+ (demangle_type): Likewise.
+ (demangle_substitution): Likewise.
+ (is_mangled_char): Likewise, for isalnum.
+
+2000-06-04 Alex Samuel <samuel@codesourcery.com>
+
+ * Makefile.in (CFILES): Add cp-demangle.c and dyn-string.c.
+ (REQUIRED_OFILES): Add cp-demangle.o and dyn-string.o.
+ (cp-demangle.o): New dependency.
+ (dyn-string.o): Likewise.
+
+ * dyn-string.c: Move here from gcc/dyn-string.c. Add new functions.
+
+ * cplus-dem.c (libiberty_demanglers): Add initializer for new-ABI
+ demangler.
+ (cplus_demangle): Call cplus_demangle_new_abi if in new-ABI
+ demangling mode.
+ (gnu_new_abi_symbol_characters): New function.
+ (main): Use gnu_new_abi_symbol_characters. * cp-demangle.c: New
+ file.
+ * cp-demangle.c: New file.
+
Tue May 30 16:45:25 2000 Andrew Cagney <cagney@b1.cygnus.com>
* floatformat.c: Add name to each floatformat field.
@@ -16,7 +88,7 @@ Tue May 30 15:07:52 2000 Jeffrey A Law (law@cygnus.com)
2000-05-29 Zack Weinberg <zack@wolery.cumb.org>
- * hashtab.c, partition.c, xmemdup.c: Include string.h
+ * hashtab.c, partition.c, sort.c, xmemdup.c: Include string.h
if HAVE_STRING_H.
* pexecute.c, xexit.c: Include stdlib.h if HAVE_STDLIB_H.
* objalloc.c: Include config.h. Include stdlib.h and don't
@@ -26,22 +98,125 @@ Tue May 30 15:07:52 2000 Jeffrey A Law (law@cygnus.com)
HAVE_STRING_H, else declare memset without prototype. Don't
include stddef.h.
- * sort.c: Bring over from GCC.
+2000-05-23 Mike Stump <mrs@wrs.com>
+
+ * Makefile.in (xmalloc.o): Add dependency for config.h, fixes make
+ -j3.
+
+2000-05-18 J. David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * xmalloc.c: Include config.h for HAVE_SBRK definition.
+
+2000-05-16 Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
+
+ * hashtab.c (hash_pointer): Delete low-order bits which are
+ probably zero, also eliminate a warning on alpha.
+
+2000-05-15 David Edelsohn <edelsohn@gnu.org>
+
+ * Makefile.in: Change "pic" to depend on $(PICFLAG), not
+ on $(enable_shared).
+
+2000-05-10 Jakub Jelinek <jakub@redhat.com>
+
+ * config.table: Use mh-sparcpic for sparc*-*-*.
-2000-05-26 Alexandre Oliva <aoliva@cygnus.com>
+2000-05-08 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.in (CFILES): Add strncmp.c.
+ (NEEDED): Add strncmp.
+
+2000-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cplus-dem.c (cplus_demangle_opname, demangle_function_name):
+ Cast the arguments to `islower' to `unsigned char'.
+ (print_demangler_list): Prototype.
+
+Thu May 4 17:14:41 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * sort.c (UCHAR_MAX): Provide fallback definition.
+
+2000-04-29 Alexandre Oliva <aoliva@cygnus.com>
* Makefile.in (maintainer-clean-subdir): Fix handling of empty
SUBDIRS.
+2000-04-28 Kenneth Block <block@zk3.dec.com>
+ Jason Merrill <jason@casey.cygnus.com>
+
+ * cplus-dem.c (libiberty_demanglers): New table for demangle styles.
+ (cplus_demangle_set_style): New function for setting style.
+ (cplus_demangle_name_to_style): New function to translate name.
+
+2000-04-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * aclocal.m4: New file with new test libiberty_AC_FUNC_STRNCMP.
+
+ * configure.in (AC_CHECK_HEADERS): Add sys/mman.h fcntl.h.
+ (libiberty_AC_FUNC_STRNCMP): Invoke.
+
+ * strncmp.c: New file.
+
+Thu Apr 27 16:58:43 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * hashtab.c (htab_expand): Add prototype.
+ (find_empty_slot_for_expand): Likewise.
+
+2000-04-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * hashtab.c (hash_pointer, eq_pointer): Make definition static to
+ match prototype.
+ (htab_expand): Cast the return value of xcalloc.
+
+2000-04-24 Mark Mitchell <mark@codesourcery.com>
+
+ * hashtab.c (hash_pointer): New function.
+ (eq_pointer): Likewise.
+ (htab_hash_pointer): New variable.
+ (htab_eq_pointer): Likewise.
+
+2000-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ * sort.c (sort_pointers): Fix endianness bugs.
+
+ * sort.c: New file.
+ * Makefile.in (CFILES): Add sort.c
+ (REQUIRED_OFILES): Add sort.o.
+ (sort.o): New target.
+
2000-04-21 Michael Sokolov <msokolov@ivan.Harhan.ORG>
* Makefile.in (*-subdir): Revamp slightly to avoid losing on
4.3BSD systems.
+Tue Apr 18 16:23:31 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * hashtab.c: Various minor cleanups.
+ (htab_find_slot_with_hash): INSERT is now enum insert_option.
+ (htab_find_slot): Likewise.
+
+2000-04-16 Dave Pitts <dpitts@cozx.com>
+
+ * cplus-dem.c (cplus_demangle_opname): Changed to use islower.
+
2000-04-05 Richard Henderson <rth@cygnus.com>
* splay-tree.c (splay_tree_remove): New.
+2000-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ * hashtab.c (find_empty_slot_for_expand): Use hashval_t for hash
+ codes.
+ (htab_find_with_hash): Likewise.
+ (htab_find_slot_with_hash): Likewise.
+
+2000-03-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * hashtab.c (htab_find_with_hash): Avoid calculating hash2
+ unless it will be used. Rearrange loop for better
+ optimization.
+ (higher_prime_number): Add static prototype.
+
Thu Mar 16 01:33:58 2000 Jeffrey A Law (law@cygnus.com)
* Makefile.in (partition.o): Depend on config.h
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index f9c1621..a95adcd 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -1,6 +1,6 @@
#
# Makefile
-# Copyright (C) 1990, 91 - 99, 2000
+# Copyright (C) 1990, 91-99, 2000
# Free Software Foundation
#
# This file is part of the libiberty library.
@@ -106,10 +106,11 @@ installcheck: installcheck-subdir
INCDIR=$(srcdir)/$(MULTISRCTOP)../include
-COMPILE.c = $(CC) -c @DEFS@ $(LIBCFLAGS) -I. -I$(INCDIR) @EXTRA_INCS@ $(HDEFINES) @ac_libiberty_warn_cflags@
+COMPILE.c = $(CC) -c @DEFS@ $(LIBCFLAGS) -I. -I$(INCDIR) $(HDEFINES) @ac_libiberty_warn_cflags@
.c.o:
- test x"$(enable_shared)" != xyes || \
- $(COMPILE.c) $(PICFLAG) $< -o pic/$@
+ if [ x"$(PICFLAG)" != x ]; then \
+ $(COMPILE.c) $(PICFLAG) $< -o pic/$@; \
+ else true; fi
$(COMPILE.c) $<
info: info-subdir
@@ -124,23 +125,25 @@ HFILES = alloca-conf.h
# (alphabetical), and add them to REQUIRED_OFILES or funcs in
# configure.in.
CFILES = asprintf.c alloca.c argv.c atexit.c basename.c bcmp.c bcopy.c \
- bzero.c calloc.c choose-temp.c clock.c concat.c cplus-dem.c fdmatch.c \
- fnmatch.c getcwd.c getpwd.c getopt.c getopt1.c getpagesize.c \
- getruntime.c floatformat.c hashtab.c hex.c index.c insque.c memchr.c \
- memcmp.c memcpy.c memmove.c memset.c mkstemps.c objalloc.c obstack.c \
- partition.c pexecute.c putenv.c random.c rename.c rindex.c \
- setenv.c sigsetmask.c spaces.c splay-tree.c strcasecmp.c \
- strncasecmp.c strchr.c strdup.c strerror.c strrchr.c \
- strsignal.c strstr.c strtod.c strtol.c strtoul.c tmpnam.c \
- vasprintf.c vfork.c vfprintf.c vprintf.c vsprintf.c waitpid.c \
- xatexit.c xexit.c xmalloc.c xmemdup.c xstrdup.c xstrerror.c
+ bzero.c calloc.c choose-temp.c clock.c concat.c cplus-dem.c \
+ cp-demangle.c dyn-string.c fdmatch.c fnmatch.c getcwd.c \
+ getpwd.c getopt.c getopt1.c getpagesize.c getruntime.c \
+ floatformat.c hashtab.c hex.c index.c insque.c memchr.c memcmp.c \
+ memcpy.c memmove.c memset.c mkstemps.c objalloc.c obstack.c \
+ partition.c pexecute.c putenv.c random.c rename.c rindex.c setenv.c \
+ sigsetmask.c sort.c spaces.c splay-tree.c strcasecmp.c strncasecmp.c \
+ strchr.c strdup.c strerror.c strncmp.c strrchr.c strsignal.c strstr.c \
+ strtod.c strtol.c strtoul.c tmpnam.c vasprintf.c vfork.c vfprintf.c \
+ vprintf.c vsprintf.c waitpid.c xatexit.c xexit.c xmalloc.c \
+ xmemdup.c xstrdup.c xstrerror.c
# These are always included in the library.
-REQUIRED_OFILES = argv.o choose-temp.o concat.o cplus-dem.o \
- fdmatch.o fnmatch.o getopt.o getopt1.o getpwd.o getruntime.o hashtab.o \
- hex.o floatformat.o objalloc.o obstack.o partition.o pexecute.o spaces.o \
- splay-tree.o strerror.o strsignal.o xatexit.o xexit.o xmalloc.o \
- xmemdup.o xstrdup.o xstrerror.o
+REQUIRED_OFILES = argv.o choose-temp.o concat.o cplus-dem.o cp-demangle.o \
+ dyn-string.o fdmatch.o fnmatch.o getopt.o getopt1.o getpwd.o \
+ getruntime.o hashtab.o hex.o floatformat.o objalloc.o obstack.o \
+ partition.o pexecute.o sort.o spaces.o splay-tree.o strerror.o \
+ strsignal.o xatexit.o xexit.o xmalloc.o xmemdup.o xstrdup.o \
+ xstrerror.o
$(TARGETLIB): $(REQUIRED_OFILES) $(EXTRA_OFILES) $(LIBOBJS) $(ALLOCA)
rm -f $(TARGETLIB)
@@ -167,7 +170,7 @@ install_to_tooldir: all
# to include there. Do not add anything LGPL to this list; libstdc++
# can't use anything encumbering.
NEEDED = atexit calloc memchr memcmp memcpy memmove memset rename strchr \
- strerror strrchr strstr strtol strtoul tmpnam vfprintf vprintf \
+ strerror strncmp strrchr strstr strtol strtoul tmpnam vfprintf vprintf \
vfork waitpid bcmp bcopy bzero
needed-list: Makefile
rm -f needed-list; touch needed-list; \
@@ -185,7 +188,7 @@ required-list: Makefile
echo $(REQUIRED_OFILES) > required-list
stamp-picdir:
- if [ x"$(enable_shared)" = xyes ] && [ ! -d pic ]; then \
+ if [ x"$(PICFLAG)" != x ] && [ ! -d pic ]; then \
mkdir pic; \
else true; fi
touch stamp-picdir
@@ -260,6 +263,8 @@ choose-temp.o: config.h
clock.o: config.h
concat.o: $(INCDIR)/libiberty.h
cplus-dem.o: config.h $(INCDIR)/demangle.h
+cp-demangle.o: config.h $(INCDIR)/dyn-string.h $(INCDIR)/demangle.h
+dyn-string.o: config.h $(INCDIR)/dyn-string.h
fdmatch.o: $(INCDIR)/libiberty.h
fnmatch.o: config.h $(INCDIR)/fnmatch.h
getcwd.o: config.h
@@ -276,13 +281,14 @@ obstack.o: config.h $(INCDIR)/obstack.h
partition.o: config.h $(INCDIR)/partition.h
pexecute.o: config.h $(INCDIR)/libiberty.h
setenv.o: config.h
+sort.o: config.h $(INCDIR)/sort.h $(INCDIR)/ansidecl.h
spaces.o: $(INCDIR)/libiberty.h
splay-tree.o: config.h $(INCDIR)/libiberty.h $(INCDIR)/splay-tree.h $(INCDIR)/ansidecl.h
strerror.o: config.h $(INCDIR)/libiberty.h
strsignal.o: config.h $(INCDIR)/libiberty.h
xatexit.o: $(INCDIR)/libiberty.h
xexit.o: $(INCDIR)/libiberty.h
-xmalloc.o: $(INCDIR)/libiberty.h
+xmalloc.o: config.h $(INCDIR)/libiberty.h
xmemdup.o: config.h $(INCDIR)/libiberty.h
xstrdup.o: config.h $(INCDIR)/libiberty.h
xstrerror.o: config.h $(INCDIR)/libiberty.h
diff --git a/libiberty/aclocal.m4 b/libiberty/aclocal.m4
new file mode 100644
index 0000000..b6a38d6
--- /dev/null
+++ b/libiberty/aclocal.m4
@@ -0,0 +1,71 @@
+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
+dnl a SEGV in some cases.
+AC_DEFUN(libiberty_AC_FUNC_STRNCMP,
+[AC_REQUIRE([AC_FUNC_MMAP])
+AC_CACHE_CHECK([for working strncmp], ac_cv_func_strncmp_works,
+[AC_TRY_RUN([
+/* Test by Jim Wilson and Kaveh Ghazi.
+ Check whether strncmp reads past the end of its string parameters. */
+#include <sys/types.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifndef MAP_ANON
+#ifdef MAP_ANONYMOUS
+#define MAP_ANON MAP_ANONYMOUS
+#else
+#define MAP_ANON MAP_FILE
+#endif
+#endif
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#define MAP_LEN 0x10000
+
+main ()
+{
+#if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE)
+ char *p;
+ int dev_zero;
+
+ dev_zero = open ("/dev/zero", O_RDONLY);
+ if (dev_zero < 0)
+ exit (1);
+
+ p = (char *) mmap (0, MAP_LEN, PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, dev_zero, 0);
+ if (p == (char *)-1)
+ exit (2);
+ else
+ {
+ char *string = "__si_type_info";
+ char *q = (char *) p + MAP_LEN - strlen (string) - 2;
+ char *r = (char *) p + 0xe;
+
+ strcpy (q, string);
+ strcpy (r, string);
+ strncmp (r, q, 14);
+ }
+#endif /* HAVE_MMAP || HAVE_MMAP_ANYWHERE */
+ exit (0);
+}
+], ac_cv_func_strncmp_works=yes, ac_cv_func_strncmp_works=no,
+ ac_cv_func_strncmp_works=no)
+rm -f core core.* *.core])
+if test $ac_cv_func_strncmp_works = no ; then
+ LIBOBJS="$LIBOBJS strncmp.o"
+fi
+])
diff --git a/libiberty/choose-temp.c b/libiberty/choose-temp.c
index 826d818..1a475dd 100644
--- a/libiberty/choose-temp.c
+++ b/libiberty/choose-temp.c
@@ -79,9 +79,11 @@ extern int mkstemps ();
If success, DIR is returned.
Otherwise NULL is returned. */
-static char *
+static const char *try PARAMS ((const char *, const char *));
+
+static const char *
try (dir, base)
- char *dir, *base;
+ const char *dir, *base;
{
if (base != 0)
return base;
@@ -102,7 +104,7 @@ try (dir, base)
char *
choose_temp_base ()
{
- char *base = 0;
+ const char *base = 0;
char *temp_filename;
int len;
static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
@@ -147,7 +149,7 @@ char *
make_temp_file (suffix)
const char *suffix;
{
- char *base = 0;
+ const char *base = 0;
char *temp_filename;
int base_len, suffix_len;
int fd;
diff --git a/libiberty/config.in b/libiberty/config.in
index 6e64208..bc0c729 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -13,6 +13,9 @@
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#undef HAVE_ALLOCA_H
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
@@ -196,6 +199,9 @@
/* Define if you have the waitpid function. */
#undef HAVE_WAITPID
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
@@ -208,6 +214,9 @@
/* Define if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
+/* Define if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
diff --git a/libiberty/config.table b/libiberty/config.table
index 4e33746..ea3312b 100644
--- a/libiberty/config.table
+++ b/libiberty/config.table
@@ -27,6 +27,7 @@ if [ "${shared}" = "yes" ]; then
i[3456]86-*-*) frags="${frags} ../../config/mh-x86pic" ;;
powerpc*-*-aix*) ;;
powerpc*-*-*) frags="${frags} ../../config/mh-ppcpic" ;;
+ sparc*-*-*) frags="${frags} ../../config/mh-sparcpic" ;;
*-*-*) frags="${frags} ../../config/mh-${host_cpu}pic" ;;
esac
fi
diff --git a/libiberty/configure b/libiberty/configure
index e16dc84..ef375bb 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -34,7 +34,6 @@ program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
-sitefile=
srcdir=
target=NONE
verbose=
@@ -149,7 +148,6 @@ Configuration:
--help print this message
--no-create do not create output files
--quiet, --silent do not print \`checking...' messages
- --site-file=FILE use FILE as the site file
--version print the version of autoconf that created configure
Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX
@@ -320,11 +318,6 @@ EOF
-site=* | --site=* | --sit=*)
site="$ac_optarg" ;;
- -site-file | --site-file | --site-fil | --site-fi | --site-f)
- ac_prev=sitefile ;;
- -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
- sitefile="$ac_optarg" ;;
-
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
@@ -490,16 +483,12 @@ fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
# Prefer explicitly selected file to automatically selected ones.
-if test -z "$sitefile"; then
- if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
fi
-else
- CONFIG_SITE="$sitefile"
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
@@ -598,7 +587,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:602: checking host system type" >&5
+echo "configure:591: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -621,7 +610,7 @@ echo "$ac_t""$host" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:625: checking build system type" >&5
+echo "configure:614: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -647,7 +636,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:651: checking for $ac_word" >&5
+echo "configure:640: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -679,7 +668,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:683: checking for $ac_word" >&5
+echo "configure:672: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -711,7 +700,7 @@ if test -n "$ac_tool_prefix"; then
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:715: checking for $ac_word" >&5
+echo "configure:704: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -757,7 +746,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:761: checking for $ac_word" >&5
+echo "configure:750: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -787,7 +776,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:791: checking for $ac_word" >&5
+echo "configure:780: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -836,7 +825,7 @@ fi
fi
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:840: checking whether we are using GNU C" >&5
+echo "configure:829: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -845,7 +834,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:849: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:838: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -856,12 +845,12 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6
if test $ac_cv_prog_gcc = yes; then
GCC=yes
- ac_libiberty_warn_cflags='-W -Wall -Wtraditional'
+ ac_libiberty_warn_cflags='-W -Wall -Wtraditional -pedantic'
ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:865: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:854: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -891,7 +880,7 @@ fi
echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
-echo "configure:895: checking for POSIXized ISC" >&5
+echo "configure:884: checking for POSIXized ISC" >&5
if test -d /etc/conf/kconfig.d &&
grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
then
@@ -929,7 +918,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:933: checking for a BSD compatible install" >&5
+echo "configure:922: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -990,7 +979,7 @@ host_makefile_frag=${frag}
# able to link anything, it had better be able to at least compile
# something.
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:994: checking how to run the C preprocessor" >&5
+echo "configure:983: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1005,13 +994,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1009 "configure"
+#line 998 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1015: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1004: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1022,13 +1011,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1026 "configure"
+#line 1015 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1032: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1021: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1039,13 +1028,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1043 "configure"
+#line 1032 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1049: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1038: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1069,21 +1058,21 @@ else
fi
echo "$ac_t""$CPP" 1>&6
-for ac_hdr in sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h
+for ac_hdr in sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1077: checking for $ac_hdr" >&5
+echo "configure:1066: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1082 "configure"
+#line 1071 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1087: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1076: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1110,12 +1099,12 @@ fi
done
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1114: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1103: checking for sys/wait.h that is POSIX.1 compatible" >&5
if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1119 "configure"
+#line 1108 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1131,7 +1120,7 @@ wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1135: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1124: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
@@ -1207,12 +1196,12 @@ if test "x" = "y"; then
for ac_func in asprintf atexit basename bcmp bcopy bzero calloc clock getcwd
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1211: checking for $ac_func" >&5
+echo "configure:1200: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1216 "configure"
+#line 1205 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1235,7 +1224,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1228: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1262,12 +1251,12 @@ done
for ac_func in getpagesize index insque mkstemps memchr memcmp memcpy memmove
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1266: checking for $ac_func" >&5
+echo "configure:1255: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1271 "configure"
+#line 1260 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1290,7 +1279,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1317,12 +1306,12 @@ done
for ac_func in memset putenv random rename rindex sigsetmask strcasecmp
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1321: checking for $ac_func" >&5
+echo "configure:1310: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1326 "configure"
+#line 1315 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1345,7 +1334,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1372,12 +1361,12 @@ done
for ac_func in setenv strchr strdup strncasecmp strrchr strstr strtod strtol
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1376: checking for $ac_func" >&5
+echo "configure:1365: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1381 "configure"
+#line 1370 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1400,7 +1389,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1393: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1427,12 +1416,12 @@ done
for ac_func in strtoul tmpnam vasprintf vfprintf vprintf vsprintf waitpid
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1431: checking for $ac_func" >&5
+echo "configure:1420: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1436 "configure"
+#line 1425 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1455,7 +1444,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1494,12 +1483,12 @@ EOF
for ac_func in getrusage on_exit psignal strerror strsignal sysconf times
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1498: checking for $ac_func" >&5
+echo "configure:1487: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1503 "configure"
+#line 1492 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1522,7 +1511,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1549,12 +1538,12 @@ done
for ac_func in sbrk gettimeofday
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1553: checking for $ac_func" >&5
+echo "configure:1542: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1558 "configure"
+#line 1547 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1577,7 +1566,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1570: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1649,11 +1638,6 @@ EOF
setobjs=yes
- if test -d ${libiberty_topdir}/newlib
- then
- EXTRA_INCS="-I${libiberty_topdir}/newlib/libc/include"
- fi
-
fi
else
@@ -1665,7 +1649,6 @@ fi
-
if test -z "${setobjs}"; then
case "${host}" in
@@ -1722,15 +1705,10 @@ if test -z "${setobjs}"; then
# 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//'`"
- LIBOBJS="$LIBOBJS random.o"
- vars="`echo $vars | sed -e 's/sys_siglist//'`"
- checkfuncs="`echo $checkfuncs | sed -e 's/strsignal//' -e 's/psignal//'`"
- fi
+ funcs="`echo $funcs | sed -e 's/random//'`"
+ LIBOBJS="$LIBOBJS random.o"
+ vars="`echo $vars | sed -e 's/sys_siglist//'`"
+ checkfuncs="`echo $checkfuncs | sed -e 's/strsignal//' -e 's/psignal//'`"
;;
*-*-mingw32*)
@@ -1770,7 +1748,7 @@ EOF
# We haven't set the list of objects yet. Use the standard autoconf
# tests. This will only work if the compiler works.
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1774: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1752: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1781,12 +1759,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
-#line 1785 "configure"
+#line 1763 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:1790: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@@ -1812,19 +1790,19 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1816: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1794: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
for ac_func in $funcs
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1823: checking for $ac_func" >&5
+echo "configure:1801: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1828 "configure"
+#line 1806 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1847,7 +1825,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1851: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1894,19 +1872,19 @@ EOF
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
# for constant arguments. Useless!
echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:1898: checking for working alloca.h" >&5
+echo "configure:1876: checking for working alloca.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1903 "configure"
+#line 1881 "configure"
#include "confdefs.h"
#include <alloca.h>
int main() {
char *p = alloca(2 * sizeof(int));
; return 0; }
EOF
-if { (eval echo configure:1910: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_header_alloca_h=yes
else
@@ -1927,12 +1905,12 @@ EOF
fi
echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:1931: checking for alloca" >&5
+echo "configure:1909: checking for alloca" >&5
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1936 "configure"
+#line 1914 "configure"
#include "confdefs.h"
#ifdef __GNUC__
@@ -1960,7 +1938,7 @@ int main() {
char *p = (char *) alloca(1);
; return 0; }
EOF
-if { (eval echo configure:1964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1942: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_func_alloca_works=yes
else
@@ -1992,12 +1970,12 @@ EOF
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:1996: checking whether alloca needs Cray hooks" >&5
+echo "configure:1974: checking whether alloca needs Cray hooks" >&5
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2001 "configure"
+#line 1979 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
@@ -2022,12 +2000,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
if test $ac_cv_os_cray = yes; then
for ac_func in _getb67 GETB67 getb67; do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2026: checking for $ac_func" >&5
+echo "configure:2004: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2031 "configure"
+#line 2009 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2050,7 +2028,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2077,7 +2055,7 @@ done
fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2081: checking stack direction for C alloca" >&5
+echo "configure:2059: checking stack direction for C alloca" >&5
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2085,7 +2063,7 @@ else
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 2089 "configure"
+#line 2067 "configure"
#include "confdefs.h"
find_stack_direction ()
{
@@ -2104,7 +2082,7 @@ main ()
exit (find_stack_direction() < 0);
}
EOF
-if { (eval echo configure:2108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_stack_direction=1
else
@@ -2129,12 +2107,12 @@ fi
esac
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2133: checking for ANSI C header files" >&5
+echo "configure:2111: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2138 "configure"
+#line 2116 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -2142,7 +2120,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2146: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2124: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -2159,7 +2137,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 2163 "configure"
+#line 2141 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -2177,7 +2155,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 2181 "configure"
+#line 2159 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -2198,7 +2176,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 2202 "configure"
+#line 2180 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2209,7 +2187,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:2213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -2233,12 +2211,12 @@ EOF
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2237: checking for pid_t" >&5
+echo "configure:2215: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2242 "configure"
+#line 2220 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2267,17 +2245,17 @@ fi
ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:2271: checking for vfork.h" >&5
+echo "configure:2249: checking for vfork.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2276 "configure"
+#line 2254 "configure"
#include "confdefs.h"
#include <vfork.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2281: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2259: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -2302,18 +2280,18 @@ else
fi
echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:2306: checking for working vfork" >&5
+echo "configure:2284: checking for working vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
echo $ac_n "checking for vfork""... $ac_c" 1>&6
-echo "configure:2312: checking for vfork" >&5
+echo "configure:2290: checking for vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2317 "configure"
+#line 2295 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vfork(); below. */
@@ -2336,7 +2314,7 @@ vfork();
; return 0; }
EOF
-if { (eval echo configure:2340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_vfork=yes"
else
@@ -2358,7 +2336,7 @@ fi
ac_cv_func_vfork_works=$ac_cv_func_vfork
else
cat > conftest.$ac_ext <<EOF
-#line 2362 "configure"
+#line 2340 "configure"
#include "confdefs.h"
/* Thanks to Paul Eggert for this test. */
#include <stdio.h>
@@ -2453,7 +2431,7 @@ main() {
}
}
EOF
-if { (eval echo configure:2457: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2435: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_vfork_works=yes
else
@@ -2480,19 +2458,19 @@ fi
fi
for v in $vars; do
echo $ac_n "checking for $v""... $ac_c" 1>&6
-echo "configure:2484: checking for $v" >&5
+echo "configure:2462: checking for $v" >&5
if eval "test \"`echo '$''{'libiberty_cv_var_$v'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2489 "configure"
+#line 2467 "configure"
#include "confdefs.h"
int *p;
int main() {
extern int $v; p = &$v;
; return 0; }
EOF
-if { (eval echo configure:2496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "libiberty_cv_var_$v=yes"
else
@@ -2518,12 +2496,109 @@ EOF
for ac_func in $checkfuncs
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2522: checking for $ac_func" >&5
+echo "configure:2500: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2505 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* 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_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2558: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2563 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2568: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2597: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2527 "configure"
+#line 2602 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2546,7 +2621,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2550: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2625: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2570,8 +2645,269 @@ else
fi
done
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:2650: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2658 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:2798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
fi
+
+echo $ac_n "checking for working strncmp""... $ac_c" 1>&6
+echo "configure:2822: checking for working strncmp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strncmp_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_strncmp_works=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2830 "configure"
+#include "confdefs.h"
+
+/* Test by Jim Wilson and Kaveh Ghazi.
+ Check whether strncmp reads past the end of its string parameters. */
+#include <sys/types.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifndef MAP_ANON
+#ifdef MAP_ANONYMOUS
+#define MAP_ANON MAP_ANONYMOUS
+#else
+#define MAP_ANON MAP_FILE
+#endif
+#endif
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#define MAP_LEN 0x10000
+
+main ()
+{
+#if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE)
+ char *p;
+ int dev_zero;
+
+ dev_zero = open ("/dev/zero", O_RDONLY);
+ if (dev_zero < 0)
+ exit (1);
+
+ p = (char *) mmap (0, MAP_LEN, PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, dev_zero, 0);
+ if (p == (char *)-1)
+ exit (2);
+ else
+ {
+ char *string = "__si_type_info";
+ char *q = (char *) p + MAP_LEN - strlen (string) - 2;
+ char *r = (char *) p + 0xe;
+
+ strcpy (q, string);
+ strcpy (r, string);
+ strncmp (r, q, 14);
+ }
+#endif /* HAVE_MMAP || HAVE_MMAP_ANYWHERE */
+ exit (0);
+}
+
+EOF
+if { (eval echo configure:2891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_strncmp_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_strncmp_works=no
+fi
+rm -fr conftest*
+fi
+
+rm -f core core.* *.core
+fi
+
+echo "$ac_t""$ac_cv_func_strncmp_works" 1>&6
+if test $ac_cv_func_strncmp_works = no ; then
+ LIBOBJS="$LIBOBJS strncmp.o"
+fi
+
+
# Install a library built with a cross compiler in $(tooldir) rather
# than $(libdir).
if test -z "${with_cross_host}"; then
@@ -2735,7 +3071,6 @@ s%@INSTALL_DATA@%$INSTALL_DATA%g
/@host_makefile_frag@/r $host_makefile_frag
s%@host_makefile_frag@%%g
s%@CPP@%$CPP%g
-s%@EXTRA_INCS@%$EXTRA_INCS%g
s%@CHECK@%$CHECK%g
s%@LIBOBJS@%$LIBOBJS%g
s%@ALLOCA@%$ALLOCA%g
diff --git a/libiberty/configure.in b/libiberty/configure.in
index cc30251..6ad054a 100644
--- a/libiberty/configure.in
+++ b/libiberty/configure.in
@@ -55,7 +55,7 @@ AC_PROG_CC_GNU
if test $ac_cv_prog_gcc = yes; then
GCC=yes
- ac_libiberty_warn_cflags='-W -Wall -Wtraditional'
+ 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.
@@ -109,7 +109,7 @@ 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 stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h)
+AC_CHECK_HEADERS(sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h)
AC_HEADER_SYS_WAIT
# This is the list of functions which libiberty will provide if they
@@ -216,11 +216,6 @@ if test -n "${with_target_subdir}"; then
setobjs=yes
- if test -d ${libiberty_topdir}/newlib
- then
- EXTRA_INCS="-I${libiberty_topdir}/newlib/libc/include"
- fi
-
fi
else
@@ -230,7 +225,6 @@ else
fi
-AC_SUBST(EXTRA_INCS)
AC_SUBST(CHECK)
if test -z "${setobjs}"; then
@@ -283,15 +277,10 @@ if test -z "${setobjs}"; then
# 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//'`"
- LIBOBJS="$LIBOBJS random.o"
- vars="`echo $vars | sed -e 's/sys_siglist//'`"
- checkfuncs="`echo $checkfuncs | sed -e 's/strsignal//' -e 's/psignal//'`"
- fi
+ funcs="`echo $funcs | sed -e 's/random//'`"
+ LIBOBJS="$LIBOBJS random.o"
+ vars="`echo $vars | sed -e 's/sys_siglist//'`"
+ checkfuncs="`echo $checkfuncs | sed -e 's/strsignal//' -e 's/psignal//'`"
;;
*-*-mingw32*)
@@ -363,6 +352,8 @@ EOF
AC_CHECK_FUNCS($checkfuncs)
fi
+libiberty_AC_FUNC_STRNCMP
+
# Install a library built with a cross compiler in $(tooldir) rather
# than $(libdir).
if test -z "${with_cross_host}"; then
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
new file mode 100644
index 0000000..b1c4055
--- /dev/null
+++ b/libiberty/cp-demangle.c
@@ -0,0 +1,3015 @@
+/* Demangler for IA64 / g++ standard C++ ABI.
+ Copyright (C) 2000 CodeSourcery LLC.
+ Written by Alex Samuel <samuel@codesourcery.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* This file implements demangling of C++ names mangled according to
+ the IA64 / g++ standard C++ ABI. Use the cp_demangle function to
+ demangle a mangled name, or compile with the preprocessor macro
+ STANDALONE_DEMANGLER defined to create a demangling filter
+ executable. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <ctype.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "dyn-string.h"
+#include "demangle.h"
+
+/* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
+ and other debugging output, will be generated. */
+#ifdef CP_DEMANGLE_DEBUG
+#define DEMANGLE_TRACE(PRODUCTION, DM) \
+ fprintf (stderr, " -> %-24s at position %3d\n", \
+ (PRODUCTION), current_position (DM));
+#else
+#define DEMANGLE_TRACE(PRODUCTION, DM)
+#endif
+
+/* If flag_verbose is zero, some simplifications will be made to the
+ output to make it easier to read and supress details that are
+ generally not of interest to the average C++ programmer.
+ Otherwise, the demangled representation will attempt to convey as
+ much information as the mangled form. */
+static int flag_verbose;
+
+/* If flag_strict is non-zero, demangle strictly according to the
+ specification -- don't demangle special g++ manglings. */
+static int flag_strict;
+
+/* String_list_t is an extended form of dyn_string_t which provides a link
+ field. A string_list_t may safely be cast to and used as a
+ dyn_string_t. */
+
+struct string_list_def
+{
+ struct dyn_string string;
+ struct string_list_def *next;
+};
+
+typedef struct string_list_def *string_list_t;
+
+/* Data structure representing a potential substitution. */
+
+struct substitution_def
+{
+ /* The demangled text of the substitution. */
+ dyn_string_t text;
+
+ /* The template parameter that this represents, indexed from zero.
+ If this is not a template paramter number, the value is
+ NOT_TEMPLATE_PARM. */
+ int template_parm_number;
+
+ /* Whether this substitution represents a template item. */
+ int template_p : 1;
+};
+
+#define NOT_TEMPLATE_PARM (-1)
+
+/* Data structure representing a template argument list. */
+
+struct template_arg_list_def
+{
+ /* The next (lower) template argument list in the stack of currently
+ active template arguments. */
+ struct template_arg_list_def *next;
+
+ /* The first element in the list of template arguments in
+ left-to-right order. */
+ string_list_t first_argument;
+
+ /* The last element in the arguments lists. */
+ string_list_t last_argument;
+};
+
+typedef struct template_arg_list_def *template_arg_list_t;
+
+/* Data structure to maintain the state of the current demangling. */
+
+struct demangling_def
+{
+ /* The full mangled name being mangled. */
+ char *name;
+
+ /* Pointer into name at the current position. */
+ char *next;
+
+ /* Stack for strings containing demangled result generated so far.
+ Text is emitted to the topmost (first) string. */
+ string_list_t result;
+
+ /* The number of presently available substitutions. */
+ int num_substitutions;
+
+ /* The allocated size of the substitutions array. */
+ int substitutions_allocated;
+
+ /* An array of available substitutions. The number of elements in
+ the array is given by num_substitions, and the allocated array
+ size in substitutions_size.
+
+ The most recent substition is at the end, so
+
+ - `S_' corresponds to substititutions[num_substitutions - 1]
+ - `S0_' corresponds to substititutions[num_substitutions - 2]
+
+ etc. */
+ struct substitution_def *substitutions;
+
+ /* The stack of template argument lists. */
+ template_arg_list_t template_arg_lists;
+
+ /* The most recently demangled source-name. */
+ dyn_string_t last_source_name;
+};
+
+typedef struct demangling_def *demangling_t;
+
+/* This type is the standard return code from most functions. Values
+ other than STATUS_OK contain descriptive messages. */
+typedef const char *status_t;
+
+/* Special values that can be used as a status_t. */
+#define STATUS_OK NULL
+#define STATUS_ERROR "Error."
+#define STATUS_UNIMPLEMENTED "Unimplemented."
+#define STATUS_INTERNAL_ERROR "Internal error."
+
+static void int_to_dyn_string
+ PARAMS ((int, dyn_string_t));
+static string_list_t string_list_new
+ PARAMS ((int));
+static void string_list_delete
+ PARAMS ((string_list_t));
+static void result_close_template_list
+ PARAMS ((demangling_t));
+static void result_push
+ PARAMS ((demangling_t));
+static string_list_t result_pop
+ PARAMS ((demangling_t));
+static int substitution_start
+ PARAMS ((demangling_t));
+static void substitution_add
+ PARAMS ((demangling_t, int, int, int));
+static dyn_string_t substitution_get
+ PARAMS ((demangling_t, int, int *));
+#ifdef CP_DEMANGLE_DEBUG
+static void substitutions_print
+ PARAMS ((demangling_t, FILE *));
+#endif
+static template_arg_list_t template_arg_list_new
+ PARAMS ((void));
+static void template_arg_list_delete
+ PARAMS ((template_arg_list_t));
+static void template_arg_list_add_arg
+ PARAMS ((template_arg_list_t, string_list_t));
+static string_list_t template_arg_list_get_arg
+ PARAMS ((template_arg_list_t, int));
+static void push_template_arg_list
+ PARAMS ((demangling_t, template_arg_list_t));
+static void pop_to_template_arg_list
+ PARAMS ((demangling_t, template_arg_list_t));
+#ifdef CP_DEMANGLE_DEBUG
+static void template_arg_list_print
+ PARAMS ((template_arg_list_t, FILE *));
+#endif
+static template_arg_list_t current_template_arg_list
+ PARAMS ((demangling_t));
+static demangling_t demangling_new
+ PARAMS ((char *));
+static void demangling_delete
+ PARAMS ((demangling_t));
+
+/* The last character of DS. Warning: DS is evaluated twice. */
+#define dyn_string_last_char(DS) \
+ (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
+
+/* Append a space character (` ') to DS if it does not already end
+ with one. */
+#define dyn_string_append_space(DS) \
+ do \
+ { \
+ if (dyn_string_length (DS) > 0 \
+ && dyn_string_last_char (DS) != ' ') \
+ dyn_string_append_char ((DS), ' '); \
+ } \
+ while (0)
+
+/* Returns the index of the current position in the mangled name. */
+#define current_position(DM) ((DM)->next - (DM)->name)
+
+/* Returns the character at the current position of the mangled name. */
+#define peek_char(DM) (*((DM)->next))
+
+/* Returns the character one past the current position of the mangled
+ name. */
+#define peek_char_next(DM) \
+ (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
+
+/* Returns the character at the current position, and advances the
+ current position to the next character. */
+#define next_char(DM) (*((DM)->next)++)
+
+/* Returns non-zero if the current position is the end of the mangled
+ name, i.e. one past the last character. */
+#define end_of_name_p(DM) (peek_char (DM) == '\0')
+
+/* Advances the current position by one character. */
+#define advance_char(DM) (++(DM)->next)
+
+/* Returns the string containing the current demangled result. */
+#define result_string(DM) (&(DM)->result->string)
+
+/* Appends a dyn_string_t to the demangled result. */
+#define result_append_string(DM, STRING) \
+ dyn_string_append (&(DM)->result->string, (STRING))
+
+/* Appends NUL-terminated string CSTR to the demangled result. */
+#define result_append(DM, CSTR) \
+ dyn_string_append_cstr (&(DM)->result->string, (CSTR))
+
+/* Appends character CHAR to the demangled result. */
+#define result_append_char(DM, CHAR) \
+ dyn_string_append_char (&(DM)->result->string, (CHAR))
+
+/* The length of the current demangled result. */
+#define result_length(DM) \
+ dyn_string_length (&(DM)->result->string)
+
+/* Appends a space to the demangled result if the last character is
+ not a space. */
+#define result_append_space(DM) \
+ dyn_string_append_space (&(DM)->result->string)
+
+/* Evaluate EXPR, which must produce a status_t. If the status code
+ indicates an error, return from the current function with that
+ status code. */
+#define RETURN_IF_ERROR(EXPR) \
+ do \
+ { \
+ status_t s = EXPR; \
+ if (s != STATUS_OK) \
+ return s; \
+ } \
+ while (0)
+
+/* Appends a base 10 representation of VALUE to DS. */
+
+static void
+int_to_dyn_string (value, ds)
+ int value;
+ dyn_string_t ds;
+{
+ int i;
+ int mask = 1;
+
+ /* Handle zero up front. */
+ if (value == 0)
+ {
+ dyn_string_append_char (ds, '0');
+ return;
+ }
+
+ /* For negative numbers, emit a minus sign. */
+ if (value < 0)
+ {
+ dyn_string_append_char (ds, '-');
+ value = -value;
+ }
+
+ /* Find the power of 10 of the first digit. */
+ i = value;
+ while (i > 9)
+ {
+ mask *= 10;
+ i /= 10;
+ }
+
+ /* Write the digits. */
+ while (mask > 0)
+ {
+ int digit = value / mask;
+ dyn_string_append_char (ds, '0' + digit);
+ value -= digit * mask;
+ mask /= 10;
+ }
+}
+
+/* Creates a new string list node. The contents of the string are
+ empty, but the initial buffer allocation is LENGTH. The string
+ list node should be deleted with string_list_delete. */
+
+static string_list_t
+string_list_new (length)
+ int length;
+{
+ string_list_t s =
+ (string_list_t) xmalloc (sizeof (struct string_list_def));
+ dyn_string_init ((dyn_string_t) s, length);
+ return s;
+}
+
+/* Deletes the entire string list starting at NODE. */
+
+static void
+string_list_delete (node)
+ string_list_t node;
+{
+ while (node != NULL)
+ {
+ string_list_t next = node->next;
+ free (node);
+ node = next;
+ }
+}
+
+/* Appends a greater-than character to the demangled result. If the
+ last character is a greater-than character, a space is inserted
+ first, so that the two greater-than characters don't look like a
+ right shift token. */
+
+static void
+result_close_template_list (dm)
+ demangling_t dm;
+{
+ dyn_string_t s = &dm->result->string;
+ if (dyn_string_last_char (s) == '>')
+ dyn_string_append_char (s, ' ');
+ dyn_string_append_char (s, '>');
+}
+
+/* Allocates and pushes a new string onto the demangled results stack
+ for DM. Subsequent demangling with DM will emit to the new string. */
+
+static void
+result_push (dm)
+ demangling_t dm;
+{
+ string_list_t new_string = string_list_new (0);
+ new_string->next = (string_list_t) dm->result;
+ dm->result = new_string;
+}
+
+/* Removes and returns the topmost element on the demangled results
+ stack for DM. The caller assumes ownership for the returned
+ string. */
+
+static string_list_t
+result_pop (dm)
+ demangling_t dm;
+{
+ string_list_t top = dm->result;
+ dm->result = top->next;
+ return top;
+}
+
+/* Returns the start position of a fragment of the demangled result
+ that will be a substitution candidate. Should be called at the
+ start of productions that can add substitutions. */
+
+static int
+substitution_start (dm)
+ demangling_t dm;
+{
+ return result_length (dm);
+}
+
+/* Adds the suffix of the current demangled result of DM starting at
+ START_POSITION as a potential substitution. If TEMPLATE_P is
+ non-zero, this potential substitution is a template-id.
+
+ If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution
+ is for that particular <template-param>, and is distinct from other
+ otherwise-identical types and other <template-param>s with
+ different indices. */
+
+static void
+substitution_add (dm, start_position, template_p, template_parm_number)
+ demangling_t dm;
+ int start_position;
+ int template_p;
+ int template_parm_number;
+{
+ dyn_string_t result = result_string (dm);
+ dyn_string_t substitution = dyn_string_new (0);
+ int i;
+
+ dyn_string_substring (substitution,
+ result, start_position, result_length (dm));
+
+ /* Check whether SUBSTITUTION already occurs. */
+ for (i = 0; i < dm->num_substitutions; ++i)
+ if (dyn_string_eq (dm->substitutions[i].text, substitution)
+ && dm->substitutions[i].template_parm_number == template_parm_number)
+ /* Found SUBSTITUTION already present. */
+ {
+ /* Callers expect this function to take ownership of
+ SUBSTITUTION, so delete it. */
+ dyn_string_delete (substitution);
+ return;
+ }
+
+ /* If there's no room for the new entry, grow the array. */
+ if (dm->substitutions_allocated == dm->num_substitutions)
+ {
+ dm->substitutions_allocated *= 2;
+ dm->substitutions = (struct substitution_def *)
+ xrealloc (dm->substitutions,
+ sizeof (struct substitution_def)
+ * dm->substitutions_allocated);
+ }
+
+ /* Add the substitution to the array. */
+ dm->substitutions[i].text = substitution;
+ dm->substitutions[i].template_p = template_p;
+ dm->substitutions[i].template_parm_number = template_parm_number;
+ ++dm->num_substitutions;
+
+#ifdef CP_DEMANGLE_DEBUG
+ substitutions_print (dm, stderr);
+#endif
+}
+
+/* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
+ non-zero if the substitution is a template-id, zero otherwise.
+ N is numbered from zero. DM retains ownership of the returned
+ string. If N is negative, or equal to or greater than the current
+ number of substitution candidates, returns NULL. */
+
+static dyn_string_t
+substitution_get (dm, n, template_p)
+ demangling_t dm;
+ int n;
+ int *template_p;
+{
+ struct substitution_def *sub;
+
+ /* Make sure N is in the valid range. */
+ if (n < 0 || n >= dm->num_substitutions)
+ return NULL;
+
+ sub = &(dm->substitutions[n]);
+ *template_p = sub->template_p;
+ return sub->text;
+}
+
+#ifdef CP_DEMANGLE_DEBUG
+/* Debugging routine to print the current substitutions to FP. */
+
+static void
+substitutions_print (dm, fp)
+ demangling_t dm;
+ FILE *fp;
+{
+ int seq_id;
+ int num = dm->num_substitutions;
+
+ fprintf (fp, "SUBSTITUTIONS:\n");
+ for (seq_id = -1; seq_id < num - 1; ++seq_id)
+ {
+ int template_p;
+ dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
+
+ if (seq_id == -1)
+ fprintf (fp, " S_ ");
+ else
+ fprintf (fp, " S%d_", seq_id);
+ fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
+ }
+}
+
+#endif /* CP_DEMANGLE_DEBUG */
+
+/* Creates a new template argument list. */
+
+static template_arg_list_t
+template_arg_list_new ()
+{
+ template_arg_list_t new_list
+ = (template_arg_list_t) xmalloc (sizeof (struct template_arg_list_def));
+ /* Initialize the new list to have no arguments. */
+ new_list->first_argument = NULL;
+ new_list->last_argument = NULL;
+ /* Return the new list. */
+ return new_list;
+}
+
+/* Deletes a template argument list and the template arguments it
+ contains. */
+
+static void
+template_arg_list_delete (list)
+ template_arg_list_t list;
+{
+ /* If there are any arguments on LIST, delete them. */
+ if (list->first_argument != NULL)
+ string_list_delete (list->first_argument);
+ /* Delete LIST. */
+ free (list);
+}
+
+/* Adds ARG to the template argument list ARG_LIST. */
+
+static void
+template_arg_list_add_arg (arg_list, arg)
+ template_arg_list_t arg_list;
+ string_list_t arg;
+{
+ if (arg_list->first_argument == NULL)
+ /* If there were no arguments before, ARG is the first one. */
+ arg_list->first_argument = arg;
+ else
+ /* Make ARG the last argument on the list. */
+ arg_list->last_argument->next = arg;
+ /* Make ARG the last on the list. */
+ arg_list->last_argument = arg;
+ arg->next = NULL;
+}
+
+/* Returns the template arugment at position INDEX in template
+ argument list ARG_LIST. */
+
+static string_list_t
+template_arg_list_get_arg (arg_list, index)
+ template_arg_list_t arg_list;
+ int index;
+{
+ string_list_t arg = arg_list->first_argument;
+ /* Scan down the list of arguments to find the one at position
+ INDEX. */
+ while (index--)
+ {
+ arg = arg->next;
+ if (arg == NULL)
+ /* Ran out of arguments before INDEX hit zero. That's an
+ error. */
+ return NULL;
+ }
+ /* Return the argument at position INDEX. */
+ return arg;
+}
+
+/* Pushes ARG_LIST onto the top of the template argument list stack. */
+
+static void
+push_template_arg_list (dm, arg_list)
+ demangling_t dm;
+ template_arg_list_t arg_list;
+{
+ arg_list->next = dm->template_arg_lists;
+ dm->template_arg_lists = arg_list;
+#ifdef CP_DEMANGLE_DEBUG
+ fprintf (stderr, " ** pushing template arg list\n");
+ template_arg_list_print (arg_list, stderr);
+#endif
+}
+
+/* Pops and deletes elements on the template argument list stack until
+ arg_list is the topmost element. If arg_list is NULL, all elements
+ are popped and deleted. */
+
+static void
+pop_to_template_arg_list (dm, arg_list)
+ demangling_t dm;
+ template_arg_list_t arg_list;
+{
+ while (dm->template_arg_lists != arg_list)
+ {
+ template_arg_list_t top = dm->template_arg_lists;
+ /* Disconnect the topmost element from the list. */
+ dm->template_arg_lists = top->next;
+ /* Delete the popped element. */
+ template_arg_list_delete (top);
+#ifdef CP_DEMANGLE_DEBUG
+ fprintf (stderr, " ** removing template arg list\n");
+#endif
+ }
+}
+
+#ifdef CP_DEMANGLE_DEBUG
+
+/* Prints the contents of ARG_LIST to FP. */
+
+static void
+template_arg_list_print (arg_list, fp)
+ template_arg_list_t arg_list;
+ FILE *fp;
+{
+ string_list_t arg;
+ int index = -1;
+
+ fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
+ for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
+ {
+ if (index == -1)
+ fprintf (fp, " T_ : ");
+ else
+ fprintf (fp, " T%d_ : ", index);
+ ++index;
+ fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
+ }
+}
+
+#endif /* CP_DEMANGLE_DEBUG */
+
+/* Returns the topmost element on the stack of template argument
+ lists. If there is no list of template arguments, returns NULL. */
+
+static template_arg_list_t
+current_template_arg_list (dm)
+ demangling_t dm;
+{
+ return dm->template_arg_lists;
+}
+
+/* Allocates a demangling_t object for demangling mangled NAME. A new
+ result must be pushed before the returned object can be used. */
+
+static demangling_t
+demangling_new (name)
+ char *name;
+{
+ demangling_t dm = (demangling_t)
+ xmalloc (sizeof (struct demangling_def));
+
+ dm->name = name;
+ dm->next = name;
+ dm->result = NULL;
+ dm->last_source_name = dyn_string_new (0);
+ dm->num_substitutions = 0;
+ dm->substitutions_allocated = 10;
+ dm->substitutions = (struct substitution_def *)
+ xmalloc (dm->substitutions_allocated * sizeof (struct substitution_def));
+ dm->template_arg_lists = NULL;
+
+ return dm;
+}
+
+/* Deallocates a demangling_t object and all memory associated with
+ it. */
+
+static void
+demangling_delete (dm)
+ demangling_t dm;
+{
+ int i;
+ template_arg_list_t arg_list = dm->template_arg_lists;
+
+ /* Delete the stack of template argument lists. */
+ while (arg_list != NULL)
+ {
+ template_arg_list_t next = arg_list->next;
+ template_arg_list_delete (arg_list);
+ arg_list = next;
+ }
+ /* Delete the list of substitutions. */
+ for (i = dm->num_substitutions; --i >= 0; )
+ dyn_string_delete (dm->substitutions[i].text);
+ free (dm->substitutions);
+ /* Delete the demangled result. */
+ string_list_delete (dm->result);
+ /* Delete the stored identifier name. */
+ dyn_string_delete (dm->last_source_name);
+ /* Delete the context object itself. */
+ free (dm);
+}
+
+/* These functions demangle an alternative of the corresponding
+ production in the mangling spec. The first argument of each is a
+ demangling context structure for the current demangling
+ operation. Most emit demangled text directly to the topmost result
+ string on the result string stack in the demangling context
+ structure. */
+
+static status_t demangle_char
+ PARAMS ((demangling_t, int));
+static status_t demangle_mangled_name
+ PARAMS ((demangling_t));
+static status_t demangle_encoding
+ PARAMS ((demangling_t));
+static status_t demangle_name
+ PARAMS ((demangling_t, int *));
+static status_t demangle_nested_name
+ PARAMS ((demangling_t, int *));
+static status_t demangle_prefix
+ PARAMS ((demangling_t, int *));
+static status_t demangle_unqualified_name
+ PARAMS ((demangling_t));
+static status_t demangle_source_name
+ PARAMS ((demangling_t));
+static status_t demangle_number
+ PARAMS ((demangling_t, int *, int, int));
+static status_t demangle_number_literally
+ PARAMS ((demangling_t, dyn_string_t, int, int));
+static status_t demangle_identifier
+ PARAMS ((demangling_t, int, dyn_string_t));
+static status_t demangle_operator_name
+ PARAMS ((demangling_t, int, int *));
+static status_t demangle_special_name
+ PARAMS ((demangling_t));
+static status_t demangle_ctor_dtor_name
+ PARAMS ((demangling_t));
+static status_t demangle_type_ptr
+ PARAMS ((demangling_t));
+static status_t demangle_type
+ PARAMS ((demangling_t));
+static status_t demangle_CV_qualifiers
+ PARAMS ((demangling_t, dyn_string_t));
+static status_t demangle_builtin_type
+ PARAMS ((demangling_t));
+static status_t demangle_function_type
+ PARAMS ((demangling_t, int));
+static status_t demangle_bare_function_type
+ PARAMS ((demangling_t, int));
+static status_t demangle_class_enum_type
+ PARAMS ((demangling_t, int *));
+static status_t demangle_array_type
+ PARAMS ((demangling_t));
+static status_t demangle_template_param
+ PARAMS ((demangling_t, int *));
+static status_t demangle_template_args
+ PARAMS ((demangling_t));
+static status_t demangle_literal
+ PARAMS ((demangling_t));
+static status_t demangle_template_arg
+ PARAMS ((demangling_t));
+static status_t demangle_expression
+ PARAMS ((demangling_t));
+static status_t demangle_scope_expression
+ PARAMS ((demangling_t));
+static status_t demangle_expr_primary
+ PARAMS ((demangling_t));
+static status_t demangle_substitution
+ PARAMS ((demangling_t, int *, int *));
+static status_t demangle_local_name
+ PARAMS ((demangling_t));
+static status_t demangle_discriminator
+ PARAMS ((demangling_t, int));
+static status_t cp_demangle
+ PARAMS ((char *, dyn_string_t));
+
+/* When passed to demangle_bare_function_type, indicates that the
+ function's return type is not encoded before its parameter types. */
+#define BFT_NO_RETURN_TYPE -1
+
+/* Check that the next character is C. If so, consume it. If not,
+ return an error. */
+
+static status_t
+demangle_char (dm, c)
+ demangling_t dm;
+ int c;
+{
+ static char *error_message = NULL;
+
+ if (peek_char (dm) == c)
+ {
+ advance_char (dm);
+ return STATUS_OK;
+ }
+ else
+ {
+ if (error_message == NULL)
+ error_message = strdup ("Expected ?");
+ error_message[9] = c;
+ return error_message;
+ }
+}
+
+/* Demangles and emits a <mangled-name>.
+
+ <mangled-name> ::= _Z <encoding> */
+
+static status_t
+demangle_mangled_name (dm)
+ demangling_t dm;
+{
+ DEMANGLE_TRACE ("mangled-name", dm);
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ RETURN_IF_ERROR (demangle_char (dm, 'Z'));
+ RETURN_IF_ERROR (demangle_encoding (dm));
+ return STATUS_OK;
+}
+
+/* Demangles and emits an <encoding>.
+
+ <encoding> ::= <function name> <bare-function-type>
+ ::= <data name>
+ ::= <substitution> */
+
+static status_t
+demangle_encoding (dm)
+ demangling_t dm;
+{
+ int template_p;
+ int special_std_substitution;
+ int start_position;
+ int start = substitution_start (dm);
+ template_arg_list_t old_arg_list = current_template_arg_list (dm);
+ char peek = peek_char (dm);
+
+ DEMANGLE_TRACE ("encoding", dm);
+
+ /* Remember where the name starts. If it turns out to be a template
+ function, we'll have to insert the return type here. */
+ start_position = result_length (dm);
+
+ if (peek == 'S')
+ {
+ RETURN_IF_ERROR (demangle_substitution (dm, &template_p,
+ &special_std_substitution));
+ if (special_std_substitution)
+ {
+ /* This was the magic `std::' substitution. */
+ result_append (dm, "::");
+ RETURN_IF_ERROR (demangle_encoding (dm));
+ }
+ }
+ else if (peek == 'G' || peek == 'T')
+ RETURN_IF_ERROR (demangle_special_name (dm));
+ else
+ {
+ /* Now demangle the name. */
+ RETURN_IF_ERROR (demangle_name (dm, &template_p));
+
+ /* If there's anything left, the name was a function name, with
+ maybe its return type, and its parameters types, following. */
+ if (!end_of_name_p (dm)
+ && peek_char (dm) != 'E')
+ {
+ if (template_p)
+ /* Template functions have their return type encoded. The
+ return type should be inserted at start_position. */
+ RETURN_IF_ERROR
+ (demangle_bare_function_type (dm, start_position));
+ else
+ /* Non-template functions don't have their return type
+ encoded. */
+ RETURN_IF_ERROR
+ (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
+ }
+
+ substitution_add (dm, start, template_p, NOT_TEMPLATE_PARM);
+ }
+
+ /* Pop off template argument lists that were built during the
+ mangling of this name, to restore the old template context. */
+ pop_to_template_arg_list (dm, old_arg_list);
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <name>.
+
+ <name> ::= <unscoped-name>
+ ::= <unscoped-template-name> <template-args>
+ ::= <nested-name>
+ ::= <local-name>
+
+ <unscoped-name> ::= <unqualified-name>
+ ::= St <unqualified-name> # ::std::
+
+ <unscoped-template-name>
+ ::= <unscoped-name>
+ ::= <substitution> */
+
+static status_t
+demangle_name (dm, template_p)
+ demangling_t dm;
+ int *template_p;
+{
+ int special_std_substitution;
+ int start = substitution_start (dm);
+
+ DEMANGLE_TRACE ("name", dm);
+
+ switch (peek_char (dm))
+ {
+ case 'N':
+ /* This is a <nested-name>. */
+ RETURN_IF_ERROR (demangle_nested_name (dm, template_p));
+ break;
+
+ case 'Z':
+ RETURN_IF_ERROR (demangle_local_name (dm));
+ break;
+
+ case 'S':
+ /* The `St' substitution allows a name nested in std:: to appear
+ without being enclosed in a nested name.
+ <name> ::= St <unqualified-name> # ::std:: */
+ if (peek_char_next (dm) == 't')
+ {
+ (void) next_char (dm);
+ (void) next_char (dm);
+ result_append (dm, "std::");
+ RETURN_IF_ERROR (demangle_unqualified_name (dm));
+ }
+ else
+ {
+ RETURN_IF_ERROR (demangle_substitution (dm, template_p,
+ &special_std_substitution));
+ if (special_std_substitution)
+ {
+ /* This was the magic `std::' substitution. We can have
+ a <nested-name> or one of the unscoped names
+ following. */
+ result_append (dm, "::");
+ RETURN_IF_ERROR (demangle_name (dm, template_p));
+ }
+ }
+ break;
+
+ default:
+ /* This is an <unscoped-name> or <unscoped-template-name>. */
+ RETURN_IF_ERROR (demangle_unqualified_name (dm));
+
+ /* If the <unqualified-name> is followed by template args, this
+ is an <unscoped-template-name>. */
+ if (peek_char (dm) == 'I')
+ {
+ /* Add a substitution for the unqualified template name. */
+ substitution_add (dm, start, 0, NOT_TEMPLATE_PARM);
+
+ RETURN_IF_ERROR (demangle_template_args (dm));
+ *template_p = 1;
+ }
+ else
+ *template_p = 0;
+
+ break;
+ }
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <nested-name>.
+
+ <nested-name> ::= N [<CV-qualifiers>] <prefix> <component> E */
+
+static status_t
+demangle_nested_name (dm, template_p)
+ demangling_t dm;
+ int *template_p;
+{
+ char peek;
+
+ DEMANGLE_TRACE ("nested-name", dm);
+
+ RETURN_IF_ERROR (demangle_char (dm, 'N'));
+
+ peek = peek_char (dm);
+ if (peek == 'r' || peek == 'V' || peek == 'K')
+ {
+ /* Snarf up and emit CV qualifiers. */
+ dyn_string_t cv_qualifiers = dyn_string_new (24);
+ demangle_CV_qualifiers (dm, cv_qualifiers);
+ result_append_string (dm, cv_qualifiers);
+ dyn_string_delete (cv_qualifiers);
+ result_append_space (dm);
+ }
+
+ RETURN_IF_ERROR (demangle_prefix (dm, template_p));
+ /* No need to demangle the final <component>; demangle_prefix will
+ handle it. */
+ RETURN_IF_ERROR (demangle_char (dm, 'E'));
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <prefix>.
+
+ <prefix> ::= <prefix> <component>
+ ::= <template-prefix> <template-args>
+ ::= # empty
+ ::= <substitution>
+
+ <template-prefix> ::= <prefix>
+ ::= <substitution>
+
+ <component> ::= <unqualified-name>
+ ::= <local-name> */
+
+static status_t
+demangle_prefix (dm, template_p)
+ demangling_t dm;
+ int *template_p;
+{
+ int start = substitution_start (dm);
+ int nested = 0;
+
+ /* TEMPLATE_P is updated as we decend the nesting chain. After
+ <template-args>, it is set to non-zero; after everything else it
+ is set to zero. */
+
+ DEMANGLE_TRACE ("prefix", dm);
+
+ while (1)
+ {
+ char peek;
+ int unused;
+
+ if (end_of_name_p (dm))
+ return "Unexpected end of name in <compound-name>.";
+
+ peek = peek_char (dm);
+
+ if (isdigit ((unsigned char) peek)
+ || (peek >= 'a' && peek <= 'z')
+ || peek == 'C' || peek == 'D'
+ || peek == 'S')
+ {
+ /* We have another level of scope qualification. */
+ if (nested)
+ result_append (dm, "::");
+ else
+ nested = 1;
+
+ if (peek == 'S')
+ /* The substitution determines whether this is a
+ template-id. */
+ RETURN_IF_ERROR (demangle_substitution (dm, template_p,
+ &unused));
+ else
+ {
+ RETURN_IF_ERROR (demangle_unqualified_name (dm));
+ *template_p = 0;
+ }
+ }
+ else if (peek == 'Z')
+ RETURN_IF_ERROR (demangle_local_name (dm));
+ else if (peek == 'I')
+ {
+ if (*template_p)
+ return STATUS_INTERNAL_ERROR;
+ /* The template name is a substitution candidate. */
+ substitution_add (dm, start, 0, NOT_TEMPLATE_PARM);
+ RETURN_IF_ERROR (demangle_template_args (dm));
+ *template_p = 1;
+ }
+ else if (peek == 'E')
+ /* All done. */
+ return STATUS_OK;
+ else
+ return "Unexpected character in <compound-name>.";
+
+ /* Add a new substitution for the prefix thus far. */
+ substitution_add (dm, start, *template_p, NOT_TEMPLATE_PARM);
+ }
+}
+
+/* Demangles and emits an <unqualified-name>. If the
+ <unqualified-name> is a function and the first element in the
+ argument list should be taken to be its return type,
+ ENCODE_RETURN_TYPE is non-zero.
+
+ <unqualified-name> ::= <operator-name>
+ ::= <special-name>
+ ::= <source-name> */
+
+static status_t
+demangle_unqualified_name (dm)
+ demangling_t dm;
+{
+ char peek = peek_char (dm);
+
+ DEMANGLE_TRACE ("unqualified-name", dm);
+
+ if (isdigit ((unsigned char) peek))
+ RETURN_IF_ERROR (demangle_source_name (dm));
+ else if (peek >= 'a' && peek <= 'z')
+ {
+ int num_args;
+ RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
+ }
+ else if (peek == 'C' || peek == 'D')
+ RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
+ else
+ return "Unexpected character in <unqualified-name>.";
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits <source-name>.
+
+ <source-name> ::= <length number> <identifier> */
+
+static status_t
+demangle_source_name (dm)
+ demangling_t dm;
+{
+ int length;
+
+ DEMANGLE_TRACE ("source-name", dm);
+
+ /* Decode the length of the identifier. */
+ RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
+ if (length == 0)
+ return "Zero length in <source-name>.";
+
+ /* Now the identifier itself. It's placed into last_source_name,
+ where it can be used to build a constructor or destructor name. */
+ RETURN_IF_ERROR (demangle_identifier (dm, length,
+ dm->last_source_name));
+
+ /* Emit it. */
+ result_append_string (dm, dm->last_source_name);
+
+ return STATUS_OK;
+}
+
+/* Demangles a number, either a <number> or a <positive-number> at the
+ current position, consuming all consecutive digit characters. Sets
+ *VALUE to the resulting numberand returns STATUS_OK. The number is
+ interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
+ is non-zero, negative numbers -- prefixed with `n' -- are accepted.
+
+ <number> ::= [n] <positive-number>
+
+ <positive-number> ::= <decimal integer> */
+
+static status_t
+demangle_number (dm, value, base, is_signed)
+ demangling_t dm;
+ int *value;
+ int base;
+ int is_signed;
+{
+ dyn_string_t number = dyn_string_new (10);
+
+ DEMANGLE_TRACE ("number", dm);
+
+ demangle_number_literally (dm, number, base, is_signed);
+ *value = strtol (dyn_string_buf (number), NULL, base);
+ dyn_string_delete (number);
+
+ return STATUS_OK;
+}
+
+/* Demangles a number at the current position. The digits (and minus
+ sign, if present) that make up the number are appended to STR.
+ Only base-BASE digits are accepted; BASE must be either 10 or 36.
+ If IS_SIGNED, negative numbers -- prefixed with `n' -- are
+ accepted. Does not consume a trailing underscore or other
+ terminating character. */
+
+static status_t
+demangle_number_literally (dm, str, base, is_signed)
+ demangling_t dm;
+ dyn_string_t str;
+ int base;
+ int is_signed;
+{
+ DEMANGLE_TRACE ("number*", dm);
+
+ if (base != 10 && base != 36)
+ return STATUS_INTERNAL_ERROR;
+
+ /* An `n' denotes a negative number. */
+ if (is_signed && peek_char (dm) == 'n')
+ {
+ /* Skip past the n. */
+ advance_char (dm);
+ /* The normal way to write a negative number is with a minus
+ sign. */
+ dyn_string_append_char (str, '-');
+ }
+
+ /* Loop until we hit a non-digit. */
+ while (1)
+ {
+ char peek = peek_char (dm);
+ if (isdigit ((unsigned char) peek)
+ || (base == 36 && peek >= 'A' && peek <= 'Z'))
+ /* Accumulate digits. */
+ dyn_string_append_char (str, next_char (dm));
+ else
+ /* Not a digit? All done. */
+ break;
+ }
+
+ return STATUS_OK;
+}
+
+/* Demangles an identifier at the current position of LENGTH
+ characters and places it in IDENTIFIER. */
+
+static status_t
+demangle_identifier (dm, length, identifier)
+ demangling_t dm;
+ int length;
+ dyn_string_t identifier;
+{
+ DEMANGLE_TRACE ("identifier", dm);
+
+ dyn_string_clear (identifier);
+ dyn_string_resize (identifier, length);
+ while (length-- > 0)
+ {
+ if (end_of_name_p (dm))
+ return "Unexpected end of name in <identifier>.";
+ dyn_string_append_char (identifier, next_char (dm));
+ }
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
+ the short form is emitted; otherwise the full source form
+ (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
+ operands that the operator takes.
+
+ <operator-name>
+ ::= nw # new
+ ::= na # new[]
+ ::= dl # delete
+ ::= da # delete[]
+ ::= ps # + (unary)
+ ::= ng # - (unary)
+ ::= ad # & (unary)
+ ::= de # * (unary)
+ ::= co # ~
+ ::= pl # +
+ ::= mi # -
+ ::= ml # *
+ ::= dv # /
+ ::= rm # %
+ ::= an # &
+ ::= or # |
+ ::= eo # ^
+ ::= aS # =
+ ::= pL # +=
+ ::= mI # -=
+ ::= mL # *=
+ ::= dV # /=
+ ::= rM # %=
+ ::= aN # &=
+ ::= oR # |=
+ ::= eO # ^=
+ ::= ls # <<
+ ::= rs # >>
+ ::= lS # <<=
+ ::= rS # >>=
+ ::= eq # ==
+ ::= ne # !=
+ ::= lt # <
+ ::= gt # >
+ ::= le # <=
+ ::= ge # >=
+ ::= nt # !
+ ::= aa # &&
+ ::= oo # ||
+ ::= pp # ++
+ ::= mm # --
+ ::= cm # ,
+ ::= pm # ->*
+ ::= pt # ->
+ ::= cl # ()
+ ::= ix # []
+ ::= qu # ?
+ ::= sz # sizeof
+ ::= cv <type> # cast
+ ::= vx <source-name> # vendor extended operator */
+
+static status_t
+demangle_operator_name (dm, short_name, num_args)
+ demangling_t dm;
+ int short_name;
+ int *num_args;
+{
+ struct operator_code
+ {
+ /* The mangled code for this operator. */
+ const char *code;
+ /* The source name of this operator. */
+ const char *name;
+ /* The number of arguments this operator takes. */
+ int num_args;
+ };
+
+ static const struct operator_code operators[] =
+ {
+ { "aN", "&=" , 2 },
+ { "aS", "=" , 2 },
+ { "aa", "&&" , 2 },
+ { "ad", "&" , 1 },
+ { "an", "&" , 2 },
+ { "cl", "()" , 0 },
+ { "cm", "," , 2 },
+ { "co", "~" , 1 },
+ { "dV", "/=" , 2 },
+ { "da", " delete[]", 1 },
+ { "de", "*" , 1 },
+ { "dl", " delete" , 1 },
+ { "dv", "/" , 2 },
+ { "eO", "^=" , 2 },
+ { "eo", "^" , 2 },
+ { "eq", "==" , 2 },
+ { "ge", ">=" , 2 },
+ { "gt", ">" , 2 },
+ { "ix", "[]" , 2 },
+ { "lS", "<<=" , 2 },
+ { "le", "<=" , 2 },
+ { "ls", "<<" , 2 },
+ { "lt", "<" , 2 },
+ { "mI", "-=" , 2 },
+ { "mL", "*=" , 2 },
+ { "mi", "-" , 2 },
+ { "ml", "*" , 2 },
+ { "mm", "--" , 1 },
+ { "na", " new[]" , 1 },
+ { "ne", "!=" , 2 },
+ { "ng", "-" , 1 },
+ { "nt", "!" , 1 },
+ { "nw", " new" , 1 },
+ { "oR", "|=" , 2 },
+ { "oo", "||" , 2 },
+ { "or", "|" , 2 },
+ { "pL", "+=" , 2 },
+ { "pl", "+" , 2 },
+ { "pm", "->*" , 2 },
+ { "pp", "++" , 1 },
+ { "ps", "+" , 1 },
+ { "qu", "?" , 3 },
+ { "rM", "%=" , 2 },
+ { "rS", ">>=" , 2 },
+ { "rm", "%" , 2 },
+ { "rs", ">>" , 2 },
+ { "sz", " sizeof" , 1 }
+ };
+
+ const int num_operators =
+ sizeof (operators) / sizeof (struct operator_code);
+
+ int c0 = next_char (dm);
+ int c1 = next_char (dm);
+ const struct operator_code* p1 = operators;
+ const struct operator_code* p2 = operators + num_operators;
+
+ DEMANGLE_TRACE ("operator-name", dm);
+
+ /* Is this a vendor extended operator? */
+ if (c0 == 'v' && c1 == 'x')
+ {
+ result_append (dm, "operator");
+ RETURN_IF_ERROR (demangle_source_name (dm));
+ *num_args = 0;
+ return STATUS_OK;
+ }
+
+ /* Is this a conversion operator? */
+ if (c0 == 'c' && c1 == 'v')
+ {
+ result_append (dm, "operator ");
+ /* Demangle the converted-to type. */
+ RETURN_IF_ERROR (demangle_type (dm));
+ *num_args = 0;
+ return STATUS_OK;
+ }
+
+ /* Perform a binary search for the operator code. */
+ while (1)
+ {
+ const struct operator_code* p = p1 + (p2 - p1) / 2;
+ char match0 = p->code[0];
+ char match1 = p->code[1];
+
+ if (c0 == match0 && c1 == match1)
+ /* Found it. */
+ {
+ if (!short_name)
+ result_append (dm, "operator");
+ result_append (dm, p->name);
+ *num_args = p->num_args;
+
+ return STATUS_OK;
+ }
+
+ if (p == p1)
+ /* Couldn't find it. */
+ return "Unknown code in <operator-name>.";
+
+ /* Try again. */
+ if (c0 < match0 || (c0 == match0 && c1 < match1))
+ p2 = p;
+ else
+ p1 = p;
+ }
+}
+
+/* Demangles and emits a <special-name>.
+
+ <special-name> ::= GV <object name> # Guard variable
+ ::= Th[n] <offset number> _ <base name> <base encoding>
+ # non-virtual base override thunk
+ ::= Tv[n] <offset number> _ <vcall offset number>
+ _ <base encoding>
+ # virtual base override thunk
+ ::= TV <type> # virtual table
+ ::= TT <type> # VTT
+ ::= TI <type> # typeinfo structure
+ ::= TS <type> # typeinfo name
+
+ Also demangles the special g++ manglings,
+
+ <special-name> ::= CT <type> <offset number> _ <base type>
+ # construction vtable
+ ::= TF <type> # typeinfo function (old ABI only)
+ ::= TJ <type> # java Class structure */
+
+static status_t
+demangle_special_name (dm)
+ demangling_t dm;
+{
+ dyn_string_t number;
+ int unused;
+ char peek = peek_char (dm);
+
+ DEMANGLE_TRACE ("special-name", dm);
+
+ if (peek == 'G')
+ {
+ /* A guard variable name. Consume the G. */
+ advance_char (dm);
+ RETURN_IF_ERROR (demangle_char (dm, 'V'));
+ result_append (dm, "guard variable for ");
+ RETURN_IF_ERROR (demangle_name (dm, &unused));
+ }
+ else if (peek == 'T')
+ {
+ /* Other C++ implementation miscellania. Consume the T. */
+ advance_char (dm);
+
+ switch (peek_char (dm))
+ {
+ case 'V':
+ /* Virtual table. */
+ advance_char (dm);
+ result_append (dm, "vtable for ");
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'T':
+ /* VTT structure. */
+ advance_char (dm);
+ result_append (dm, "VTT for ");
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'I':
+ /* Typeinfo structure. */
+ advance_char (dm);
+ result_append (dm, "typeinfo for ");
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'F':
+ /* Typeinfo function. Used only in old ABI with new mangling. */
+ advance_char (dm);
+ result_append (dm, "typeinfo fn for ");
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'S':
+ /* Character string containing type name, used in typeinfo. */
+ advance_char (dm);
+ result_append (dm, "typeinfo name for ");
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'J':
+ /* The java Class variable corresponding to a C++ class. */
+ advance_char (dm);
+ result_append (dm, "java Class for ");
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'h':
+ /* Non-virtual thunk. */
+ advance_char (dm);
+ result_append (dm, "non-virtual thunk");
+ /* Demangle and emit the offset. */
+ number = dyn_string_new (4);
+ demangle_number_literally (dm, number, 10, 1);
+ /* Don't display the offset unless in verbose mode. */
+ if (flag_verbose)
+ {
+ result_append_char (dm, ' ');
+ result_append_string (dm, number);
+ }
+ dyn_string_delete (number);
+ /* Demangle the separator. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ /* Demangle and emit the target name and function type. */
+ result_append (dm, " to ");
+ RETURN_IF_ERROR (demangle_encoding (dm));
+ break;
+
+ case 'v':
+ /* Virtual thunk. */
+ advance_char (dm);
+ result_append (dm, "virtual thunk ");
+ /* Demangle and emit the offset. */
+ number = dyn_string_new (4);
+ demangle_number_literally (dm, number, 10, 1);
+ /* Don't display the offset unless in verbose mode. */
+ if (flag_verbose)
+ {
+ result_append_string (dm, number);
+ result_append_char (dm, ' ');
+ }
+ dyn_string_delete (number);
+ /* Demangle the separator. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ /* Demangle and emit the vcall offset. */
+ number = dyn_string_new (4);
+ demangle_number_literally (dm, number, 10, 1);
+ /* Don't display the vcall offset unless in verbose mode. */
+ if (flag_verbose)
+ {
+ result_append_string (dm, number);
+ result_append_char (dm, ' ');
+ }
+ dyn_string_delete (number);
+ /* Demangle the separator. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ /* Demangle and emit the target function. */
+ result_append (dm, "to ");
+ RETURN_IF_ERROR (demangle_encoding (dm));
+ break;
+
+ case 'C':
+ /* TC is a special g++ mangling for a construction vtable. */
+ if (!flag_strict)
+ {
+ advance_char (dm);
+ result_append (dm, "construction vtable for ");
+ RETURN_IF_ERROR (demangle_type (dm));
+ /* Demangle the offset. */
+ number = dyn_string_new (4);
+ demangle_number_literally (dm, number, 10, 1);
+ /* Demangle the underscore separator. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ /* Demangle the base type. */
+ result_append (dm, "-in-");
+ RETURN_IF_ERROR (demangle_type (dm));
+ /* Don't display the offset unless in verbose mode. */
+ if (flag_verbose)
+ {
+ result_append_char (dm, ' ');
+ result_append_string (dm, number);
+ }
+ dyn_string_delete (number);
+ break;
+ }
+ /* If flag_strict, fall through. */
+
+ default:
+ return "Unrecognized <special-name>.";
+ }
+ }
+ else
+ return STATUS_ERROR;
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <ctor-dtor-name>.
+
+ <ctor-dtor-name>
+ ::= C1 # complete object (in-charge) ctor
+ ::= C2 # base object (not-in-charge) ctor
+ ::= C3 # complete object (in-charge) allocating ctor
+ ::= C4 # base object (not-in-charge) allocating ctor
+ ::= D0 # deleting (in-charge) dtor
+ ::= D1 # complete object (in-charge) dtor
+ ::= D2 # base object (not-in-charge) dtor */
+
+static status_t
+demangle_ctor_dtor_name (dm)
+ demangling_t dm;
+{
+ static const char *const ctor_flavors[] =
+ {
+ "in-charge",
+ "not-in-charge",
+ "in-charge allocating",
+ "not-in-charge allocating"
+ };
+ static const char *const dtor_flavors[] =
+ {
+ "in-charge deleting",
+ "in-charge",
+ "not-in-charge"
+ };
+
+ int flavor;
+ char peek = peek_char (dm);
+
+ DEMANGLE_TRACE ("ctor-dtor-name", dm);
+
+ if (peek == 'C')
+ {
+ /* A constructor name. Consume the C. */
+ advance_char (dm);
+ if (peek_char (dm) < '1' || peek_char (dm) > '4')
+ return "Unrecognized constructor.";
+ result_append_string (dm, dm->last_source_name);
+ /* Print the flavor of the constructor if in verbose mode. */
+ flavor = next_char (dm) - '1';
+ if (flag_verbose)
+ {
+ result_append (dm, "[");
+ result_append (dm, ctor_flavors[flavor]);
+ result_append_char (dm, ']');
+ }
+ }
+ else if (peek == 'D')
+ {
+ /* A destructor name. Consume the D. */
+ advance_char (dm);
+ if (peek_char (dm) < '0' || peek_char (dm) > '2')
+ return "Unrecognized destructor.";
+ result_append_char (dm, '~');
+ result_append_string (dm, dm->last_source_name);
+ /* Print the flavor of the destructor if in verbose mode. */
+ flavor = next_char (dm) - '0';
+ if (flag_verbose)
+ {
+ result_append (dm, " [");
+ result_append (dm, dtor_flavors[flavor]);
+ result_append_char (dm, ']');
+ }
+ }
+ else
+ return STATUS_ERROR;
+
+ return STATUS_OK;
+}
+
+/* Handle pointer, reference, and pointer-to-member cases for
+ demangle_type. All consecutive `P's, `R's, and 'M's are joined to
+ build a pointer/reference type. We snarf all these, plus the
+ following <type>, all at once since we need to know whether we have
+ a pointer to data or pointer to function to construct the right
+ output syntax. C++'s pointer syntax is hairy.
+
+ <type> ::= P <type>
+ ::= R <type>
+ ::= <pointer-to-member-type>
+
+ <pointer-to-member-type> ::= M </class/ type> </member/ type> */
+
+static status_t
+demangle_type_ptr (dm)
+ demangling_t dm;
+{
+ char next;
+ status_t status;
+
+ /* Collect pointer symbols into this string. */
+ dyn_string_t symbols = dyn_string_new (10);
+
+ DEMANGLE_TRACE ("type*", dm);
+
+ /* Scan forward, collecting pointers and references into symbols,
+ until we hit something else. Then emit the type. */
+ while (1)
+ {
+ next = peek_char (dm);
+ if (next == 'P')
+ {
+ dyn_string_append_char (symbols, '*');
+ advance_char (dm);
+ }
+ else if (next == 'R')
+ {
+ dyn_string_append_char (symbols, '&');
+ advance_char (dm);
+ }
+ else if (next == 'M')
+ {
+ /* Pointer-to-member. */
+ dyn_string_t class_type;
+
+ /* Eat the 'M'. */
+ advance_char (dm);
+
+ /* Capture the type of which this is a pointer-to-member. */
+ result_push (dm);
+ RETURN_IF_ERROR (demangle_type (dm));
+ class_type = (dyn_string_t) result_pop (dm);
+
+ /* Build the pointer-to-member notation. It comes before
+ other pointer and reference qualifiers -- */
+ dyn_string_prepend_cstr (symbols, "::*");
+ dyn_string_prepend (symbols, class_type);
+ dyn_string_delete (class_type);
+
+ if (peek_char (dm) == 'F')
+ continue;
+
+ /* Demangle the type of the pointed-to member. */
+ status = demangle_type (dm);
+ /* Make it pretty. */
+ result_append_space (dm);
+ /* Add the pointer-to-member syntax, and other pointer and
+ reference symbols. */
+ result_append_string (dm, symbols);
+ /* Clean up. */
+ dyn_string_delete (symbols);
+
+ RETURN_IF_ERROR (status);
+ return STATUS_OK;
+ }
+ else if (next == 'F')
+ {
+ /* Ooh, tricky, a pointer-to-function. */
+ int position = result_length (dm);
+ result_append_char (dm, '(');
+ result_append_string (dm, symbols);
+ result_append_char (dm, ')');
+ dyn_string_delete (symbols);
+
+ RETURN_IF_ERROR (demangle_function_type (dm, position));
+ return STATUS_OK;
+ }
+ else
+ {
+ /* No more pointe or reference tokens. Finish up. */
+ status = demangle_type (dm);
+
+ result_append_string (dm, symbols);
+ dyn_string_delete (symbols);
+
+ RETURN_IF_ERROR (status);
+ return STATUS_OK;
+ }
+ }
+}
+
+/* Demangles and emits a <type>.
+
+ <type> ::= <builtin-type>
+ ::= <function-type>
+ ::= <class-enum-type>
+ ::= <array-type>
+ ::= <pointer-to-member-type>
+ ::= <template-param>
+ ::= <CV-qualifiers> <type>
+ ::= P <type> # pointer-to
+ ::= R <type> # reference-to
+ ::= C <type> # complex pair (C 2000)
+ ::= G <type> # imaginary (C 2000)
+ ::= U <source-name> <type> # vendor extended type qualifier
+ ::= <substitution> */
+
+static status_t
+demangle_type (dm)
+ demangling_t dm;
+{
+ int start = substitution_start (dm);
+ char peek = peek_char (dm);
+ int template_p = 0;
+ int special_std_substitution;
+ int is_builtin_type = 0;
+ template_arg_list_t old_arg_list = current_template_arg_list (dm);
+ int template_parm = NOT_TEMPLATE_PARM;
+
+ DEMANGLE_TRACE ("type", dm);
+
+ /* A <class-enum-type> can start with a digit (a <source-name>), an
+ N (a <nested-name>), or a Z (a <local-name>). */
+ if (isdigit ((unsigned char) peek) || peek == 'N' || peek == 'Z')
+ RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
+ else if (peek >= 'a' && peek <= 'z')
+ {
+ RETURN_IF_ERROR (demangle_builtin_type (dm));
+ is_builtin_type = 1;
+ }
+ else
+ switch (peek)
+ {
+ case 'r':
+ case 'V':
+ case 'K':
+ {
+ status_t status;
+ dyn_string_t cv_qualifiers = dyn_string_new (24);
+ demangle_CV_qualifiers (dm, cv_qualifiers);
+
+ /* If the qualifiers apply to a pointer or reference, they
+ need to come after the whole qualified type. */
+ if (peek_char (dm) == 'P' || peek_char (dm) == 'R')
+ {
+ status = demangle_type (dm);
+ result_append_space (dm);
+ result_append_string (dm, cv_qualifiers);
+ }
+ /* Otherwise, the qualifiers come first. */
+ else
+ {
+ result_append_string (dm, cv_qualifiers);
+ result_append_space (dm);
+ status = demangle_type (dm);
+ }
+
+ dyn_string_delete (cv_qualifiers);
+ RETURN_IF_ERROR (status);
+ }
+ break;
+
+ case 'F':
+ return "Non-pointer or -reference function type.";
+
+ case 'A':
+ RETURN_IF_ERROR (demangle_array_type (dm));
+ break;
+
+ case 'T':
+ RETURN_IF_ERROR (demangle_template_param (dm, &template_parm));
+ break;
+
+ case 'S':
+ RETURN_IF_ERROR (demangle_substitution (dm, &template_p,
+ &special_std_substitution));
+ if (special_std_substitution)
+ {
+ /* This was the magic `std::' substitution. What follows
+ must be a class name in that namespace. */
+ result_append (dm, "::");
+ RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
+ }
+ break;
+
+ case 'P':
+ case 'R':
+ case 'M':
+ RETURN_IF_ERROR (demangle_type_ptr (dm));
+ break;
+
+ case 'C':
+ /* A C99 complex type. */
+ result_append (dm, "complex ");
+ advance_char (dm);
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'G':
+ /* A C99 imaginary type. */
+ result_append (dm, "imaginary ");
+ advance_char (dm);
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ case 'U':
+ /* Vendor extended type qualifier. */
+ advance_char (dm);
+ RETURN_IF_ERROR (demangle_source_name (dm));
+ result_append_char (dm, ' ');
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+
+ default:
+ return "Unexpected character in <type>.";
+ }
+
+ /* Unqualified builin types are not substitution candidates. */
+ if (!is_builtin_type)
+ /* Add a new substitution for the type. If this type was a
+ <template-param>, pass its index since from the point of
+ substitutions, a <template-param> token is a substitution
+ candidate distinct from the type that is substituted for it. */
+ substitution_add (dm, start, template_p, template_parm);
+
+ /* Pop off template argument lists added during mangling of this
+ type. */
+ pop_to_template_arg_list (dm, old_arg_list);
+
+ return STATUS_OK;
+}
+
+/* C++ source names of builtin types, indexed by the mangled code
+ letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
+static const char *const builtin_type_names[26] =
+{
+ "signed char", /* a */
+ "bool", /* b */
+ "char", /* c */
+ "double", /* d */
+ "long double", /* e */
+ "float", /* f */
+ "__float128", /* g */
+ "unsigned char", /* h */
+ "int", /* i */
+ "unsigned", /* j */
+ NULL, /* k */
+ "long", /* l */
+ "unsigned long", /* m */
+ "__int128", /* n */
+ "unsigned __int128", /* o */
+ NULL, /* p */
+ NULL, /* q */
+ NULL, /* r */
+ "short", /* s */
+ "unsigned short", /* t */
+ NULL, /* u */
+ "void", /* v */
+ "wchar_t", /* w */
+ "long long", /* x */
+ "unsigned long long", /* y */
+ "..." /* z */
+};
+
+/* Demangles and emits a <builtin-type>.
+
+ <builtin-type> ::= v # void
+ ::= w # wchar_t
+ ::= b # bool
+ ::= c # char
+ ::= a # signed char
+ ::= h # unsigned char
+ ::= s # short
+ ::= t # unsigned short
+ ::= i # int
+ ::= j # unsigned int
+ ::= l # long
+ ::= m # unsigned long
+ ::= x # long long, __int64
+ ::= y # unsigned long long, __int64
+ ::= n # __int128
+ ::= o # unsigned __int128
+ ::= f # float
+ ::= d # double
+ ::= e # long double, __float80
+ ::= g # __float128
+ ::= z # ellipsis
+ ::= u <source-name> # vendor extended type */
+
+static status_t
+demangle_builtin_type (dm)
+ demangling_t dm;
+{
+
+ char code = peek_char (dm);
+
+ DEMANGLE_TRACE ("builtin-type", dm);
+
+ if (code == 'u')
+ {
+ advance_char (dm);
+ RETURN_IF_ERROR (demangle_source_name (dm));
+ return STATUS_OK;
+ }
+ else if (code >= 'a' && code <= 'z')
+ {
+ const char *type_name = builtin_type_names[code - 'a'];
+ if (type_name == NULL)
+ return "Unrecognized <builtin-type> code.";
+
+ result_append (dm, type_name);
+ advance_char (dm);
+ return STATUS_OK;
+ }
+ else
+ return "Non-alphabetic <builtin-type> code.";
+}
+
+/* Demangles all consecutive CV-qualifiers (const, volatile, and
+ restrict) at the current position. The qualifiers are appended to
+ QUALIFIERS. Returns STATUS_OK. */
+
+static status_t
+demangle_CV_qualifiers (dm, qualifiers)
+ demangling_t dm;
+ dyn_string_t qualifiers;
+{
+ DEMANGLE_TRACE ("CV-qualifiers", dm);
+
+ while (1)
+ {
+ switch (peek_char (dm))
+ {
+ case 'r':
+ dyn_string_append_space (qualifiers);
+ dyn_string_append_cstr (qualifiers, "restrict");
+ break;
+
+ case 'V':
+ dyn_string_append_space (qualifiers);
+ dyn_string_append_cstr (qualifiers, "volatile");
+ break;
+
+ case 'K':
+ dyn_string_append_space (qualifiers);
+ dyn_string_append_cstr (qualifiers, "const");
+ break;
+
+ default:
+ return STATUS_OK;
+ }
+
+ advance_char (dm);
+ }
+}
+
+/* Demangles and emits a <function-type> FUNCTION_NAME_POS is the
+ position in the result string of the start of the function
+ identifier, at which the function's return type will be inserted.
+
+ <function-type> ::= F [Y] <bare-function-type> E */
+
+static status_t
+demangle_function_type (dm, function_name_pos)
+ demangling_t dm;
+ int function_name_pos;
+{
+ DEMANGLE_TRACE ("function-type", dm);
+ RETURN_IF_ERROR (demangle_char (dm, 'F'));
+ if (peek_char (dm) == 'Y')
+ {
+ /* Indicate this function has C linkage if in verbose mode. */
+ if (flag_verbose)
+ result_append (dm, " [extern \"C\"] ");
+ advance_char (dm);
+ }
+ RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
+ RETURN_IF_ERROR (demangle_char (dm, 'E'));
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
+ position in the result string at which the function return type
+ should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
+ function's return type is assumed not to be encoded.
+
+ <bare-function-type> ::= <signature type>+ */
+
+static status_t
+demangle_bare_function_type (dm, return_type_pos)
+ demangling_t dm;
+ int return_type_pos;
+{
+ /* Sequence is the index of the current function parameter, counting
+ from zero. The value -1 denotes the return type. */
+ int sequence =
+ (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
+
+ DEMANGLE_TRACE ("bare-function-type", dm);
+
+ result_append_char (dm, '(');
+ while (!end_of_name_p (dm) && peek_char (dm) != 'E')
+ {
+ if (sequence == -1)
+ /* We're decoding the function's return type. */
+ {
+ dyn_string_t return_type;
+
+ /* Decode the return type off to the side. */
+ result_push (dm);
+ RETURN_IF_ERROR (demangle_type (dm));
+ return_type = (dyn_string_t) result_pop (dm);
+
+ /* Add a space to the end of the type. */
+ dyn_string_append_space (return_type);
+
+ /* Insert the return type where we've been asked to. */
+ dyn_string_insert (result_string (dm), return_type_pos,
+ return_type);
+ dyn_string_delete (return_type);
+ }
+ else
+ {
+ /* Skip `void' parameter types. One should only occur as
+ the only type in a parameter list; in that case, we want
+ to print `foo ()' instead of `foo (void)'. */
+ if (peek_char (dm) == 'v')
+ {
+ /* Consume the v. */
+ advance_char (dm);
+ continue;
+ }
+ /* Separate parameter types by commas. */
+ if (sequence > 0)
+ result_append (dm, ", ");
+ /* Demangle the type. */
+ RETURN_IF_ERROR (demangle_type (dm));
+ }
+
+ ++sequence;
+ }
+ result_append_char (dm, ')');
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to
+ non-zero if the type is a template-id, zero otherwise.
+
+ <class-enum-type> ::= <name> */
+
+static status_t
+demangle_class_enum_type (dm, template_p)
+ demangling_t dm;
+ int *template_p;
+{
+ DEMANGLE_TRACE ("class-enum-type", dm);
+
+ RETURN_IF_ERROR (demangle_name (dm, template_p));
+ return STATUS_OK;
+}
+
+/* Demangles and emits an <array-type>.
+
+ <array-type> ::= A [<dimension number>] _ <element type> */
+
+static status_t
+demangle_array_type (dm)
+ demangling_t dm;
+{
+ dyn_string_t array_size = dyn_string_new (10);
+
+ RETURN_IF_ERROR (demangle_char (dm, 'A'));
+
+ /* Demangle the array size into array_size. */
+ RETURN_IF_ERROR (demangle_number_literally (dm, array_size, 10, 0));
+
+ /* Demangle the base type of the array. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ RETURN_IF_ERROR (demangle_type (dm));
+
+ /* Emit the array dimension syntax. */
+ result_append_char (dm, '[');
+ result_append_string (dm, array_size);
+ result_append_char (dm, ']');
+ dyn_string_delete (array_size);
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <template-param>. The zero-indexed position
+ in the parameter list is placed in *TEMPLATE_PARM_NUMBER.
+
+ <template-param> ::= T_ # first template parameter
+ ::= T <parameter-2 number> _ */
+
+static status_t
+demangle_template_param (dm, template_parm_number)
+ demangling_t dm;
+ int *template_parm_number;
+{
+ int parm_number;
+ template_arg_list_t current_arg_list = current_template_arg_list (dm);
+ string_list_t arg;
+
+ DEMANGLE_TRACE ("template-param", dm);
+
+ /* Make sure there is a template argmust list in which to look up
+ this parameter reference. */
+ if (current_arg_list == NULL)
+ return "Template parameter outside of template.";
+
+ RETURN_IF_ERROR (demangle_char (dm, 'T'));
+ if (peek_char (dm) == '_')
+ parm_number = 0;
+ else
+ {
+ RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
+ ++parm_number;
+ }
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+
+ arg = template_arg_list_get_arg (current_arg_list, parm_number);
+ if (arg == NULL)
+ /* parm_number exceeded the number of arguments in the current
+ template argument list. */
+ return "Template parameter number out of bounds.";
+ result_append_string (dm, (dyn_string_t) arg);
+
+ if (peek_char (dm) == 'I')
+ RETURN_IF_ERROR (demangle_template_args (dm));
+
+ *template_parm_number = parm_number;
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <template-args>.
+
+ <template-args> ::= I <template-arg>+ E */
+
+static status_t
+demangle_template_args (dm)
+ demangling_t dm;
+{
+ int first = 1;
+ template_arg_list_t arg_list = template_arg_list_new ();
+
+ /* Preserve the most recently demangled source name. */
+ dyn_string_t old_last_source_name = dm->last_source_name;
+ dm->last_source_name = dyn_string_new (0);
+
+ DEMANGLE_TRACE ("template-args", dm);
+
+ RETURN_IF_ERROR (demangle_char (dm, 'I'));
+ result_append_char (dm, '<');
+ do
+ {
+ string_list_t arg;
+
+ if (first)
+ first = 0;
+ else
+ result_append (dm, ", ");
+
+ /* Capture the template arg. */
+ result_push (dm);
+ RETURN_IF_ERROR (demangle_template_arg (dm));
+ arg = result_pop (dm);
+
+ /* Emit it in the demangled name. */
+ result_append_string (dm, (dyn_string_t) arg);
+
+ /* Save it for use in expanding <template-param>s. */
+ template_arg_list_add_arg (arg_list, arg);
+ }
+ while (peek_char (dm) != 'E');
+ /* Append the '>'. */
+ result_close_template_list (dm);
+
+ /* Consume the 'E'. */
+ advance_char (dm);
+
+ /* Restore the most recent demangled source name. */
+ dyn_string_delete (dm->last_source_name);
+ dm->last_source_name = old_last_source_name;
+
+ /* Push the list onto the top of the stack of template argument
+ lists, so that arguments from it are used from now on when
+ expanding <template-param>s. */
+ push_template_arg_list (dm, arg_list);
+
+ return STATUS_OK;
+}
+
+/* This function, which does not correspond to a production in the
+ mangling spec, handles the `literal' production for both
+ <template-arg> and <expr-primary>. It does not expect or consume
+ the initial `L' or final `E'. The demangling is given by:
+
+ <literal> ::= <type> </value/ number>
+
+ and the emitted output is `(type)number'. */
+
+static status_t
+demangle_literal (dm)
+ demangling_t dm;
+{
+ dyn_string_t value = dyn_string_new (0);
+ char peek = peek_char (dm);
+
+ DEMANGLE_TRACE ("literal", dm);
+
+ if (!flag_verbose && peek >= 'a' && peek <= 'z')
+ {
+ /* If not in verbose mode and this is a builtin type, see if we
+ can produce simpler numerical output. In particular, for
+ integer types shorter than `long', just write the number
+ without type information; for bools, write `true' or `false'.
+ Other refinements could be made here too. */
+
+ /* This constant string is used to map from <builtin-type> codes
+ (26 letters of the alphabet) to codes that determine how the
+ value will be displayed. The codes are:
+ b: display as bool
+ i: display as int
+ l: display as long
+ A space means the value will be represented using cast
+ notation. */
+ static const char *const code_map = "ibi iii ll ii i ";
+
+ char code = code_map[peek - 'a'];
+ /* FIXME: Implement demangling of floats and doubles. */
+ if (code == 'u')
+ return STATUS_UNIMPLEMENTED;
+ if (code == 'b')
+ {
+ /* It's a boolean. */
+ char value;
+
+ /* Consume the b. */
+ advance_char (dm);
+ /* Look at the next character. It should be 0 or 1,
+ corresponding to false or true, respectively. */
+ value = peek_char (dm);
+ if (value == '0')
+ result_append (dm, "false");
+ else if (value == '1')
+ result_append (dm, "true");
+ else
+ return "Unrecognized bool constant.";
+ /* Consume the 0 or 1. */
+ advance_char (dm);
+ return STATUS_OK;
+ }
+ else if (code == 'i' || code == 'l')
+ {
+ /* It's an integer or long. */
+
+ /* Consume the type character. */
+ advance_char (dm);
+ /* Demangle the number and write it out. */
+ RETURN_IF_ERROR (demangle_number_literally (dm, value, 10, 1));
+ result_append_string (dm, value);
+ /* For long integers, append an l. */
+ if (code == 'l')
+ result_append_char (dm, code);
+ return STATUS_OK;
+ }
+ /* ...else code == ' ', so fall through to represent this
+ literal's type explicitly using cast syntax. */
+ }
+
+ result_append_char (dm, '(');
+ RETURN_IF_ERROR (demangle_type (dm));
+ result_append_char (dm, ')');
+
+ RETURN_IF_ERROR (demangle_number_literally (dm, value, 10, 1));
+ result_append_string (dm, value);
+ dyn_string_delete (value);
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <template-arg>.
+
+ <template-arg> ::= <type> # type
+ ::= L <type> <value number> E # literal
+ ::= LZ <encoding> E # external name
+ ::= X <expression> E # expression */
+
+static status_t
+demangle_template_arg (dm)
+ demangling_t dm;
+{
+ DEMANGLE_TRACE ("template-arg", dm);
+
+ switch (peek_char (dm))
+ {
+ case 'L':
+ advance_char (dm);
+
+ if (peek_char (dm) == 'Z')
+ {
+ /* External name. */
+ advance_char (dm);
+ /* FIXME: Standard is contradictory here. */
+ RETURN_IF_ERROR (demangle_encoding (dm));
+ }
+ else
+ RETURN_IF_ERROR (demangle_literal (dm));
+ RETURN_IF_ERROR (demangle_char (dm, 'E'));
+ break;
+
+ case 'X':
+ /* Expression. */
+ advance_char (dm);
+ RETURN_IF_ERROR (demangle_expression (dm));
+ break;
+
+ default:
+ RETURN_IF_ERROR (demangle_type (dm));
+ break;
+ }
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits an <expression>.
+
+ <expression> ::= <unary operator-name> <expression>
+ ::= <binary operator-name> <expression> <expression>
+ ::= <expr-primary>
+ ::= <scope-expression> */
+
+static status_t
+demangle_expression (dm)
+ demangling_t dm;
+{
+ char peek = peek_char (dm);
+
+ DEMANGLE_TRACE ("expression", dm);
+
+ if (peek == 'L' || peek == 'T')
+ RETURN_IF_ERROR (demangle_expr_primary (dm));
+ else if (peek == 's' && peek_char_next (dm) == 'r')
+ RETURN_IF_ERROR (demangle_scope_expression (dm));
+ else
+ /* An operator expression. */
+ {
+ int num_args;
+ dyn_string_t operator_name;
+
+ /* We have an operator name. Since we want to output binary
+ operations in infix notation, capture the operator name
+ first. */
+ result_push (dm);
+ RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
+ operator_name = (dyn_string_t) result_pop (dm);
+
+ /* If it's binary, do an operand first. */
+ if (num_args > 1)
+ {
+ result_append_char (dm, '(');
+ RETURN_IF_ERROR (demangle_expression (dm));
+ result_append_char (dm, ')');
+ }
+
+ /* Now emit the operator, followed by its second (if binary) or
+ only (if unary) operand. */
+ result_append_string (dm, operator_name);
+ dyn_string_delete (operator_name);
+ result_append_char (dm, '(');
+ RETURN_IF_ERROR (demangle_expression (dm));
+ result_append_char (dm, ')');
+
+ /* The ternary operator takes a third operand. */
+ if (num_args == 3)
+ {
+ result_append (dm, ":(");
+ RETURN_IF_ERROR (demangle_expression (dm));
+ result_append_char (dm, ')');
+ }
+ }
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <scope-expression>.
+
+ <scope-expression> ::= sr <qualifying type> <source-name>
+ ::= sr <qualifying type> <encoding> */
+
+static status_t
+demangle_scope_expression (dm)
+ demangling_t dm;
+{
+ RETURN_IF_ERROR (demangle_char (dm, 's'));
+ RETURN_IF_ERROR (demangle_char (dm, 'r'));
+ RETURN_IF_ERROR (demangle_type (dm));
+ result_append (dm, "::");
+ RETURN_IF_ERROR (demangle_encoding (dm));
+ return STATUS_OK;
+}
+
+/* Demangles and emits an <expr-primary>.
+
+ <expr-primary> ::= <template-param>
+ ::= L <type> <value number> E # literal
+ ::= L <mangled-name> E # external name */
+
+static status_t
+demangle_expr_primary (dm)
+ demangling_t dm;
+{
+ char peek = peek_char (dm);
+ int unused;
+
+ DEMANGLE_TRACE ("expr-primary", dm);
+
+ if (peek == 'T')
+ RETURN_IF_ERROR (demangle_template_param (dm, &unused));
+ else if (peek == 'L')
+ {
+ /* Consume the `L'. */
+ advance_char (dm);
+ peek = peek_char (dm);
+
+ if (peek == '_')
+ RETURN_IF_ERROR (demangle_mangled_name (dm));
+ else
+ RETURN_IF_ERROR (demangle_literal (dm));
+
+ RETURN_IF_ERROR (demangle_char (dm, 'E'));
+ }
+ else
+ return STATUS_ERROR;
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
+ if the substitution is the name of a template, zero otherwise. If
+ the substitution token is St, which corresponds to the `::std::'
+ namespace and can appear in a non-nested name, sets
+ *SPECIAL_STD_SUBSTITUTION to non-zero; zero otherwise.
+
+ <substitution> ::= S <seq-id> _
+ ::= S_
+
+ ::= St # ::std::
+ ::= Sa # ::std::allocator
+ ::= Sb # ::std::basic_string
+ ::= Ss # ::std::basic_string<char,
+ ::std::char_traits<char>,
+ ::std::allocator<char> >
+ ::= Si # ::std::basic_istream<char,
+ std::char_traits<char> >
+ ::= So # ::std::basic_ostream<char,
+ std::char_traits<char> >
+ ::= Sd # ::std::basic_iostream<char,
+ std::char_traits<char> >
+*/
+
+static status_t
+demangle_substitution (dm, template_p, special_std_substitution)
+ demangling_t dm;
+ int *template_p;
+ int *special_std_substitution;
+{
+ int seq_id;
+ int peek;
+ dyn_string_t text;
+
+ DEMANGLE_TRACE ("substitution", dm);
+
+ RETURN_IF_ERROR (demangle_char (dm, 'S'));
+ *special_std_substitution = 0;
+
+ /* Scan the substitution sequence index. A missing number denotes
+ the first index. */
+ peek = peek_char (dm);
+ if (peek == '_')
+ seq_id = -1;
+ /* If the following character is 0-9 or a capital letter, interpret
+ the sequence up to the next underscore as a base-36 substitution
+ index. */
+ else if (isdigit ((unsigned char) peek)
+ || (peek >= 'A' && peek <= 'Z'))
+ RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
+ else
+ {
+ switch (peek)
+ {
+ case 't':
+ result_append (dm, "std");
+ *special_std_substitution = 1;
+ break;
+
+ case 'a':
+ result_append (dm, "std::allocator");
+ dyn_string_copy_cstr (dm->last_source_name, "allocator");
+ break;
+
+ case 'b':
+ result_append (dm, "std::basic_string");
+ dyn_string_copy_cstr (dm->last_source_name, "basic_string");
+ break;
+
+ case 's':
+ if (!flag_verbose)
+ {
+ result_append (dm, "std::string");
+ dyn_string_copy_cstr (dm->last_source_name, "string");
+ }
+ else
+ {
+ result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >");
+ dyn_string_copy_cstr (dm->last_source_name, "basic_string");
+ }
+ break;
+
+ case 'i':
+ if (!flag_verbose)
+ {
+ result_append (dm, "std::istream");
+ dyn_string_copy_cstr (dm->last_source_name, "istream");
+ }
+ else
+ {
+ result_append (dm, "std::basic_istream<char, std::char_traints<char> >");
+ dyn_string_copy_cstr (dm->last_source_name, "basic_istream");
+ }
+ break;
+
+ case 'o':
+ if (!flag_verbose)
+ {
+ result_append (dm, "std::ostream");
+ dyn_string_copy_cstr (dm->last_source_name, "ostream");
+ }
+ else
+ {
+ result_append (dm, "std::basic_ostream<char, std::char_traits<char> >");
+ dyn_string_copy_cstr (dm->last_source_name, "basic_ostream");
+ }
+ break;
+
+ case 'd':
+ if (!flag_verbose)
+ {
+ result_append (dm, "std::iostream");
+ dyn_string_copy_cstr (dm->last_source_name, "iostream");
+ }
+ else
+ {
+ result_append (dm, "std::basic_iostream<char, std::char_traits<char> >");
+ dyn_string_copy_cstr (dm->last_source_name, "basic_iostream");
+ }
+ break;
+
+ default:
+ return "Unrecognized <substitution>.";
+ }
+
+ advance_char (dm);
+ return STATUS_OK;
+ }
+
+ /* Look up the substitution text. Since `S_' is the most recent
+ substitution, `S0_' is the second-most-recent, etc., shift the
+ numbering by one. */
+ text = substitution_get (dm, seq_id + 1, template_p);
+ if (text == NULL)
+ return "Substitution number out of range.";
+
+ /* Emit the substitution text. */
+ result_append_string (dm, text);
+
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <local-name>.
+
+ <local-name> := Z <function encoding> E <entity name> [<discriminator>]
+ := Z <function encoding> E s [<discriminator>] */
+
+static status_t
+demangle_local_name (dm)
+ demangling_t dm;
+{
+ DEMANGLE_TRACE ("local-name", dm);
+
+ RETURN_IF_ERROR (demangle_char (dm, 'Z'));
+ RETURN_IF_ERROR (demangle_encoding (dm));
+ RETURN_IF_ERROR (demangle_char (dm, 'E'));
+ result_append (dm, "'s ");
+
+ if (peek_char (dm) == 's')
+ {
+ /* Local character string literal. */
+ result_append (dm, "string literal");
+ /* Consume the s. */
+ advance_char (dm);
+ RETURN_IF_ERROR (demangle_discriminator (dm, 0));
+ }
+ else
+ {
+ int unused;
+ result_append (dm, "local ");
+ /* Local name for some other entity. Demangle its name. */
+ RETURN_IF_ERROR (demangle_name (dm, &unused));
+ RETURN_IF_ERROR (demangle_discriminator (dm, 1));
+ }
+
+ return STATUS_OK;
+ }
+
+ /* Optimonally demangles and emits a <discriminator>. If there is no
+ <discriminator> at the current position in the mangled string, the
+ descriminator is assumed to be zero. Emit the discriminator number
+ in parentheses, unless SUPPRESS_FIRST is non-zero and the
+ discriminator is zero.
+
+ <discriminator> ::= _ <number> */
+
+static status_t
+demangle_discriminator (dm, suppress_first)
+ demangling_t dm;
+ int suppress_first;
+{
+ /* Output for <discriminator>s to the demangled name is completely
+ supressed if not in verbose mode. */
+
+ if (peek_char (dm) == '_')
+ {
+ /* Consume the underscore. */
+ advance_char (dm);
+ if (flag_verbose)
+ result_append (dm, " [#");
+ /* Check if there's a number following the underscore. */
+ if (isdigit ((unsigned char) peek_char (dm)))
+ {
+ int discriminator;
+ /* Demangle the number. */
+ RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
+ if (flag_verbose)
+ /* Write the discriminator. The mangled number is two
+ less than the discriminator ordinal, counting from
+ zero. */
+ int_to_dyn_string (discriminator + 2,
+ (dyn_string_t) dm->result);
+ }
+ else
+ {
+ if (flag_verbose)
+ /* A missing digit correspond to one. */
+ result_append_char (dm, '1');
+ }
+ if (flag_verbose)
+ result_append_char (dm, ']');
+ }
+ else if (!suppress_first)
+ {
+ if (flag_verbose)
+ result_append (dm, " [#0]");
+ }
+
+ return STATUS_OK;
+}
+
+/* Demangle NAME into RESULT, which must be an initialized
+ dyn_string_t. On success, returns STATUS_OK. On failure, returns
+ an error message, and the contents of RESULT are unchanged. */
+
+static status_t
+cp_demangle (name, result)
+ char *name;
+ dyn_string_t result;
+{
+ status_t status;
+ int length = strlen (name);
+
+ if (length > 2 && name[0] == '_' && name[1] == 'Z')
+ {
+ demangling_t dm = demangling_new (name);
+
+ result_push (dm);
+ status = demangle_mangled_name (dm);
+
+ if (status == STATUS_OK)
+ {
+ dyn_string_t demangled = (dyn_string_t) result_pop (dm);
+ dyn_string_copy (result, demangled);
+ dyn_string_delete (demangled);
+ }
+
+ demangling_delete (dm);
+ }
+ else
+ {
+ /* It's evidently not a mangled C++ name. It could be the name
+ of something with C linkage, though, so just copy NAME into
+ RESULT. */
+ dyn_string_copy_cstr (result, name);
+ status = STATUS_OK;
+ }
+
+ return status;
+}
+
+/* Variant entry point for integration with the existing cplus-dem
+ demangler. Attempts to demangle MANGLED. If the demangling
+ succeeds, returns a buffer, allocated with malloc, containing the
+ demangled name. The caller must deallocate the buffer using free.
+ If the demangling failes, returns NULL. */
+
+char *
+cplus_demangle_new_abi (mangled)
+ const char* mangled;
+{
+ /* Create a dyn_string to hold the demangled name. */
+ dyn_string_t demangled = dyn_string_new (0);
+ /* Attempt the demangling. */
+ status_t status = cp_demangle ((char *) mangled, demangled);
+ if (status == STATUS_OK)
+ /* Demangling succeeded. */
+ {
+ /* Grab the demangled result from the dyn_string. It was
+ allocated with malloc, so we can return it directly. */
+ char *return_value = dyn_string_release (demangled);
+ /* The dyn_string can go away. */
+ dyn_string_delete (demangled);
+ /* Hand back the demangled name. */
+ return return_value;
+ }
+ else
+ /* Demangling failed. */
+ {
+ dyn_string_delete (demangled);
+ return NULL;
+ }
+}
+
+#ifdef STANDALONE_DEMANGLER
+
+#include "getopt.h"
+
+static void print_usage
+ PARAMS ((FILE* fp, int exit_value));
+
+/* Non-zero if CHAR is a character than can occur in a mangled name. */
+#define is_mangled_char(CHAR) \
+ (isalnum ((unsigned char) (CHAR)) || (CHAR) == '_')
+
+/* The name of this program, as invoked. */
+const char* program_name;
+
+/* Prints usage summary to FP and then exits with EXIT_VALUE. */
+
+static void
+print_usage (fp, exit_value)
+ FILE* fp;
+ int exit_value;
+{
+ fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
+ fprintf (fp, "Options:\n", program_name);
+ fprintf (fp, " -h,--help Display this message.\n");
+ fprintf (fp, " -s,--strict Demangle standard names only.\n");
+ fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
+ fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
+
+ exit (exit_value);
+}
+
+/* Option specification for getopt_long. */
+static struct option long_options[] =
+{
+ { "help", no_argument, NULL, 'h' },
+ { "strict", no_argument, NULL, 's' },
+ { "verbose", no_argument, NULL, 'v' },
+ { NULL, no_argument, NULL, 0 },
+};
+
+/* Main entry for a demangling filter executable. It will demangle
+ its command line arguments, if any. If none are provided, it will
+ filter stdin to stdout, replacing any recognized mangled C++ names
+ with their demangled equivalents. */
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ status_t status;
+ int i;
+ int opt_char;
+
+ /* Use the program name of this program, as invoked. */
+ program_name = argv[0];
+
+ /* Parse options. */
+ do
+ {
+ opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
+ switch (opt_char)
+ {
+ case '?': /* Unrecognized option. */
+ print_usage (stderr, 1);
+ break;
+
+ case 'h':
+ print_usage (stdout, 0);
+ break;
+
+ case 's':
+ flag_strict = 1;
+ break;
+
+ case 'v':
+ flag_verbose = 1;
+ break;
+ }
+ }
+ while (opt_char != -1);
+
+ if (optind == argc)
+ /* No command line arguments were provided. Filter stdin. */
+ {
+ dyn_string_t mangled = dyn_string_new (3);
+ dyn_string_t demangled = dyn_string_new (0);
+ status_t status;
+
+ /* Read all of input. */
+ while (!feof (stdin))
+ {
+ char c = getchar ();
+
+ /* The first character of a mangled name is an underscore. */
+ if (feof (stdin))
+ break;
+ if (c != '_')
+ {
+ /* It's not a mangled name. Print the character and go
+ on. */
+ putchar (c);
+ continue;
+ }
+ c = getchar ();
+
+ /* The second character of a mangled name is a capital `Z'. */
+ if (feof (stdin))
+ break;
+ if (c != 'Z')
+ {
+ /* It's not a mangled name. Print the previous
+ underscore, the `Z', and go on. */
+ putchar ('_');
+ putchar (c);
+ continue;
+ }
+
+ /* Start keeping track of the candidate mangled name. */
+ dyn_string_append_char (mangled, '_');
+ dyn_string_append_char (mangled, 'Z');
+
+ /* Pile characters into mangled until we hit one that can't
+ occur in a mangled name. */
+ c = getchar ();
+ while (!feof (stdin) && is_mangled_char (c))
+ {
+ dyn_string_append_char (mangled, c);
+ if (feof (stdin))
+ break;
+ c = getchar ();
+ }
+
+ /* Attempt to demangle the name. */
+ status = cp_demangle (dyn_string_buf (mangled), demangled);
+
+ /* If the demangling succeeded, great! Print out the
+ demangled version. */
+ if (status == STATUS_OK)
+ fputs (dyn_string_buf (demangled), stdout);
+ /* Otherwise, it might not have been a mangled name. Just
+ print out the original text. */
+ else
+ fputs (dyn_string_buf (mangled), stdout);
+
+ /* If we haven't hit EOF yet, we've read one character that
+ can't occur in a mangled name, so print it out. */
+ if (!feof (stdin))
+ putchar (c);
+
+ /* Clear the candidate mangled name, to start afresh next
+ time we hit a `_Z'. */
+ dyn_string_clear (mangled);
+ }
+
+ dyn_string_delete (mangled);
+ dyn_string_delete (demangled);
+ }
+ else
+ /* Demangle command line arguments. */
+ {
+ dyn_string_t result = dyn_string_new (0);
+
+ /* Loop over command line arguments. */
+ for (i = optind; i < argc; ++i)
+ {
+ /* Attempt to demangle. */
+ status = cp_demangle (argv[i], result);
+
+ /* If it worked, print the demangled name. */
+ if (status == STATUS_OK)
+ printf ("%s\n", dyn_string_buf (result));
+ /* If not, print the error message to stderr instead. */
+ else
+ fprintf (stderr, "%s\n", status);
+ }
+ dyn_string_delete (result);
+ }
+
+ return 0;
+}
+
+#endif /* STANDALONE_DEMANGLER */
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 52249d2..44d1196 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -252,6 +252,55 @@ typedef enum type_kind_t
tk_real
} type_kind_t;
+struct demangler_engine libiberty_demanglers[] =
+{
+ {
+ AUTO_DEMANGLING_STYLE_STRING,
+ auto_demangling,
+ "Automatic selection based on executable"
+ }
+ ,
+ {
+ GNU_DEMANGLING_STYLE_STRING,
+ gnu_demangling,
+ "GNU (g++) style demangling"
+ }
+ ,
+ {
+ LUCID_DEMANGLING_STYLE_STRING,
+ lucid_demangling,
+ "Lucid (lcc) style demangling"
+ }
+ ,
+ {
+ ARM_DEMANGLING_STYLE_STRING,
+ arm_demangling,
+ "ARM style demangling"
+ }
+ ,
+ {
+ HP_DEMANGLING_STYLE_STRING,
+ hp_demangling,
+ "HP (aCC) style demangling"
+ }
+ ,
+ {
+ EDG_DEMANGLING_STYLE_STRING,
+ edg_demangling,
+ "EDG style demangling"
+ }
+ ,
+ {
+ GNU_NEW_ABI_DEMANGLING_STYLE_STRING,
+ gnu_new_abi_demangling,
+ "GNU (g++) new-ABI-style demangling"
+ }
+ ,
+ {
+ NULL, unknown_demangling, NULL
+ }
+};
+
#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
string_prepend(str, " ");}
@@ -636,8 +685,8 @@ cplus_demangle_opname (opname, result, options)
}
}
else if (opname[0] == '_' && opname[1] == '_'
- && opname[2] >= 'a' && opname[2] <= 'z'
- && opname[3] >= 'a' && opname[3] <= 'z')
+ && islower((unsigned char)opname[2])
+ && islower((unsigned char)opname[3]))
{
if (opname[4] == '\0')
{
@@ -733,6 +782,7 @@ cplus_demangle_opname (opname, result, options)
return ret;
}
+
/* Takes operator name as e.g. "++" and returns mangled
operator name (e.g. "postincrement_expr"), or NULL if not found.
@@ -758,6 +808,40 @@ cplus_mangle_opname (opname, options)
return (0);
}
+/* Add a routine to set the demangling style to be sure it is valid and
+ allow for any demangler initialization that maybe necessary. */
+
+enum demangling_styles
+cplus_demangle_set_style (style)
+ enum demangling_styles style;
+{
+ struct demangler_engine *demangler = libiberty_demanglers;
+
+ for (; demangler->demangling_style != unknown_demangling; ++demangler)
+ if (style == demangler->demangling_style)
+ {
+ current_demangling_style = style;
+ return current_demangling_style;
+ }
+
+ return unknown_demangling;
+}
+
+/* Do string name to style translation */
+
+enum demangling_styles
+cplus_demangle_name_to_style (name)
+ const char *name;
+{
+ struct demangler_engine *demangler = libiberty_demanglers;
+
+ for (; demangler->demangling_style != unknown_demangling; ++demangler)
+ if (strcmp (name, demangler->demangling_style_name) == 0)
+ return demangler->demangling_style;
+
+ return unknown_demangling;
+}
+
/* char *cplus_demangle (const char *mangled, int options)
If MANGLED is a mangled function name produced by GNU C++, then
@@ -798,6 +882,10 @@ cplus_demangle (mangled, options)
if ((work -> options & DMGL_STYLE_MASK) == 0)
work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
+ /* The new-ABI demangling is implemented elsewhere. */
+ if (GNU_NEW_ABI_DEMANGLING)
+ return cplus_demangle_new_abi (mangled);
+
ret = internal_cplus_demangle (work, mangled);
squangle_mop_up (work);
return (ret);
@@ -4188,8 +4276,8 @@ demangle_function_name (work, mangled, declp, scan)
}
}
else if (declp->b[0] == '_' && declp->b[1] == '_'
- && declp->b[2] >= 'a' && declp->b[2] <= 'z'
- && declp->b[3] >= 'a' && declp->b[3] <= 'z')
+ && islower((unsigned char)declp->b[2])
+ && islower((unsigned char)declp->b[3]))
{
if (declp->b[4] == '\0')
{
@@ -4402,6 +4490,7 @@ static int flags = DMGL_PARAMS | DMGL_ANSI;
static void demangle_it PARAMS ((char *));
static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
+static void print_demangler_list PARAMS ((FILE *));
static void
demangle_it (mangled_name)
@@ -4421,16 +4510,43 @@ demangle_it (mangled_name)
}
}
+static void
+print_demangler_list (stream)
+ FILE *stream;
+{
+ struct demangler_engine *demangler;
+
+ fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
+
+ for (demangler = libiberty_demanglers + 1;
+ demangler->demangling_style != unknown_demangling;
+ ++demangler)
+ fprintf (stream, ",%s", demangler->demangling_style_name);
+
+ fprintf (stream, "}");
+}
+
static void
usage (stream, status)
FILE *stream;
int status;
{
fprintf (stream, "\
-Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
- [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
- [--help] [--version] [arg...]\n",
+Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n",
program_name);
+
+ fprintf (stream, "\
+ [-s ");
+ print_demangler_list (stream);
+ fprintf (stream, "]\n");
+
+ fprintf (stream, "\
+ [--format ");
+ print_demangler_list (stream);
+ fprintf (stream, "]\n");
+
+ fprintf (stream, "\
+ [--help] [--version] [arg...]\n");
exit (status);
}
@@ -4468,6 +4584,9 @@ standard_symbol_characters PARAMS ((void));
static const char *
hp_symbol_characters PARAMS ((void));
+static const char *
+gnu_new_abi_symbol_characters PARAMS ((void));
+
/* Return the string of non-alnum characters that may occur
as a valid symbol component, in the standard assembler symbol
syntax. */
@@ -4516,6 +4635,17 @@ hp_symbol_characters ()
}
+/* Return the string of non-alnum characters that may occur
+ as a valid symbol component in the GNU standard C++ ABI mangling
+ scheme. */
+
+static const char *
+gnu_new_abi_symbol_characters ()
+{
+ return "_";
+}
+
+
extern int main PARAMS ((int, char **));
int
@@ -4553,32 +4683,19 @@ main (argc, argv)
flags |= DMGL_JAVA;
break;
case 's':
- if (strcmp (optarg, "gnu") == 0)
- {
- current_demangling_style = gnu_demangling;
- }
- else if (strcmp (optarg, "lucid") == 0)
- {
- current_demangling_style = lucid_demangling;
- }
- else if (strcmp (optarg, "arm") == 0)
- {
- current_demangling_style = arm_demangling;
- }
- else if (strcmp (optarg, "hp") == 0)
- {
- current_demangling_style = hp_demangling;
- }
- else if (strcmp (optarg, "edg") == 0)
- {
- current_demangling_style = edg_demangling;
- }
- else
- {
- fprintf (stderr, "%s: unknown demangling style `%s'\n",
- program_name, optarg);
- return (1);
- }
+ {
+ enum demangling_styles style;
+
+ style = cplus_demangle_name_to_style (optarg);
+ if (style == unknown_demangling)
+ {
+ fprintf (stderr, "%s: unknown demangling style `%s'\n",
+ program_name, optarg);
+ return (1);
+ }
+ else
+ cplus_demangle_set_style (style);
+ }
break;
}
}
@@ -4603,6 +4720,9 @@ main (argc, argv)
case hp_demangling:
valid_symbols = hp_symbol_characters ();
break;
+ case gnu_new_abi_demangling:
+ valid_symbols = gnu_new_abi_symbol_characters ();
+ break;
default:
/* Folks should explicitly indicate the appropriate alphabet for
each demangling. Providing a default would allow the
diff --git a/libiberty/dyn-string.c b/libiberty/dyn-string.c
new file mode 100644
index 0000000..f4a9d9a
--- /dev/null
+++ b/libiberty/dyn-string.c
@@ -0,0 +1,333 @@
+/* An abstract string datatype.
+ Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "libiberty.h"
+#include "dyn-string.h"
+
+/* Performs in-place initialization of a dyn_string struct. This
+ function can be used with a dyn_string struct on the stack or
+ embedded in another object. The contents of of the string itself
+ are still dynamically allocated. The string initially is capable
+ of holding at least SPACE characeters, including the terminating
+ NUL. If SPACE is 0, it will silently be increated to 1. */
+
+void
+dyn_string_init (ds_struct_ptr, space)
+ struct dyn_string *ds_struct_ptr;
+ int space;
+{
+ /* We need at least one byte in which to store the terminating NUL. */
+ if (space == 0)
+ space = 1;
+
+ ds_struct_ptr->allocated = space;
+ ds_struct_ptr->s = (char *) xmalloc (space);
+ ds_struct_ptr->length = 0;
+ ds_struct_ptr->s[0] = '\0';
+}
+
+/* Create a new dynamic string capable of holding at least SPACE characters,
+ including the terminating NUL. If SPACE is 0, it will be silently
+ increased to 1. */
+
+dyn_string_t
+dyn_string_new (space)
+ int space;
+{
+ dyn_string_t result = (dyn_string_t) xmalloc (sizeof (struct dyn_string));
+ dyn_string_init (result, space);
+ return result;
+}
+
+/* Free the memory used by DS. */
+
+void
+dyn_string_delete (ds)
+ dyn_string_t ds;
+{
+ free (ds->s);
+ free (ds);
+}
+
+/* Returns the contents of DS in a buffer allocated with malloc. It
+ is the caller's responsibility to deallocate the buffer using free.
+ DS is then set to the empty string. */
+
+char*
+dyn_string_release (ds)
+ dyn_string_t ds;
+{
+ /* Store the old buffer. */
+ char* result = ds->s;
+ /* The buffer is no longer owned by DS. */
+ ds->s = NULL;
+ /* Reinitialize DS to the empty string. */
+ dyn_string_init (ds, 0);
+ /* Return the old buffer. */
+ return result;
+}
+
+/* Increase the capacity of DS so it can hold at least SPACE
+ characters, plus the terminating NUL. This function will not (at
+ present) reduce the capacity of DS. */
+
+dyn_string_t
+dyn_string_resize (ds, space)
+ dyn_string_t ds;
+ int space;
+{
+ int new_allocated = ds->allocated;
+
+ /* Increase SPACE to hold the NUL termination. */
+ ++space;
+
+ while (space > new_allocated)
+ new_allocated *= 2;
+
+ if (new_allocated != ds->allocated)
+ {
+ /* We actually need more space. */
+ ds->allocated = new_allocated;
+ ds->s = (char *) xrealloc (ds->s, ds->allocated);
+ }
+
+ return ds;
+}
+
+/* Sets the contents of DS to the empty string. */
+
+void
+dyn_string_clear (ds)
+ dyn_string_t ds;
+{
+ /* A dyn_string always has room for at least the NUL terminator. */
+ ds->s[0] = '\0';
+ ds->length = 0;
+}
+
+/* Makes the contents of DEST the same as the contents of SRC. DEST
+ and SRC must be distinct. */
+
+void
+dyn_string_copy (dest, src)
+ dyn_string_t dest;
+ dyn_string_t src;
+{
+ if (dest == src)
+ abort ();
+
+ /* Make room in DEST. */
+ dyn_string_resize (dest, src->length);
+ /* Copy DEST into SRC. */
+ strcpy (dest->s, src->s);
+ /* Update the size of DEST. */
+ dest->length = src->length;
+}
+
+/* Copies SRC, a NUL-terminated string, into DEST. */
+
+void
+dyn_string_copy_cstr (dest, src)
+ dyn_string_t dest;
+ const char *src;
+{
+ int length = strlen (src);
+ /* Make room in DEST. */
+ dyn_string_resize (dest, length);
+ /* Copy DEST into SRC. */
+ strcpy (dest->s, src);
+ /* Update the size of DEST. */
+ dest->length = length;
+}
+
+/* Inserts SRC at the beginning of DEST. DEST is expanded as
+ necessary. SRC and DEST must be distinct. */
+
+void
+dyn_string_prepend (dest, src)
+ dyn_string_t dest;
+ dyn_string_t src;
+{
+ dyn_string_insert (dest, 0, src);
+}
+
+/* Inserts SRC, a NUL-terminated string, at the beginning of DEST.
+ DEST is expanded as necessary. */
+
+void
+dyn_string_prepend_cstr (dest, src)
+ dyn_string_t dest;
+ const char *src;
+{
+ dyn_string_insert_cstr (dest, 0, src);
+}
+
+/* Inserts SRC into DEST starting at position POS. DEST is expanded as
+ necessary. SRC and DEST must be distinct. */
+
+void
+dyn_string_insert (dest, pos, src)
+ dyn_string_t dest;
+ int pos;
+ dyn_string_t src;
+{
+ int i;
+
+ if (src == dest)
+ abort ();
+
+ dyn_string_resize (dest, dest->length + src->length);
+ /* Make room for the insertion. Be sure to copy the NUL. */
+ for (i = dest->length; i >= pos; --i)
+ dest->s[i + src->length] = dest->s[i];
+ /* Splice in the new stuff. */
+ strncpy (dest->s + pos, src->s, src->length);
+ /* Compute the new length. */
+ dest->length += src->length;
+}
+
+/* Inserts SRC, a NUL-terminated string, into DEST starting at
+ position POS. DEST is expanded as necessary. */
+
+void
+dyn_string_insert_cstr (dest, pos, src)
+ dyn_string_t dest;
+ int pos;
+ const char *src;
+{
+ int i;
+ int length = strlen (src);
+
+ dyn_string_resize (dest, dest->length + length);
+ /* Make room for the insertion. Be sure to copy the NUL. */
+ for (i = dest->length; i >= pos; --i)
+ dest->s[i + length] = dest->s[i];
+ /* Splice in the new stuff. */
+ strncpy (dest->s + pos, src, length);
+ /* Compute the new length. */
+ dest->length += length;
+}
+
+/* Append S to DS, resizing DS if necessary. Returns DS. */
+
+dyn_string_t
+dyn_string_append (ds, s)
+ dyn_string_t ds;
+ dyn_string_t s;
+{
+ dyn_string_resize (ds, ds->length + s->length);
+ strcpy (ds->s + ds->length, s->s);
+ ds->length += s->length;
+ return ds;
+}
+
+/* Append the NUL-terminated string S to DS, resizing DS if necessary.
+ Returns DS. */
+
+dyn_string_t
+dyn_string_append_cstr (ds, s)
+ dyn_string_t ds;
+ const char *s;
+{
+ int len = strlen (s);
+
+ /* The new length is the old length plus the size of our string, plus
+ one for the null at the end. */
+ dyn_string_resize (ds, ds->length + len);
+ strcpy (ds->s + ds->length, s);
+ ds->length += len;
+
+ return ds;
+}
+
+/* Appends C to the end of DS. */
+
+dyn_string_t
+dyn_string_append_char (ds, c)
+ dyn_string_t ds;
+ int c;
+{
+ /* Make room for the extra character. */
+ dyn_string_resize (ds, ds->length + 1);
+ /* Append the character; it will overwrite the old NUL. */
+ ds->s[ds->length] = c;
+ /* Add a new NUL at the end. */
+ ds->s[ds->length + 1] = '\0';
+ /* Update the length. */
+ ++(ds->length);
+ return ds;
+}
+
+/* Sets the contents of DEST to the substring of SRC starting at START
+ and ending before END. START must be less than or equal to END,
+ and both must be between zero and the length of SRC, inclusive. */
+
+void
+dyn_string_substring (dest, src, start, end)
+ dyn_string_t dest;
+ dyn_string_t src;
+ int start;
+ int end;
+{
+ int i;
+ int length = end - start;
+
+ if (start > end || start > src->length || end > src->length)
+ abort ();
+
+ /* Make room for the substring. */
+ dyn_string_resize (dest, length);
+ /* Copy the characters in the substring, */
+ for (i = length; --i >= 0; )
+ dest->s[i] = src->s[start + i];
+ /* NUL-terimate the result. */
+ dest->s[length] = '\0';
+ /* Record the length of the substring. */
+ dest->length = length;
+}
+
+/* Returns non-zero if DS1 and DS2 have the same contents. */
+
+int
+dyn_string_eq (ds1, ds2)
+ dyn_string_t ds1;
+ dyn_string_t ds2;
+{
+ /* If DS1 and DS2 have different lengths, they must not be the same. */
+ if (ds1->length != ds2->length)
+ return 0;
+ else
+ return !strcmp (ds1->s, ds2->s);
+}
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index 6ae34aa..57b4041 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -1,5 +1,5 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
This file is part of the libiberty library.
@@ -59,8 +59,20 @@ Boston, MA 02111-1307, USA. */
#define DELETED_ENTRY ((void *) 1)
+static unsigned long higher_prime_number PARAMS ((unsigned long));
+static hashval_t hash_pointer PARAMS ((const void *));
+static int eq_pointer PARAMS ((const void *, const void *));
+static void htab_expand PARAMS ((htab_t));
+static void **find_empty_slot_for_expand PARAMS ((htab_t, hashval_t));
+
+/* At some point, we could make these be NULL, and modify the
+ hash-table routines to handle NULL specially; that would avoid
+ function-call overhead for the common case of hashing pointers. */
+htab_hash htab_hash_pointer = hash_pointer;
+htab_eq htab_eq_pointer = eq_pointer;
+
/* The following function returns the nearest prime number which is
- greater than given source number. */
+ greater than a given source number, N. */
static unsigned long
higher_prime_number (n)
@@ -68,24 +80,47 @@ higher_prime_number (n)
{
unsigned long i;
- n |= 0x01; /* Force N to be odd. */
+ /* Ensure we have a larger number and then force to odd. */
+ n++;
+ n |= 0x01;
+
+ /* All odd numbers < 9 are prime. */
if (n < 9)
- return n; /* All odd numbers < 9 are prime. */
+ return n;
+
+ /* Otherwise find the next prime using a sieve. */
next:
- n += 2;
- i = 3;
- do
- {
- if (n % i == 0)
- goto next;
- i += 2;
- }
- while ((i * i) <= n);
+
+ for (i = 3; i * i <= n; i += 2)
+ if (n % i == 0)
+ {
+ n += 2;
+ goto next;
+ }
return n;
}
+/* Returns a hash code for P. */
+
+static hashval_t
+hash_pointer (p)
+ const void *p;
+{
+ return (hashval_t) ((long)p >> 3);
+}
+
+/* Returns non-zero if P1 and P2 are equal. */
+
+static int
+eq_pointer (p1, p2)
+ const void *p1;
+ const void *p2;
+{
+ return p1 == p2;
+}
+
/* This function creates table with length slightly longer than given
source length. Created hash table is initiated as empty (all the
hash table entries are EMPTY_ENTRY). The function returns the
@@ -118,13 +153,12 @@ htab_delete (htab)
htab_t htab;
{
int i;
+
if (htab->del_f)
for (i = htab->size - 1; i >= 0; i--)
- {
- if (htab->entries[i] != EMPTY_ENTRY
- && htab->entries[i] != DELETED_ENTRY)
- (*htab->del_f) (htab->entries[i]);
- }
+ if (htab->entries[i] != EMPTY_ENTRY
+ && htab->entries[i] != DELETED_ENTRY)
+ (*htab->del_f) (htab->entries[i]);
free (htab->entries);
free (htab);
@@ -137,13 +171,12 @@ htab_empty (htab)
htab_t htab;
{
int i;
+
if (htab->del_f)
for (i = htab->size - 1; i >= 0; i--)
- {
- if (htab->entries[i] != EMPTY_ENTRY
- && htab->entries[i] != DELETED_ENTRY)
- (*htab->del_f) (htab->entries[i]);
- }
+ if (htab->entries[i] != EMPTY_ENTRY
+ && htab->entries[i] != DELETED_ENTRY)
+ (*htab->del_f) (htab->entries[i]);
memset (htab->entries, 0, htab->size * sizeof (void *));
}
@@ -154,22 +187,23 @@ htab_empty (htab)
hash table.
This function also assumes there are no deleted entries in the table.
HASH is the hash value for the element to be inserted. */
+
static void **
find_empty_slot_for_expand (htab, hash)
htab_t htab;
- unsigned int hash;
+ hashval_t hash;
{
size_t size = htab->size;
- unsigned int hash2 = 1 + hash % (size - 2);
+ hashval_t hash2 = 1 + hash % (size - 2);
unsigned int index = hash % size;
for (;;)
{
void **slot = htab->entries + index;
+
if (*slot == EMPTY_ENTRY)
return slot;
-
- if (*slot == DELETED_ENTRY)
+ else if (*slot == DELETED_ENTRY)
abort ();
index += hash2;
@@ -196,7 +230,7 @@ htab_expand (htab)
olimit = oentries + htab->size;
htab->size = higher_prime_number (htab->size * 2);
- htab->entries = xcalloc (htab->size, sizeof (void **));
+ htab->entries = (void **) xcalloc (htab->size, sizeof (void **));
htab->n_elements -= htab->n_deleted;
htab->n_deleted = 0;
@@ -205,14 +239,18 @@ htab_expand (htab)
do
{
void *x = *p;
+
if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
{
void **q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x));
+
*q = x;
}
+
p++;
}
while (p < olimit);
+
free (oentries);
}
@@ -223,33 +261,41 @@ void *
htab_find_with_hash (htab, element, hash)
htab_t htab;
const void *element;
- unsigned int hash;
+ hashval_t hash;
{
- unsigned int index, hash2;
+ unsigned int index;
+ hashval_t hash2;
size_t size;
+ void *entry;
htab->searches++;
size = htab->size;
- hash2 = 1 + hash % (size - 2);
index = hash % size;
+ entry = htab->entries[index];
+ if (entry == EMPTY_ENTRY
+ || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
+ return entry;
+
+ hash2 = 1 + hash % (size - 2);
+
for (;;)
{
- void *entry = htab->entries[index];
- if (entry == EMPTY_ENTRY)
- return NULL;
- else if (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))
- return entry;
-
htab->collisions++;
index += hash2;
if (index >= size)
index -= size;
+
+ entry = htab->entries[index];
+ if (entry == EMPTY_ENTRY
+ || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
+ return entry;
}
}
/* Like htab_find_slot_with_hash, but compute the hash value from the
element. */
+
void *
htab_find (htab, element)
htab_t htab;
@@ -268,14 +314,15 @@ void **
htab_find_slot_with_hash (htab, element, hash, insert)
htab_t htab;
const void *element;
- unsigned int hash;
- int insert;
+ hashval_t hash;
+ enum insert_option insert;
{
void **first_deleted_slot;
- unsigned int index, hash2;
+ unsigned int index;
+ hashval_t hash2;
size_t size;
- if (insert && htab->size * 3 <= htab->n_elements * 4)
+ if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4)
htab_expand (htab);
size = htab->size;
@@ -290,7 +337,7 @@ htab_find_slot_with_hash (htab, element, hash, insert)
void *entry = htab->entries[index];
if (entry == EMPTY_ENTRY)
{
- if (!insert)
+ if (insert == NO_INSERT)
return NULL;
htab->n_elements++;
@@ -309,11 +356,8 @@ htab_find_slot_with_hash (htab, element, hash, insert)
if (!first_deleted_slot)
first_deleted_slot = &htab->entries[index];
}
- else
- {
- if ((*htab->eq_f) (entry, element))
- return &htab->entries[index];
- }
+ else if ((*htab->eq_f) (entry, element))
+ return &htab->entries[index];
htab->collisions++;
index += hash2;
@@ -324,11 +368,12 @@ htab_find_slot_with_hash (htab, element, hash, insert)
/* Like htab_find_slot_with_hash, but compute the hash value from the
element. */
+
void **
htab_find_slot (htab, element, insert)
htab_t htab;
const void *element;
- int insert;
+ enum insert_option insert;
{
return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element),
insert);
@@ -345,7 +390,7 @@ htab_remove_elt (htab, element)
{
void **slot;
- slot = htab_find_slot (htab, element, 0);
+ slot = htab_find_slot (htab, element, NO_INSERT);
if (*slot == EMPTY_ENTRY)
return;
@@ -368,8 +413,10 @@ htab_clear_slot (htab, slot)
if (slot < htab->entries || slot >= htab->entries + htab->size
|| *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY)
abort ();
+
if (htab->del_f)
(*htab->del_f) (*slot);
+
*slot = DELETED_ENTRY;
htab->n_deleted++;
}
@@ -385,12 +432,13 @@ htab_traverse (htab, callback, info)
htab_trav callback;
void *info;
{
- void **slot, **limit;
- slot = htab->entries;
- limit = slot + htab->size;
+ void **slot = htab->entries;
+ void **limit = slot + htab->size;
+
do
{
void *x = *slot;
+
if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
if (!(*callback) (slot, info))
break;
@@ -398,7 +446,7 @@ htab_traverse (htab, callback, info)
while (++slot < limit);
}
-/* The following function returns current size of given hash table. */
+/* Return the current size of given hash table. */
size_t
htab_size (htab)
@@ -407,8 +455,7 @@ htab_size (htab)
return htab->size;
}
-/* The following function returns current number of elements in given
- hash table. */
+/* Return the current number of elements in given hash table. */
size_t
htab_elements (htab)
@@ -417,17 +464,15 @@ htab_elements (htab)
return htab->n_elements - htab->n_deleted;
}
-/* The following function returns number of percents of fixed
- collisions during all work with given hash table. */
+/* Return the fraction of fixed collisions during all work with given
+ hash table. */
double
htab_collisions (htab)
htab_t htab;
{
- int searches;
-
- searches = htab->searches;
- if (searches == 0)
+ if (htab->searches == 0)
return 0.0;
- return (double)htab->collisions / (double)searches;
+
+ return (double) htab->collisions / (double) htab->searches;
}
diff --git a/libiberty/memcmp.c b/libiberty/memcmp.c
index 127ae0c..0fd21ca 100644
--- a/libiberty/memcmp.c
+++ b/libiberty/memcmp.c
@@ -25,8 +25,8 @@ int
DEFUN(memcmp, (str1, str2, count),
const PTR str1 AND const PTR str2 AND size_t count)
{
- register unsigned char *s1 = (unsigned char*)str1;
- register unsigned char *s2 = (unsigned char*)str2;
+ register const unsigned char *s1 = (const unsigned char*)str1;
+ register const unsigned char *s2 = (const unsigned char*)str2;
while (count-- > 0)
{
diff --git a/libiberty/mkstemps.c b/libiberty/mkstemps.c
index 16c16a2..6ef526e 100644
--- a/libiberty/mkstemps.c
+++ b/libiberty/mkstemps.c
@@ -39,7 +39,7 @@
/* We need to provide a type for gcc_uint64_t. */
#ifdef __GNUC__
-typedef unsigned long long gcc_uint64_t;
+__extension__ typedef unsigned long long gcc_uint64_t;
#else
typedef unsigned long gcc_uint64_t;
#endif
diff --git a/libiberty/partition.c b/libiberty/partition.c
index 52fb128..a5a7349 100644
--- a/libiberty/partition.c
+++ b/libiberty/partition.c
@@ -34,6 +34,8 @@
#include "libiberty.h"
#include "partition.h"
+static int elem_compare PARAMS ((const void *, const void *));
+
/* Creates a partition of NUM_ELEMENTS elements. Initially each
element is in a class by itself. */
@@ -128,8 +130,8 @@ elem_compare (elem1, elem2)
const void *elem1;
const void *elem2;
{
- int e1 = * (int *) elem1;
- int e2 = * (int *) elem2;
+ int e1 = * (const int *) elem1;
+ int e2 = * (const int *) elem2;
if (e1 < e2)
return -1;
else if (e1 > e2)
@@ -175,7 +177,7 @@ partition_print (part, fp)
c = elements[c].next - elements;
}
/* Sort them. */
- qsort ((void *) class_elements, count, sizeof (int), &elem_compare);
+ qsort ((void *) class_elements, count, sizeof (int), elem_compare);
/* Print them. */
fputc ('(', fp);
for (i = 0; i < count; ++i)
diff --git a/libiberty/setenv.c b/libiberty/setenv.c
index eec1300..a90c83a 100644
--- a/libiberty/setenv.c
+++ b/libiberty/setenv.c
@@ -72,11 +72,13 @@ setenv (name, value, replace)
size = 0;
if (__environ != NULL)
- for (ep = __environ; *ep != NULL; ++ep)
- if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
- break;
- else
- ++size;
+ {
+ for (ep = __environ; *ep != NULL; ++ep)
+ if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
+ break;
+ else
+ ++size;
+ }
if (__environ == NULL || *ep == NULL)
{
diff --git a/libiberty/strncmp.c b/libiberty/strncmp.c
new file mode 100644
index 0000000..b3b9de1
--- /dev/null
+++ b/libiberty/strncmp.c
@@ -0,0 +1,28 @@
+/* strncmp -- compare two strings, stop after n bytes.
+ This function is in the public domain. */
+
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+int
+strncmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ register unsigned char u1, u2;
+
+ while (n-- > 0)
+ {
+ u1 = (unsigned char) *s1++;
+ u2 = (unsigned char) *s2++;
+ if (u1 != u2)
+ return u1 - u2;
+ if (u1 == '\0')
+ return 0;
+ }
+ return 0;
+}
diff --git a/libiberty/xmalloc.c b/libiberty/xmalloc.c
index 621c6d2..08c23f8 100644
--- a/libiberty/xmalloc.c
+++ b/libiberty/xmalloc.c
@@ -17,6 +17,9 @@ 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. */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include "ansidecl.h"
#include "libiberty.h"