aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2011-12-02 22:46:53 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2011-12-02 22:46:53 +0000
commit29b4be759a1cb9071f684712a745e4b92bd366d0 (patch)
tree420c69d9e3125fa5ccbd4216e27d200b25f01bed /src
parentf823497bd9d420a2cf83fa56f5090d4227ba73f5 (diff)
downloadsrc-29b4be759a1cb9071f684712a745e4b92bd366d0.tar.gz
src-29b4be759a1cb9071f684712a745e4b92bd366d0.zip
import gperf 3.0.3 latest GPLv2vendor/gperf/3.0.3vendor/gperf
Approved by: cognet
Notes
Notes: svn path=/vendor/gperf/dist/; revision=228214 svn path=/vendor/gperf/3.0.3/; revision=228215; tag=vendor/gperf/3.0.3
Diffstat (limited to 'src')
-rw-r--r--src/Makefile77
-rw-r--r--src/Makefile.in87
-rw-r--r--src/bool-array.cc46
-rw-r--r--src/bool-array.h83
-rw-r--r--src/bool-array.icc93
-rw-r--r--src/boolarray.c90
-rw-r--r--src/boolarray.h48
-rw-r--r--src/config.h.in27
-rw-r--r--src/config.h_vms20
-rwxr-xr-xsrc/configure5243
-rw-r--r--src/configure.ac (renamed from src/configure.in)47
-rw-r--r--src/gen-perf.cc359
-rw-r--r--src/gen-perf.h50
-rw-r--r--src/getopt.c413
-rw-r--r--src/gperf-to-do22
-rw-r--r--src/hash-table.cc210
-rw-r--r--src/hash-table.h69
-rw-r--r--src/hashtable.c132
-rw-r--r--src/hashtable.h37
-rw-r--r--src/input.cc1005
-rw-r--r--src/input.h69
-rw-r--r--src/iterator.c106
-rw-r--r--src/iterator.cc87
-rw-r--r--src/iterator.h51
-rw-r--r--src/key-list.cc2184
-rw-r--r--src/key-list.h96
-rw-r--r--src/keylist.c1033
-rw-r--r--src/keylist.h54
-rw-r--r--src/keyword-list.cc175
-rw-r--r--src/keyword-list.h85
-rw-r--r--src/keyword-list.icc53
-rw-r--r--src/keyword.cc161
-rw-r--r--src/keyword.h116
-rw-r--r--src/keyword.icc42
-rw-r--r--src/list-node.cc102
-rw-r--r--src/list-node.h46
-rw-r--r--src/listnode.c111
-rw-r--r--src/listnode.h43
-rw-r--r--src/main.c96
-rw-r--r--src/main.cc201
-rw-r--r--src/new.cc87
-rw-r--r--src/options.c444
-rw-r--r--src/options.cc1118
-rw-r--r--src/options.h372
-rw-r--r--src/options.icc190
-rw-r--r--src/output.cc2100
-rw-r--r--src/output.h154
-rw-r--r--src/perfect.c350
-rw-r--r--src/perfect.h45
-rw-r--r--src/positions.cc177
-rw-r--r--src/positions.h175
-rw-r--r--src/positions.icc285
-rw-r--r--src/prototype.h15
-rw-r--r--src/read-line.cc97
-rw-r--r--src/read-line.h53
-rw-r--r--src/read-line.icc47
-rw-r--r--src/readline.c87
-rw-r--r--src/readline.h31
-rw-r--r--src/search.cc1684
-rw-r--r--src/search.h165
-rw-r--r--src/stderr.c90
-rw-r--r--src/stderr.h29
-rw-r--r--src/trace.cc35
-rw-r--r--src/trace.h40
-rw-r--r--src/vectors.cc25
-rw-r--r--src/vectors.h37
-rw-r--r--src/version.c22
-rw-r--r--src/version.cc36
-rw-r--r--src/version.h30
-rw-r--r--src/xmalloc.c78
70 files changed, 12245 insertions, 8922 deletions
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 05f59a4bdabb..000000000000
--- a/src/Makefile
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 1989 Free Software Foundation, Inc.
-# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-#
-# This file is part of GNU GPERF.
-#
-# GNU GPERF 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 1, or (at your option)
-# any later version.
-#
-# GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-CC = gcc
-DFLAGS= -DLO_CAL -DGATHER_STATISTICS #-DRLIMIT_STACK
-OFLAGS= -O -p -g -fstrength-reduce -fomit-frame-pointer -fdelayed-branch -finline-functions # gcc options
-CFLAGS= $(DFLAGS) $(OFLAGS)
-OBJS = options.o iterator.o main.o perfect.o keylist.o listnode.o xmalloc.o \
- hashtable.o boolarray.o readline.o stderr.o version.o getopt.o
-SOURCES = options.c iterator.c main.c perfect.c keylist.c listnode.c xmalloc.c \
- hashtable.c boolarray.c readline.c stderr.c version.c getopt.c
-
-all: gperf
-
-gperf: $(OBJS)
- $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
-
-clean:
- -rm -f *.o core *~ #*#
-
-realclean: clean
- -rm -f gperf
-
-# dependencies
-# DO NOT DELETE THIS LINE -- mkdep uses it.
-# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
-
-boolarray.o: boolarray.c /usr/include/stdio.h boolarray.h prototype.h options.h
-boolarray.o: /usr/include/stdio.h prototype.h
-getopt.o: getopt.c /usr/include/stdio.h
-hashtable.o: hashtable.c /usr/include/stdio.h hashtable.h keylist.h
-hashtable.o: /usr/include/stdio.h listnode.h prototype.h prototype.h options.h
-hashtable.o: /usr/include/stdio.h prototype.h
-iterator.o: iterator.c /usr/include/stdio.h /usr/include/ctype.h iterator.h
-iterator.o: prototype.h
-keylist.o: keylist.c /usr/include/assert.h /usr/include/stdio.h options.h
-keylist.o: /usr/include/stdio.h prototype.h readline.h prototype.h keylist.h
-keylist.o: /usr/include/stdio.h listnode.h prototype.h hashtable.h keylist.h
-keylist.o: prototype.h stderr.h prototype.h /usr/include/varargs.h
-listnode.o: listnode.c /usr/include/stdio.h options.h /usr/include/stdio.h
-listnode.o: prototype.h listnode.h prototype.h stderr.h prototype.h
-listnode.o: /usr/include/varargs.h
-main.o: main.c /usr/include/stdio.h stderr.h prototype.h /usr/include/varargs.h
-main.o: options.h /usr/include/stdio.h prototype.h perfect.h prototype.h
-main.o: keylist.h /usr/include/stdio.h listnode.h prototype.h boolarray.h
-main.o: prototype.h
-options.o: options.c /usr/include/stdio.h /usr/include/assert.h options.h
-options.o: /usr/include/stdio.h prototype.h iterator.h prototype.h stderr.h
-options.o: prototype.h /usr/include/varargs.h
-perfect.o: perfect.c /usr/include/stdio.h /usr/include/assert.h
-perfect.o: /usr/include/ctype.h options.h /usr/include/stdio.h prototype.h
-perfect.o: perfect.h prototype.h keylist.h /usr/include/stdio.h listnode.h
-perfect.o: prototype.h boolarray.h prototype.h stderr.h prototype.h
-perfect.o: /usr/include/varargs.h
-readline.o: readline.c /usr/include/stdio.h readline.h prototype.h
-stderr.o: stderr.c /usr/include/stdio.h stderr.h prototype.h
-stderr.o: /usr/include/varargs.h
-version.o: version.c
-xmalloc.o: xmalloc.c /usr/include/stdio.h
-
-# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/src/Makefile.in b/src/Makefile.in
index 60f73c735a34..19defc482c70 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,13 +1,14 @@
# Makefile for gperf/src
-# Copyright (C) 1989, 1992, 1993, 1998, 2000 Free Software Foundation, Inc.
-# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+# Copyright (C) 1989, 1992, 1993, 1998, 2000, 2002, 2006 Free Software Foundation, Inc.
+# Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+# and Bruno Haible <bruno@clisp.org>.
#
# This file is part of GNU GPERF.
#
# GNU GPERF 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 1, or (at your option)
+# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU GPERF is distributed in the hope that it will be useful,
@@ -16,8 +17,9 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with GNU GPERF; see the file COPYING. If not, write to the Free
-# Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+# along with this program; see the file COPYING.
+# If not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#### Start of system configuration section. ####
@@ -41,6 +43,8 @@ CXXFLAGS = @CXXFLAGS@
CXXCPP = @CXXCPP@
# Both C and C++ compiler
LDFLAGS = @LDFLAGS@
+OBJEXT = @OBJEXT@
+EXEEXT = @EXEEXT@
# Other
MV = mv
LN = ln
@@ -59,12 +63,12 @@ SHELL = /bin/sh
VPATH = $(srcdir)
-OBJECTS = new.o options.o iterator.o main.o gen-perf.o key-list.o list-node.o \
- hash-table.o bool-array.o read-line.o trace.o vectors.o version.o
-LIBS = ../lib/libgp.a -lm
+OBJECTS = version.$(OBJEXT) positions.$(OBJEXT) options.$(OBJEXT) keyword.$(OBJEXT) keyword-list.$(OBJEXT) \
+ input.$(OBJEXT) bool-array.$(OBJEXT) hash-table.$(OBJEXT) search.$(OBJEXT) output.$(OBJEXT) main.$(OBJEXT)
+LIBS = ../lib/libgp.a @GPERF_LIBM@
CPPFLAGS = -I. -I$(srcdir)/../lib
-TARGETPROG = gperf
+TARGETPROG = gperf$(EXEEXT)
all : $(TARGETPROG)
@@ -83,43 +87,38 @@ $(TARGETPROG): $(OBJECTS)
# Dependencies.
CONFIG_H = config.h
VERSION_H = version.h
-VECTORS_H = vectors.h
-TRACE_H = trace.h
-READ_LINE_H = read-line.h read-line.icc $(TRACE_H)
-OPTIONS_H = options.h options.icc $(TRACE_H)
-LIST_NODE_H = list-node.h $(VECTORS_H)
-KEY_LIST_H = key-list.h $(LIST_NODE_H) $(VECTORS_H) $(READ_LINE_H)
-ITERATOR_H = iterator.h
-HASH_TABLE_H = hash-table.h $(LIST_NODE_H)
-BOOL_ARRAY_H = bool-array.h bool-array.icc $(TRACE_H) $(OPTIONS_H)
-GEN_PERF_H = gen-perf.h $(KEY_LIST_H) $(BOOL_ARRAY_H)
-
-bool-array.o : bool-array.cc $(BOOL_ARRAY_H) $(OPTIONS_H) $(TRACE_H)
+POSITIONS_H = positions.h positions.icc
+OPTIONS_H = options.h options.icc $(POSITIONS_H)
+KEYWORD_H = keyword.h keyword.icc
+KEYWORD_LIST_H = keyword-list.h keyword-list.icc $(KEYWORD_H)
+INPUT_H = input.h $(KEYWORD_LIST_H)
+BOOL_ARRAY_H = bool-array.h bool-array.icc $(OPTIONS_H)
+HASH_TABLE_H = hash-table.h $(KEYWORD_H)
+SEARCH_H = search.h $(KEYWORD_LIST_H) $(POSITIONS_H) $(BOOL_ARRAY_H)
+OUTPUT_H = output.h $(KEYWORD_LIST_H) $(POSITIONS_H)
+
+version.$(OBJEXT): version.cc $(VERSION_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/version.cc
+positions.$(OBJEXT): positions.cc $(POSITIONS_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/positions.cc
+options.$(OBJEXT): options.cc $(OPTIONS_H) $(VERSION_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/options.cc
+keyword.$(OBJEXT): keyword.cc $(KEYWORD_H) $(POSITIONS_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/keyword.cc
+keyword-list.$(OBJEXT): keyword-list.cc $(KEYWORD_LIST_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/keyword-list.cc
+input.$(OBJEXT): input.cc $(INPUT_H) $(OPTIONS_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/input.cc
+bool-array.$(OBJEXT): bool-array.cc $(BOOL_ARRAY_H) $(OPTIONS_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/bool-array.cc
-gen-perf.o : gen-perf.cc $(GEN_PERF_H) $(OPTIONS_H) $(TRACE_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/gen-perf.cc
-hash-table.o : hash-table.cc $(HASH_TABLE_H) $(OPTIONS_H) $(TRACE_H)
+hash-table.$(OBJEXT): hash-table.cc $(HASH_TABLE_H) $(OPTIONS_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/hash-table.cc
-iterator.o : iterator.cc $(ITERATOR_H) $(TRACE_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/iterator.cc
-key-list.o : key-list.cc $(KEY_LIST_H) $(OPTIONS_H) $(READ_LINE_H) $(HASH_TABLE_H) $(TRACE_H) $(VERSION_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/key-list.cc
-list-node.o : list-node.cc $(LIST_NODE_H) $(OPTIONS_H) $(TRACE_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/list-node.cc
-main.o : main.cc $(OPTIONS_H) $(GEN_PERF_H) $(TRACE_H) $(CONFIG_H)
+search.$(OBJEXT): search.cc $(SEARCH_H) $(OPTIONS_H) $(HASH_TABLE_H) $(CONFIG_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/search.cc
+output.$(OBJEXT): output.cc $(OUTPUT_H) $(OPTIONS_H) $(VERSION_H)
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/output.cc
+main.$(OBJEXT): main.cc $(OPTIONS_H) $(INPUT_H) $(SEARCH_H) $(OUTPUT_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/main.cc
-new.o : new.cc $(TRACE_H) $(CONFIG_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/new.cc
-options.o : options.cc $(OPTIONS_H) $(ITERATOR_H) $(TRACE_H) $(VECTORS_H) $(VERSION_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/options.cc
-read-line.o : read-line.cc $(READ_LINE_H) $(OPTIONS_H) $(TRACE_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/read-line.cc
-trace.o : trace.cc $(TRACE_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/trace.cc
-vectors.o : vectors.cc $(VECTORS_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/vectors.cc
-version.o : version.cc $(VERSION_H)
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/version.cc
install : all force
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
@@ -136,7 +135,7 @@ check : all
mostlyclean : clean
clean : force
- $(RM) *~ *.s *.o *.a $(TARGETPROG) core
+ $(RM) *~ *.s *.$(OBJEXT) *.a $(TARGETPROG) core
distclean : clean
$(RM) config.status config.log config.cache Makefile config.h
diff --git a/src/bool-array.cc b/src/bool-array.cc
index 0774b2d65265..ca3c50149afd 100644
--- a/src/bool-array.cc
+++ b/src/bool-array.cc
@@ -1,43 +1,41 @@
/* Fast lookup table abstraction implemented as an Iteration Number Array
- Copyright (C) 1989-1998 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+/* Specification. */
#include "bool-array.h"
#include <stdio.h>
#include <string.h>
#include "options.h"
-#include "trace.h"
-STORAGE_TYPE * Bool_Array::storage_array;
-STORAGE_TYPE Bool_Array::iteration_number;
-unsigned int Bool_Array::size;
-
-/* Prints out debugging diagnostics. */
-
-Bool_Array::~Bool_Array (void)
+/* Frees this object. */
+Bool_Array::~Bool_Array ()
{
- T (Trace t ("Bool_Array::~Bool_Array");)
+ /* Print out debugging diagnostics. */
if (option[DEBUG])
fprintf (stderr, "\ndumping boolean array information\n"
"size = %d\niteration number = %d\nend of array dump\n",
- size, iteration_number);
+ _size, _iteration_number);
+ delete[] const_cast<unsigned int *>(_storage_array);
}
#ifndef __OPTIMIZE__
diff --git a/src/bool-array.h b/src/bool-array.h
index 8330fcd22019..ddfbd869b501 100644
--- a/src/bool-array.h
+++ b/src/bool-array.h
@@ -2,54 +2,67 @@
/* Simple lookup table abstraction implemented as an Iteration Number Array.
- Copyright (C) 1989-1998 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Define and implement a simple boolean array abstraction,
- uses an Iteration Numbering implementation to save on initialization time. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef bool_array_h
#define bool_array_h 1
-#include "trace.h"
-
-#ifdef LO_CAL
-/* If we are on a memory diet then we'll only make these use a limited
- amount of storage space. */
-typedef unsigned short STORAGE_TYPE;
-#else
-typedef unsigned int STORAGE_TYPE;
-#endif
+/* A Bool_Array instance is a bit array of fixed size, optimized for being
+ filled sparsely and cleared frequently. For example, when processing
+ tests/chill.gperf, the array will be:
+ - of size 15391,
+ - clear will be called 3509 times,
+ - set_bit will be called 300394 times.
+ With a conventional bit array implementation, clear would be too slow.
+ With a tree/hash based bit array implementation, set_bit would be slower. */
class Bool_Array
{
+public:
+ /* Initializes the bit array with room for SIZE bits, numbered from
+ 0 to SIZE-1. */
+ Bool_Array (unsigned int size);
+
+ /* Frees this object. */
+ ~Bool_Array ();
+
+ /* Resets all bits to zero. */
+ void clear ();
+
+ /* Sets the specified bit to true.
+ Returns its previous value (false or true). */
+ bool set_bit (unsigned int index);
+
private:
- static STORAGE_TYPE *storage_array; /* Initialization of the index space. */
- static STORAGE_TYPE iteration_number; /* Keep track of the current iteration. */
- static unsigned int size; /* Keep track of array size. */
+ /* Size of array. */
+ unsigned int const _size;
-public:
- Bool_Array (void);
- ~Bool_Array (void);
- static void init (STORAGE_TYPE *buffer, unsigned int s);
- static int find (int hash_value);
- static void reset (void);
+ /* Current iteration number. Always nonzero. Starts out as 1, and is
+ incremented each time clear() is called. */
+ unsigned int _iteration_number;
+
+ /* For each index, we store in storage_array[index] the iteration_number at
+ the time set_bit(index) was last called. */
+ unsigned int * const _storage_array;
};
#ifdef __OPTIMIZE__ /* efficiency hack! */
diff --git a/src/bool-array.icc b/src/bool-array.icc
index 6de6f236e712..fba4a31ace8b 100644
--- a/src/bool-array.icc
+++ b/src/bool-array.icc
@@ -1,84 +1,77 @@
/* Inline Functions for bool-array.{h,cc}.
- Copyright (C) 1989-1998 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
// This needs:
//#include <stdio.h>
//#include <string.h>
//#include "options.h"
-//#include "trace.h"
+/* Initializes the bit array with room for SIZE bits, numbered from
+ 0 to SIZE-1. */
INLINE
-Bool_Array::Bool_Array (void)
+Bool_Array::Bool_Array (unsigned int size)
+ : _size (size),
+ _iteration_number (1),
+ _storage_array (new unsigned int [size])
{
- T (Trace t ("Bool_Array::Bool_Array");)
- storage_array = 0;
- iteration_number = size = 0;
-}
-
-INLINE void
-Bool_Array::init (STORAGE_TYPE *buffer, unsigned int s)
-{
- T (Trace t ("Bool_Array::init");)
- size = s;
- iteration_number = 1;
- storage_array = buffer;
- memset (storage_array, 0, s * sizeof (*storage_array));
+ memset (_storage_array, 0, size * sizeof (_storage_array[0]));
if (option[DEBUG])
fprintf (stderr, "\nbool array size = %d, total bytes = %d\n",
- size, (unsigned int) (size * sizeof (*storage_array)));
+ _size,
+ static_cast<unsigned int> (_size * sizeof (_storage_array[0])));
}
-INLINE int
-Bool_Array::find (int index)
+/* Sets the specified bit to true.
+ Returns its previous value (false or true). */
+INLINE bool
+Bool_Array::set_bit (unsigned int index)
{
- T (Trace t ("Bool_Array::find");)
- if (storage_array[index] == iteration_number)
- return 1;
+ if (_storage_array[index] == _iteration_number)
+ /* The bit was set since the last clear() call. */
+ return true;
else
{
- storage_array[index] = iteration_number;
- return 0;
+ /* The last operation on this bit was clear(). Set it now. */
+ _storage_array[index] = _iteration_number;
+ return false;
}
}
+/* Resets all bits to zero. */
INLINE void
-Bool_Array::reset (void)
+Bool_Array::clear ()
{
- T (Trace t ("Bool_Array::reset");)
/* If we wrap around it's time to zero things out again! However, this only
- occurs once about every 2^31 or 2^15 iterations, so it should probably
- never happen! */
+ occurs once about every 2^32 iterations, so it will not happen more
+ frequently than once per second. */
- if (++iteration_number == 0)
+ if (++_iteration_number == 0)
{
+ _iteration_number = 1;
+ memset (_storage_array, 0, _size * sizeof (_storage_array[0]));
if (option[DEBUG])
{
- fprintf (stderr, "(re-initializing bool_array)...");
- fflush (stderr);
- }
- iteration_number = 1;
- memset (storage_array, 0, size * sizeof (*storage_array));
- if (option[DEBUG])
- {
- fprintf (stderr, "done\n");
+ fprintf (stderr, "(re-initialized bool_array)\n");
fflush (stderr);
}
}
diff --git a/src/boolarray.c b/src/boolarray.c
deleted file mode 100644
index 890613499200..000000000000
--- a/src/boolarray.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Fast lookup table abstraction implemented as a Guilmette Array
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdio.h>
-#include "boolarray.h"
-#include "options.h"
-
-/* Locally visible BOOL_ARRAY object. */
-
-static BOOL_ARRAY bool_array;
-
-/* Prints out debugging diagnostics. */
-
-void
-bool_array_destroy ()
-{
- if (OPTION_ENABLED (option, DEBUG))
- fprintf (stderr, "\ndumping boolean array information\niteration number = %d\nend of array dump\n",
- bool_array.iteration_number);
- free ((char *) bool_array.storage_array);
-}
-
-void
-bool_array_init (size)
- int size;
-{
- STORAGE_TYPE *xmalloc ();
- bool_array.iteration_number = 1;
- bool_array.size = size;
- bool_array.storage_array = xmalloc (size * sizeof *bool_array.storage_array);
- bzero (bool_array.storage_array, size * sizeof *bool_array.storage_array);
- if (OPTION_ENABLED (option, DEBUG))
- fprintf (stderr, "\nbool array size = %d, total bytes = %d\n",
- bool_array.size, bool_array.size * sizeof *bool_array.storage_array);
-}
-
-bool
-lookup (index)
- int index;
-{
- if (bool_array.storage_array[index] == bool_array.iteration_number)
- return 1;
- else
- {
- bool_array.storage_array[index] = bool_array.iteration_number;
- return 0;
- }
-}
-
-/* Simple enough to reset, eh?! */
-
-void
-bool_array_reset ()
-{
- /* If we wrap around it's time to zero things out again! */
-
-
- if (++bool_array.iteration_number == 0)
- {
- if (OPTION_ENABLED (option, DEBUG))
- {
- fprintf (stderr, "(re-initializing bool_array)...");
- fflush (stderr);
- }
- bool_array.iteration_number = 1;
- bzero (bool_array.storage_array, bool_array.size * sizeof *bool_array.storage_array);
- if (OPTION_ENABLED (option, DEBUG))
- {
- fprintf (stderr, "done\n");
- fflush (stderr);
- }
- }
-}
diff --git a/src/boolarray.h b/src/boolarray.h
deleted file mode 100644
index 48339755060a..000000000000
--- a/src/boolarray.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Simple lookup table abstraction implemented as a Guilmette Array.
-
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Define and implement a simple boolean array abstraction,
- uses a Guilmette array implementation to save on initialization time. */
-
-#ifndef _boolarray_h
-#define _boolarray_h
-#include "prototype.h"
-
-#ifdef LO_CAL
-/* If we are on a memory diet then we'll only make these use a limited
- amount of storage space. */
-typedef unsigned short STORAGE_TYPE;
-#else
-typedef int STORAGE_TYPE;
-#endif
-typedef struct bool_array
-{
- STORAGE_TYPE *storage_array; /* Initialization of the index space. */
- STORAGE_TYPE iteration_number; /* Keep track of the current iteration. */
- int size; /* Size of the entire array (dynamically initialized). */
-} BOOL_ARRAY;
-
-extern void bool_array_init P ((int size));
-extern void bool_array_destroy P ((void));
-extern bool lookup P ((int hash_value));
-extern void bool_array_reset P ((void));
-
-#endif /* _boolarray_h */
diff --git a/src/config.h.in b/src/config.h.in
index 4d3d76212d6c..1f3dc586b572 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -1,19 +1,20 @@
-/* config.h.in. Generated automatically from configure.in by autoheader. */
+/* config.h.in. Generated from configure.ac by autoheader. */
-/* Define if the C++ compiler supports "throw ()" declarations. */
-#undef HAVE_THROW_DECL
+/* Define if the C++ compiler supports stack-allocated variable-size arrays.
+ */
+#undef HAVE_DYNAMIC_ARRAY
-/* Define if you have the getrlimit function. */
-#undef HAVE_GETRLIMIT
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
-/* Define if you have the setrlimit function. */
-#undef HAVE_SETRLIMIT
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
-/* Define if you have the <sys/resource.h> header file. */
-#undef HAVE_SYS_RESOURCE_H
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
-/* Define if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
-/* Define if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
diff --git a/src/config.h_vms b/src/config.h_vms
new file mode 100644
index 000000000000..1f3dc586b572
--- /dev/null
+++ b/src/config.h_vms
@@ -0,0 +1,20 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if the C++ compiler supports stack-allocated variable-size arrays.
+ */
+#undef HAVE_DYNAMIC_ARRAY
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
diff --git a/src/configure b/src/configure
index edd1fd7f0520..ab7048103e08 100755
--- a/src/configure
+++ b/src/configure
@@ -1,26 +1,662 @@
#! /bin/sh
-
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+# Generated by GNU Autoconf 2.61.
#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
-# Defaults:
-ac_help=
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell autoconf@gnu.org about your system,
+ echo including any error possibly output before this
+ echo message
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
ac_default_prefix=/usr/local
-# Any additions from configure.in:
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="main.cc"
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+SET_MAKE
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CC
+EXEEXT
+OBJEXT
+CPP
+CXX
+CXXFLAGS
+ac_ct_CXX
+CXXCPP
+INSTALL
+INSTALL_PROGRAM
+INSTALL_DATA
+GPERF_LIBM
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+CXXCPP'
+
# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
# The variables have the same names as the options, with
# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
+cache_file=/dev/null
exec_prefix=NONE
-host=NONE
no_create=
-nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
@@ -29,94 +665,117 @@ program_transform_name=s,x,x,
silent=
site=
srcdir=
-target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
ac_prev=
+ac_dashdash=
for ac_option
do
-
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
+ eval $ac_prev=\$ac_option
ac_prev=
continue
fi
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
- case "$ac_option" in
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
+ bindir=$ac_optarg ;;
-build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
+ ac_prev=build_alias ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
+ build_alias=$ac_optarg ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ -datadir | --datadir | --datadi | --datad)
ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
-disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
+ expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+ eval enable_$ac_feature=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
-enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
+ expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+ eval enable_$ac_feature=\$ac_optarg ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -125,116 +784,77 @@ do
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
+ exec_prefix=$ac_optarg ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
-host | --host | --hos | --ho)
- ac_prev=host ;;
+ ac_prev=host_alias ;;
-host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
+ includedir=$ac_optarg ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
+ infodir=$ac_optarg ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
+ libdir=$ac_optarg ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
+ | --localstate | --localstat | --localsta | --localst | --locals)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
+ mandir=$ac_optarg ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
+ | --no-cr | --no-c | -n)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
@@ -248,26 +868,26 @@ EOF
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
+ oldincludedir=$ac_optarg ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
+ prefix=$ac_optarg ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
+ program_prefix=$ac_optarg ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
+ program_suffix=$ac_optarg ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
@@ -284,7 +904,17 @@ EOF
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
@@ -294,7 +924,7 @@ EOF
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
+ sbindir=$ac_optarg ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
@@ -305,58 +935,53 @@ EOF
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
+ sharedstatedir=$ac_optarg ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
+ site=$ac_optarg ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
+ srcdir=$ac_optarg ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
+ sysconfdir=$ac_optarg ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
+ ac_prev=target_alias ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
+ target_alias=$ac_optarg ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.13"
- exit 0 ;;
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
-with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
+ expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+ eval with_$ac_package=\$ac_optarg ;;
-without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
+ expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+ eval with_$ac_package=no ;;
--x)
# Obsolete; use --with-x.
@@ -367,396 +992,1478 @@ EOF
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
+ x_includes=$ac_optarg ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
+ x_libraries=$ac_optarg ;;
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
;;
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
*)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
;;
esac
done
if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
fi
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+# Be sure to have absolute directory names.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
fi
-exec 5>./config.log
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
+test "$silent" = yes && exec 6>/dev/null
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { echo "$as_me: error: Working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=gen-perf.cc
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
+ if test ! -r "$srcdir/$ac_unique_file"; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ CXXCPP C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" || continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.61
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
# Prefer explicitly selected file to automatically selected ones.
-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 -n "$CONFIG_SITE"; then
+ set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+ set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+ set x "$ac_default_prefix/share/config.site" \
+ "$ac_default_prefix/etc/config.site"
fi
-for ac_site_file in $CONFIG_SITE; do
+shift
+for ac_site_file
+do
if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
. "$ac_site_file"
fi
done
if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
else
- echo "creating cache $cache_file"
- > $cache_file
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
fi
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
fi
-else
- ac_n= ac_c='\c' ac_t=
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:527: checking whether ${MAKE-make} sets \${MAKE}" >&5
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
+set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftestmake <<\EOF
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
all:
- @echo 'ac_maketemp="${MAKE}"'
-EOF
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
-if test -n "$ac_maketemp"; then
- eval ac_cv_prog_make_${ac_make}_set=yes
-else
- eval ac_cv_prog_make_${ac_make}_set=no
-fi
-rm -f conftestmake
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
- echo "$ac_t""yes" 1>&6
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
SET_MAKE=
else
- echo "$ac_t""no" 1>&6
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
SET_MAKE="MAKE=${MAKE-make}"
fi
-# Extract the first word of "gcc", so it can be a program name with args.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # 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:556: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
fi
fi
-CC="$ac_cv_prog_CC"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
else
- echo "$ac_t""no" 1>&6
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
+
+ fi
+fi
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:586: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
- if test $# -gt 0; then
+ if test $# != 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
fi
-CC="$ac_cv_prog_CC"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
else
- echo "$ac_t""no" 1>&6
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
- if test -z "$CC"; then
- case "`uname -s`" in
- *win32* | *WIN32*)
- # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:637: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="cl"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
fi
fi
-CC="$ac_cv_prog_CC"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
else
- echo "$ac_t""no" 1>&6
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
- ;;
- esac
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
fi
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:669: 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.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 680 "configure"
-#include "confdefs.h"
-
-main(){return(0);}
-EOF
-if { (eval echo configure:685: \"$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
- ac_cv_prog_cc_cross=no
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
else
- ac_cv_prog_cc_cross=yes
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort. b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions. Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
+ ac_file=''
fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-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:711: 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
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:716: 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
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:725: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
+
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+if test -z "$ac_file"; then
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
else
- ac_cv_prog_gcc=no
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
else
- GCC=
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
fi
-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:744: 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
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
ac_cv_prog_cc_g=yes
else
- ac_cv_prog_cc_g=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
fi
-rm -f conftest*
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
+ CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
@@ -770,216 +2477,702 @@ else
CFLAGS=
fi
fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+ xno)
+ { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
- echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:776: checking how to run the C preprocessor" >&5
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 791 "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:797: \"$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
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 808 "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:814: \"$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
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
:
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -nologo -E"
- cat > conftest.$ac_ext <<EOF
-#line 825 "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:831: \"$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
- :
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
fi
-rm -f conftest*
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
fi
-rm -f conftest*
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
fi
- CPP="$ac_cv_prog_CPP"
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
else
- ac_cv_prog_CPP="$CPP"
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$CPP" 1>&6
- for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:860: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CXX"; then
ac_cv_prog_CXX="$CXX" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CXX="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
fi
fi
-CXX="$ac_cv_prog_CXX"
+CXX=$ac_cv_prog_CXX
if test -n "$CXX"; then
- echo "$ac_t""$CXX" 1>&6
+ { echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6; }
else
- echo "$ac_t""no" 1>&6
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
-test -n "$CXX" && break
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
done
-test -n "$CXX" || CXX="gcc"
+IFS=$as_save_IFS
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:892: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
-ac_ext=C
-# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cxx_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 903 "configure"
-#include "confdefs.h"
-
-int main(){return(0);}
-EOF
-if { (eval echo configure:908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cxx_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cxx_cross=no
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
else
- ac_cv_prog_cxx_cross=yes
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cxx_works=no
fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
-if test $ac_cv_prog_cxx_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 ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:934: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
-cross_compiling=$ac_cv_prog_cxx_cross
-
-echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:939: checking whether we are using GNU C++" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.C <<EOF
-#ifdef __GNUC__
- yes;
+
+ fi
+fi
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
#endif
-EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:948: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gxx=yes
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
else
- ac_cv_prog_gxx=no
-fi
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
fi
-echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
-if test $ac_cv_prog_gxx = yes; then
- GXX=yes
-else
- GXX=
fi
-
-ac_test_CXXFLAGS="${CXXFLAGS+set}"
-ac_save_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS=
-echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:967: checking whether ${CXX-g++} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
else
- echo 'void f(){}' > conftest.cc
-if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
ac_cv_prog_cxx_g=yes
else
- ac_cv_prog_cxx_g=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest*
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS="$ac_save_CXXFLAGS"
+ CXXFLAGS=$ac_save_CXXFLAGS
elif test $ac_cv_prog_cxx_g = yes; then
if test "$GXX" = yes; then
CXXFLAGS="-g -O2"
@@ -993,49 +3186,237 @@ else
CXXFLAGS=
fi
fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
- echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
-echo "configure:999: checking how to run the C++ preprocessor" >&5
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
if test -z "$CXXCPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ if test "${ac_cv_prog_CXXCPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- ac_ext=C
-# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cxx_cross
- CXXCPP="${CXX-g++} -E"
- cat > conftest.$ac_ext <<EOF
-#line 1012 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1017: \"$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
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
:
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CXXCPP=/lib/cpp
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
fi
-rm -f conftest*
- ac_cv_prog_CXXCPP="$CXXCPP"
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
-CXXCPP="$ac_cv_prog_CXXCPP"
-echo "$ac_t""$CXXCPP" 1>&6
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -1047,11 +3428,11 @@ echo "$ac_t""$CXXCPP" 1>&6
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# 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:1052: checking for a BSD compatible install" >&5
+{ echo "$as_me:$LINENO: checking for a BSD compatible install" >&5
+echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6; }
if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'cl_cv_path_install'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test "${cl_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
@@ -1089,7 +3470,8 @@ else
fi
INSTALL="$cl_cv_path_install"
fi
-echo "$ac_t""$INSTALL" 1>&6
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='$(INSTALL)'
@@ -1100,561 +3482,1244 @@ if test -z "$INSTALL_DATA"; then
esac
fi
- echo $ac_n "checking for working throw()""... $ac_c" 1>&6
-echo "configure:1105: checking for working throw()" >&5
-if eval "test \"`echo '$''{'gp_cv_cxx_throw_decl'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ { echo "$as_me:$LINENO: checking for stack-allocated variable-size arrays" >&5
+echo $ECHO_N "checking for stack-allocated variable-size arrays... $ECHO_C" >&6; }
+
+if test "${gp_cv_cxx_dynamic_array+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
-
-ac_ext=C
-# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+
+ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cxx_cross
-
-cat > conftest.$ac_ext <<EOF
-#line 1119 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-void operator delete (void* ptr) throw() {}
-int main() {
-
-; return 0; }
-EOF
-if { (eval echo configure:1127: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- gp_cv_cxx_throw_decl=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gp_cv_cxx_throw_decl=no
-fi
-rm -f conftest*
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int func (int n) { int dynamic_array[n]; }
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ gp_cv_cxx_dynamic_array=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ gp_cv_cxx_dynamic_array=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
-echo "$ac_t""$gp_cv_cxx_throw_decl" 1>&6
-if test $gp_cv_cxx_throw_decl = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_THROW_DECL 1
-EOF
-
-fi
-for ac_hdr in unistd.h sys/time.h sys/resource.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1158: 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 1163 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1168: \"$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
+{ echo "$as_me:$LINENO: result: $gp_cv_cxx_dynamic_array" >&5
+echo "${ECHO_T}$gp_cv_cxx_dynamic_array" >&6; }
+if test $gp_cv_cxx_dynamic_array = yes; then
- if test $ac_cv_header_sys_resource_h = yes; then
-for ac_func in getrlimit
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1198: 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 1203 "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
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DYNAMIC_ARRAY 1
+_ACEOF
-; return 0; }
-EOF
-if { (eval echo configure:1226: \"$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
-
+{ echo "$as_me:$LINENO: checking for rand in -lm" >&5
+echo $ECHO_N "checking for rand in -lm... $ECHO_C" >&6; }
+if test "${ac_cv_lib_m_rand+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- echo "$ac_t""no" 1>&6
-fi
-done
-
- if test $ac_cv_func_getrlimit = yes; then
-for ac_func in setrlimit
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1254: 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 1259 "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();
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1282: \"$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"
+char rand ();
+int
+main ()
+{
+return rand ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_m_rand=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*
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_m_rand=no
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
-
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_rand" >&5
+echo "${ECHO_T}$ac_cv_lib_m_rand" >&6; }
+if test $ac_cv_lib_m_rand = yes; then
+ GPERF_LIBM="-lm"
else
- echo "$ac_t""no" 1>&6
+ GPERF_LIBM=""
fi
-done
- fi
-fi
-trap '' 1 2 15
-cat > confcache <<\EOF
+
+ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
#
-EOF
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
+# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote substitution
- # turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
else
- echo "not updating unwritable cache $cache_file"
+ { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
fi
fi
rm -f confcache
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
+DEFS=-DHAVE_CONFIG_H
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
-DEFS=-DHAVE_CONFIG_H
+LTLIBOBJS=$ac_ltlibobjs
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.13"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
+fi
-ac_given_srcdir=$srcdir
-trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@SET_MAKE@%$SET_MAKE%g
-s%@CC@%$CC%g
-s%@CPP@%$CPP%g
-s%@CXX@%$CXX%g
-s%@CXXCPP@%$CXXCPP%g
-s%@INSTALL@%$INSTALL%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
else
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ PATH_SEPARATOR=:
fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
else
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
fi
done
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
else
- ac_dir_suffix= ac_dots=
+ as_ls_L_option=
fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.61,
+ with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
esac
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ { echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ CONFIG_SHELL=$SHELL
+ export CONFIG_SHELL
+ exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-if test "${CONFIG_HEADERS+set}" != set; then
-EOF
-cat >> $CONFIG_STATUS <<EOF
- CONFIG_HEADERS="config.h"
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-fi
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+SET_MAKE!$SET_MAKE$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+CPP!$CPP$ac_delim
+CXX!$CXX$ac_delim
+CXXFLAGS!$CXXFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
+CXXCPP!$CXXCPP$ac_delim
+INSTALL!$INSTALL$ac_delim
+INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
+INSTALL_DATA!$INSTALL_DATA$ac_delim
+GPERF_LIBM!$GPERF_LIBM$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 56; then
+ break
+ elif $ac_last_try; then
+ { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+ ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+ ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ ac_file_inputs="$ac_file_inputs $ac_f"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input="Generated from "`IFS=:
+ echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ fi
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin";;
+ esac
+ ;;
esac
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- cat $ac_file_inputs > conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments. This is necessary, for
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out"; rm -f "$tmp/out";;
+ *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+ esac
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+_ACEOF
+
+# Transform confdefs.h into a sed script `conftest.defines', that
+# substitutes the proper values into config.h.in to produce config.h.
+rm -f conftest.defines conftest.tail
+# First, append a space to every undef/define line, to ease matching.
+echo 's/$/ /' >conftest.defines
+# Then, protect against being on the right side of a sed subst, or in
+# an unquoted here document, in config.status. If some macros were
+# called several times there might be several #defines for the same
+# symbol, which is useless. But do not sort them, since the last
+# AC_DEFINE must be honored.
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
+# NAME is the cpp macro being defined, VALUE is the value it is being given.
+# PARAMS is the parameter list in the macro definition--in most cases, it's
+# just an empty string.
+ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*'
+ac_dB='\\)[ (].*,\\1define\\2'
+ac_dC=' '
+ac_dD=' ,'
+
+uniq confdefs.h |
+ sed -n '
+ t rset
+ :rset
+ s/^[ ]*#[ ]*define[ ][ ]*//
+ t ok
+ d
+ :ok
+ s/[\\&,]/\\&/g
+ s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
+ s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
+ ' >>conftest.defines
+
+# Remove the space that was appended to ease matching.
+# Then replace #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
+# (The regexp can be short, since the line contains either #define or #undef.)
+echo 's/ $//
+s,^[ #]*u.*,/* & */,' >>conftest.defines
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
+# Break up conftest.defines:
+ac_max_sed_lines=50
+
+# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1"
+# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2"
+# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1"
+# et cetera.
+ac_in='$ac_file_inputs'
+ac_out='"$tmp/out1"'
+ac_nxt='"$tmp/out2"'
-rm -f conftest.tail
while :
do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ # Write a here document:
+ cat >>$CONFIG_STATUS <<_ACEOF
+ # First, check the format of the line:
+ cat >"\$tmp/defines.sed" <<\\CEOF
+/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def
+/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def
+b
+:def
+_ACEOF
+ sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
+ sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
+ ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
+ sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
+ grep . conftest.tail >/dev/null || break
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
- else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
+rm -f conftest.defines conftest.tail
+
+echo "ac_result=$ac_in" >>$CONFIG_STATUS
+cat >>$CONFIG_STATUS <<\_ACEOF
+ if test x"$ac_file" != x-; then
+ echo "/* $configure_input */" >"$tmp/config.h"
+ cat "$ac_result" >>"$tmp/config.h"
+ if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f $ac_file
+ mv "$tmp/config.h" $ac_file
fi
- rm -f $ac_file
- mv conftest.h $ac_file
+ else
+ echo "/* $configure_input */"
+ cat "$ac_result"
fi
-fi; done
+ rm -f "$tmp/out12"
+ ;;
+
-EOF
-cat >> $CONFIG_STATUS <<EOF
+ esac
+
+done # for ac_tag
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-exit 0
-EOF
+{ (exit 0); exit 0; }
+_ACEOF
chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
diff --git a/src/configure.in b/src/configure.ac
index e8880d507f85..b7b91a0b191e 100644
--- a/src/configure.in
+++ b/src/configure.ac
@@ -1,13 +1,14 @@
dnl autoconf configuration for gperf/src
-dnl Copyright (C) 1998, 2000 Free Software Foundation, Inc.
-dnl written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+dnl Copyright (C) 1998, 2000, 2002-2003, 2007 Free Software Foundation, Inc.
+dnl Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+dnl and Bruno Haible <bruno@clisp.org>.
dnl
dnl This file is part of GNU GPERF.
dnl
dnl GNU GPERF is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
-dnl the Free Software Foundation; either version 1, or (at your option)
+dnl the Free Software Foundation; either version 2, or (at your option)
dnl any later version.
dnl
dnl GNU GPERF is distributed in the hope that it will be useful,
@@ -16,11 +17,12 @@ dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
-dnl along with GNU GPERF; see the file COPYING. If not, write to the
-dnl Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-dnl MA 02111-1307, USA.
+dnl along with this program; see the file COPYING.
+dnl If not, write to the Free Software Foundation, Inc.,
+dnl 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-AC_INIT(gen-perf.cc)
+AC_PREREQ([2.60])
+AC_INIT(main.cc)
AC_CONFIG_HEADER(config.h)
AC_PROG_MAKE_SET
dnl
@@ -39,32 +41,27 @@ CL_PROG_INSTALL
dnl
dnl checks for compiler characteristics
dnl
-AC_MSG_CHECKING([for working throw()])
-AC_CACHE_VAL(gp_cv_cxx_throw_decl,[
+AC_MSG_CHECKING([for stack-allocated variable-size arrays])
+AC_CACHE_VAL(gp_cv_cxx_dynamic_array, [
AC_LANG_SAVE()
AC_LANG_CPLUSPLUS()
-AC_TRY_COMPILE([#include <stdlib.h>
-void operator delete (void* ptr) throw() {}], [],
-gp_cv_cxx_throw_decl=yes, gp_cv_cxx_throw_decl=no)
+AC_TRY_COMPILE([int func (int n) { int dynamic_array[n]; }], [],
+gp_cv_cxx_dynamic_array=yes, gp_cv_cxx_dynamic_array=no)
AC_LANG_RESTORE()
])
-AC_MSG_RESULT([$]gp_cv_cxx_throw_decl)
-if test [$]gp_cv_cxx_throw_decl = yes; then
- AC_DEFINE(HAVE_THROW_DECL)
+AC_MSG_RESULT($gp_cv_cxx_dynamic_array)
+if test $gp_cv_cxx_dynamic_array = yes; then
+ AC_DEFINE(HAVE_DYNAMIC_ARRAY, 1,
+ [Define if the C++ compiler supports stack-allocated variable-size arrays.])
fi
dnl
dnl checks for functions and declarations
dnl
-AC_CHECK_HEADERS(unistd.h sys/time.h sys/resource.h)
- dnl DEFs HAVE_UNISTD_H, HAVE_SYS_TIME_H, HAVE_SYS_RESOURCE_H
-if test $ac_cv_header_sys_resource_h = yes; then
-AC_CHECK_FUNCS(getrlimit)
- dnl DEFS HAVE_GETRLIMIT
-if test $ac_cv_func_getrlimit = yes; then
-AC_CHECK_FUNCS(setrlimit)
- dnl DEFS HAVE_SETRLIMIT
-fi
-fi
+dnl
+dnl checks for libraries
+dnl
+AC_CHECK_LIB(m, rand, GPERF_LIBM="-lm", GPERF_LIBM="")
+AC_SUBST(GPERF_LIBM)
dnl
dnl That's it.
dnl
diff --git a/src/gen-perf.cc b/src/gen-perf.cc
deleted file mode 100644
index 0b5109d4ff4d..000000000000
--- a/src/gen-perf.cc
+++ /dev/null
@@ -1,359 +0,0 @@
-/* Provides high-level routines to manipulate the keywork list
- structures the code generation output.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include <stdio.h>
-#include <stdlib.h> /* declares rand(), srand() */
-#include <time.h> /* declares time() */
-#include "options.h"
-#include "gen-perf.h"
-#include "trace.h"
-
-/* Efficiently returns the least power of two greater than or equal to X! */
-#define POW(X) ((!X)?1:(X-=1,X|=X>>1,X|=X>>2,X|=X>>4,X|=X>>8,X|=X>>16,(++X)))
-
-/* Reads input keys, possibly applies the reordering heuristic, sets the
- maximum associated value size (rounded up to the nearest power of 2),
- may initialize the associated values array, and determines the maximum
- hash table size. Note: using the random numbers is often helpful,
- though not as deterministic, of course! */
-
-Gen_Perf::Gen_Perf (void)
-{
- T (Trace t ("Gen_Perf::Gen_Perf");)
- int asso_value_max;
- int non_linked_length;
-
- Key_List::read_keys ();
- if (option[ORDER])
- reorder ();
- asso_value_max = option.get_asso_max ();
- non_linked_length = Key_List::keyword_list_length ();
- num_done = 1;
- fewest_collisions = 0;
- if (asso_value_max == 0)
- asso_value_max = non_linked_length;
- else if (asso_value_max > 0)
- asso_value_max *= non_linked_length;
- else /* if (asso_value_max < 0) */
- asso_value_max = non_linked_length / -asso_value_max;
- option.set_asso_max (POW (asso_value_max));
-
- if (option[RANDOM])
- {
- srand ((long) time (0));
-
- for (int i = 0; i < ALPHA_SIZE; i++)
- asso_values[i] = (rand () & asso_value_max - 1);
- }
- else
- {
- int asso_value = option.initial_value ();
-
- if (asso_value) /* Initialize array if user requests non-zero default. */
- for (int i = ALPHA_SIZE - 1; i >= 0; i--)
- asso_values[i] = asso_value & option.get_asso_max () - 1;
- }
- max_hash_value = Key_List::max_key_length () + option.get_asso_max () *
- option.get_max_keysig_size ();
-
- if (option[DEBUG])
- fprintf (stderr, "total non-linked keys = %d\nmaximum associated value is %d"
- "\nmaximum size of generated hash table is %d\n",
- non_linked_length, asso_value_max, max_hash_value);
-}
-
-/* Merge two disjoint hash key multisets to form the ordered disjoint union of the sets.
- (In a multiset, an element can occur multiple times.)
- Precondition: both set_1 and set_2 must be ordered. Returns the length
- of the combined set. */
-
-inline int
-Gen_Perf::compute_disjoint_union (const char *set_1, int size_1, const char *set_2, int size_2, char *set_3)
-{
- T (Trace t ("Gen_Perf::compute_disjoint_union");)
- char *base = set_3;
-
- while (size_1 > 0 && size_2 > 0)
- if (*set_1 == *set_2)
- set_1++, size_1--, set_2++, size_2--;
- else
- {
- char next;
- if (*set_1 < *set_2)
- next = *set_1++, size_1--;
- else
- next = *set_2++, size_2--;
- if (set_3 == base || next != set_3[-1])
- *set_3++ = next;
- }
-
- while (size_1 > 0)
- {
- char next;
- next = *set_1++, size_1--;
- if (set_3 == base || next != set_3[-1])
- *set_3++ = next;
- }
-
- while (size_2 > 0)
- {
- char next;
- next = *set_2++, size_2--;
- if (set_3 == base || next != set_3[-1])
- *set_3++ = next;
- }
- return set_3 - base;
-}
-
-/* Sort the UNION_SET in increasing frequency of occurrence.
- This speeds up later processing since we may assume the resulting
- set (Set_3, in this case), is ordered. Uses insertion sort, since
- the UNION_SET is typically short. */
-
-inline void
-Gen_Perf::sort_set (char *union_set, int len)
-{
- T (Trace t ("Gen_Perf::sort_set");)
- int i, j;
-
- for (i = 0, j = len - 1; i < j; i++)
- {
- int curr;
- char tmp;
-
- for (curr = i + 1, tmp = union_set[curr];
- curr > 0 && occurrences[(unsigned char)tmp] < occurrences[(unsigned char)(union_set[curr-1])];
- curr--)
- union_set[curr] = union_set[curr - 1];
-
- union_set[curr] = tmp;
- }
-}
-
-/* Generate a key set's hash value. */
-
-inline int
-Gen_Perf::hash (List_Node *key_node)
-{
- T (Trace t ("Gen_Perf::hash");)
- int sum = option[NOLENGTH] ? 0 : key_node->key_length;
-
- const char *p = key_node->char_set;
- int i = key_node->char_set_length;
- for (; i > 0; p++, i--)
- sum += asso_values[(unsigned char)(*p)];
-
- return key_node->hash_value = sum;
-}
-
-/* Find out how character value change affects successfully hashed items.
- Returns FALSE if no other hash values are affected, else returns TRUE.
- Note that because Option.Get_Asso_Max is a power of two we can guarantee
- that all legal Asso_Values are visited without repetition since
- Option.Get_Jump was forced to be an odd value! */
-
-inline int
-Gen_Perf::affects_prev (char c, List_Node *curr)
-{
- T (Trace t ("Gen_Perf::affects_prev");)
- int original_char = asso_values[(unsigned char)c];
- int total_iterations = !option[FAST]
- ? option.get_asso_max () : option.get_iterations () ? option.get_iterations () : keyword_list_length ();
-
- /* Try all legal associated values. */
-
- for (int i = total_iterations - 1; i >= 0; i--)
- {
- int collisions = 0;
-
- asso_values[(unsigned char)c] =
- (asso_values[(unsigned char)c] + (option.get_jump () ? option.get_jump () : rand ()))
- & (option.get_asso_max () - 1);
-
- /* Iteration Number array is a win, O(1) intialization time! */
- reset ();
-
- /* See how this asso_value change affects previous keywords. If
- it does better than before we'll take it! */
-
- for (List_Node *ptr = head;
- !Bool_Array::find (hash (ptr)) || ++collisions < fewest_collisions;
- ptr = ptr->next)
- if (ptr == curr)
- {
- fewest_collisions = collisions;
- if (option[DEBUG])
- fprintf (stderr, "- resolved after %d iterations", total_iterations - i);
- return 0;
- }
- }
-
- /* Restore original values, no more tries. */
- asso_values[(unsigned char)c] = original_char;
- /* If we're this far it's time to try the next character.... */
- return 1;
-}
-
-/* Change a character value, try least-used characters first. */
-
-void
-Gen_Perf::change (List_Node *prior, List_Node *curr)
-{
- T (Trace t ("Gen_Perf::change");)
- static char *union_set;
- int union_set_length;
-
- if (!union_set)
- union_set = new char [2 * option.get_max_keysig_size ()];
-
- if (option[DEBUG])
- {
- fprintf (stderr, "collision on keyword #%d, prior = \"%.*s\", curr = \"%.*s\" hash = %d\n",
- num_done,
- prior->key_length, prior->key,
- curr->key_length, curr->key,
- curr->hash_value);
- fflush (stderr);
- }
- union_set_length = compute_disjoint_union (prior->char_set, prior->char_set_length, curr->char_set, curr->char_set_length, union_set);
- sort_set (union_set, union_set_length);
-
- /* Try changing some values, if change doesn't alter other values continue normal action. */
- fewest_collisions++;
-
- const char *p = union_set;
- int i = union_set_length;
- for (; i > 0; p++, i--)
- if (!affects_prev (*p, curr))
- {
- if (option[DEBUG])
- {
- fprintf (stderr, " by changing asso_value['%c'] (char #%d) to %d\n",
- *p, p - union_set + 1, asso_values[(unsigned char)(*p)]);
- fflush (stderr);
- }
- return; /* Good, doesn't affect previous hash values, we'll take it. */
- }
-
- for (List_Node *ptr = head; ptr != curr; ptr = ptr->next)
- hash (ptr);
-
- hash (curr);
-
- if (option[DEBUG])
- {
- fprintf (stderr, "** collision not resolved after %d iterations, %d duplicates remain, continuing...\n",
- !option[FAST] ? option.get_asso_max () : option.get_iterations () ? option.get_iterations () : keyword_list_length (),
- fewest_collisions + total_duplicates);
- fflush (stderr);
- }
-}
-
-/* Does the hard stuff....
- Initializes the Iteration Number array, and attempts to find a perfect
- function that will hash all the key words without getting any
- duplications. This is made much easier since we aren't attempting
- to generate *minimum* functions, only perfect ones.
- If we can't generate a perfect function in one pass *and* the user
- hasn't enabled the DUP option, we'll inform the user to try the
- randomization option, use -D, or choose alternative key positions.
- The alternatives (e.g., back-tracking) are too time-consuming, i.e,
- exponential in the number of keys. */
-
-int
-Gen_Perf::operator() (void)
-{
- T (Trace t ("Gen_Perf::operator()");)
-#if LARGE_STACK_ARRAYS
- STORAGE_TYPE buffer[max_hash_value + 1];
-#else
- // Note: we don't use new, because that invokes a custom operator new.
- STORAGE_TYPE *buffer
- = (STORAGE_TYPE*) malloc (sizeof(STORAGE_TYPE) * (max_hash_value + 1));
- if (buffer == NULL)
- abort ();
-#endif
-
- Bool_Array::init (buffer, max_hash_value + 1);
-
- List_Node *curr;
- for (curr = head; curr; curr = curr->next)
- {
- hash (curr);
-
- for (List_Node *ptr = head; ptr != curr; ptr = ptr->next)
- if (ptr->hash_value == curr->hash_value)
- {
- change (ptr, curr);
- break;
- }
- num_done++;
- }
-
- /* Make one final check, just to make sure nothing weird happened.... */
-
- Bool_Array::reset ();
-
- for (curr = head; curr; curr = curr->next)
- if (Bool_Array::find (hash (curr)))
- if (option[DUP]) /* Keep track of this number... */
- total_duplicates++;
- else /* Yow, big problems. we're outta here! */
- {
- fprintf (stderr, "\nInternal error, duplicate value %d:\n"
- "try options -D or -r, or use new key positions.\n\n", hash (curr));
-#if !LARGE_STACK_ARRAYS
- free ((char *) buffer);
-#endif
- return 1;
- }
-
- /* Sorts the key word list by hash value, and then outputs the list.
- The generated hash table code is only output if the early stage of
- processing turned out O.K. */
-
- sort ();
- output ();
-#if !LARGE_STACK_ARRAYS
- free ((char *) buffer);
-#endif
- return 0;
-}
-
-/* Prints out some diagnostics upon completion. */
-
-Gen_Perf::~Gen_Perf (void)
-{
- T (Trace t ("Gen_Perf::~Gen_Perf");)
- if (option[DEBUG])
- {
- fprintf (stderr, "\ndumping occurrence and associated values tables\n");
-
- for (int i = 0; i < ALPHA_SIZE; i++)
- if (occurrences[i])
- fprintf (stderr, "asso_values[%c] = %6d, occurrences[%c] = %6d\n",
- i, asso_values[i], i, occurrences[i]);
-
- fprintf (stderr, "end table dumping\n");
-
- }
-}
-
diff --git a/src/gen-perf.h b/src/gen-perf.h
deleted file mode 100644
index 602d160131d3..000000000000
--- a/src/gen-perf.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This may look like C code, but it is really -*- C++ -*- */
-
-/* Provides high-level routines to manipulate the keyword list
- structures the code generation output.
-
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#ifndef gen_perf_h
-#define gen_perf_h 1
-
-#include "key-list.h"
-#include "bool-array.h"
-
-class Gen_Perf : private Key_List, private Bool_Array
-{
-private:
- int max_hash_value; /* Maximum possible hash value. */
- int fewest_collisions; /* Records fewest # of collisions for asso value. */
- int num_done; /* Number of keywords processed without a collision. */
-
- void change (List_Node *prior, List_Node *curr);
- int affects_prev (char c, List_Node *curr);
- static int hash (List_Node *key_node);
- static int compute_disjoint_union (const char *set_1, int size_1, const char *set_2, int size_2, char *set_3);
- static void sort_set (char *union_set, int len);
-
-public:
- Gen_Perf (void);
- ~Gen_Perf (void);
- int operator () (void);
-};
-
-#endif
diff --git a/src/getopt.c b/src/getopt.c
deleted file mode 100644
index 4eb3c2090887..000000000000
--- a/src/getopt.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/* Getopt for GNU.
- Copyright (C) 1987, 1989 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of `argv' so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include <stdio.h>
-
-#ifdef sparc
-#include <alloca.h>
-#endif
-#ifdef USG
-#define bcopy(s, d, l) memcpy((d), (s), (l))
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = 0;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-int optind = 0;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- UNSPECIFIED means the caller did not specify anything;
- the default is then REQUIRE_ORDER if the environment variable
- _OPTIONS_FIRST is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options.
- Stop option processing when the first non-option is seen.
- This is what Unix does.
-
- PERMUTE is the default. We permute the contents of `argv' as we scan,
- so that eventually all the options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code zero.
- Using `-' as the first character of the list of option characters
- requests this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return EOF with `optind' != ARGC. */
-
-static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-static void
-exchange (argv)
- char **argv;
-{
- int nonopts_size
- = (last_nonopt - first_nonopt) * sizeof (char *);
- char **temp = (char **) alloca (nonopts_size);
-
- /* Interchange the two blocks of data in argv. */
-
- bcopy (&argv[first_nonopt], temp, nonopts_size);
- bcopy (&argv[last_nonopt], &argv[first_nonopt],
- (optind - last_nonopt) * sizeof (char *));
- bcopy (temp, &argv[first_nonopt + optind - last_nonopt],
- nonopts_size);
-
- /* Update records for the slots the non-options now occupy. */
-
- first_nonopt += (optind - last_nonopt);
- last_nonopt = optind;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of theoption characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns `EOF'.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- A colon in OPTSTRING means that the previous character is an option
- that wants an argument. The argument is taken from the rest of the
- current ARGV-element, or from the following ARGV-element,
- and returned in `optarg'.
-
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg'.
-
- If OPTSTRING starts with `-', it requests a different method of handling the
- non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
-
-int
-getopt (argc, argv, optstring)
- int argc;
- char **argv;
- char *optstring;
-{
- /* Initialize the internal data when the first call is made.
- Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- if (optind == 0)
- {
- first_nonopt = last_nonopt = optind = 1;
-
- nextchar = 0;
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- ordering = RETURN_IN_ORDER;
- else if (getenv ("_POSIX_OPTION_ORDER") != 0)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
- }
-
- if (nextchar == 0 || *nextchar == 0)
- {
- if (ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange (argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Now skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (optind < argc
- && (argv[optind][0] != '-'
- || argv[optind][1] == 0))
- optind++;
- last_nonopt = optind;
- }
-
- /* Special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp (argv[optind], "--"))
- {
- optind++;
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange (argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return EOF;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if (argv[optind][0] != '-' || argv[optind][1] == 0)
- {
- if (ordering == REQUIRE_ORDER)
- return EOF;
- optarg = argv[optind++];
- return 0;
- }
-
- /* We have found another option-ARGV-element.
- Start decoding its characters. */
-
- nextchar = argv[optind] + 1;
- }
-
- /* Look at and handle the next option-character. */
-
- {
- char c = *nextchar++;
- char *temp = (char *) index (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*nextchar == 0)
- optind++;
-
- if (temp == 0 || c == ':')
- {
- if (opterr != 0)
- {
- if (c < 040 || c >= 0177)
- fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
- argv[0], c);
- else
- fprintf (stderr, "%s: unrecognized option `-%c'\n",
- argv[0], c);
- }
- return '?';
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != 0)
- {
- optarg = nextchar;
- optind++;
- }
- else
- optarg = 0;
- nextchar = 0;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*nextchar != 0)
- {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- }
- else if (optind == argc)
- {
- if (opterr != 0)
- fprintf (stderr, "%s: no argument for `-%c' option\n",
- argv[0], c);
- c = '?';
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = 0;
- }
- }
- return c;
- }
-}
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- char c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind;
- if ((c = getopt (argc, argv, "abc:d:0123456789")) == EOF)
- break;
-
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- return 0;
-}
-
-#endif /* TEST */
diff --git a/src/gperf-to-do b/src/gperf-to-do
deleted file mode 100644
index 05caecca9dbd..000000000000
--- a/src/gperf-to-do
+++ /dev/null
@@ -1,22 +0,0 @@
-1. provide output diagnostics that explain how many input keys total,
- how many after dealing with static links, and finally, after the
- algorithm is complete, how many dynamic duplicates do we now
- have.
-2. fix up GATHER_STATISTICS for all instrumentation.
-3. Useful idea:
-
- a. Generate the wordlist as a contiguous block of keywords, as before.
- This wordlist *must* be sorted by hash value.
-
- b. generate the lookup_array, which are an array of signed {chars,shorts,ints},
- which ever allows full coverage of the wordlist dimensions. If the
- value v, where v = lookup_array[hash(str,len)], is >= 0, then we
- simply use this result as a direct access into wordlist to snag
- the keyword for comparison.
-
- c. Otherwise, if v is < 0 this is an indication that we'll need to
- search through some number of duplicates hash values. Using a
- hash linking scheme we'd then index into a duplicate_address
- table that would provide the starting index and total length of
- the duplicate entries to consider sequentially.
-
diff --git a/src/hash-table.cc b/src/hash-table.cc
index a147674b3074..d98d90a21109 100644
--- a/src/hash-table.cc
+++ b/src/hash-table.cc
@@ -1,95 +1,167 @@
/* Hash table for checking keyword links. Implemented using double hashing.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+/* Specification. */
#include "hash-table.h"
#include <stdio.h>
#include <string.h> /* declares memset(), strcmp() */
#include <hash.h>
#include "options.h"
-#include "trace.h"
-
-/* The size of the hash table is always the smallest power of 2 >= the size
- indicated by the user. This allows several optimizations, including
- the use of double hashing and elimination of the mod instruction.
- Note that the size had better be larger than the number of items
- in the hash table, else there's trouble!!! Note that the memory
- for the hash table is allocated *outside* the intialization routine.
- This compromises information hiding somewhat, but greatly reduces
- memory fragmentation, since we can now use alloca! */
-
-Hash_Table::Hash_Table (List_Node **table_ptr, int s, int ignore_len):
- table (table_ptr), size (s), collisions (0), ignore_length (ignore_len)
-{
- T (Trace t ("Hash_Table::Hash_Table");)
- memset ((char *) table, 0, size * sizeof (*table));
-}
-Hash_Table::~Hash_Table (void)
+/* We use a hash table with double hashing. This is the simplest kind of
+ hash table, given that we always only insert and never remove entries
+ from the hash table. */
+
+/* To make double hashing efficient, there need to be enough spare entries. */
+static const int size_factor = 10;
+
+/* We make the size of the hash table a power of 2. This allows for two
+ optimizations: It eliminates the modulo instruction, and allows for an
+ easy secondary hashing function. */
+
+/* Constructor. */
+Hash_Table::Hash_Table (unsigned int size, bool ignore_length)
+ : _ignore_length (ignore_length),
+ _collisions (0)
{
- T (Trace t ("Hash_Table::~Hash_Table");)
- if (option[DEBUG])
+ /* There need to be enough spare entries. */
+ size = size * size_factor;
+
+ /* Find smallest power of 2 that is >= size. */
+ unsigned int shift = 0;
+ if ((size >> 16) > 0)
+ {
+ size = size >> 16;
+ shift += 16;
+ }
+ if ((size >> 8) > 0)
+ {
+ size = size >> 8;
+ shift += 8;
+ }
+ if ((size >> 4) > 0)
+ {
+ size = size >> 4;
+ shift += 4;
+ }
+ if ((size >> 2) > 0)
+ {
+ size = size >> 2;
+ shift += 2;
+ }
+ if ((size >> 1) > 0)
{
- int field_width = option.get_max_keysig_size ();
-
- fprintf (stderr,
- "\ndumping the hash table\n"
- "total available table slots = %d, total bytes = %d, total collisions = %d\n"
- "location, %*s, keyword\n",
- size, size * (int) sizeof (*table), collisions,
- field_width, "keysig");
-
- for (int i = size - 1; i >= 0; i--)
- if (table[i])
- fprintf (stderr, "%8d, %*.*s, %.*s\n",
- i,
- field_width, table[i]->char_set_length, table[i]->char_set,
- table[i]->key_length, table[i]->key);
-
- fprintf (stderr, "\nend dumping hash table\n\n");
+ size = size >> 1;
+ shift += 1;
}
+ _log_size = shift;
+ _size = 1 << shift;
+
+ /* Allocate table. */
+ _table = new KeywordExt*[_size];
+ memset (_table, 0, _size * sizeof (*_table));
}
-/* If the ITEM is already in the hash table return the item found
- in the table. Otherwise inserts the ITEM, and returns FALSE.
- Uses double hashing. */
+/* Destructor. */
+Hash_Table::~Hash_Table ()
+{
+ delete[] _table;
+}
-List_Node *
-Hash_Table::insert (List_Node *item)
+/* Print the table's contents. */
+void
+Hash_Table::dump () const
{
- T (Trace t ("Hash_Table::operator()");)
- unsigned hash_val = hashpjw (item->char_set, item->char_set_length);
- int probe = hash_val & (size - 1);
- int increment = ((hash_val ^ item->key_length) | 1) & (size - 1);
+ int field_width;
+
+ field_width = 0;
+ {
+ for (int i = _size - 1; i >= 0; i--)
+ if (_table[i])
+ if (field_width < _table[i]->_selchars_length)
+ field_width = _table[i]->_selchars_length;
+ }
+
+ fprintf (stderr,
+ "\ndumping the hash table\n"
+ "total available table slots = %d, total bytes = %d, total collisions = %d\n"
+ "location, %*s, keyword\n",
+ _size, _size * static_cast<unsigned int>(sizeof (*_table)),
+ _collisions, field_width, "keysig");
+
+ for (int i = _size - 1; i >= 0; i--)
+ if (_table[i])
+ {
+ fprintf (stderr, "%8d, ", i);
+ if (field_width > _table[i]->_selchars_length)
+ fprintf (stderr, "%*s", field_width - _table[i]->_selchars_length, "");
+ for (int j = 0; j < _table[i]->_selchars_length; j++)
+ putc (_table[i]->_selchars[j], stderr);
+ fprintf (stderr, ", %.*s\n",
+ _table[i]->_allchars_length, _table[i]->_allchars);
+ }
+
+ fprintf (stderr, "\nend dumping hash table\n\n");
+}
- while (table[probe])
+/* Compares two items. */
+inline bool
+Hash_Table::equal (KeywordExt *item1, KeywordExt *item2) const
+{
+ return item1->_selchars_length == item2->_selchars_length
+ && memcmp (item1->_selchars, item2->_selchars,
+ item2->_selchars_length * sizeof (unsigned int))
+ == 0
+ && (_ignore_length
+ || item1->_allchars_length == item2->_allchars_length);
+}
+
+/* Attempts to insert ITEM in the table. If there is already an equal
+ entry in it, returns it. Otherwise inserts ITEM and returns NULL. */
+KeywordExt *
+Hash_Table::insert (KeywordExt *item)
+{
+ unsigned hash_val =
+ hashpjw (reinterpret_cast<const unsigned char *>(item->_selchars),
+ item->_selchars_length * sizeof (unsigned int));
+ unsigned int probe = hash_val & (_size - 1);
+ unsigned int increment =
+ (((hash_val >> _log_size)
+ ^ (_ignore_length ? 0 : item->_allchars_length))
+ << 1) + 1;
+ /* Note that because _size is a power of 2 and increment is odd,
+ we have gcd(increment,_size) = 1, which guarantees that we'll find
+ an empty entry during the loop. */
+
+ while (_table[probe] != NULL)
{
- if (table[probe]->char_set_length == item->char_set_length
- && memcmp (table[probe]->char_set, item->char_set, item->char_set_length) == 0
- && (ignore_length || table[probe]->key_length == item->key_length))
- return table[probe];
+ if (equal (_table[probe], item))
+ return _table[probe];
- collisions++;
- probe = (probe + increment) & (size - 1);
+ _collisions++;
+ probe = (probe + increment) & (_size - 1);
}
- table[probe] = item;
- return (List_Node *) 0;
+ _table[probe] = item;
+ return NULL;
}
diff --git a/src/hash-table.h b/src/hash-table.h
index 86438d00f7d6..d6938eb4d1f0 100644
--- a/src/hash-table.h
+++ b/src/hash-table.h
@@ -2,42 +2,65 @@
/* Hash table used to check for duplicate keyword entries.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef hash_table_h
#define hash_table_h 1
-#include "list-node.h"
+#include "keyword.h"
+
+/* Hash table of KeywordExt* entries.
+ Two entries are considered equal if their _selchars are the same and
+ - if !ignore_length - if their _allchars_length are the same. */
class Hash_Table
{
+public:
+ /* Constructor.
+ size is the maximum number of entries.
+ ignore_length determines a detail in the comparison function. */
+ Hash_Table (unsigned int size, bool ignore_length);
+ /* Destructor. */
+ ~Hash_Table ();
+ /* Attempts to insert ITEM in the table. If there is already an equal
+ entry in it, returns it. Otherwise inserts ITEM and returns NULL. */
+ KeywordExt * insert (KeywordExt *item);
+ /* Print the table's contents. */
+ void dump () const;
+
private:
- List_Node **table; /* Vector of pointers to linked lists of List_Node's. */
- int size; /* Size of the vector. */
- int collisions; /* Find out how well our double hashing is working! */
- int ignore_length;
+ /* Vector of entries. */
+ KeywordExt ** _table;
+ /* Size of the vector. */
+ unsigned int _size;
+ /* log2(_size). */
+ unsigned int _log_size;
+ /* A detail of the comparison function. */
+ bool const _ignore_length;
+ /* Statistics: Number of collisions so far. */
+ unsigned int _collisions;
-public:
- Hash_Table (List_Node **t, int s, int ignore_len);
- ~Hash_Table (void);
- List_Node *insert (List_Node *item);
+ /* Compares two items. */
+ bool equal (KeywordExt *item1, KeywordExt *item2) const;
};
#endif
diff --git a/src/hashtable.c b/src/hashtable.c
deleted file mode 100644
index c256addd307c..000000000000
--- a/src/hashtable.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Hash table for checking keyword links. Implemented using double hashing.
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdio.h>
-#include "hashtable.h"
-#include "options.h"
-
-#ifdef GATHER_STATISTICS
-/* Find out how well our double hashing is working! */
-static collisions = 0;
-#endif
-
-/* Locally visible hash table. */
-static HASH_TABLE hash_table;
-
-/* Basically the algorithm from the Dragon book. */
-
-static unsigned
-hash_pjw (str)
- char *str;
-{
- char *temp;
- unsigned g, h = 0;
-
- for (temp = str; *temp; temp++)
- {
- h = (h << 4) + (*temp * 13);
- if (g = h & 0xf0000000)
- {
- h ^= (g >> 24);
- h ^= g;
- }
- }
-
- return h;
-}
-
-/* The size of the hash table is always the smallest power of 2 >= the size
- indicated by the user. This allows several optimizations, including
- the use of double hashing and elimination of the mod instruction.
- Note that the size had better be larger than the number of items
- in the hash table, else there's trouble!!! Note that the memory
- for the hash table is allocated *outside* the intialization routine.
- This compromises information hiding somewhat, but greatly reduces
- memory fragmentation, since we can now use alloca! */
-
-void
-hash_table_init (table, s)
- LIST_NODE **table;
- int s;
-{
- hash_table.size = s;
- hash_table.table = table;
- bzero ((char *) hash_table.table, hash_table.size * sizeof *hash_table.table);
-}
-
-/* Frees the dynamically allocated table. Note that since we don't
- really need this space anymore, and since it is potentially quite
- big it is best to return it when we are done. */
-
-void
-hash_table_destroy ()
-{
- if (OPTION_ENABLED (option, DEBUG))
- {
- int i;
-
- fprintf (stderr, "\ndumping the hash table\ntotal elements = %d, bytes = %d\n",
- hash_table.size, hash_table.size * sizeof *hash_table.table);
-
- for (i = hash_table.size - 1; i >= 0; i--)
- if (hash_table.table[i])
- fprintf (stderr, "location[%d] has charset \"%s\" and keyword \"%s\"\n",
- i, hash_table.table[i]->char_set, hash_table.table[i]->key);
-
-#ifdef GATHER_STATISTICS
- fprintf (stderr, "\ntotal collisions during hashing = %d\n", collisions);
-#endif
- fprintf (stderr, "end dumping hash table\n\n");
- }
-}
-
-/* If the ITEM is already in the hash table return the item found
- in the table. Otherwise inserts the ITEM, and returns FALSE.
- Uses double hashing. */
-
-LIST_NODE *
-retrieve (item, ignore_length)
- LIST_NODE *item;
- int ignore_length;
-{
- unsigned hash_val = hash_pjw (item->char_set);
- int probe = hash_val & hash_table.size - 1;
- int increment = (hash_val ^ item->length | 1) & hash_table.size - 1;
-
- while (hash_table.table[probe]
- && (strcmp (hash_table.table[probe]->char_set, item->char_set)
- || (!ignore_length && hash_table.table[probe]->length != item->length)))
- {
-#ifdef GATHER_STATISTICS
- collisions++;
-#endif
- probe = probe + increment & hash_table.size - 1;
- }
-
- if (hash_table.table[probe])
- return hash_table.table[probe];
- else
- {
- hash_table.table[probe] = item;
- return 0;
- }
-}
-
-
diff --git a/src/hashtable.h b/src/hashtable.h
deleted file mode 100644
index 218e9874a1d1..000000000000
--- a/src/hashtable.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Hash table used to check for duplicate keyword entries.
-
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef _hashtable_h
-#define _hashtable_h
-#include "keylist.h"
-#include "prototype.h"
-
-typedef struct hash_table
-{
- LIST_NODE **table; /* Vector of pointers to linked lists of List_Node's. */
- int size; /* Size of the vector. */
-} HASH_TABLE;
-
-extern void hash_table_init P ((LIST_NODE **table, int size));
-extern void hash_table_destroy P ((void));
-extern LIST_NODE *retrieve P ((LIST_NODE *item, int ignore_length));
-
-#endif /* _hashtable_h */
diff --git a/src/input.cc b/src/input.cc
new file mode 100644
index 000000000000..247b5a4df745
--- /dev/null
+++ b/src/input.cc
@@ -0,0 +1,1005 @@
+/* Input routines.
+ Copyright (C) 1989-1998, 2002-2004 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Specification. */
+#include "input.h"
+
+#include <stdio.h>
+#include <stdlib.h> /* declares exit() */
+#include <string.h> /* declares strncpy(), strchr() */
+#include <limits.h> /* defines UCHAR_MAX etc. */
+#include "options.h"
+#include "getline.h"
+
+Input::Input (FILE *stream, Keyword_Factory *keyword_factory)
+ : _stream (stream), _factory (keyword_factory)
+{
+}
+
+/* Returns a pretty representation of the input file name, for error and
+ warning messages. */
+static const char *
+pretty_input_file_name ()
+{
+ if (option.get_input_file_name ())
+ return option.get_input_file_name ();
+ else
+ return "(standard input)";
+}
+
+/* Returns true if the given line contains a "%DECL" declaration. */
+static bool
+is_declaration (const char *line, const char *line_end, unsigned int lineno,
+ const char *decl)
+{
+ /* Skip '%'. */
+ line++;
+
+ /* Skip DECL. */
+ for (const char *d = decl; *d; d++)
+ {
+ if (!(line < line_end))
+ return false;
+ if (!(*line == *d || (*d == '-' && *line == '_')))
+ return false;
+ line++;
+ }
+ if (line < line_end
+ && ((*line >= 'A' && *line <= 'Z')
+ || (*line >= 'a' && *line <= 'z')
+ || *line == '-' || *line == '_'))
+ return false;
+
+ /* OK, found DECL. */
+
+ /* Skip whitespace. */
+ while (line < line_end && (*line == ' ' || *line == '\t'))
+ line++;
+
+ /* Expect end of line. */
+ if (line < line_end && *line != '\n')
+ {
+ fprintf (stderr, "%s:%u: junk after declaration\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+
+ return true;
+}
+
+/* Tests if the given line contains a "%DECL=ARG" declaration.
+ If yes, it sets *ARGP to the argument, and returns true.
+ Otherwise, it returns false. */
+static bool
+is_declaration_with_arg (const char *line, const char *line_end,
+ unsigned int lineno,
+ const char *decl, char **argp)
+{
+ /* Skip '%'. */
+ line++;
+
+ /* Skip DECL. */
+ for (const char *d = decl; *d; d++)
+ {
+ if (!(line < line_end))
+ return false;
+ if (!(*line == *d || (*d == '-' && *line == '_')))
+ return false;
+ line++;
+ }
+ if (line < line_end
+ && ((*line >= 'A' && *line <= 'Z')
+ || (*line >= 'a' && *line <= 'z')
+ || *line == '-' || *line == '_'))
+ return false;
+
+ /* OK, found DECL. */
+
+ /* Skip '='. */
+ if (!(line < line_end && *line == '='))
+ {
+ fprintf (stderr, "%s:%u: missing argument in %%%s=ARG declaration.\n",
+ pretty_input_file_name (), lineno, decl);
+ exit (1);
+ }
+ line++;
+
+ /* The next word is the argument. */
+ char *arg = new char[line_end - line + 1];
+ char *p = arg;
+ while (line < line_end && !(*line == ' ' || *line == '\t' || *line == '\n'))
+ *p++ = *line++;
+ *p = '\0';
+
+ /* Skip whitespace. */
+ while (line < line_end && (*line == ' ' || *line == '\t'))
+ line++;
+
+ /* Expect end of line. */
+ if (line < line_end && *line != '\n')
+ {
+ fprintf (stderr, "%s:%u: junk after declaration\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+
+ *argp = arg;
+ return true;
+}
+
+/* Tests if the given line contains a "%define DECL ARG" declaration.
+ If yes, it sets *ARGP to the argument, and returns true.
+ Otherwise, it returns false. */
+static bool
+is_define_declaration (const char *line, const char *line_end,
+ unsigned int lineno,
+ const char *decl, char **argp)
+{
+ /* Skip '%'. */
+ line++;
+
+ /* Skip "define". */
+ {
+ for (const char *d = "define"; *d; d++)
+ {
+ if (!(line < line_end))
+ return false;
+ if (!(*line == *d))
+ return false;
+ line++;
+ }
+ if (!(line < line_end && (*line == ' ' || *line == '\t')))
+ return false;
+ }
+
+ /* Skip whitespace. */
+ while (line < line_end && (*line == ' ' || *line == '\t'))
+ line++;
+
+ /* Skip DECL. */
+ for (const char *d = decl; *d; d++)
+ {
+ if (!(line < line_end))
+ return false;
+ if (!(*line == *d || (*d == '-' && *line == '_')))
+ return false;
+ line++;
+ }
+ if (line < line_end
+ && ((*line >= 'A' && *line <= 'Z')
+ || (*line >= 'a' && *line <= 'z')
+ || *line == '-' || *line == '_'))
+ return false;
+
+ /* OK, found DECL. */
+
+ /* Skip whitespace. */
+ if (!(line < line_end && (*line == ' ' || *line == '\t')))
+ {
+ fprintf (stderr, "%s:%u:"
+ " missing argument in %%define %s ARG declaration.\n",
+ pretty_input_file_name (), lineno, decl);
+ exit (1);
+ }
+ do
+ line++;
+ while (line < line_end && (*line == ' ' || *line == '\t'));
+
+ /* The next word is the argument. */
+ char *arg = new char[line_end - line + 1];
+ char *p = arg;
+ while (line < line_end && !(*line == ' ' || *line == '\t' || *line == '\n'))
+ *p++ = *line++;
+ *p = '\0';
+
+ /* Skip whitespace. */
+ while (line < line_end && (*line == ' ' || *line == '\t'))
+ line++;
+
+ /* Expect end of line. */
+ if (line < line_end && *line != '\n')
+ {
+ fprintf (stderr, "%s:%u: junk after declaration\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+
+ *argp = arg;
+ return true;
+}
+
+/* Reads the entire input file. */
+void
+Input::read_input ()
+{
+ /* The input file has the following structure:
+ DECLARATIONS
+ %%
+ KEYWORDS
+ %%
+ ADDITIONAL_CODE
+ Since the DECLARATIONS and the ADDITIONAL_CODE sections are optional,
+ we have to read the entire file in the case there is only one %%
+ separator line, in order to determine whether the structure is
+ DECLARATIONS
+ %%
+ KEYWORDS
+ or
+ KEYWORDS
+ %%
+ ADDITIONAL_CODE
+ When the option -t is given or when the first section contains
+ declaration lines starting with %, we go for the first interpretation,
+ otherwise for the second interpretation. */
+
+ char *input = NULL;
+ size_t input_size = 0;
+ int input_length = get_delim (&input, &input_size, EOF, _stream);
+ if (input_length < 0)
+ {
+ if (ferror (_stream))
+ fprintf (stderr, "%s: error while reading input file\n",
+ pretty_input_file_name ());
+ else
+ fprintf (stderr, "%s: The input file is empty!\n",
+ pretty_input_file_name ());
+ exit (1);
+ }
+
+ /* We use input_end as a limit, in order to cope with NUL bytes in the
+ input. But note that one trailing NUL byte has been added after
+ input_end, for convenience. */
+ char *input_end = input + input_length;
+
+ const char *declarations;
+ const char *declarations_end;
+ const char *keywords;
+ const char *keywords_end;
+ unsigned int keywords_lineno;
+
+ /* Break up the input into the three sections. */
+ {
+ const char *separator[2] = { NULL, NULL };
+ unsigned int separator_lineno[2] = { 0, 0 };
+ int separators = 0;
+ {
+ unsigned int lineno = 1;
+ for (const char *p = input; p < input_end; )
+ {
+ if (p[0] == '%' && p[1] == '%')
+ {
+ separator[separators] = p;
+ separator_lineno[separators] = lineno;
+ if (++separators == 2)
+ break;
+ }
+ lineno++;
+ p = (const char *) memchr (p, '\n', input_end - p);
+ if (p != NULL)
+ p++;
+ else
+ p = input_end;
+ }
+ }
+
+ bool has_declarations;
+ if (separators == 1)
+ {
+ if (option[TYPE])
+ has_declarations = true;
+ else
+ {
+ has_declarations = false;
+ for (const char *p = input; p < separator[0]; )
+ {
+ if (p[0] == '%')
+ {
+ has_declarations = true;
+ break;
+ }
+ p = (const char *) memchr (p, '\n', separator[0] - p);
+ if (p != NULL)
+ p++;
+ else
+ p = separator[0];
+ }
+ }
+ }
+ else
+ has_declarations = (separators > 0);
+
+ if (has_declarations)
+ {
+ declarations = input;
+ declarations_end = separator[0];
+ /* Give a warning if the separator line is nonempty. */
+ bool nonempty_line = false;
+ const char *p;
+ for (p = declarations_end + 2; p < input_end; )
+ {
+ if (*p == '\n')
+ {
+ p++;
+ break;
+ }
+ if (!(*p == ' ' || *p == '\t'))
+ nonempty_line = true;
+ p++;
+ }
+ if (nonempty_line)
+ fprintf (stderr, "%s:%u: warning: junk after %%%% is ignored\n",
+ pretty_input_file_name (), separator_lineno[0]);
+ keywords = p;
+ keywords_lineno = separator_lineno[0] + 1;
+ }
+ else
+ {
+ declarations = NULL;
+ declarations_end = NULL;
+ keywords = input;
+ keywords_lineno = 1;
+ }
+
+ if (separators > (has_declarations ? 1 : 0))
+ {
+ keywords_end = separator[separators-1];
+ _verbatim_code = separator[separators-1] + 2;
+ _verbatim_code_end = input_end;
+ _verbatim_code_lineno = separator_lineno[separators-1];
+ }
+ else
+ {
+ keywords_end = input_end;
+ _verbatim_code = NULL;
+ _verbatim_code_end = NULL;
+ _verbatim_code_lineno = 0;
+ }
+ }
+
+ /* Parse the declarations section. */
+
+ _verbatim_declarations = NULL;
+ _verbatim_declarations_end = NULL;
+ _verbatim_declarations_lineno = 0;
+ _struct_decl = NULL;
+ _struct_decl_lineno = 0;
+ _return_type = NULL;
+ _struct_tag = NULL;
+ {
+ unsigned int lineno = 1;
+ char *struct_decl = NULL;
+ unsigned int *struct_decl_linenos = NULL;
+ unsigned int struct_decl_linecount = 0;
+ for (const char *line = declarations; line < declarations_end; )
+ {
+ const char *line_end;
+ line_end = (const char *) memchr (line, '\n', declarations_end - line);
+ if (line_end != NULL)
+ line_end++;
+ else
+ line_end = declarations_end;
+
+ if (*line == '%')
+ {
+ if (line[1] == '{')
+ {
+ /* Handle %{. */
+ if (_verbatim_declarations != NULL)
+ {
+ fprintf (stderr, "%s:%u:\n%s:%u:"
+ " only one %%{...%%} section is allowed\n",
+ pretty_input_file_name (),
+ _verbatim_declarations_lineno,
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+ _verbatim_declarations = line + 2;
+ _verbatim_declarations_lineno = lineno;
+ }
+ else if (line[1] == '}')
+ {
+ /* Handle %}. */
+ if (_verbatim_declarations == NULL)
+ {
+ fprintf (stderr, "%s:%u:"
+ " %%} outside of %%{...%%} section\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+ if (_verbatim_declarations_end != NULL)
+ {
+ fprintf (stderr, "%s:%u:"
+ " %%{...%%} section already closed\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+ _verbatim_declarations_end = line;
+ /* Give a warning if the rest of the line is nonempty. */
+ bool nonempty_line = false;
+ const char *q;
+ for (q = line + 2; q < line_end; q++)
+ {
+ if (*q == '\n')
+ {
+ q++;
+ break;
+ }
+ if (!(*q == ' ' || *q == '\t'))
+ nonempty_line = true;
+ }
+ if (nonempty_line)
+ fprintf (stderr, "%s:%u:"
+ " warning: junk after %%} is ignored\n",
+ pretty_input_file_name (), lineno);
+ }
+ else if (_verbatim_declarations != NULL
+ && _verbatim_declarations_end == NULL)
+ {
+ fprintf (stderr, "%s:%u:"
+ " warning: %% directives are ignored"
+ " inside the %%{...%%} section\n",
+ pretty_input_file_name (), lineno);
+ }
+ else
+ {
+ char *arg;
+
+ if (is_declaration_with_arg (line, line_end, lineno,
+ "delimiters", &arg))
+ option.set_delimiters (arg);
+ else
+
+ if (is_declaration (line, line_end, lineno, "struct-type"))
+ option.set (TYPE);
+ else
+
+ if (is_declaration (line, line_end, lineno, "ignore-case"))
+ option.set (UPPERLOWER);
+ else
+
+ if (is_declaration_with_arg (line, line_end, lineno,
+ "language", &arg))
+ option.set_language (arg);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "slot-name", &arg))
+ option.set_slot_name (arg);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "initializer-suffix", &arg))
+ option.set_initializer_suffix (arg);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "hash-function-name", &arg))
+ option.set_hash_name (arg);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "lookup-function-name", &arg))
+ option.set_function_name (arg);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "class-name", &arg))
+ option.set_class_name (arg);
+ else
+
+ if (is_declaration (line, line_end, lineno, "7bit"))
+ option.set (SEVENBIT);
+ else
+
+ if (is_declaration (line, line_end, lineno, "compare-lengths"))
+ option.set (LENTABLE);
+ else
+
+ if (is_declaration (line, line_end, lineno, "compare-strncmp"))
+ option.set (COMP);
+ else
+
+ if (is_declaration (line, line_end, lineno, "readonly-tables"))
+ option.set (CONST);
+ else
+
+ if (is_declaration (line, line_end, lineno, "enum"))
+ option.set (ENUM);
+ else
+
+ if (is_declaration (line, line_end, lineno, "includes"))
+ option.set (INCLUDE);
+ else
+
+ if (is_declaration (line, line_end, lineno, "global-table"))
+ option.set (GLOBAL);
+ else
+
+ if (is_declaration (line, line_end, lineno, "pic"))
+ option.set (SHAREDLIB);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "string-pool-name", &arg))
+ option.set_stringpool_name (arg);
+ else
+
+ if (is_declaration (line, line_end, lineno, "null-strings"))
+ option.set (NULLSTRINGS);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "word-array-name", &arg))
+ option.set_wordlist_name (arg);
+ else
+
+ if (is_define_declaration (line, line_end, lineno,
+ "length-table-name", &arg))
+ option.set_lengthtable_name (arg);
+ else
+
+ if (is_declaration_with_arg (line, line_end, lineno,
+ "switch", &arg))
+ {
+ option.set_total_switches (atoi (arg));
+ if (option.get_total_switches () <= 0)
+ {
+ fprintf (stderr, "%s:%u: number of switches %s"
+ " must be a positive number\n",
+ pretty_input_file_name (), lineno, arg);
+ exit (1);
+ }
+ }
+ else
+
+ if (is_declaration (line, line_end, lineno, "omit-struct-type"))
+ option.set (NOTYPE);
+ else
+
+ {
+ fprintf (stderr, "%s:%u: unrecognized %% directive\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+ }
+ }
+ else if (!(_verbatim_declarations != NULL
+ && _verbatim_declarations_end == NULL))
+ {
+ /* Append the line to struct_decl. */
+ size_t old_len = (struct_decl ? strlen (struct_decl) : 0);
+ size_t line_len = line_end - line;
+ size_t new_len = old_len + line_len + 1;
+ char *new_struct_decl = new char[new_len];
+ if (old_len > 0)
+ memcpy (new_struct_decl, struct_decl, old_len);
+ memcpy (new_struct_decl + old_len, line, line_len);
+ new_struct_decl[old_len + line_len] = '\0';
+ if (struct_decl)
+ delete[] struct_decl;
+ struct_decl = new_struct_decl;
+ /* Append the lineno to struct_decl_linenos. */
+ unsigned int *new_struct_decl_linenos =
+ new unsigned int[struct_decl_linecount + 1];
+ if (struct_decl_linecount > 0)
+ memcpy (new_struct_decl_linenos, struct_decl_linenos,
+ struct_decl_linecount * sizeof (unsigned int));
+ new_struct_decl_linenos[struct_decl_linecount] = lineno;
+ if (struct_decl_linenos)
+ delete[] struct_decl_linenos;
+ struct_decl_linenos = new_struct_decl_linenos;
+ /* Increment struct_decl_linecount. */
+ struct_decl_linecount++;
+ }
+ lineno++;
+ line = line_end;
+ }
+ if (_verbatim_declarations != NULL && _verbatim_declarations_end == NULL)
+ {
+ fprintf (stderr, "%s:%u: unterminated %%{ section\n",
+ pretty_input_file_name (), _verbatim_declarations_lineno);
+ exit (1);
+ }
+
+ /* Determine _struct_decl, _return_type, _struct_tag. */
+ if (option[TYPE])
+ {
+ if (struct_decl)
+ {
+ /* Drop leading whitespace and comments. */
+ {
+ char *p = struct_decl;
+ unsigned int *l = struct_decl_linenos;
+ for (;;)
+ {
+ if (p[0] == ' ' || p[0] == '\t')
+ {
+ p++;
+ continue;
+ }
+ if (p[0] == '\n')
+ {
+ l++;
+ p++;
+ continue;
+ }
+ if (p[0] == '/')
+ {
+ if (p[1] == '*')
+ {
+ /* Skip over ANSI C style comment. */
+ p += 2;
+ while (p[0] != '\0')
+ {
+ if (p[0] == '*' && p[1] == '/')
+ {
+ p += 2;
+ break;
+ }
+ if (p[0] == '\n')
+ l++;
+ p++;
+ }
+ continue;
+ }
+ if (p[1] == '/')
+ {
+ /* Skip over ISO C99 or C++ style comment. */
+ p += 2;
+ while (p[0] != '\0' && p[0] != '\n')
+ p++;
+ if (p[0] == '\n')
+ {
+ l++;
+ p++;
+ }
+ continue;
+ }
+ }
+ break;
+ }
+ if (p != struct_decl)
+ {
+ size_t len = strlen (p);
+ char *new_struct_decl = new char[len + 1];
+ memcpy (new_struct_decl, p, len + 1);
+ delete[] struct_decl;
+ struct_decl = new_struct_decl;
+ }
+ _struct_decl_lineno = *l;
+ }
+ /* Drop trailing whitespace. */
+ for (char *p = struct_decl + strlen (struct_decl); p > struct_decl;)
+ if (p[-1] == '\n' || p[-1] == ' ' || p[-1] == '\t')
+ *--p = '\0';
+ else
+ break;
+ }
+ if (struct_decl == NULL || struct_decl[0] == '\0')
+ {
+ fprintf (stderr, "%s: missing struct declaration"
+ " for option --struct-type\n",
+ pretty_input_file_name ());
+ exit (1);
+ }
+ {
+ /* Ensure trailing semicolon. */
+ size_t old_len = strlen (struct_decl);
+ if (struct_decl[old_len - 1] != ';')
+ {
+ char *new_struct_decl = new char[old_len + 2];
+ memcpy (new_struct_decl, struct_decl, old_len);
+ new_struct_decl[old_len] = ';';
+ new_struct_decl[old_len + 1] = '\0';
+ delete[] struct_decl;
+ struct_decl = new_struct_decl;
+ }
+ }
+ /* Set _struct_decl to the entire declaration. */
+ _struct_decl = struct_decl;
+ /* Set _struct_tag to the naked "struct something". */
+ const char *p;
+ for (p = struct_decl; *p && *p != '{' && *p != ';' && *p != '\n'; p++)
+ ;
+ for (; p > struct_decl;)
+ if (p[-1] == '\n' || p[-1] == ' ' || p[-1] == '\t')
+ --p;
+ else
+ break;
+ size_t struct_tag_length = p - struct_decl;
+ char *struct_tag = new char[struct_tag_length + 1];
+ memcpy (struct_tag, struct_decl, struct_tag_length);
+ struct_tag[struct_tag_length] = '\0';
+ _struct_tag = struct_tag;
+ /* The return type of the lookup function is "struct something *".
+ No "const" here, because if !option[CONST], some user code might
+ want to modify the structure. */
+ char *return_type = new char[struct_tag_length + 3];
+ memcpy (return_type, struct_decl, struct_tag_length);
+ return_type[struct_tag_length] = ' ';
+ return_type[struct_tag_length + 1] = '*';
+ return_type[struct_tag_length + 2] = '\0';
+ _return_type = return_type;
+ }
+
+ if (struct_decl_linenos)
+ delete[] struct_decl_linenos;
+ }
+
+ /* Parse the keywords section. */
+ {
+ Keyword_List **list_tail = &_head;
+ const char *delimiters = option.get_delimiters ();
+ unsigned int lineno = keywords_lineno;
+ bool charset_dependent = false;
+ for (const char *line = keywords; line < keywords_end; )
+ {
+ const char *line_end;
+ line_end = (const char *) memchr (line, '\n', keywords_end - line);
+ if (line_end != NULL)
+ line_end++;
+ else
+ line_end = keywords_end;
+
+ if (line[0] == '#')
+ ; /* Comment line. */
+ else if (line[0] == '%')
+ {
+ fprintf (stderr, "%s:%u:"
+ " declarations are not allowed in the keywords section.\n"
+ "To declare a keyword starting with %%, enclose it in"
+ " double-quotes.\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+ else
+ {
+ /* An input line carrying a keyword. */
+ const char *keyword;
+ size_t keyword_length;
+ const char *rest;
+
+ if (line[0] == '"')
+ {
+ /* Parse a string in ANSI C syntax. */
+ char *kp = new char[line_end-line];
+ keyword = kp;
+ const char *lp = line + 1;
+
+ for (;;)
+ {
+ if (lp == line_end)
+ {
+ fprintf (stderr, "%s:%u: unterminated string\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+
+ char c = *lp;
+ if (c == '\\')
+ {
+ c = *++lp;
+ switch (c)
+ {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ {
+ int code = 0;
+ int count = 0;
+ while (count < 3 && *lp >= '0' && *lp <= '7')
+ {
+ code = (code << 3) + (*lp - '0');
+ lp++;
+ count++;
+ }
+ if (code > UCHAR_MAX)
+ fprintf (stderr,
+ "%s:%u: octal escape out of range\n",
+ pretty_input_file_name (), lineno);
+ *kp = static_cast<char>(code);
+ break;
+ }
+ case 'x':
+ {
+ int code = 0;
+ int count = 0;
+ lp++;
+ while ((*lp >= '0' && *lp <= '9')
+ || (*lp >= 'A' && *lp <= 'F')
+ || (*lp >= 'a' && *lp <= 'f'))
+ {
+ code = (code << 4)
+ + (*lp >= 'A' && *lp <= 'F'
+ ? *lp - 'A' + 10 :
+ *lp >= 'a' && *lp <= 'f'
+ ? *lp - 'a' + 10 :
+ *lp - '0');
+ lp++;
+ count++;
+ }
+ if (count == 0)
+ fprintf (stderr, "%s:%u: hexadecimal escape"
+ " without any hex digits\n",
+ pretty_input_file_name (), lineno);
+ if (code > UCHAR_MAX)
+ fprintf (stderr, "%s:%u: hexadecimal escape"
+ " out of range\n",
+ pretty_input_file_name (), lineno);
+ *kp = static_cast<char>(code);
+ break;
+ }
+ case '\\': case '\'': case '"':
+ *kp = c;
+ lp++;
+ charset_dependent = true;
+ break;
+ case 'n':
+ *kp = '\n';
+ lp++;
+ charset_dependent = true;
+ break;
+ case 't':
+ *kp = '\t';
+ lp++;
+ charset_dependent = true;
+ break;
+ case 'r':
+ *kp = '\r';
+ lp++;
+ charset_dependent = true;
+ break;
+ case 'f':
+ *kp = '\f';
+ lp++;
+ charset_dependent = true;
+ break;
+ case 'b':
+ *kp = '\b';
+ lp++;
+ charset_dependent = true;
+ break;
+ case 'a':
+ *kp = '\a';
+ lp++;
+ charset_dependent = true;
+ break;
+ case 'v':
+ *kp = '\v';
+ lp++;
+ charset_dependent = true;
+ break;
+ default:
+ fprintf (stderr, "%s:%u: invalid escape sequence"
+ " in string\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+ }
+ else if (c == '"')
+ break;
+ else
+ {
+ *kp = c;
+ lp++;
+ charset_dependent = true;
+ }
+ kp++;
+ }
+ lp++;
+ if (lp < line_end && *lp != '\n')
+ {
+ if (strchr (delimiters, *lp) == NULL)
+ {
+ fprintf (stderr, "%s:%u: string not followed"
+ " by delimiter\n",
+ pretty_input_file_name (), lineno);
+ exit (1);
+ }
+ lp++;
+ }
+ keyword_length = kp - keyword;
+ if (option[TYPE])
+ {
+ char *line_rest = new char[line_end - lp + 1];
+ memcpy (line_rest, lp, line_end - lp);
+ line_rest[line_end - lp -
+ (line_end > lp && line_end[-1] == '\n' ? 1 : 0)]
+ = '\0';
+ rest = line_rest;
+ }
+ else
+ rest = empty_string;
+ }
+ else
+ {
+ /* Not a string. Look for the delimiter. */
+ const char *lp = line;
+ for (;;)
+ {
+ if (!(lp < line_end && *lp != '\n'))
+ {
+ keyword = line;
+ keyword_length = lp - line;
+ rest = empty_string;
+ break;
+ }
+ if (strchr (delimiters, *lp) != NULL)
+ {
+ keyword = line;
+ keyword_length = lp - line;
+ lp++;
+ if (option[TYPE])
+ {
+ char *line_rest = new char[line_end - lp + 1];
+ memcpy (line_rest, lp, line_end - lp);
+ line_rest[line_end - lp -
+ (line_end > lp && line_end[-1] == '\n'
+ ? 1 : 0)]
+ = '\0';
+ rest = line_rest;
+ }
+ else
+ rest = empty_string;
+ break;
+ }
+ lp++;
+ }
+ if (keyword_length > 0)
+ charset_dependent = true;
+ }
+
+ /* Allocate Keyword and add it to the list. */
+ Keyword *new_kw = _factory->create_keyword (keyword, keyword_length,
+ rest);
+ new_kw->_lineno = lineno;
+ *list_tail = new Keyword_List (new_kw);
+ list_tail = &(*list_tail)->rest();
+ }
+
+ lineno++;
+ line = line_end;
+ }
+ *list_tail = NULL;
+
+ if (_head == NULL)
+ {
+ fprintf (stderr, "%s: No keywords in input file!\n",
+ pretty_input_file_name ());
+ exit (1);
+ }
+
+ _charset_dependent = charset_dependent;
+ }
+
+ /* To be freed in the destructor. */
+ _input = input;
+ _input_end = input_end;
+}
+
+Input::~Input ()
+{
+ /* Free allocated memory. */
+ delete[] const_cast<char*>(_return_type);
+ delete[] const_cast<char*>(_struct_tag);
+ delete[] const_cast<char*>(_struct_decl);
+ delete[] _input;
+}
diff --git a/src/input.h b/src/input.h
new file mode 100644
index 000000000000..76ba01282cc4
--- /dev/null
+++ b/src/input.h
@@ -0,0 +1,69 @@
+/* This may look like C code, but it is really -*- C++ -*- */
+
+/* Input routines.
+
+ Copyright (C) 1989-1998, 2002-2003 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef input_h
+#define input_h 1
+
+#include <stdio.h>
+#include "keyword-list.h"
+
+class Input
+{
+public:
+ Input (FILE *stream, Keyword_Factory *keyword_factory);
+ ~Input ();
+ void read_input ();
+private:
+ /* Input stream. */
+ FILE * _stream;
+ /* Creates the keywords. */
+ Keyword_Factory * const _factory;
+public:
+ /* Memory block containing the entire input. */
+ char * _input;
+ char * _input_end;
+ /* The C code from the declarations section. */
+ const char * _verbatim_declarations;
+ const char * _verbatim_declarations_end;
+ unsigned int _verbatim_declarations_lineno;
+ /* The C code from the end of the file. */
+ const char * _verbatim_code;
+ const char * _verbatim_code_end;
+ unsigned int _verbatim_code_lineno;
+ /* Declaration of struct type for a keyword and its attributes. */
+ const char * _struct_decl;
+ unsigned int _struct_decl_lineno;
+ /* Return type of the lookup function. */
+ const char * _return_type;
+ /* Shorthand for user-defined struct tag type. */
+ const char * _struct_tag;
+ /* List of all keywords. */
+ Keyword_List * _head;
+ /* Whether the keyword chars would have different values in a different
+ character set. */
+ bool _charset_dependent;
+};
+
+#endif
diff --git a/src/iterator.c b/src/iterator.c
deleted file mode 100644
index b5930f089bb2..000000000000
--- a/src/iterator.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Provides an Iterator for keyword characters.
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdio.h>
-#include <ctype.h>
-#include "iterator.h"
-
-/* Locally visible ITERATOR object. */
-
-ITERATOR iterator;
-
-/* Constructor for ITERATOR. */
-
-void
-iterator_init (s, lo, hi, word_end, bad_val, key_end)
- char *s;
- int lo;
- int hi;
- int word_end;
- int bad_val;
- int key_end;
-{
- iterator.end = key_end;
- iterator.error_value = bad_val;
- iterator.end_word = word_end;
- iterator.str = s;
- iterator.hi_bound = hi;
- iterator.lo_bound = lo;
-}
-
-/* Define several useful macros to clarify subsequent code. */
-#define ISPOSDIGIT(X) ((X)<='9'&&(X)>'0')
-#define TODIGIT(X) ((X)-'0')
-
-/* Provide an Iterator, returning the ``next'' value from
- the list of valid values given in the constructor. */
-
-int
-next ()
-{
-/* Variables to record the Iterator's status when handling ranges, e.g., 3-12. */
-
- static int size;
- static int curr_value;
- static int upper_bound;
-
- if (size)
- {
- if (++curr_value >= upper_bound)
- size = 0;
- return curr_value;
- }
- else
- {
- while (*iterator.str)
- {
- if (*iterator.str == ',')
- iterator.str++;
- else if (*iterator.str == '$')
- {
- iterator.str++;
- return iterator.end_word;
- }
- else if (ISPOSDIGIT (*iterator.str))
- {
-
- for (curr_value = 0; isdigit (*iterator.str); iterator.str++)
- curr_value = curr_value * 10 + *iterator.str - '0';
-
- if (*iterator.str == '-')
- {
-
- for (size = 1, upper_bound = 0;
- isdigit (*++iterator.str);
- upper_bound = upper_bound * 10 + *iterator.str - '0');
-
- if (upper_bound <= curr_value || upper_bound > iterator.hi_bound)
- return iterator.error_value;
- }
- return curr_value >= iterator.lo_bound && curr_value <= iterator.hi_bound
- ? curr_value : iterator.error_value;
- }
- else
- return iterator.error_value;
- }
-
- return iterator.end;
- }
-}
diff --git a/src/iterator.cc b/src/iterator.cc
deleted file mode 100644
index ca66bbb8aca4..000000000000
--- a/src/iterator.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Provides an Iterator for keyword characters.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include "iterator.h"
-
-#include <ctype.h>
-#include "trace.h"
-
-/* Constructor for Iterator. */
-
-Iterator::Iterator (const char *s, int lo, int hi, int word_end, int bad_val, int key_end)
-{
- T (Trace t ("Iterator::Iterator");)
- end = key_end;
- error_value = bad_val;
- end_word = word_end;
- str = s;
- hi_bound = hi;
- lo_bound = lo;
-}
-
-/* Provide an Iterator, returning the ``next'' value from
- the list of valid values given in the constructor. */
-
-int
-Iterator::operator() (void)
-{
- T (Trace t ("Iterator::operator()");)
-/* Variables to record the Iterator's status when handling ranges, e.g., 3-12. */
-
- static int size;
- static int curr_value;
- static int upper_bound;
-
- if (size)
- {
- if (++curr_value >= upper_bound)
- size = 0;
- return curr_value;
- }
- else
- {
- while (*str)
- switch (*str)
- {
- default: return error_value;
- case ',': str++; break;
- case '$': str++; return end_word;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- for (curr_value = 0; isdigit ((unsigned char)(*str)); str++)
- curr_value = curr_value * 10 + (*str - '0');
-
- if (*str == '-')
- {
-
- for (size = 1, upper_bound = 0;
- isdigit ((unsigned char)(*++str));
- upper_bound = upper_bound * 10 + (*str - '0'));
-
- if (upper_bound <= curr_value || upper_bound > hi_bound)
- return error_value;
- }
- return curr_value >= lo_bound && curr_value <= hi_bound
- ? curr_value : error_value;
- }
-
- return end;
- }
-}
diff --git a/src/iterator.h b/src/iterator.h
deleted file mode 100644
index d5138ab99447..000000000000
--- a/src/iterator.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This may look like C code, but it is really -*- C++ -*- */
-
-/* Provides an Iterator for keyword characters.
-
- Copyright (C) 1989-1998 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Provides an Iterator that expands and decodes a control string containing digits
- and ranges, returning an integer every time the generator function is called.
- This is used to decode the user's key position requests. For example:
- "-k 1,2,5-10,$" will return 1, 2, 5, 6, 7, 8, 9, 10, and 0 ( representing
- the abstract ``last character of the key'' on successive calls to the
- member function operator ().
- No errors are handled in these routines, they are passed back to the
- calling routines via a user-supplied Error_Value */
-
-#ifndef iterator_h
-#define iterator_h 1
-
-class Iterator
-{
-private:
- const char *str; /* A pointer to the string provided by the user. */
- int end; /* Value returned after last key is processed. */
- int end_word; /* A value marking the abstract ``end of word'' ( usually '$'). */
- int error_value; /* Error value returned when input is syntactically erroneous. */
- int hi_bound; /* Greatest possible value, inclusive. */
- int lo_bound; /* Smallest possible value, inclusive. */
-
-public:
- Iterator (const char *s, int lo, int hi, int word_end, int bad_val, int key_end);
- int operator () (void);
-};
-
-#endif
diff --git a/src/key-list.cc b/src/key-list.cc
deleted file mode 100644
index 1c941a453579..000000000000
--- a/src/key-list.cc
+++ /dev/null
@@ -1,2184 +0,0 @@
-/* Routines for building, ordering, and printing the keyword list.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include <stdio.h>
-#include <string.h> /* declares strncpy(), strchr() */
-#include <stdlib.h> /* declares malloc(), free(), abs(), exit(), abort() */
-#include <ctype.h> /* declares isprint() */
-#include <assert.h> /* defines assert() */
-#include <limits.h> /* defines SCHAR_MAX etc. */
-#include "options.h"
-#include "read-line.h"
-#include "hash-table.h"
-#include "key-list.h"
-#include "trace.h"
-#include "version.h"
-
-/* Make the hash table 8 times larger than the number of keyword entries. */
-static const int TABLE_MULTIPLE = 10;
-
-/* Efficiently returns the least power of two greater than or equal to X! */
-#define POW(X) ((!X)?1:(X-=1,X|=X>>1,X|=X>>2,X|=X>>4,X|=X>>8,X|=X>>16,(++X)))
-
-int Key_List::determined[MAX_ALPHA_SIZE];
-
-/* Destructor dumps diagnostics during debugging. */
-
-Key_List::~Key_List (void)
-{
- T (Trace t ("Key_List::~Key_List");)
- if (option[DEBUG])
- {
- fprintf (stderr, "\nDumping key list information:\ntotal non-static linked keywords = %d"
- "\ntotal keywords = %d\ntotal duplicates = %d\nmaximum key length = %d\n",
- list_len, total_keys, total_duplicates, max_key_len);
- dump ();
- fprintf (stderr, "End dumping list.\n\n");
- }
-}
-
-/* Gathers the input stream into a buffer until one of two things occur:
-
- 1. We read a '%' followed by a '%'
- 2. We read a '%' followed by a '}'
-
- The first symbolizes the beginning of the keyword list proper,
- The second symbolizes the end of the C source code to be generated
- verbatim in the output file.
-
- I assume that the keys are separated from the optional preceding struct
- declaration by a consecutive % followed by either % or } starting in
- the first column. The code below uses an expandible buffer to scan off
- and return a pointer to all the code (if any) appearing before the delimiter. */
-
-const char *
-Key_List::get_special_input (char delimiter)
-{
- T (Trace t ("Key_List::get_special_input");)
- int size = 80;
- char *buf = new char[size];
- int c, i;
-
- for (i = 0; (c = getchar ()) != EOF; i++)
- {
- if (c == '%')
- {
- if ((c = getchar ()) == delimiter)
- {
-
- while ((c = getchar ()) != '\n')
- ; /* discard newline */
-
- if (i == 0)
- return "";
- else
- {
- buf[delimiter == '%' && buf[i - 2] == ';' ? i - 2 : i - 1] = '\0';
- return buf;
- }
- }
- else
- buf[i++] = '%';
- }
- else if (i >= size) /* Yikes, time to grow the buffer! */
- {
- char *temp = new char[size *= 2];
- int j;
-
- for (j = 0; j < i; j++)
- temp[j] = buf[j];
-
- buf = temp;
- }
- buf[i] = c;
- }
-
- return 0; /* Problem here. */
-}
-
-/* Stores any C text that must be included verbatim into the
- generated code output. */
-
-const char *
-Key_List::save_include_src (void)
-{
- T (Trace t ("Key_List::save_include_src");)
- int c;
-
- if ((c = getchar ()) != '%')
- ungetc (c, stdin);
- else if ((c = getchar ()) != '{')
- {
- fprintf (stderr, "internal error, %c != '{' on line %d in file %s", c, __LINE__, __FILE__);
- exit (1);
- }
- else
- return get_special_input ('}');
- return "";
-}
-
-/* Determines from the input file whether the user wants to build a table
- from a user-defined struct, or whether the user is content to simply
- use the default array of keys. */
-
-const char *
-Key_List::get_array_type (void)
-{
- T (Trace t ("Key_List::get_array_type");)
- return get_special_input ('%');
-}
-
-/* strcspn - find length of initial segment of S consisting entirely
- of characters not from REJECT (borrowed from Henry Spencer's
- ANSI string package, when GNU libc comes out I'll replace this...). */
-
-#ifndef strcspn
-inline int
-Key_List::strcspn (const char *s, const char *reject)
-{
- T (Trace t ("Key_List::strcspn");)
- const char *scan;
- const char *rej_scan;
- int count = 0;
-
- for (scan = s; *scan; scan++)
- {
-
- for (rej_scan = reject; *rej_scan; rej_scan++)
- if (*scan == *rej_scan)
- return count;
-
- count++;
- }
-
- return count;
-}
-#endif
-
-/* Sets up the Return_Type, the Struct_Tag type and the Array_Type
- based upon various user Options. */
-
-void
-Key_List::set_output_types (void)
-{
- T (Trace t ("Key_List::set_output_types");)
- if (option[TYPE])
- {
- array_type = get_array_type ();
- if (!array_type)
- /* Something's wrong, but we'll catch it later on, in read_keys()... */
- return;
- /* Yow, we've got a user-defined type... */
- int i = strcspn (array_type, "{\n\0");
- /* Remove trailing whitespace. */
- while (i > 0 && strchr (" \t", array_type[i-1]))
- i--;
- int struct_tag_length = i;
-
- /* Set `struct_tag' to a naked "struct something". */
- char *structtag = new char[struct_tag_length + 1];
- strncpy (structtag, array_type, struct_tag_length);
- structtag[struct_tag_length] = '\0';
- struct_tag = structtag;
-
- /* The return type of the lookup function is "struct something *".
- No "const" here, because if !option[CONST], some user code might want
- to modify the structure. */
- char *rettype = new char[struct_tag_length + 3];
- strncpy (rettype, array_type, struct_tag_length);
- rettype[struct_tag_length] = ' ';
- rettype[struct_tag_length + 1] = '*';
- rettype[struct_tag_length + 2] = '\0';
- return_type = rettype;
- }
-}
-
-/* Extracts a key from an input line and creates a new List_Node for it. */
-
-static List_Node *
-parse_line (const char *line, const char *delimiters)
-{
- if (*line == '"')
- {
- /* Parse a string in ANSI C syntax. */
- char *key = new char[strlen(line)];
- char *kp = key;
- const char *lp = line + 1;
-
- for (; *lp;)
- {
- char c = *lp;
-
- if (c == '\0')
- {
- fprintf (stderr, "unterminated string: %s\n", line);
- exit (1);
- }
- else if (c == '\\')
- {
- c = *++lp;
- switch (c)
- {
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- {
- int code = 0;
- int count = 0;
- while (count < 3 && *lp >= '0' && *lp <= '7')
- {
- code = (code << 3) + (*lp - '0');
- lp++;
- count++;
- }
- if (code > UCHAR_MAX)
- fprintf (stderr, "octal escape out of range: %s\n", line);
- *kp = (char) code;
- break;
- }
- case 'x':
- {
- int code = 0;
- int count = 0;
- lp++;
- while ((*lp >= '0' && *lp <= '9')
- || (*lp >= 'A' && *lp <= 'F')
- || (*lp >= 'a' && *lp <= 'f'))
- {
- code = (code << 4)
- + (*lp >= 'A' && *lp <= 'F' ? *lp - 'A' + 10 :
- *lp >= 'a' && *lp <= 'f' ? *lp - 'a' + 10 :
- *lp - '0');
- lp++;
- count++;
- }
- if (count == 0)
- fprintf (stderr, "hexadecimal escape without any hex digits: %s\n", line);
- if (code > UCHAR_MAX)
- fprintf (stderr, "hexadecimal escape out of range: %s\n", line);
- *kp = (char) code;
- break;
- }
- case '\\': case '\'': case '"':
- *kp = c;
- lp++;
- break;
- case 'n':
- *kp = '\n';
- lp++;
- break;
- case 't':
- *kp = '\t';
- lp++;
- break;
- case 'r':
- *kp = '\r';
- lp++;
- break;
- case 'f':
- *kp = '\f';
- lp++;
- break;
- case 'b':
- *kp = '\b';
- lp++;
- break;
- case 'a':
- *kp = '\a';
- lp++;
- break;
- case 'v':
- *kp = '\v';
- lp++;
- break;
- default:
- fprintf (stderr, "invalid escape sequence in string: %s\n", line);
- exit (1);
- }
- }
- else if (c == '"')
- break;
- else
- {
- *kp = c;
- lp++;
- }
- kp++;
- }
- lp++;
- if (*lp != '\0')
- {
- if (strchr (delimiters, *lp) == NULL)
- {
- fprintf (stderr, "string not followed by delimiter: %s\n", line);
- exit (1);
- }
- lp++;
- }
- return new List_Node (key, kp - key, option[TYPE] ? lp : "");
- }
- else
- {
- /* Not a string. Look for the delimiter. */
- int len = strcspn (line, delimiters);
- const char *rest;
-
- if (line[len] == '\0')
- rest = "";
- else
- /* Skip the first delimiter. */
- rest = &line[len + 1];
- return new List_Node (line, len, option[TYPE] ? rest : "");
- }
-}
-
-/* Reads in all keys from standard input and creates a linked list pointed
- to by Head. This list is then quickly checked for ``links,'' i.e.,
- unhashable elements possessing identical key sets and lengths. */
-
-void
-Key_List::read_keys (void)
-{
- T (Trace t ("Key_List::read_keys");)
- char *ptr;
-
- include_src = save_include_src ();
- set_output_types ();
-
- /* Oops, problem with the input file. */
- if (! (ptr = Read_Line::get_line ()))
- {
- fprintf (stderr, "No words in input file, did you forget to prepend %s or use -t accidentally?\n", "%%");
- exit (1);
- }
-
- /* Read in all the keywords from the input file. */
- else
- {
- const char *delimiter = option.get_delimiter ();
- List_Node *temp, *trail = 0;
-
- head = parse_line (ptr, delimiter);
-
- for (temp = head;
- (ptr = Read_Line::get_line ()) && strcmp (ptr, "%%");
- temp = temp->next)
- {
- temp->next = parse_line (ptr, delimiter);
- total_keys++;
- }
-
- /* See if any additional C code is included at end of this file. */
- if (ptr)
- additional_code = 1;
-
- /* Hash table this number of times larger than keyword number. */
- int table_size = (list_len = total_keys) * TABLE_MULTIPLE;
-
-#if LARGE_STACK_ARRAYS
- /* By allocating the memory here we save on dynamic allocation overhead.
- Table must be a power of 2 for the hash function scheme to work. */
- List_Node *table[POW (table_size)];
-#else
- // Note: we don't use new, because that invokes a custom operator new.
- int malloc_size = POW (table_size) * sizeof(List_Node*);
- if (malloc_size == 0) malloc_size = 1;
- List_Node **table = (List_Node**)malloc(malloc_size);
- if (table == NULL)
- abort ();
-#endif
-
- /* Make large hash table for efficiency. */
- Hash_Table found_link (table, table_size, option[NOLENGTH]);
-
- /* Test whether there are any links and also set the maximum length of
- an identifier in the keyword list. */
-
- for (temp = head; temp; temp = temp->next)
- {
- List_Node *ptr = found_link.insert (temp);
-
- /* Check for links. We deal with these by building an equivalence class
- of all duplicate values (i.e., links) so that only 1 keyword is
- representative of the entire collection. This *greatly* simplifies
- processing during later stages of the program. */
-
- if (ptr)
- {
- total_duplicates++;
- list_len--;
- trail->next = temp->next;
- temp->link = ptr->link;
- ptr->link = temp;
-
- /* Complain if user hasn't enabled the duplicate option. */
- if (!option[DUP] || option[DEBUG])
- fprintf (stderr, "Key link: \"%.*s\" = \"%.*s\", with key set \"%.*s\".\n",
- temp->key_length, temp->key,
- ptr->key_length, ptr->key,
- temp->char_set_length, temp->char_set);
- }
- else
- trail = temp;
-
- /* Update minimum and maximum keyword length, if needed. */
- if (max_key_len < temp->key_length)
- max_key_len = temp->key_length;
- if (min_key_len > temp->key_length)
- min_key_len = temp->key_length;
- }
-
-#if !LARGE_STACK_ARRAYS
- free ((char *) table);
-#endif
-
- /* Exit program if links exists and option[DUP] not set, since we can't continue */
- if (total_duplicates)
- {
- if (option[DUP])
- fprintf (stderr, "%d input keys have identical hash values, examine output carefully...\n",
- total_duplicates);
- else
- {
- fprintf (stderr, "%d input keys have identical hash values,\ntry different key positions or use option -D.\n",
- total_duplicates);
- exit (1);
- }
- }
- /* Exit program if an empty string is used as key, since the comparison
- expressions don't work correctly for looking up an empty string. */
- if (min_key_len == 0)
- {
- fprintf (stderr, "Empty input key is not allowed.\nTo recognize an empty input key, your code should check for\nlen == 0 before calling the gperf generated lookup function.\n");
- exit (1);
- }
- if (option[ALLCHARS])
- option.set_keysig_size (max_key_len);
- }
-}
-
-/* Recursively merges two sorted lists together to form one sorted list. The
- ordering criteria is by frequency of occurrence of elements in the key set
- or by the hash value. This is a kludge, but permits nice sharing of
- almost identical code without incurring the overhead of a function
- call comparison. */
-
-List_Node *
-Key_List::merge (List_Node *list1, List_Node *list2)
-{
- T (Trace t ("Key_List::merge");)
- List_Node *result;
- List_Node **resultp = &result;
- for (;;)
- {
- if (!list1)
- {
- *resultp = list2;
- break;
- }
- if (!list2)
- {
- *resultp = list1;
- break;
- }
- if (occurrence_sort && list1->occurrence < list2->occurrence
- || hash_sort && list1->hash_value > list2->hash_value)
- {
- *resultp = list2;
- resultp = &list2->next; list2 = list1; list1 = *resultp;
- }
- else
- {
- *resultp = list1;
- resultp = &list1->next; list1 = *resultp;
- }
- }
- return result;
-}
-
-/* Applies the merge sort algorithm to recursively sort the key list by
- frequency of occurrence of elements in the key set. */
-
-List_Node *
-Key_List::merge_sort (List_Node *head)
-{
- T (Trace t ("Key_List::merge_sort");)
- if (!head || !head->next)
- return head;
- else
- {
- List_Node *middle = head;
- List_Node *temp = head->next->next;
-
- while (temp)
- {
- temp = temp->next;
- middle = middle->next;
- if (temp)
- temp = temp->next;
- }
-
- temp = middle->next;
- middle->next = 0;
- return merge (merge_sort (head), merge_sort (temp));
- }
-}
-
-/* Returns the frequency of occurrence of elements in the key set. */
-
-inline int
-Key_List::get_occurrence (List_Node *ptr)
-{
- T (Trace t ("Key_List::get_occurrence");)
- int value = 0;
-
- const char *p = ptr->char_set;
- unsigned int i = ptr->char_set_length;
- for (; i > 0; p++, i--)
- value += occurrences[(unsigned char)(*p)];
-
- return value;
-}
-
-/* Enables the index location of all key set elements that are now
- determined. */
-
-inline void
-Key_List::set_determined (List_Node *ptr)
-{
- T (Trace t ("Key_List::set_determined");)
-
- const char *p = ptr->char_set;
- unsigned int i = ptr->char_set_length;
- for (; i > 0; p++, i--)
- determined[(unsigned char)(*p)] = 1;
-}
-
-/* Returns TRUE if PTR's key set is already completely determined. */
-
-inline int
-Key_List::already_determined (List_Node *ptr)
-{
- T (Trace t ("Key_List::already_determined");)
- int is_determined = 1;
-
- const char *p = ptr->char_set;
- unsigned int i = ptr->char_set_length;
- for (; is_determined && i > 0; p++, i--)
- is_determined = determined[(unsigned char)(*p)];
-
- return is_determined;
-}
-
-/* Reorders the table by first sorting the list so that frequently occuring
- keys appear first, and then the list is reorded so that keys whose values
- are already determined will be placed towards the front of the list. This
- helps prune the search time by handling inevitable collisions early in the
- search process. See Cichelli's paper from Jan 1980 JACM for details.... */
-
-void
-Key_List::reorder (void)
-{
- T (Trace t ("Key_List::reorder");)
- List_Node *ptr;
- for (ptr = head; ptr; ptr = ptr->next)
- ptr->occurrence = get_occurrence (ptr);
-
- hash_sort = 0;
- occurrence_sort = 1;
-
- for (ptr = head = merge_sort (head); ptr->next; ptr = ptr->next)
- {
- set_determined (ptr);
-
- if (already_determined (ptr->next))
- continue;
- else
- {
- List_Node *trail_ptr = ptr->next;
- List_Node *run_ptr = trail_ptr->next;
-
- for (; run_ptr; run_ptr = trail_ptr->next)
- {
-
- if (already_determined (run_ptr))
- {
- trail_ptr->next = run_ptr->next;
- run_ptr->next = ptr->next;
- ptr = ptr->next = run_ptr;
- }
- else
- trail_ptr = run_ptr;
- }
- }
- }
-}
-
-/* ============================ Output routines ============================ */
-
-/* The "const " qualifier. */
-static const char *const_always;
-
-/* The "const " qualifier, for read-only arrays. */
-static const char *const_readonly_array;
-
-/* The "const " qualifier, for the array type. */
-static const char *const_for_struct;
-
-/* Returns the smallest unsigned C type capable of holding integers up to N. */
-
-static const char *
-smallest_integral_type (int n)
-{
- if (n <= UCHAR_MAX) return "unsigned char";
- if (n <= USHRT_MAX) return "unsigned short";
- return "unsigned int";
-}
-
-/* Returns the smallest signed C type capable of holding integers
- from MIN to MAX. */
-
-static const char *
-smallest_integral_type (int min, int max)
-{
- if (option[ANSIC] | option[CPLUSPLUS])
- if (min >= SCHAR_MIN && max <= SCHAR_MAX) return "signed char";
- if (min >= SHRT_MIN && max <= SHRT_MAX) return "short";
- return "int";
-}
-
-/* A cast from `char' to a valid array index. */
-static const char *char_to_index;
-
-/* ------------------------------------------------------------------------- */
-
-/* Computes the maximum and minimum hash values. Since the
- list is already sorted by hash value all we need to do is
- find the final item! */
-
-void
-Key_List::compute_min_max (void)
-{
- T (Trace t ("Key_List::compute_min_max");)
- List_Node *temp;
- for (temp = head; temp->next; temp = temp->next)
- ;
-
- min_hash_value = head->hash_value;
- max_hash_value = temp->hash_value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Returns the number of different hash values. */
-
-int
-Key_List::num_hash_values (void)
-{
- T (Trace t ("Key_List::num_hash_values");)
- int count = 1;
- List_Node *temp;
- int value;
-
- for (temp = head, value = temp->hash_value; temp->next; )
- {
- temp = temp->next;
- if (value != temp->hash_value)
- {
- value = temp->hash_value;
- count++;
- }
- }
- return count;
-}
-
-/* -------------------- Output_Constants and subclasses -------------------- */
-
-/* This class outputs an enumeration defining some constants. */
-
-struct Output_Constants
-{
- virtual void output_start () = 0;
- virtual void output_item (const char *name, int value) = 0;
- virtual void output_end () = 0;
- Output_Constants () {}
- virtual ~Output_Constants () {}
-};
-
-/* This class outputs an enumeration in #define syntax. */
-
-struct Output_Defines : public Output_Constants
-{
- virtual void output_start ();
- virtual void output_item (const char *name, int value);
- virtual void output_end ();
- Output_Defines () {}
- virtual ~Output_Defines () {}
-};
-
-void Output_Defines::output_start ()
-{
- T (Trace t ("Output_Defines::output_start");)
- printf ("\n");
-}
-
-void Output_Defines::output_item (const char *name, int value)
-{
- T (Trace t ("Output_Defines::output_item");)
- printf ("#define %s %d\n", name, value);
-}
-
-void Output_Defines::output_end ()
-{
- T (Trace t ("Output_Defines::output_end");)
-}
-
-/* This class outputs an enumeration using `enum'. */
-
-struct Output_Enum : public Output_Constants
-{
- virtual void output_start ();
- virtual void output_item (const char *name, int value);
- virtual void output_end ();
- Output_Enum (const char *indent) : indentation (indent) {}
- virtual ~Output_Enum () {}
-private:
- const char *indentation;
- int pending_comma;
-};
-
-void Output_Enum::output_start ()
-{
- T (Trace t ("Output_Enum::output_start");)
- printf ("%senum\n"
- "%s {\n",
- indentation, indentation);
- pending_comma = 0;
-}
-
-void Output_Enum::output_item (const char *name, int value)
-{
- T (Trace t ("Output_Enum::output_item");)
- if (pending_comma)
- printf (",\n");
- printf ("%s %s = %d", indentation, name, value);
- pending_comma = 1;
-}
-
-void Output_Enum::output_end ()
-{
- T (Trace t ("Output_Enum::output_end");)
- if (pending_comma)
- printf ("\n");
- printf ("%s };\n\n", indentation);
-}
-
-/* Outputs the maximum and minimum hash values etc. */
-
-void
-Key_List::output_constants (struct Output_Constants& style)
-{
- T (Trace t ("Key_List::output_constants");)
-
- style.output_start ();
- style.output_item ("TOTAL_KEYWORDS", total_keys);
- style.output_item ("MIN_WORD_LENGTH", min_key_len);
- style.output_item ("MAX_WORD_LENGTH", max_key_len);
- style.output_item ("MIN_HASH_VALUE", min_hash_value);
- style.output_item ("MAX_HASH_VALUE", max_hash_value);
- style.output_end ();
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Outputs a keyword, as a string: enclosed in double quotes, escaping
- backslashes, double quote and unprintable characters. */
-
-static void
-output_string (const char *key, int len)
-{
- T (Trace t ("output_string");)
-
- putchar ('"');
- for (; len > 0; len--)
- {
- unsigned char c = (unsigned char) *key++;
- if (isprint (c))
- {
- if (c == '"' || c == '\\')
- putchar ('\\');
- putchar (c);
- }
- else
- {
- /* Use octal escapes, not hexadecimal escapes, because some old
- C compilers didn't understand hexadecimal escapes, and because
- hexadecimal escapes are not limited to 2 digits, thus needing
- special care if the following character happens to be a digit. */
- putchar ('\\');
- putchar ('0' + ((c >> 6) & 7));
- putchar ('0' + ((c >> 3) & 7));
- putchar ('0' + (c & 7));
- }
- }
- putchar ('"');
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Outputs a type and a const specifier.
- The output is terminated with a space. */
-
-static void
-output_const_type (const char *const_string, const char *type_string)
-{
- if (type_string[strlen(type_string)-1] == '*')
- printf ("%s %s", type_string, const_string);
- else
- printf ("%s%s ", const_string, type_string);
-}
-
-/* ----------------------- Output_Expr and subclasses ----------------------- */
-
-/* This class outputs a general expression. */
-
-struct Output_Expr
-{
- virtual void output_expr () const = 0;
- Output_Expr () {}
- virtual ~Output_Expr () {}
-};
-
-/* This class outputs an expression formed by a single string. */
-
-struct Output_Expr1 : public Output_Expr
-{
- virtual void output_expr () const;
- Output_Expr1 (const char *piece1) : p1 (piece1) {}
- virtual ~Output_Expr1 () {}
-private:
- const char *p1;
-};
-
-void Output_Expr1::output_expr () const
-{
- T (Trace t ("Output_Expr1::output_expr");)
- printf ("%s", p1);
-}
-
-#if 0 /* unused */
-
-/* This class outputs an expression formed by the concatenation of two
- strings. */
-
-struct Output_Expr2 : public Output_Expr
-{
- virtual void output_expr () const;
- Output_Expr2 (const char *piece1, const char *piece2)
- : p1 (piece1), p2 (piece2) {}
- virtual ~Output_Expr2 () {}
-private:
- const char *p1;
- const char *p2;
-};
-
-void Output_Expr2::output_expr () const
-{
- T (Trace t ("Output_Expr2::output_expr");)
- printf ("%s%s", p1, p2);
-}
-
-#endif
-
-/* --------------------- Output_Compare and subclasses --------------------- */
-
-/* This class outputs a comparison expression. */
-
-struct Output_Compare
-{
- virtual void output_comparison (const Output_Expr& expr1,
- const Output_Expr& expr2) const = 0;
- Output_Compare () {}
- virtual ~Output_Compare () {}
-};
-
-/* This class outputs a comparison using strcmp. */
-
-struct Output_Compare_Strcmp : public Output_Compare
-{
- virtual void output_comparison (const Output_Expr& expr1,
- const Output_Expr& expr2) const;
- Output_Compare_Strcmp () {}
- virtual ~Output_Compare_Strcmp () {}
-};
-
-void Output_Compare_Strcmp::output_comparison (const Output_Expr& expr1,
- const Output_Expr& expr2) const
-{
- T (Trace t ("Output_Compare_Strcmp::output_comparison");)
- printf ("*");
- expr1.output_expr ();
- printf (" == *");
- expr2.output_expr ();
- printf (" && !strcmp (");
- expr1.output_expr ();
- printf (" + 1, ");
- expr2.output_expr ();
- printf (" + 1)");
-}
-
-/* This class outputs a comparison using strncmp.
- Note that the length of expr1 will be available through the local variable
- `len'. */
-
-struct Output_Compare_Strncmp : public Output_Compare
-{
- virtual void output_comparison (const Output_Expr& expr1,
- const Output_Expr& expr2) const;
- Output_Compare_Strncmp () {}
- virtual ~Output_Compare_Strncmp () {}
-};
-
-void Output_Compare_Strncmp::output_comparison (const Output_Expr& expr1,
- const Output_Expr& expr2) const
-{
- T (Trace t ("Output_Compare_Strncmp::output_comparison");)
- printf ("*");
- expr1.output_expr ();
- printf (" == *");
- expr2.output_expr ();
- printf (" && !strncmp (");
- expr1.output_expr ();
- printf (" + 1, ");
- expr2.output_expr ();
- printf (" + 1, len - 1) && ");
- expr2.output_expr ();
- printf ("[len] == '\\0'");
-}
-
-/* This class outputs a comparison using memcmp.
- Note that the length of expr1 (available through the local variable `len')
- must be verified to be equal to the length of expr2 prior to this
- comparison. */
-
-struct Output_Compare_Memcmp : public Output_Compare
-{
- virtual void output_comparison (const Output_Expr& expr1,
- const Output_Expr& expr2) const;
- Output_Compare_Memcmp () {}
- virtual ~Output_Compare_Memcmp () {}
-};
-
-void Output_Compare_Memcmp::output_comparison (const Output_Expr& expr1,
- const Output_Expr& expr2) const
-{
- T (Trace t ("Output_Compare_Memcmp::output_comparison");)
- printf ("*");
- expr1.output_expr ();
- printf (" == *");
- expr2.output_expr ();
- printf (" && !memcmp (");
- expr1.output_expr ();
- printf (" + 1, ");
- expr2.output_expr ();
- printf (" + 1, len - 1)");
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Generates C code for the hash function that returns the
- proper encoding for each key word. */
-
-void
-Key_List::output_hash_function (void)
-{
- T (Trace t ("Key_List::output_hash_function");)
- const int max_column = 10;
- int field_width;
-
- /* Calculate maximum number of digits required for MAX_HASH_VALUE. */
- field_width = 2;
- for (int trunc = max_hash_value; (trunc /= 10) > 0;)
- field_width++;
-
- /* Output the function's head. */
- if (option[CPLUSPLUS])
- printf ("inline ");
- else if (option[KRC] | option[C] | option[ANSIC])
- printf ("#ifdef __GNUC__\n"
- "__inline\n"
- "#else\n"
- "#ifdef __cplusplus\n"
- "inline\n"
- "#endif\n"
- "#endif\n");
-
- if (option[KRC] | option[C] | option[ANSIC])
- printf ("static ");
- printf ("unsigned int\n");
- if (option[CPLUSPLUS])
- printf ("%s::", option.get_class_name ());
- printf ("%s ", option.get_hash_name ());
- printf (option[KRC] ?
- "(str, len)\n"
- " register char *str;\n"
- " register unsigned int len;\n" :
- option[C] ?
- "(str, len)\n"
- " register const char *str;\n"
- " register unsigned int len;\n" :
- option[ANSIC] | option[CPLUSPLUS] ?
- "(register const char *str, register unsigned int len)\n" :
- "");
-
- /* Note that when the hash function is called, it has already been verified
- that min_key_len <= len <= max_key_len. */
-
- /* Output the function's body. */
- printf ("{\n");
-
- /* First the asso_values array. */
- printf (" static %s%s asso_values[] =\n"
- " {",
- const_readonly_array,
- smallest_integral_type (max_hash_value + 1));
-
- for (int count = 0; count < ALPHA_SIZE; count++)
- {
- if (count > 0)
- printf (",");
- if (!(count % max_column))
- printf ("\n ");
- printf ("%*d", field_width,
- occurrences[count] ? asso_values[count] : max_hash_value + 1);
- }
-
- printf ("\n"
- " };\n");
-
- /* Optimize special case of ``-k 1,$'' */
- if (option[DEFAULTCHARS])
- printf (" return %sasso_values[%sstr[len - 1]] + asso_values[%sstr[0]];\n",
- option[NOLENGTH] ? "" : "len + ",
- char_to_index, char_to_index);
- else
- {
- int key_pos;
-
- option.reset ();
-
- /* Get first (also highest) key position. */
- key_pos = option.get ();
-
- if (!option[ALLCHARS] && (key_pos == WORD_END || key_pos <= min_key_len))
- {
- /* We can perform additional optimizations here:
- Write it out as a single expression. Note that the values
- are added as `int's even though the asso_values array may
- contain `unsigned char's or `unsigned short's. */
-
- printf (" return %s",
- option[NOLENGTH] ? "" : "len + ");
-
- for (; key_pos != WORD_END; )
- {
- printf ("asso_values[%sstr[%d]]", char_to_index, key_pos - 1);
- if ((key_pos = option.get ()) != EOS)
- printf (" + ");
- else
- break;
- }
-
- if (key_pos == WORD_END)
- printf ("asso_values[%sstr[len - 1]]", char_to_index);
-
- printf (";\n");
- }
- else
- {
- /* We've got to use the correct, but brute force, technique. */
- printf (" register int hval = %s;\n\n"
- " switch (%s)\n"
- " {\n"
- " default:\n",
- option[NOLENGTH] ? "0" : "len",
- option[NOLENGTH] ? "len" : "hval");
-
- /* User wants *all* characters considered in hash. */
- if (option[ALLCHARS])
- {
- for (int i = max_key_len; i > 0; i--)
- printf (" case %d:\n"
- " hval += asso_values[%sstr[%d]];\n",
- i, char_to_index, i - 1);
-
- printf (" break;\n"
- " }\n"
- " return hval;\n");
- }
- else /* do the hard part... */
- {
- while (key_pos != WORD_END && key_pos > max_key_len)
- if ((key_pos = option.get ()) == EOS)
- break;
-
- if (key_pos != EOS && key_pos != WORD_END)
- {
- int i = key_pos;
- do
- {
- for ( ; i >= key_pos; i--)
- printf (" case %d:\n", i);
-
- printf (" hval += asso_values[%sstr[%d]];\n",
- char_to_index, key_pos - 1);
-
- key_pos = option.get ();
- }
- while (key_pos != EOS && key_pos != WORD_END);
-
- for ( ; i >= min_key_len; i--)
- printf (" case %d:\n", i);
- }
-
- printf (" break;\n"
- " }\n"
- " return hval");
- if (key_pos == WORD_END)
- printf (" + asso_values[%sstr[len - 1]]", char_to_index);
- printf (";\n");
- }
- }
- }
- printf ("}\n\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Prints out a table of keyword lengths, for use with the
- comparison code in generated function ``in_word_set''. */
-
-void
-Key_List::output_keylength_table (void)
-{
- T (Trace t ("Key_List::output_keylength_table");)
- const int columns = 14;
- int index;
- int column;
- const char *indent = option[GLOBAL] ? "" : " ";
- List_Node *temp;
-
- printf ("%sstatic %s%s lengthtable[] =\n%s {",
- indent, const_readonly_array,
- smallest_integral_type (max_key_len),
- indent);
-
- /* Generate an array of lengths, similar to output_keyword_table. */
-
- column = 0;
- for (temp = head, index = 0; temp; temp = temp->next)
- {
- if (option[SWITCH] && !option[TYPE]
- && !(temp->link
- || (temp->next && temp->hash_value == temp->next->hash_value)))
- continue;
-
- if (index < temp->hash_value && !option[SWITCH] && !option[DUP])
- {
- /* Some blank entries. */
- for ( ; index < temp->hash_value; index++)
- {
- if (index > 0)
- printf (",");
- if ((column++ % columns) == 0)
- printf ("\n%s ", indent);
- printf ("%3d", 0);
- }
- }
-
- if (index > 0)
- printf (",");
- if ((column++ % columns) == 0)
- printf("\n%s ", indent);
- printf ("%3d", temp->key_length);
-
- /* Deal with links specially. */
- if (temp->link) // implies option[DUP]
- for (List_Node *links = temp->link; links; links = links->link)
- {
- ++index;
- printf (",");
- if ((column++ % columns) == 0)
- printf("\n%s ", indent);
- printf ("%3d", links->key_length);
- }
-
- index++;
- }
-
- printf ("\n%s };\n", indent);
- if (option[GLOBAL])
- printf ("\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void
-output_keyword_entry (List_Node *temp, const char *indent)
-{
- printf ("%s ", indent);
- if (option[TYPE])
- printf ("{");
- output_string (temp->key, temp->key_length);
- if (option[TYPE])
- {
- if (strlen (temp->rest) > 0)
- printf (",%s", temp->rest);
- printf ("}");
- }
- if (option[DEBUG])
- printf (" /* hash value = %d, index = %d */",
- temp->hash_value, temp->index);
-}
-
-static void
-output_keyword_blank_entries (int count, const char *indent)
-{
- int columns;
- if (option[TYPE])
- {
- columns = 58 / (6 + strlen (option.get_initializer_suffix()));
- if (columns == 0)
- columns = 1;
- }
- else
- {
- columns = 9;
- }
- int column = 0;
- for (int i = 0; i < count; i++)
- {
- if ((column % columns) == 0)
- {
- if (i > 0)
- printf (",\n");
- printf ("%s ", indent);
- }
- else
- {
- if (i > 0)
- printf (", ");
- }
- if (option[TYPE])
- printf ("{\"\"%s}", option.get_initializer_suffix());
- else
- printf ("\"\"");
- column++;
- }
-}
-
-/* Prints out the array containing the key words for the hash function. */
-
-void
-Key_List::output_keyword_table (void)
-{
- T (Trace t ("Key_List::output_keyword_table");)
- const char *indent = option[GLOBAL] ? "" : " ";
- int index;
- List_Node *temp;
-
- printf ("%sstatic ",
- indent);
- output_const_type (const_readonly_array, struct_tag);
- printf ("%s[] =\n"
- "%s {\n",
- option.get_wordlist_name (),
- indent);
-
- /* Generate an array of reserved words at appropriate locations. */
-
- for (temp = head, index = 0; temp; temp = temp->next)
- {
- if (option[SWITCH] && !option[TYPE]
- && !(temp->link
- || (temp->next && temp->hash_value == temp->next->hash_value)))
- continue;
-
- if (index > 0)
- printf (",\n");
-
- if (index < temp->hash_value && !option[SWITCH] && !option[DUP])
- {
- /* Some blank entries. */
- output_keyword_blank_entries (temp->hash_value - index, indent);
- printf (",\n");
- index = temp->hash_value;
- }
-
- temp->index = index;
-
- output_keyword_entry (temp, indent);
-
- /* Deal with links specially. */
- if (temp->link) // implies option[DUP]
- for (List_Node *links = temp->link; links; links = links->link)
- {
- links->index = ++index;
- printf (",\n");
- output_keyword_entry (links, indent);
- }
-
- index++;
- }
- if (index > 0)
- printf ("\n");
-
- printf ("%s };\n\n", indent);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Generates the large, sparse table that maps hash values into
- the smaller, contiguous range of the keyword table. */
-
-void
-Key_List::output_lookup_array (void)
-{
- T (Trace t ("Key_List::output_lookup_array");)
- if (option[DUP])
- {
- const int DEFAULT_VALUE = -1;
-
- /* Because of the way output_keyword_table works, every duplicate set is
- stored contiguously in the wordlist array. */
- struct duplicate_entry
- {
- int hash_value; /* Hash value for this particular duplicate set. */
- int index; /* Index into the main keyword storage array. */
- int count; /* Number of consecutive duplicates at this index. */
- };
-
-#if LARGE_STACK_ARRAYS
- duplicate_entry duplicates[total_duplicates];
- int lookup_array[max_hash_value + 1 + 2*total_duplicates];
-#else
- // Note: we don't use new, because that invokes a custom operator new.
- duplicate_entry *duplicates = (duplicate_entry *)
- malloc (total_duplicates * sizeof(duplicate_entry) + 1);
- int *lookup_array = (int *)
- malloc ((max_hash_value + 1 + 2*total_duplicates) * sizeof(int));
- if (duplicates == NULL || lookup_array == NULL)
- abort();
-#endif
- int lookup_array_size = max_hash_value + 1;
- duplicate_entry *dup_ptr = &duplicates[0];
- int *lookup_ptr = &lookup_array[max_hash_value + 1 + 2*total_duplicates];
-
- while (lookup_ptr > lookup_array)
- *--lookup_ptr = DEFAULT_VALUE;
-
- /* Now dup_ptr = &duplicates[0] and lookup_ptr = &lookup_array[0]. */
-
- for (List_Node *temp = head; temp; temp = temp->next)
- {
- int hash_value = temp->hash_value;
- lookup_array[hash_value] = temp->index;
- if (option[DEBUG])
- fprintf (stderr, "keyword = %.*s, index = %d\n",
- temp->key_length, temp->key, temp->index);
- if (temp->link
- || (temp->next && hash_value == temp->next->hash_value))
- {
- /* Start a duplicate entry. */
- dup_ptr->hash_value = hash_value;
- dup_ptr->index = temp->index;
- dup_ptr->count = 1;
-
- for (;;)
- {
- for (List_Node *ptr = temp->link; ptr; ptr = ptr->link)
- {
- dup_ptr->count++;
- if (option[DEBUG])
- fprintf (stderr,
- "static linked keyword = %.*s, index = %d\n",
- ptr->key_length, ptr->key, ptr->index);
- }
-
- if (!(temp->next && hash_value == temp->next->hash_value))
- break;
-
- temp = temp->next;
-
- dup_ptr->count++;
- if (option[DEBUG])
- fprintf (stderr, "dynamic linked keyword = %.*s, index = %d\n",
- temp->key_length, temp->key, temp->index);
- }
- assert (dup_ptr->count >= 2);
- dup_ptr++;
- }
- }
-
- while (dup_ptr > duplicates)
- {
- dup_ptr--;
-
- if (option[DEBUG])
- fprintf (stderr,
- "dup_ptr[%d]: hash_value = %d, index = %d, count = %d\n",
- dup_ptr - duplicates,
- dup_ptr->hash_value, dup_ptr->index, dup_ptr->count);
-
- int i;
- /* Start searching for available space towards the right part
- of the lookup array. */
- for (i = dup_ptr->hash_value; i < lookup_array_size-1; i++)
- if (lookup_array[i] == DEFAULT_VALUE
- && lookup_array[i + 1] == DEFAULT_VALUE)
- goto found_i;
- /* If we didn't find it to the right look to the left instead... */
- for (i = dup_ptr->hash_value-1; i >= 0; i--)
- if (lookup_array[i] == DEFAULT_VALUE
- && lookup_array[i + 1] == DEFAULT_VALUE)
- goto found_i;
- /* Append to the end of lookup_array. */
- i = lookup_array_size;
- lookup_array_size += 2;
- found_i:
- /* Put in an indirection from dup_ptr->hash_value to i.
- At i and i+1 store dup_ptr->index and dup_ptr->count. */
- assert (lookup_array[dup_ptr->hash_value] == dup_ptr->index);
- lookup_array[dup_ptr->hash_value] = - 1 - total_keys - i;
- lookup_array[i] = - total_keys + dup_ptr->index;
- lookup_array[i + 1] = - dup_ptr->count;
- /* All these three values are <= -2, distinct from DEFAULT_VALUE. */
- }
-
- /* The values of the lookup array are now known. */
-
- int min = INT_MAX;
- int max = INT_MIN;
- lookup_ptr = lookup_array + lookup_array_size;
- while (lookup_ptr > lookup_array)
- {
- int val = *--lookup_ptr;
- if (min > val)
- min = val;
- if (max < val)
- max = val;
- }
-
- const char *indent = option[GLOBAL] ? "" : " ";
- printf ("%sstatic %s%s lookup[] =\n"
- "%s {",
- indent, const_readonly_array, smallest_integral_type (min, max),
- indent);
-
- int field_width;
- /* Calculate maximum number of digits required for MIN..MAX. */
- {
- field_width = 2;
- for (int trunc = max; (trunc /= 10) > 0;)
- field_width++;
- }
- if (min < 0)
- {
- int neg_field_width = 2;
- for (int trunc = -min; (trunc /= 10) > 0;)
- neg_field_width++;
- neg_field_width++; /* account for the minus sign */
- if (field_width < neg_field_width)
- field_width = neg_field_width;
- }
-
- const int columns = 42 / field_width;
- int column;
-
- column = 0;
- for (int i = 0; i < lookup_array_size; i++)
- {
- if (i > 0)
- printf (",");
- if ((column++ % columns) == 0)
- printf("\n%s ", indent);
- printf ("%*d", field_width, lookup_array[i]);
- }
- printf ("\n%s };\n\n", indent);
-
-#if !LARGE_STACK_ARRAYS
- free ((char *) duplicates);
- free ((char *) lookup_array);
-#endif
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Generate all the tables needed for the lookup function. */
-
-void
-Key_List::output_lookup_tables (void)
-{
- T (Trace t ("Key_List::output_lookup_tables");)
-
- if (option[SWITCH])
- {
- /* Use the switch in place of lookup table. */
- if (option[LENTABLE] && (option[DUP] && total_duplicates > 0))
- output_keylength_table ();
- if (option[TYPE] || (option[DUP] && total_duplicates > 0))
- output_keyword_table ();
- }
- else
- {
- /* Use the lookup table, in place of switch. */
- if (option[LENTABLE])
- output_keylength_table ();
- output_keyword_table ();
- output_lookup_array ();
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Output a single switch case (including duplicates). Advance list. */
-
-static List_Node *
-output_switch_case (List_Node *list, int indent, int *jumps_away)
-{
- T (Trace t ("output_switch_case");)
-
- if (option[DEBUG])
- printf ("%*s/* hash value = %4d, keyword = \"%.*s\" */\n",
- indent, "", list->hash_value, list->key_length, list->key);
-
- if (option[DUP]
- && (list->link
- || (list->next && list->hash_value == list->next->hash_value)))
- {
- if (option[LENTABLE])
- printf ("%*slengthptr = &lengthtable[%d];\n",
- indent, "", list->index);
- printf ("%*swordptr = &%s[%d];\n",
- indent, "", option.get_wordlist_name (), list->index);
-
- int count = 0;
- for (List_Node *temp = list; ; temp = temp->next)
- {
- for (List_Node *links = temp; links; links = links->link)
- count++;
- if (!(temp->next && temp->hash_value == temp->next->hash_value))
- break;
- }
-
- printf ("%*swordendptr = wordptr + %d;\n"
- "%*sgoto multicompare;\n",
- indent, "", count,
- indent, "");
- *jumps_away = 1;
- }
- else
- {
- if (option[LENTABLE])
- {
- printf ("%*sif (len == %d)\n"
- "%*s {\n",
- indent, "", list->key_length,
- indent, "");
- indent += 4;
- }
- printf ("%*sresword = ",
- indent, "");
- if (option[TYPE])
- printf ("&%s[%d]", option.get_wordlist_name (), list->index);
- else
- output_string (list->key, list->key_length);
- printf (";\n");
- printf ("%*sgoto compare;\n",
- indent, "");
- if (option[LENTABLE])
- {
- indent -= 4;
- printf ("%*s }\n",
- indent, "");
- }
- else
- *jumps_away = 1;
- }
-
- while (list->next && list->hash_value == list->next->hash_value)
- list = list->next;
- list = list->next;
- return list;
-}
-
-/* Output a total of size cases, grouped into num_switches switch statements,
- where 0 < num_switches <= size. */
-
-static void
-output_switches (List_Node *list, int num_switches, int size, int min_hash_value, int max_hash_value, int indent)
-{
- T (Trace t ("output_switches");)
-
- if (option[DEBUG])
- printf ("%*s/* know %d <= key <= %d, contains %d cases */\n",
- indent, "", min_hash_value, max_hash_value, size);
-
- if (num_switches > 1)
- {
- int part1 = num_switches / 2;
- int part2 = num_switches - part1;
- int size1 = (int)((double)size / (double)num_switches * (double)part1 + 0.5);
- int size2 = size - size1;
-
- List_Node *temp = list;
- for (int count = size1; count > 0; count--)
- {
- while (temp->hash_value == temp->next->hash_value)
- temp = temp->next;
- temp = temp->next;
- }
-
- printf ("%*sif (key < %d)\n"
- "%*s {\n",
- indent, "", temp->hash_value,
- indent, "");
-
- output_switches (list, part1, size1, min_hash_value, temp->hash_value-1, indent+4);
-
- printf ("%*s }\n"
- "%*selse\n"
- "%*s {\n",
- indent, "", indent, "", indent, "");
-
- output_switches (temp, part2, size2, temp->hash_value, max_hash_value, indent+4);
-
- printf ("%*s }\n",
- indent, "");
- }
- else
- {
- /* Output a single switch. */
- int lowest_case_value = list->hash_value;
- if (size == 1)
- {
- int jumps_away = 0;
- assert (min_hash_value <= lowest_case_value);
- assert (lowest_case_value <= max_hash_value);
- if (min_hash_value == max_hash_value)
- output_switch_case (list, indent, &jumps_away);
- else
- {
- printf ("%*sif (key == %d)\n"
- "%*s {\n",
- indent, "", lowest_case_value,
- indent, "");
- output_switch_case (list, indent+4, &jumps_away);
- printf ("%*s }\n",
- indent, "");
- }
- }
- else
- {
- if (lowest_case_value == 0)
- printf ("%*sswitch (key)\n", indent, "");
- else
- printf ("%*sswitch (key - %d)\n", indent, "", lowest_case_value);
- printf ("%*s {\n",
- indent, "");
- for (; size > 0; size--)
- {
- int jumps_away = 0;
- printf ("%*s case %d:\n",
- indent, "", list->hash_value - lowest_case_value);
- list = output_switch_case (list, indent+6, &jumps_away);
- if (!jumps_away)
- printf ("%*s break;\n",
- indent, "");
- }
- printf ("%*s }\n",
- indent, "");
- }
- }
-}
-
-/* Generates C code to perform the keyword lookup. */
-
-void
-Key_List::output_lookup_function_body (const Output_Compare& comparison)
-{
- T (Trace t ("Key_List::output_lookup_function_body");)
-
- printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n"
- " {\n"
- " register int key = %s (str, len);\n\n",
- option.get_hash_name ());
-
- if (option[SWITCH])
- {
- int switch_size = num_hash_values ();
- int num_switches = option.get_total_switches ();
- if (num_switches > switch_size)
- num_switches = switch_size;
-
- printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"
- " {\n");
- if (option[DUP])
- {
- if (option[LENTABLE])
- printf (" register %s%s *lengthptr;\n",
- const_always, smallest_integral_type (max_key_len));
- printf (" register ");
- output_const_type (const_readonly_array, struct_tag);
- printf ("*wordptr;\n");
- printf (" register ");
- output_const_type (const_readonly_array, struct_tag);
- printf ("*wordendptr;\n");
- }
- if (option[TYPE])
- {
- printf (" register ");
- output_const_type (const_readonly_array, struct_tag);
- printf ("*resword;\n\n");
- }
- else
- printf (" register %sresword;\n\n",
- struct_tag);
-
- output_switches (head, num_switches, switch_size, min_hash_value, max_hash_value, 10);
-
- if (option[DUP])
- {
- int indent = 8;
- printf ("%*s return 0;\n"
- "%*smulticompare:\n"
- "%*s while (wordptr < wordendptr)\n"
- "%*s {\n",
- indent, "", indent, "", indent, "", indent, "");
- if (option[LENTABLE])
- {
- printf ("%*s if (len == *lengthptr)\n"
- "%*s {\n",
- indent, "", indent, "");
- indent += 4;
- }
- printf ("%*s register %schar *s = ",
- indent, "", const_always);
- if (option[TYPE])
- printf ("wordptr->%s", option.get_key_name ());
- else
- printf ("*wordptr");
- printf (";\n\n"
- "%*s if (",
- indent, "");
- comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
- printf (")\n"
- "%*s return %s;\n",
- indent, "",
- option[TYPE] ? "wordptr" : "s");
- if (option[LENTABLE])
- {
- indent -= 4;
- printf ("%*s }\n",
- indent, "");
- }
- if (option[LENTABLE])
- printf ("%*s lengthptr++;\n",
- indent, "");
- printf ("%*s wordptr++;\n"
- "%*s }\n",
- indent, "", indent, "");
- }
- printf (" return 0;\n"
- " compare:\n");
- if (option[TYPE])
- {
- printf (" {\n"
- " register %schar *s = resword->%s;\n\n"
- " if (",
- const_always, option.get_key_name ());
- comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
- printf (")\n"
- " return resword;\n"
- " }\n");
- }
- else
- {
- printf (" if (");
- comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("resword"));
- printf (")\n"
- " return resword;\n");
- }
- printf (" }\n");
- }
- else
- {
- printf (" if (key <= MAX_HASH_VALUE && key >= 0)\n");
-
- if (option[DUP])
- {
- int indent = 8;
- printf ("%*s{\n"
- "%*s register int index = lookup[key];\n\n"
- "%*s if (index >= 0)\n",
- indent, "", indent, "", indent, "");
- if (option[LENTABLE])
- {
- printf ("%*s {\n"
- "%*s if (len == lengthtable[index])\n",
- indent, "", indent, "");
- indent += 4;
- }
- printf ("%*s {\n"
- "%*s register %schar *s = %s[index]",
- indent, "",
- indent, "", const_always, option.get_wordlist_name ());
- if (option[TYPE])
- printf (".%s", option.get_key_name ());
- printf (";\n\n"
- "%*s if (",
- indent, "");
- comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
- printf (")\n"
- "%*s return ",
- indent, "");
- if (option[TYPE])
- printf ("&%s[index]", option.get_wordlist_name ());
- else
- printf ("s");
- printf (";\n"
- "%*s }\n",
- indent, "");
- if (option[LENTABLE])
- {
- indent -= 4;
- printf ("%*s }\n", indent, "");
- }
- if (total_duplicates > 0)
- {
- printf ("%*s else if (index < -TOTAL_KEYWORDS)\n"
- "%*s {\n"
- "%*s register int offset = - 1 - TOTAL_KEYWORDS - index;\n",
- indent, "", indent, "", indent, "");
- if (option[LENTABLE])
- printf ("%*s register %s%s *lengthptr = &lengthtable[TOTAL_KEYWORDS + lookup[offset]];\n",
- indent, "", const_always, smallest_integral_type (max_key_len));
- printf ("%*s register ",
- indent, "");
- output_const_type (const_readonly_array, struct_tag);
- printf ("*wordptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n",
- option.get_wordlist_name ());
- printf ("%*s register ",
- indent, "");
- output_const_type (const_readonly_array, struct_tag);
- printf ("*wordendptr = wordptr + -lookup[offset + 1];\n\n");
- printf ("%*s while (wordptr < wordendptr)\n"
- "%*s {\n",
- indent, "", indent, "");
- if (option[LENTABLE])
- {
- printf ("%*s if (len == *lengthptr)\n"
- "%*s {\n",
- indent, "", indent, "");
- indent += 4;
- }
- printf ("%*s register %schar *s = ",
- indent, "", const_always);
- if (option[TYPE])
- printf ("wordptr->%s", option.get_key_name ());
- else
- printf ("*wordptr");
- printf (";\n\n"
- "%*s if (",
- indent, "");
- comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
- printf (")\n"
- "%*s return %s;\n",
- indent, "",
- option[TYPE] ? "wordptr" : "s");
- if (option[LENTABLE])
- {
- indent -= 4;
- printf ("%*s }\n",
- indent, "");
- }
- if (option[LENTABLE])
- printf ("%*s lengthptr++;\n",
- indent, "");
- printf ("%*s wordptr++;\n"
- "%*s }\n"
- "%*s }\n",
- indent, "", indent, "", indent, "");
- }
- printf ("%*s}\n",
- indent, "");
- }
- else
- {
- int indent = 8;
- if (option[LENTABLE])
- {
- printf ("%*sif (len == lengthtable[key])\n",
- indent, "");
- indent += 2;
- }
-
- printf ("%*s{\n"
- "%*s register %schar *s = %s[key]",
- indent, "",
- indent, "", const_always, option.get_wordlist_name ());
-
- if (option[TYPE])
- printf (".%s", option.get_key_name ());
-
- printf (";\n\n"
- "%*s if (",
- indent, "");
- comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
- printf (")\n"
- "%*s return ",
- indent, "");
- if (option[TYPE])
- printf ("&%s[key]", option.get_wordlist_name ());
- else
- printf ("s");
- printf (";\n"
- "%*s}\n",
- indent, "");
- }
- }
- printf (" }\n"
- " return 0;\n");
-}
-
-/* Generates C code for the lookup function. */
-
-void
-Key_List::output_lookup_function (void)
-{
- T (Trace t ("Key_List::output_lookup_function");)
-
- /* Output the function's head. */
- if (option[KRC] | option[C] | option[ANSIC])
- printf ("#ifdef __GNUC__\n"
- "__inline\n"
- "#endif\n");
-
- printf ("%s%s\n",
- const_for_struct, return_type);
- if (option[CPLUSPLUS])
- printf ("%s::", option.get_class_name ());
- printf ("%s ", option.get_function_name ());
- printf (option[KRC] ?
- "(str, len)\n"
- " register char *str;\n"
- " register unsigned int len;\n" :
- option[C] ?
- "(str, len)\n"
- " register const char *str;\n"
- " register unsigned int len;\n" :
- option[ANSIC] | option[CPLUSPLUS] ?
- "(register const char *str, register unsigned int len)\n" :
- "");
-
- /* Output the function's body. */
- printf ("{\n");
-
- if (option[ENUM] && !option[GLOBAL])
- {
- Output_Enum style (" ");
- output_constants (style);
- }
-
- if (!option[GLOBAL])
- output_lookup_tables ();
-
- if (option[LENTABLE])
- output_lookup_function_body (Output_Compare_Memcmp ());
- else
- {
- if (option[COMP])
- output_lookup_function_body (Output_Compare_Strncmp ());
- else
- output_lookup_function_body (Output_Compare_Strcmp ());
- }
-
- printf ("}\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Generates the hash function and the key word recognizer function
- based upon the user's Options. */
-
-void
-Key_List::output (void)
-{
- T (Trace t ("Key_List::output");)
-
- compute_min_max ();
-
- if (option[C] | option[ANSIC] | option[CPLUSPLUS])
- {
- const_always = "const ";
- const_readonly_array = (option[CONST] ? "const " : "");
- const_for_struct = ((option[CONST] && option[TYPE]) ? "const " : "");
- }
- else
- {
- const_always = "";
- const_readonly_array = "";
- const_for_struct = "";
- }
-
- if (!option[TYPE])
- {
- return_type = (const_always[0] ? "const char *" : "char *");
- struct_tag = (const_always[0] ? "const char *" : "char *");
- }
-
- char_to_index = (option[SEVENBIT] ? "" : "(unsigned char)");
-
- printf ("/* ");
- if (option[KRC])
- printf ("KR-C");
- else if (option[C])
- printf ("C");
- else if (option[ANSIC])
- printf ("ANSI-C");
- else if (option[CPLUSPLUS])
- printf ("C++");
- printf (" code produced by gperf version %s */\n", version_string);
- Options::print_options ();
-
- printf ("%s\n", include_src);
-
- if (option[TYPE] && !option[NOTYPE]) /* Output type declaration now, reference it later on.... */
- printf ("%s;\n", array_type);
-
- if (option[INCLUDE])
- printf ("#include <string.h>\n"); /* Declare strlen(), strcmp(), strncmp(). */
-
- if (!option[ENUM])
- {
- Output_Defines style;
- output_constants (style);
- }
- else if (option[GLOBAL])
- {
- Output_Enum style ("");
- output_constants (style);
- }
-
- printf ("/* maximum key range = %d, duplicates = %d */\n\n",
- max_hash_value - min_hash_value + 1, total_duplicates);
-
- if (option[CPLUSPLUS])
- printf ("class %s\n"
- "{\n"
- "private:\n"
- " static inline unsigned int %s (const char *str, unsigned int len);\n"
- "public:\n"
- " static %s%s%s (const char *str, unsigned int len);\n"
- "};\n"
- "\n",
- option.get_class_name (), option.get_hash_name (),
- const_for_struct, return_type, option.get_function_name ());
-
- output_hash_function ();
-
- if (option[GLOBAL])
- output_lookup_tables ();
-
- output_lookup_function ();
-
- if (additional_code)
- for (int c; (c = getchar ()) != EOF; putchar (c))
- ;
-
- fflush (stdout);
-}
-
-/* ========================= End of Output routines ========================= */
-
-/* Sorts the keys by hash value. */
-
-void
-Key_List::sort (void)
-{
- T (Trace t ("Key_List::sort");)
- hash_sort = 1;
- occurrence_sort = 0;
-
- head = merge_sort (head);
-}
-
-/* Dumps the key list to stderr stream. */
-
-void
-Key_List::dump ()
-{
- T (Trace t ("Key_List::dump");)
- int field_width = option.get_max_keysig_size ();
-
- fprintf (stderr, "\nList contents are:\n(hash value, key length, index, %*s, keyword):\n",
- field_width, "char_set");
-
- for (List_Node *ptr = head; ptr; ptr = ptr->next)
- fprintf (stderr, "%11d,%11d,%6d, %*.*s, %.*s\n",
- ptr->hash_value, ptr->key_length, ptr->index,
- field_width, ptr->char_set_length, ptr->char_set,
- ptr->key_length, ptr->key);
-}
-
-/* Simple-minded constructor action here... */
-
-Key_List::Key_List (void)
-{
- T (Trace t ("Key_List::Key_List");)
- total_keys = 1;
- max_key_len = INT_MIN;
- min_key_len = INT_MAX;
- array_type = 0;
- return_type = 0;
- struct_tag = 0;
- head = 0;
- total_duplicates = 0;
- additional_code = 0;
-}
-
-/* Returns the length of entire key list. */
-
-int
-Key_List::keyword_list_length (void)
-{
- T (Trace t ("Key_List::keyword_list_length");)
- return list_len;
-}
-
-/* Returns length of longest key read. */
-
-int
-Key_List::max_key_length (void)
-{
- T (Trace t ("Key_List::max_key_length");)
- return max_key_len;
-}
-
diff --git a/src/key-list.h b/src/key-list.h
deleted file mode 100644
index 98b8fa5e0c84..000000000000
--- a/src/key-list.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* This may look like C code, but it is really -*- C++ -*- */
-
-/* Data and function member declarations for the keyword list class.
-
- Copyright (C) 1989-1998 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-/* The key word list is a useful abstraction that keeps track of
- various pieces of information that enable that fast generation
- of the Gen_Perf.hash function. A Key_List is a singly-linked
- list of List_Nodes. */
-
-#ifndef key_list_h
-#define key_list_h 1
-
-#include "list-node.h"
-#include "vectors.h"
-#include "read-line.h"
-
-/* OSF/1 cxx needs these forward declarations. */
-struct Output_Constants;
-struct Output_Compare;
-
-class Key_List : private Read_Line, public Vectors
-{
-private:
- const char *array_type; /* Pointer to the type for word list. */
- const char *return_type; /* Pointer to return type for lookup function. */
- const char *struct_tag; /* Shorthand for user-defined struct tag type. */
- const char *include_src; /* C source code to be included verbatim. */
- int max_key_len; /* Maximum length of the longest keyword. */
- int min_key_len; /* Minimum length of the shortest keyword. */
- int min_hash_value; /* Minimum hash value for all keywords. */
- int max_hash_value; /* Maximum hash value for all keywords. */
- int occurrence_sort; /* True if sorting by occurrence. */
- int hash_sort; /* True if sorting by hash value. */
- int additional_code; /* True if any additional C code is included. */
- int list_len; /* Length of head's Key_List, not counting duplicates. */
- int total_keys; /* Total number of keys, counting duplicates. */
- static int determined[MAX_ALPHA_SIZE]; /* Used in function reorder, below. */
- static int get_occurrence (List_Node *ptr);
-#ifndef strcspn
- static int strcspn (const char *s, const char *reject);
-#endif
- static int already_determined (List_Node *ptr);
- static void set_determined (List_Node *ptr);
- void compute_min_max (void);
- int num_hash_values (void);
- void output_constants (struct Output_Constants&);
- void output_hash_function (void);
- void output_keylength_table (void);
- void output_keyword_table (void);
- void output_lookup_array (void);
- void output_lookup_tables (void);
- void output_lookup_function_body (const struct Output_Compare&);
- void output_lookup_function (void);
- void set_output_types (void);
- void dump (void);
- const char *get_array_type (void);
- const char *save_include_src (void);
- const char *get_special_input (char delimiter);
- List_Node *merge (List_Node *list1, List_Node *list2);
- List_Node *merge_sort (List_Node *head);
-
-protected:
- List_Node *head; /* Points to the head of the linked list. */
- int total_duplicates; /* Total number of duplicate hash values. */
-
-public:
- Key_List (void);
- ~Key_List (void);
- int keyword_list_length (void);
- int max_key_length (void);
- void reorder (void);
- void sort (void);
- void read_keys (void);
- void output (void);
-};
-
-#endif
diff --git a/src/keylist.c b/src/keylist.c
deleted file mode 100644
index f92d97549694..000000000000
--- a/src/keylist.c
+++ /dev/null
@@ -1,1033 +0,0 @@
-/* Routines for building, ordering, and printing the keyword list.
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <assert.h>
-#include <stdio.h>
-#include "options.h"
-#include "readline.h"
-#include "keylist.h"
-#include "hashtable.h"
-#include "stderr.h"
-#ifdef sparc
-#include <alloca.h>
-#endif
-
-/* Current release version. */
-extern char *version_string;
-
-/* See comments in perfect.cc. */
-extern int occurrences[ALPHABET_SIZE];
-
-/* Ditto. */
-extern int asso_values[ALPHABET_SIZE];
-
-/* Used in function reorder, below. */
-static bool determined[ALPHABET_SIZE];
-
-/* Default type for generated code. */
-static char *default_array_type = "char *";
-
-/* Generated function ``in_word_set'' default return type. */
-static char *default_return_type = "char *";
-
-/* Largest positive integer value. */
-#define MAX_INT ((~(unsigned)0)>>1)
-
-/* Most negative integer value. */
-#define NEG_MAX_INT ((~(unsigned)0)^((~(unsigned)0)>>1))
-
-/* Maximum value an unsigned char can take. */
-#define MAX_UNSIGNED_CHAR 256
-
-/* Maximum value an unsigned short can take. */
-#define MAX_UNSIGNED_SHORT 65536
-
-/* Make the hash table 5 times larger than the number of keyword entries. */
-#define TABLE_MULTIPLE 5
-
-/* Efficiently returns the least power of two greater than or equal to X! */
-#define POW(X) ((!X)?1:(X-=1,X|=X>>1,X|=X>>2,X|=X>>4,X|=X>>8,X|=X>>16,(++X)))
-
-/* How wide the printed field width must be to contain the maximum hash value. */
-static int field_width = 2;
-
-/* Globally visible KEY_LIST object. */
-
-KEY_LIST key_list;
-
-/* Gathers the input stream into a buffer until one of two things occur:
-
- 1. We read a '%' followed by a '%'
- 2. We read a '%' followed by a '}'
-
- The first symbolizes the beginning of the keyword list proper,
- The second symbolizes the end of the C source code to be generated
- verbatim in the output file.
-
- I assume that the keys are separated from the optional preceding struct
- declaration by a consecutive % followed by either % or } starting in
- the first column. The code below uses an expandible buffer to scan off
- and return a pointer to all the code (if any) appearing before the delimiter. */
-
-static char *
-get_special_input (delimiter)
- char delimiter;
-{
- char *xmalloc ();
- int size = 80;
- char *buf = xmalloc (size);
- int c, i;
-
- for (i = 0; (c = getchar ()) != EOF; i++)
- {
- if (c == '%')
- {
- if ((c = getchar ()) == delimiter)
- {
-
- while ((c = getchar ()) != '\n')
- ; /* Discard newline. */
-
- if (i == 0)
- return "";
- else
- {
- buf[delimiter == '%' && buf[i - 2] == ';' ? i - 2 : i - 1] = '\0';
- return buf;
- }
- }
- else
- ungetc (c, stdin);
- }
- else if (i >= size) /* Yikes, time to grow the buffer! */
- {
- char *temp = xmalloc (size *= 2);
- int j;
-
- for (j = 0; j < i; j++)
- temp[j] = buf[j];
-
- free (buf);
- buf = temp;
- }
- buf[i] = c;
- }
-
- return NULL; /* Problem here. */
-}
-
-/* Stores any C text that must be included verbatim into the
- generated code output. */
-
-static char *
-save_include_src ()
-{
- int c;
-
- if ((c = getchar ()) != '%')
- {
- ungetc (c, stdin);
- return "";
- }
- else if ((c = getchar ()) != '{')
- report_error ("internal error, %c != '{' on line %d in file %s%a", c, __LINE__, __FILE__);
- /*NOT REACHED*/
- else
- return get_special_input ('}');
-}
-
-/* strcspn - find length of initial segment of s consisting entirely
- of characters not from reject (borrowed from Henry Spencer's
- ANSI string package). */
-
-static int
-strcspn (s, reject)
- char *s;
- char *reject;
-{
- char *scan;
- char *rej_scan;
- int count = 0;
-
- for (scan = s; *scan; scan++)
- {
-
- for (rej_scan = reject; *rej_scan;)
- if (*scan == *rej_scan++)
- return count;
-
- count++;
- }
-
- return count;
-}
-
-/* Determines from the input file whether the user wants to build a table
- from a user-defined struct, or whether the user is content to simply
- use the default array of keys. */
-
-static char *
-get_array_type ()
-{
- return get_special_input ('%');
-}
-
-/* Sets up the Return_Type, the Struct_Tag type and the Array_Type
- based upon various user Options. */
-
-static void
-set_output_types ()
-{
- char *xmalloc ();
-
- if (OPTION_ENABLED (option, TYPE) && !(key_list.array_type = get_array_type ()))
- return; /* Something's wrong, bug we'll catch it later on.... */
- else if (OPTION_ENABLED (option, TYPE)) /* Yow, we've got a user-defined type... */
- {
- int struct_tag_length = strcspn (key_list.array_type, "{\n\0");
-
- if (OPTION_ENABLED (option, POINTER)) /* And it must return a pointer... */
- {
- key_list.return_type = xmalloc (struct_tag_length + 2);
- strncpy (key_list.return_type, key_list.array_type, struct_tag_length);
- key_list.return_type[struct_tag_length] = '\0';
- strcat (key_list.return_type, "*");
- }
-
- key_list.struct_tag = (char *) xmalloc (struct_tag_length + 1);
- strncpy (key_list.struct_tag, key_list.array_type, struct_tag_length);
- key_list.struct_tag[struct_tag_length] = '\0';
- }
- else if (OPTION_ENABLED (option, POINTER)) /* Return a char *. */
- key_list.return_type = default_array_type;
-}
-
-/* Reads in all keys from standard input and creates a linked list pointed
- to by Head. This list is then quickly checked for ``links,'' i.e.,
- unhashable elements possessing identical key sets and lengths. */
-
-void
-read_keys ()
-{
- char *ptr;
-
- key_list.include_src = save_include_src ();
- set_output_types ();
-
- /* Oops, problem with the input file. */
- if (! (ptr = read_line ()))
- report_error ("No words in input file, did you forget\
- to prepend %s or use -t accidentally?\n%a", "%%");
-
- /* Read in all the keywords from the input file. */
- else
- {
- LIST_NODE *temp, *trail;
- char *delimiter = GET_DELIMITER (option);
-
- for (temp = key_list.head = make_list_node (ptr, strcspn (ptr, delimiter));
- (ptr = read_line ()) && strcmp (ptr, "%%");
- key_list.total_keys++, temp = temp->next)
- temp->next = make_list_node (ptr, strcspn (ptr, delimiter));
-
- /* See if any additional C code is included at end of this file. */
- if (ptr)
- key_list.additional_code = TRUE;
- {
- /* If this becomes TRUE we've got a link. */
- bool link = FALSE;
-
- /* Make large hash table for efficiency. */
- int table_size = (key_list.list_len = key_list.total_keys) * TABLE_MULTIPLE;
-
- /* By allocating the memory here we save on dynamic allocation overhead.
- Table must be a power of 2 for the hash function scheme to work. */
- LIST_NODE **table = (LIST_NODE **) alloca (POW (table_size) * sizeof (LIST_NODE *));
-
- hash_table_init (table, table_size);
-
- /* Test whether there are any links and also set the maximum length of
- an identifier in the keyword list. */
-
- for (temp = key_list.head, trail = NULL; temp; temp = temp->next)
- {
- LIST_NODE *ptr = retrieve (temp, OPTION_ENABLED (option, NOLENGTH));
-
- /* Check for links. We deal with these by building an equivalence class
- of all duplicate values (i.e., links) so that only 1 keyword is
- representative of the entire collection. This *greatly* simplifies
- processing during later stages of the program. */
-
- if (ptr)
- {
- key_list.list_len--;
- trail->next = temp->next;
- temp->link = ptr->link;
- ptr->link = temp;
- link = TRUE;
-
- /* Complain if user hasn't enabled the duplicate option. */
- if (!OPTION_ENABLED (option, DUP))
- fprintf (stderr, "Key link: \"%s\" = \"%s\", with key set \"%s\".\n",
- temp->key, ptr->key, temp->char_set);
- else if (OPTION_ENABLED (option, DEBUG))
- fprintf (stderr, "Key link: \"%s\" = \"%s\", with key set \"%s\".\n",
- temp->key, ptr->key, temp->char_set);
- }
- else
- trail = temp;
-
- /* Update minimum and maximum keyword length, if needed. */
- if (temp->length > key_list.max_key_len)
- key_list.max_key_len = temp->length;
- if (temp->length < key_list.min_key_len)
- key_list.min_key_len = temp->length;
- }
-
- /* Free up the dynamic memory used in the hash table. */
- hash_table_destroy ();
-
- /* Exit program if links exists and option[DUP] not set, since we can't continue safely. */
- if (link)
- report_error (OPTION_ENABLED (option, DUP)
- ? "Some input keys have identical hash values, examine output carefully...\n"
- : "Some input keys have identical hash values,\ntry different key positions or use option -D.\n%a");
- }
- if (OPTION_ENABLED (option, ALLCHARS))
- SET_CHARSET_SIZE (option, key_list.max_key_len);
- }
-}
-
-/* Recursively merges two sorted lists together to form one sorted list. The
- ordering criteria is by frequency of occurrence of elements in the key set
- or by the hash value. This is a kludge, but permits nice sharing of
- almost identical code without incurring the overhead of a function
- call comparison. */
-
-static LIST_NODE *
-merge (list1, list2)
- LIST_NODE *list1;
- LIST_NODE *list2;
-{
- if (!list1)
- return list2;
- else if (!list2)
- return list1;
- else if (key_list.occurrence_sort && list1->occurrence < list2->occurrence
- || key_list.hash_sort && list1->hash_value > list2->hash_value)
- {
- list2->next = merge (list2->next, list1);
- return list2;
- }
- else
- {
- list1->next = merge (list1->next, list2);
- return list1;
- }
-}
-
-/* Applies the merge sort algorithm to recursively sort the key list by
- frequency of occurrence of elements in the key set. */
-
-static LIST_NODE *
-merge_sort (head)
- LIST_NODE *head;
-{
- if (!head || !head->next)
- return head;
- else
- {
- LIST_NODE *middle = head;
- LIST_NODE *temp = head->next->next;
-
- while (temp)
- {
- temp = temp->next;
- middle = middle->next;
- if (temp)
- temp = temp->next;
- }
-
- temp = middle->next;
- middle->next = NULL;
- return merge (merge_sort (head), merge_sort (temp));
- }
-}
-
-/* Returns the frequency of occurrence of elements in the key set. */
-
-static int
-get_occurrence (ptr)
- LIST_NODE *ptr;
-{
- int value = 0;
- char *temp;
-
- for (temp = ptr->char_set; *temp; temp++)
- value += occurrences[*temp];
-
- return value;
-}
-
-/* Enables the index location of all key set elements that are now
- determined. */
-
-static void
-set_determined (ptr)
- LIST_NODE *ptr;
-{
- char *temp;
-
- for (temp = ptr->char_set; *temp; temp++)
- determined[*temp] = TRUE;
-
-}
-
-/* Returns TRUE if PTR's key set is already completely determined. */
-
-static bool
-already_determined (ptr)
- LIST_NODE *ptr;
-{
- bool is_determined = TRUE;
- char *temp;
-
- for (temp = ptr->char_set; is_determined && *temp; temp++)
- is_determined = determined[*temp];
-
- return is_determined;
-}
-
-/* Reorders the table by first sorting the list so that frequently occuring
- keys appear first, and then the list is reorded so that keys whose values
- are already determined will be placed towards the front of the list. This
- helps prune the search time by handling inevitable collisions early in the
- search process. See Cichelli's paper from Jan 1980 JACM for details.... */
-
-void
-reorder ()
-{
- LIST_NODE *ptr;
-
- for (ptr = key_list.head; ptr; ptr = ptr->next)
- ptr->occurrence = get_occurrence (ptr);
-
- key_list.hash_sort = FALSE;
- key_list.occurrence_sort = TRUE;
-
- for (ptr = key_list.head = merge_sort (key_list.head); ptr->next; ptr = ptr->next)
- {
- set_determined (ptr);
-
- if (already_determined (ptr->next))
- continue;
- else
- {
- LIST_NODE *trail_ptr = ptr->next;
- LIST_NODE *run_ptr = trail_ptr->next;
-
- for (; run_ptr; run_ptr = trail_ptr->next)
- {
-
- if (already_determined (run_ptr))
- {
- trail_ptr->next = run_ptr->next;
- run_ptr->next = ptr->next;
- ptr = ptr->next = run_ptr;
- }
- else
- trail_ptr = run_ptr;
- }
- }
- }
-}
-
-/* Determines the maximum and minimum hash values. One notable feature is
- Ira Pohl's optimal algorithm to calculate both the maximum and minimum
- items in a list in O(3n/2) time (faster than the O (2n) method).
- Returns the maximum hash value encountered. */
-
-static int
-print_min_max ()
-{
- int min_hash_value;
- int max_hash_value;
- LIST_NODE *temp;
-
- if (ODD (key_list.list_len)) /* Pre-process first item, list now has an even length. */
- {
- min_hash_value = max_hash_value = key_list.head->hash_value;
- temp = key_list.head->next;
- }
- else /* List is already even length, no extra work necessary. */
- {
- min_hash_value = MAX_INT;
- max_hash_value = NEG_MAX_INT;
- temp = key_list.head;
- }
-
- for ( ; temp; temp = temp->next) /* Find max and min in optimal o(3n/2) time. */
- {
- static int i;
- int key_2, key_1 = temp->hash_value;
- temp = temp->next;
- key_2 = temp->hash_value;
- i++;
-
- if (key_1 < key_2)
- {
- if (key_1 < min_hash_value)
- min_hash_value = key_1;
- if (key_2 > max_hash_value)
- max_hash_value = key_2;
- }
- else
- {
- if (key_2 < min_hash_value)
- min_hash_value = key_2;
- if (key_1 > max_hash_value)
- max_hash_value = key_1;
- }
- }
-
- printf ("\n#define MIN_WORD_LENGTH %d\n#define MAX_WORD_LENGTH %d\
-\n#define MIN_HASH_VALUE %d\n#define MAX_HASH_VALUE %d\
-\n/*\n%5d keywords\n%5d is the maximum key range\n*/\n\n",
- key_list.min_key_len == MAX_INT ? key_list.max_key_len : key_list.min_key_len,
- key_list.max_key_len, min_hash_value, max_hash_value,
- key_list.total_keys, (max_hash_value - min_hash_value + 1));
- return max_hash_value;
-}
-
-/* Generates the output using a C switch. This trades increased search
- time for decreased table space (potentially *much* less space for
- sparse tables). It the user has specified their own struct in the
- keyword file *and* they enable the POINTER option we have extra work to
- do. The solution here is to maintain a local static array of user
- defined struct's, as with the Print_Lookup_Function. Then we use for
- switch statements to perform a strcmp or strncmp, returning 0 if the str
- fails to match, and otherwise returning a pointer to appropriate index
- location in the local static array. */
-
-static void
-print_switch ()
-{
- char *comp_buffer;
- LIST_NODE *curr = key_list.head;
- int pointer_and_type_enabled = OPTION_ENABLED (option, POINTER) && OPTION_ENABLED (option, TYPE);
- int total_switches = GET_TOTAL_SWITCHES (option);
- int switch_size = keyword_list_length () / total_switches;
-
- if (pointer_and_type_enabled)
- {
- comp_buffer = (char *) alloca (strlen ("*str == *resword->%s && !strncmp (str + 1, resword->%s + 1, len - 1)")
- + 2 * strlen (GET_KEY_NAME (option)) + 1);
- sprintf (comp_buffer, OPTION_ENABLED (option, COMP)
- ? "*str == *resword->%s && !strncmp (str + 1, resword->%s + 1, len - 1)"
- : "*str == *resword->%s && !strcmp (str + 1, resword->%s + 1)",
- GET_KEY_NAME (option), GET_KEY_NAME (option));
- }
- else
- comp_buffer = OPTION_ENABLED (option, COMP)
- ? "*str == *resword && !strncmp (str + 1, resword + 1, len - 1)"
- : "*str == *resword && !strcmp (str + 1, resword + 1)";
-
- printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n {\n\
- register int key = %s (str, len);\n\n\
- if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n {\n", GET_HASH_NAME (option));
-
- /* Properly deal with user's who request multiple switch statements. */
-
- while (curr)
- {
- LIST_NODE *temp = curr;
- int lowest_case_value = curr->hash_value;
- int number_of_cases = 0;
-
- /* Figure out a good cut point to end this switch. */
-
- for (; temp && ++number_of_cases < switch_size; temp = temp->next)
- if (temp->next && temp->hash_value == temp->next->hash_value)
- while (temp->next && temp->hash_value == temp->next->hash_value)
- temp = temp->next;
-
- if (temp)
- printf (" if (key <= %d)\n {\n", temp->hash_value);
- else
- printf (" {\n");
-
- /* Output each keyword as part of a switch statement indexed by hash value. */
-
- if (OPTION_ENABLED (option, POINTER) || OPTION_ENABLED (option, DUP))
- {
- int i = 0;
-
- printf (" %s%s *resword; %s\n\n",
- OPTION_ENABLED (option, CONST) ? "const " : "",
- pointer_and_type_enabled ? key_list.struct_tag : "char",
- OPTION_ENABLED (option, LENTABLE) && !OPTION_ENABLED (option, DUP) ? "int key_len;" : "");
- printf (" switch (key - %d)\n {\n", lowest_case_value);
-
- for (temp = curr; temp && ++i <= number_of_cases; temp = temp->next)
- {
- printf (" case %*d:", field_width, temp->hash_value - lowest_case_value);
- if (OPTION_ENABLED (option, DEBUG))
- printf (" /* hash value = %4d, keyword = \"%s\" */", temp->hash_value, temp->key);
- putchar ('\n');
-
- /* Handle `natural links,' i.e., those that occur statically. */
-
- if (temp->link)
- {
- LIST_NODE *links;
-
- for (links = temp; links; links = links->link)
- {
- if (pointer_and_type_enabled)
- printf (" resword = &wordlist[%d];\n", links->index);
- else
- printf (" resword = \"%s\";\n", links->key);
- printf (" if (%s) return resword;\n", comp_buffer);
- }
- }
- /* Handle unresolved duplicate hash values. These are guaranteed
- to be adjacent since we sorted the keyword list by increasing
- hash values. */
- if (temp->next && temp->hash_value == temp->next->hash_value)
- {
-
- for ( ; temp->next && temp->hash_value == temp->next->hash_value;
- temp = temp->next)
- {
- if (pointer_and_type_enabled)
- printf (" resword = &wordlist[%d];\n", temp->index);
- else
- printf (" resword = \"%s\";\n", temp->key);
- printf (" if (%s) return resword;\n", comp_buffer);
- }
- if (pointer_and_type_enabled)
- printf (" resword = &wordlist[%d];\n", temp->index);
- else
- printf (" resword = \"%s\";\n", temp->key);
- printf (" return %s ? resword : 0;\n", comp_buffer);
- }
- else if (temp->link)
- printf (" return 0;\n");
- else
- {
- if (pointer_and_type_enabled)
- printf (" resword = &wordlist[%d];", temp->index);
- else
- printf (" resword = \"%s\";", temp->key);
- if (OPTION_ENABLED (option, LENTABLE) && !OPTION_ENABLED (option, DUP))
- printf (" key_len = %d;", temp->length);
- printf (" break;\n");
- }
- }
- printf (" default: return 0;\n }\n");
- printf (OPTION_ENABLED (option, LENTABLE) && !OPTION_ENABLED (option, DUP)
- ? " if (len == key_len && %s)\n return resword;\n"
- : " if (%s)\n return resword;\n", comp_buffer);
- printf (" return 0;\n }\n");
- curr = temp;
- }
- else /* Nothing special required here. */
- {
- int i = 0;
- printf (" char *s;\n\n switch (key - %d)\n {\n",
- lowest_case_value);
-
- for (temp = curr; temp && ++i <= number_of_cases; temp = temp->next)
- if (OPTION_ENABLED (option, LENTABLE))
- printf (" case %*d: if (len == %d) s = \"%s\"; else return 0; break;\n",
- field_width, temp->hash_value - lowest_case_value,
- temp->length, temp->key);
- else
- printf (" case %*d: s = \"%s\"; break;\n",
- field_width, temp->hash_value - lowest_case_value, temp->key);
-
- printf (" default: return 0;\n }\n ");
- printf ("return *s == *str && !%s;\n }\n",
- OPTION_ENABLED (option, COMP)
- ? "strncmp (s + 1, str + 1, len - 1)" : "strcmp (s + 1, str + 1)");
- curr = temp;
- }
- }
- printf (" }\n }\n return 0;\n}\n");
-}
-
-/* Prints out a table of keyword lengths, for use with the
- comparison code in generated function ``in_word_set.'' */
-
-static void
-print_keylength_table ()
-{
- int max_column = 15;
- int index = 0;
- int column = 0;
- char *indent = OPTION_ENABLED (option, GLOBAL) ? "" : " ";
- LIST_NODE *temp;
-
- if (!OPTION_ENABLED (option, DUP) && !OPTION_ENABLED (option, SWITCH))
- {
- printf ("\n%sstatic %sunsigned %s lengthtable[] =\n%s%s{\n ",
- indent, OPTION_ENABLED (option, CONST) ? "const " : "",
- key_list.max_key_len < MAX_UNSIGNED_CHAR ? "char" :
- (key_list.max_key_len < MAX_UNSIGNED_SHORT ? "short" : "long"),
- indent, indent);
-
- for (temp = key_list.head; temp; temp = temp->next, index++)
- {
-
- if (index < temp->hash_value)
- {
-
- for ( ; index < temp->hash_value; index++)
- printf ("%3d%s", 0, ++column % (max_column - 1) ? "," : ",\n ");
- }
-
- printf ("%3d%s", temp->length, ++column % (max_column - 1 ) ? "," : ",\n ");
- }
-
- printf ("\n%s%s};\n\n", indent, indent);
- }
-}
-
-/* Prints out the array containing the key words for the Perfect
- hash function. */
-
-static void
-print_keyword_table ()
-{
- char *l_brace = *key_list.head->rest ? "{" : "";
- char *r_brace = *key_list.head->rest ? "}," : "";
- int doing_switch = OPTION_ENABLED (option, SWITCH);
- char *indent = OPTION_ENABLED (option, GLOBAL) ? "" : " ";
- int index = 0;
- LIST_NODE *temp;
-
- printf ("\n%sstatic %s%s wordlist[] =\n%s%s{\n",
- indent, OPTION_ENABLED (option, CONST) ? "const " : "",
- key_list.struct_tag, indent, indent);
-
- /* Generate an array of reserved words at appropriate locations. */
-
- for (temp = key_list.head; temp; temp = temp->next, index++)
- {
- temp->index = index;
-
- if (!doing_switch && index < temp->hash_value)
- {
- int column;
-
- printf (" ");
-
- for (column = 1; index < temp->hash_value; index++, column++)
- printf ("%s\"\",%s %s", l_brace, r_brace, column % 9 ? "" : "\n ");
-
- if (column % 10)
- printf ("\n");
- else
- {
- printf ("%s\"%s\", %s%s\n", l_brace, temp->key, temp->rest, r_brace);
- continue;
- }
- }
-
- printf (" %s\"%s\", %s%s\n", l_brace, temp->key, temp->rest, r_brace);
-
- /* Deal with links specially. */
- if (temp->link)
- {
- LIST_NODE *links;
-
- for (links = temp->link; links; links = links->link)
- {
- links->index = ++index;
- printf (" %s\"%s\", %s%s\n", l_brace, links->key, links->rest, r_brace);
- }
- }
-
- }
-
- printf ("%s%s};\n\n", indent, indent);
-}
-
-/* Generates C code for the hash function that returns the
- proper encoding for each key word. */
-
-static void
-print_hash_function (max_hash_value)
- int max_hash_value;
-{
- int max_column = 10;
- int count = max_hash_value;
-
- /* Calculate maximum number of digits required for MAX_HASH_VALUE. */
-
- while ((count /= 10) > 0)
- field_width++;
-
- if (OPTION_ENABLED (option, GNU))
- printf ("#ifdef __GNUC__\ninline\n#endif\n");
-
- printf (OPTION_ENABLED (option, ANSI)
- ? "static int\n%s (register const char *str, register int len)\n{\n static %sunsigned %s hash_table[] =\n {"
- : "static int\n%s (str, len)\n register char *str;\n register unsigned int len;\n{\n static %sunsigned %s hash_table[] =\n {",
- GET_HASH_NAME (option), OPTION_ENABLED (option, CONST) ? "const " : "",
- max_hash_value < MAX_UNSIGNED_CHAR
- ? "char" : (max_hash_value < MAX_UNSIGNED_SHORT ? "short" : "int"));
-
- for (count = 0; count < ALPHABET_SIZE; ++count)
- {
- if (!(count % max_column))
- printf ("\n ");
-
- printf ("%*d,", field_width, occurrences[count] ? asso_values[count] : max_hash_value);
- }
-
- /* Optimize special case of ``-k 1,$'' */
- if (OPTION_ENABLED (option, DEFAULTCHARS))
- printf ("\n };\n return %s + hash_table[str[len - 1]] + hash_table[str[0]];\n}\n\n",
- OPTION_ENABLED (option, NOLENGTH) ? "0" : "len");
- else
- {
- int key_pos;
-
- RESET (option);
-
- /* Get first (also highest) key position. */
- key_pos = GET (option);
-
- /* We can perform additional optimizations here. */
- if (!OPTION_ENABLED (option, ALLCHARS) && key_pos <= key_list.min_key_len)
- {
- printf ("\n };\n return %s", OPTION_ENABLED (option, NOLENGTH) ? "0" : "len");
-
- for ( ; key_pos != EOS && key_pos != WORD_END; key_pos = GET (option))
- printf (" + hash_table[str[%d]]", key_pos - 1);
-
- printf ("%s;\n}\n\n", key_pos == WORD_END ? " + hash_table[str[len - 1]]" : "");
- }
-
- /* We've got to use the correct, but brute force, technique. */
- else
- {
- printf ("\n };\n register int hval = %s;\n\n switch (%s)\n {\n default:\n",
- OPTION_ENABLED (option, NOLENGTH)
- ? "0" : "len", OPTION_ENABLED (option, NOLENGTH) ? "len" : "hval");
-
- /* User wants *all* characters considered in hash. */
- if (OPTION_ENABLED (option, ALLCHARS))
- {
- int i;
-
- for (i = key_list.max_key_len; i > 0; i--)
- printf (" case %d:\n hval += hash_table[str[%d]];\n", i, i - 1);
-
- printf (" }\n return hval;\n}\n\n");
- }
- else /* do the hard part... */
- {
- count = key_pos + 1;
-
- do
- {
-
- while (--count > key_pos)
- printf (" case %d:\n", count);
-
- printf (" case %d:\n hval += hash_table[str[%d]];\n",
- key_pos, key_pos - 1);
- }
- while ((key_pos = GET (option)) != EOS && key_pos != WORD_END);
-
- printf (" }\n return hval%s ;\n}\n\n", key_pos == WORD_END
- ? " + hash_table[str[len - 1]]" : "");
- }
- }
- }
-}
-
-/* Generates C code to perform the keyword lookup. */
-
-static void
-print_lookup_function ()
-{
- printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n {\n\
- register int key = %s (str, len);\n\n\
- if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n {\n\
- register %schar *s = wordlist[key]",
- GET_HASH_NAME (option), OPTION_ENABLED (option, CONST) ? "const " : "");
- if (key_list.array_type != default_array_type)
- printf (".%s", GET_KEY_NAME (option));
-
- printf (";\n\n if (%s*s == *str && !%s)\n return %s",
- OPTION_ENABLED (option, LENTABLE) ? "len == lengthtable[key]\n && " : "",
- OPTION_ENABLED (option, COMP) ? "strncmp (str + 1, s + 1, len - 1)" : "strcmp (str + 1, s + 1)",
- OPTION_ENABLED (option, TYPE) && OPTION_ENABLED (option, POINTER) ? "&wordlist[key]" : "s");
- printf (";\n }\n }\n return 0;\n}\n");
-}
-
-/* Generates the hash function and the key word recognizer function
- based upon the user's Options. */
-
-void
-print_output ()
-{
- int global_table = OPTION_ENABLED (option, GLOBAL);
-
- printf ("%s\n", key_list.include_src);
-
- /* Potentially output type declaration now, reference it later on.... */
- if (OPTION_ENABLED (option, TYPE) && !OPTION_ENABLED (option, NOTYPE))
- printf ("%s;\n", key_list.array_type);
-
- print_hash_function (print_min_max ());
-
- if (global_table)
- if (OPTION_ENABLED (option, SWITCH))
- {
- if (OPTION_ENABLED (option, LENTABLE) && OPTION_ENABLED (option, DUP))
- print_keylength_table ();
- if (OPTION_ENABLED (option, POINTER) && OPTION_ENABLED (option, TYPE))
- print_keyword_table ();
- }
- else
- {
- if (OPTION_ENABLED (option, LENTABLE))
- print_keylength_table ();
- print_keyword_table ();
- }
- /* Use the inline keyword to remove function overhead. */
- if (OPTION_ENABLED (option, GNU))
- printf ("#ifdef __GNUC__\ninline\n#endif\n");
-
- /* Use ANSI function prototypes. */
- printf (OPTION_ENABLED (option, ANSI)
- ? "%s%s\n%s (register const char *str, register int len)\n{\n"
- : "%s%s\n%s (str, len)\n register char *str;\n register unsigned int len;\n{\n",
- OPTION_ENABLED (option, CONST) ? "const " : "",
- key_list.return_type, GET_FUNCTION_NAME (option));
-
- /* Use the switch in place of lookup table. */
- if (OPTION_ENABLED (option, SWITCH))
- {
- if (!global_table)
- {
- if (OPTION_ENABLED (option, LENTABLE) && OPTION_ENABLED (option, DUP))
- print_keylength_table ();
- if (OPTION_ENABLED (option, POINTER) && OPTION_ENABLED (option, TYPE))
- print_keyword_table ();
- }
- print_switch ();
- }
- else /* Use the lookup table, in place of switch. */
- {
- if (!global_table)
- {
- if (OPTION_ENABLED (option, LENTABLE))
- print_keylength_table ();
- print_keyword_table ();
- }
- print_lookup_function ();
- }
-
- if (key_list.additional_code)
- {
- int c;
-
- while ((c = getchar ()) != EOF)
- putchar (c);
- }
- fflush (stdout);
-}
-
-/* Sorts the keys by hash value. */
-
-void
-sort ()
-{
- key_list.hash_sort = TRUE;
- key_list.occurrence_sort = FALSE;
-
- key_list.head = merge_sort (key_list.head);
-}
-
-/* Dumps the key list to stderr stream. */
-
-static void
-dump ()
-{
- LIST_NODE *ptr;
-
- fprintf (stderr, "\nList contents are:\n(hash value, key length, index, key set, key):\n");
-
- for (ptr = key_list.head; ptr; ptr = ptr->next)
- fprintf (stderr, "%7d,%7d,%6d, %s, %s\n",
- ptr->hash_value, ptr->length, ptr->index,
- ptr->char_set, ptr->key);
-}
-
-/* Simple-minded constructor action here... */
-
-void
-key_list_init ()
-{
- key_list.total_keys = 1;
- key_list.max_key_len = NEG_MAX_INT;
- key_list.min_key_len = MAX_INT;
- key_list.return_type = default_return_type;
- key_list.array_type = key_list.struct_tag = default_array_type;
- key_list.head = NULL;
- key_list.additional_code = FALSE;
-}
-
-/* Returns the length of entire key list. */
-
-int
-keyword_list_length ()
-{
- return key_list.list_len;
-}
-
-/* Returns length of longest key read. */
-
-int
-max_key_length ()
-{
- return key_list.max_key_len;
-}
-
-/* DESTRUCTOR dumps diagnostics during debugging. */
-
-void
-key_list_destroy ()
-{
- if (OPTION_ENABLED (option, DEBUG))
- {
- fprintf (stderr, "\nDumping key list information:\ntotal unique keywords = %d\
-\ntotal keywords = %d\nmaximum key length = %d.\n",
- key_list.list_len, key_list.total_keys, key_list.max_key_len);
- dump ();
- fprintf (stderr, "End dumping list.\n\n");
- }
-}
-
diff --git a/src/keylist.h b/src/keylist.h
deleted file mode 100644
index 38143b73cb14..000000000000
--- a/src/keylist.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Data and function member declarations for the keyword list class.
-
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* The key word list is a useful abstraction that keeps track of
- various pieces of information that enable that fast generation
- of the Perfect.hash function. A Key_List is a singly-linked
- list of List_Nodes. */
-
-#ifndef _keylist_h
-#define _keylist_h
-#include <stdio.h>
-#include "listnode.h"
-
-typedef struct key_list
-{
- LIST_NODE *head; /* Points to the head of the linked list. */
- char *array_type; /* Pointer to the type for word list. */
- char *return_type; /* Pointer to return type for lookup function. */
- char *struct_tag; /* Shorthand for user-defined struct tag type. */
- char *include_src; /* C source code to be included verbatim. */
- int list_len; /* Length of head's Key_List, not counting duplicates. */
- int total_keys; /* Total number of keys, counting duplicates. */
- int max_key_len; /* Maximum length of the longest keyword. */
- int min_key_len; /* Minimum length of the shortest keyword. */
- bool occurrence_sort; /* True if sorting by occurrence. */
- bool hash_sort; /* True if sorting by hash value. */
- bool additional_code; /* True if any additional C code is included. */
-} KEY_LIST;
-
-extern void key_list_init P ((void));
-extern void key_list_destroy P ((void));
-extern void print_output P ((void));
-extern int keyword_list_length P ((void));
-extern int max_key_length P ((void));
-extern KEY_LIST key_list;
-#endif /* _keylist_h */
diff --git a/src/keyword-list.cc b/src/keyword-list.cc
new file mode 100644
index 000000000000..ac559f7933d2
--- /dev/null
+++ b/src/keyword-list.cc
@@ -0,0 +1,175 @@
+/* Keyword list.
+
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Specification. */
+#include "keyword-list.h"
+
+#include <stddef.h>
+
+/* -------------------------- Keyword_List class --------------------------- */
+
+/* Constructor. */
+Keyword_List::Keyword_List (Keyword *car)
+ : _cdr (NULL), _car (car)
+{
+}
+
+/* ------------------------- KeywordExt_List class ------------------------- */
+
+/* Constructor. */
+KeywordExt_List::KeywordExt_List (KeywordExt *car)
+ : Keyword_List (car)
+{
+}
+
+/* ------------------------ Keyword_List functions ------------------------- */
+
+/* Copies a linear list, sharing the list elements. */
+Keyword_List *
+copy_list (Keyword_List *list)
+{
+ Keyword_List *result;
+ Keyword_List **lastp = &result;
+ while (list != NULL)
+ {
+ Keyword_List *new_cons = new Keyword_List (list->first());
+ *lastp = new_cons;
+ lastp = &new_cons->rest();
+ list = list->rest();
+ }
+ *lastp = NULL;
+ return result;
+}
+
+/* Copies a linear list, sharing the list elements. */
+KeywordExt_List *
+copy_list (KeywordExt_List *list)
+{
+ return static_cast<KeywordExt_List *> (copy_list (static_cast<Keyword_List *> (list)));
+}
+
+/* Deletes a linear list, keeping the list elements in memory. */
+void
+delete_list (Keyword_List *list)
+{
+ while (list != NULL)
+ {
+ Keyword_List *rest = list->rest();
+ delete list;
+ list = rest;
+ }
+}
+
+/* Type of a comparison function. */
+typedef bool (*Keyword_Comparison) (Keyword *keyword1, Keyword *keyword2);
+
+/* Merges two sorted lists together to form one sorted list. */
+static Keyword_List *
+merge (Keyword_List *list1, Keyword_List *list2, Keyword_Comparison less)
+{
+ Keyword_List *result;
+ Keyword_List **resultp = &result;
+ for (;;)
+ {
+ if (!list1)
+ {
+ *resultp = list2;
+ break;
+ }
+ if (!list2)
+ {
+ *resultp = list1;
+ break;
+ }
+ if (less (list2->first(), list1->first()))
+ {
+ *resultp = list2;
+ resultp = &list2->rest();
+ /* We would have a stable sorting if the next line would read:
+ list2 = *resultp; */
+ list2 = list1; list1 = *resultp;
+ }
+ else
+ {
+ *resultp = list1;
+ resultp = &list1->rest();
+ list1 = *resultp;
+ }
+ }
+ return result;
+}
+
+/* Sorts a linear list, given a comparison function.
+ Note: This uses a variant of mergesort that is *not* a stable sorting
+ algorithm. */
+Keyword_List *
+mergesort_list (Keyword_List *list, Keyword_Comparison less)
+{
+ if (list == NULL || list->rest() == NULL)
+ /* List of length 0 or 1. Nothing to do. */
+ return list;
+ else
+ {
+ /* Determine a list node in the middle. */
+ Keyword_List *middle = list;
+ for (Keyword_List *temp = list->rest();;)
+ {
+ temp = temp->rest();
+ if (temp == NULL)
+ break;
+ temp = temp->rest();
+ middle = middle->rest();
+ if (temp == NULL)
+ break;
+ }
+
+ /* Cut the list into two halves.
+ If the list has n elements, the left half has ceiling(n/2) elements
+ and the right half has floor(n/2) elements. */
+ Keyword_List *right_half = middle->rest();
+ middle->rest() = NULL;
+
+ /* Sort the two halves, then merge them. */
+ return merge (mergesort_list (list, less),
+ mergesort_list (right_half, less),
+ less);
+ }
+}
+
+KeywordExt_List *
+mergesort_list (KeywordExt_List *list,
+ bool (*less) (KeywordExt *keyword1, KeywordExt *keyword2))
+{
+ return
+ static_cast<KeywordExt_List *>
+ (mergesort_list (static_cast<Keyword_List *> (list),
+ reinterpret_cast<Keyword_Comparison> (less)));
+}
+
+
+#ifndef __OPTIMIZE__
+
+#define INLINE /* not inline */
+#include "keyword-list.icc"
+#undef INLINE
+
+#endif /* not defined __OPTIMIZE__ */
diff --git a/src/keyword-list.h b/src/keyword-list.h
new file mode 100644
index 000000000000..a15b3b4adf0f
--- /dev/null
+++ b/src/keyword-list.h
@@ -0,0 +1,85 @@
+/* This may look like C code, but it is really -*- C++ -*- */
+
+/* Keyword list.
+
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef keyword_list_h
+#define keyword_list_h 1
+
+#include "keyword.h"
+
+/* List node of a linear list of Keyword. */
+class Keyword_List
+{
+public:
+ /* Constructor. */
+ Keyword_List (Keyword *car);
+
+ /* Access to first element of list. */
+ Keyword * first () const;
+ /* Access to next element of list. */
+ Keyword_List *& rest ();
+
+protected:
+ Keyword_List * _cdr;
+ Keyword * const _car;
+};
+
+/* List node of a linear list of KeywordExt. */
+class KeywordExt_List : public Keyword_List
+{
+public:
+ /* Constructor. */
+ KeywordExt_List (KeywordExt *car);
+
+ /* Access to first element of list. */
+ KeywordExt * first () const;
+ /* Access to next element of list. */
+ KeywordExt_List *& rest ();
+};
+
+/* Copies a linear list, sharing the list elements. */
+extern Keyword_List * copy_list (Keyword_List *list);
+extern KeywordExt_List * copy_list (KeywordExt_List *list);
+
+/* Deletes a linear list, keeping the list elements in memory. */
+extern void delete_list (Keyword_List *list);
+
+/* Sorts a linear list, given a comparison function.
+ Note: This uses a variant of mergesort that is *not* a stable sorting
+ algorithm. */
+extern Keyword_List * mergesort_list (Keyword_List *list,
+ bool (*less) (Keyword *keyword1,
+ Keyword *keyword2));
+extern KeywordExt_List * mergesort_list (KeywordExt_List *list,
+ bool (*less) (KeywordExt *keyword1,
+ KeywordExt *keyword2));
+
+#ifdef __OPTIMIZE__
+
+#define INLINE inline
+#include "keyword-list.icc"
+#undef INLINE
+
+#endif
+
+#endif
diff --git a/src/keyword-list.icc b/src/keyword-list.icc
new file mode 100644
index 000000000000..7fbdaacb2ccb
--- /dev/null
+++ b/src/keyword-list.icc
@@ -0,0 +1,53 @@
+/* Inline Functions for keyword-list.{h,cc}.
+
+ Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* -------------------------- Keyword_List class --------------------------- */
+
+/* Access to first element of list. */
+INLINE Keyword *
+Keyword_List::first () const
+{
+ return _car;
+}
+
+/* Access to next element of list. */
+INLINE Keyword_List *&
+Keyword_List::rest ()
+{
+ return _cdr;
+}
+
+/* ------------------------- KeywordExt_List class ------------------------- */
+
+/* Access to first element of list. */
+INLINE KeywordExt *
+KeywordExt_List::first () const
+{
+ return static_cast<KeywordExt*>(_car);
+}
+
+/* Access to next element of list. */
+INLINE KeywordExt_List *&
+KeywordExt_List::rest ()
+{
+ return *reinterpret_cast<KeywordExt_List**>(&_cdr);
+}
diff --git a/src/keyword.cc b/src/keyword.cc
new file mode 100644
index 000000000000..ae53bcca320a
--- /dev/null
+++ b/src/keyword.cc
@@ -0,0 +1,161 @@
+/* Keyword data.
+ Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Specification. */
+#include "keyword.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "positions.h"
+
+
+/* --------------------------- KeywordExt class --------------------------- */
+
+/* Sort a small set of 'unsigned int', base[0..len-1], in place. */
+static inline void sort_char_set (unsigned int *base, int len)
+{
+ /* Bubble sort is sufficient here. */
+ for (int i = 1; i < len; i++)
+ {
+ int j;
+ unsigned int tmp;
+
+ for (j = i, tmp = base[j]; j > 0 && tmp < base[j - 1]; j--)
+ base[j] = base[j - 1];
+
+ base[j] = tmp;
+ }
+}
+
+/* Initializes selchars and selchars_length.
+
+ General idea:
+ The hash function will be computed as
+ asso_values[allchars[key_pos[0]]] +
+ asso_values[allchars[key_pos[1]]] + ...
+ We compute selchars as the multiset
+ { allchars[key_pos[0]], allchars[key_pos[1]], ... }
+ so that the hash function becomes
+ asso_values[selchars[0]] + asso_values[selchars[1]] + ...
+ Furthermore we sort the selchars array, to ease detection of duplicates
+ later.
+
+ More in detail: The arguments alpha_unify (used for case-insensitive
+ hash functions) and alpha_inc (used to disambiguate permutations)
+ apply slight modifications. The hash function will be computed as
+ sum (j=0,1,...: k = key_pos[j]:
+ asso_values[alpha_unify[allchars[k]+alpha_inc[k]]])
+ + (allchars_length if !option[NOLENGTH], 0 otherwise).
+ We compute selchars as the multiset
+ { alpha_unify[allchars[k]+alpha_inc[k]] : j=0,1,..., k = key_pos[j] }
+ so that the hash function becomes
+ asso_values[selchars[0]] + asso_values[selchars[1]] + ...
+ + (allchars_length if !option[NOLENGTH], 0 otherwise).
+ */
+
+unsigned int *
+KeywordExt::init_selchars_low (const Positions& positions, const unsigned int *alpha_unify, const unsigned int *alpha_inc)
+{
+ /* Iterate through the list of positions, initializing selchars
+ (via ptr). */
+ PositionIterator iter = positions.iterator(_allchars_length);
+
+ unsigned int *key_set = new unsigned int[iter.remaining()];
+ unsigned int *ptr = key_set;
+
+ for (int i; (i = iter.next ()) != PositionIterator::EOS; )
+ {
+ unsigned int c;
+ if (i == Positions::LASTCHAR)
+ /* Special notation for last KEY position, i.e. '$'. */
+ c = static_cast<unsigned char>(_allchars[_allchars_length - 1]);
+ else if (i < _allchars_length)
+ {
+ /* Within range of KEY length, so we'll keep it. */
+ c = static_cast<unsigned char>(_allchars[i]);
+ if (alpha_inc)
+ c += alpha_inc[i];
+ }
+ else
+ /* Out of range of KEY length, the iterator should not have
+ produced this. */
+ abort ();
+ if (alpha_unify)
+ c = alpha_unify[c];
+ *ptr = c;
+ ptr++;
+ }
+
+ _selchars = key_set;
+ _selchars_length = ptr - key_set;
+
+ return key_set;
+}
+
+void
+KeywordExt::init_selchars_tuple (const Positions& positions, const unsigned int *alpha_unify)
+{
+ init_selchars_low (positions, alpha_unify, NULL);
+}
+
+void
+KeywordExt::init_selchars_multiset (const Positions& positions, const unsigned int *alpha_unify, const unsigned int *alpha_inc)
+{
+ unsigned int *selchars =
+ init_selchars_low (positions, alpha_unify, alpha_inc);
+
+ /* Sort the selchars elements alphabetically. */
+ sort_char_set (selchars, _selchars_length);
+}
+
+/* Deletes selchars. */
+void
+KeywordExt::delete_selchars ()
+{
+ delete[] const_cast<unsigned int *>(_selchars);
+}
+
+
+/* ------------------------- Keyword_Factory class ------------------------- */
+
+Keyword_Factory::Keyword_Factory ()
+{
+}
+
+Keyword_Factory::~Keyword_Factory ()
+{
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+char empty_string[1] = "";
+
+
+#ifndef __OPTIMIZE__
+
+#define INLINE /* not inline */
+#include "keyword.icc"
+#undef INLINE
+
+#endif /* not defined __OPTIMIZE__ */
diff --git a/src/keyword.h b/src/keyword.h
new file mode 100644
index 000000000000..88243506c2e3
--- /dev/null
+++ b/src/keyword.h
@@ -0,0 +1,116 @@
+/* This may look like C code, but it is really -*- C++ -*- */
+
+/* Keyword data.
+
+ Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef keyword_h
+#define keyword_h 1
+
+/* Class defined in "positions.h". */
+class Positions;
+
+/* An instance of this class is a keyword, as specified in the input file. */
+
+struct Keyword
+{
+ /* Constructor. */
+ Keyword (const char *allchars, int allchars_length,
+ const char *rest);
+
+ /* Data members defined immediately by the input file. */
+ /* The keyword as a string, possibly containing NUL bytes. */
+ const char *const _allchars;
+ int const _allchars_length;
+ /* Additional stuff seen on the same line of the input file. */
+ const char *const _rest;
+ /* Line number of this keyword in the input file. */
+ unsigned int _lineno;
+};
+
+/* A keyword, in the context of a given keyposition list. */
+
+struct KeywordExt : public Keyword
+{
+ /* Constructor. */
+ KeywordExt (const char *allchars, int allchars_length,
+ const char *rest);
+
+ /* Data members depending on the keyposition list. */
+ /* The selected characters that participate for the hash function,
+ selected according to the keyposition list, as a canonically reordered
+ multiset. */
+ const unsigned int * _selchars;
+ int _selchars_length;
+ /* Chained list of keywords having the same _selchars and
+ - if !option[NOLENGTH] - also the same _allchars_length.
+ Note that these duplicates are not members of the main keyword list. */
+ KeywordExt * _duplicate_link;
+
+ /* Methods depending on the keyposition list. */
+ /* Initializes selchars and selchars_length, without reordering. */
+ void init_selchars_tuple (const Positions& positions, const unsigned int *alpha_unify);
+ /* Initializes selchars and selchars_length, with reordering. */
+ void init_selchars_multiset (const Positions& positions, const unsigned int *alpha_unify, const unsigned int *alpha_inc);
+ /* Deletes selchars. */
+ void delete_selchars ();
+
+ /* Data members used by the algorithm. */
+ int _hash_value; /* Hash value for the keyword. */
+
+ /* Data members used by the output routines. */
+ int _final_index;
+
+private:
+ unsigned int * init_selchars_low (const Positions& positions, const unsigned int *alpha_unify, const unsigned int *alpha_inc);
+};
+
+/* An abstract factory for creating Keyword instances.
+ This factory is used to make the Input class independent of the concrete
+ class KeywordExt. */
+
+class Keyword_Factory
+{
+public:
+ /* Constructor. */
+ Keyword_Factory ();
+ /* Destructor. */
+ virtual ~Keyword_Factory ();
+
+ /* Creates a new Keyword. */
+ virtual /*abstract*/ Keyword *
+ create_keyword (const char *allchars, int allchars_length,
+ const char *rest) = 0;
+};
+
+/* A statically allocated empty string. */
+extern char empty_string[1];
+
+#ifdef __OPTIMIZE__
+
+#define INLINE inline
+#include "keyword.icc"
+#undef INLINE
+
+#endif
+
+#endif
diff --git a/src/keyword.icc b/src/keyword.icc
new file mode 100644
index 000000000000..ba0bb56eebc1
--- /dev/null
+++ b/src/keyword.icc
@@ -0,0 +1,42 @@
+/* Inline Functions for keyword.{h,cc}.
+
+ Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* ----------------------------- Keyword class ----------------------------- */
+
+/* Constructor. */
+INLINE
+Keyword::Keyword (const char *allchars, int allchars_length, const char *rest)
+ : _allchars (allchars), _allchars_length (allchars_length), _rest (rest)
+{
+}
+
+
+/* --------------------------- KeywordExt class --------------------------- */
+
+/* Constructor. */
+INLINE
+KeywordExt::KeywordExt (const char *allchars, int allchars_length, const char *rest)
+ : Keyword (allchars, allchars_length, rest),
+ _final_index (-1)
+{
+}
diff --git a/src/list-node.cc b/src/list-node.cc
deleted file mode 100644
index 57a04a071fe4..000000000000
--- a/src/list-node.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Creates and initializes a new list node.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include "list-node.h"
-
-#include <stdio.h>
-#include <stdlib.h> /* declares exit() */
-#include "options.h"
-#include "trace.h"
-
-/* Sorts the key set alphabetically to speed up subsequent operations.
- Uses insertion sort since the set is probably quite small. */
-
-inline void
-List_Node::set_sort (char *base, int len)
-{
- T (Trace t ("List_Node::set_sort");)
- int i, j;
-
- for (i = 0, j = len - 1; i < j; i++)
- {
- char curr, tmp;
-
- for (curr = i + 1, tmp = base[curr]; curr > 0 && tmp < base[curr-1]; curr--)
- base[curr] = base[curr - 1];
-
- base[curr] = tmp;
-
- }
-}
-
-/* Initializes a List_Node. This requires obtaining memory for the CHAR_SET
- initializing them using the information stored in the KEY_POSITIONS array in Options,
- and checking for simple errors. It's important to note that KEY and REST are
- both pointers to the different offsets into the same block of dynamic memory pointed
- to by parameter K. The data member REST is used to store any additional fields
- of the input file (it is set to the "" string if Option[TYPE] is not enabled).
- This is useful if the user wishes to incorporate a lookup structure,
- rather than just an array of keys. Finally, KEY_NUMBER contains a count
- of the total number of keys seen so far. This is used to initialize
- the INDEX field to some useful value. */
-
-List_Node::List_Node (const char *k, int len, const char *r):
- link (0), next (0), key (k), key_length (len), rest (r), index (0)
-{
- T (Trace t ("List_Node::List_Node");)
- char *key_set = new char[(option[ALLCHARS] ? len : option.get_max_keysig_size ())];
- char *ptr = key_set;
- int i;
-
- if (option[ALLCHARS]) /* Use all the character positions in the KEY. */
- for (i = len; i > 0; k++, ptr++, i--)
- ++occurrences[(unsigned char)(*ptr = *k)];
- else /* Only use those character positions specified by the user. */
- {
- /* Iterate through the list of key_positions, initializing occurrences table
- and char_set (via char * pointer ptr). */
-
- for (option.reset (); (i = option.get ()) != EOS; )
- {
- if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */
- *ptr = key[len - 1];
- else if (i <= len) /* Within range of KEY length, so we'll keep it. */
- *ptr = key[i - 1];
- else /* Out of range of KEY length, so we'll just skip it. */
- continue;
- ++occurrences[(unsigned char)(*ptr++)];
- }
-
- /* Didn't get any hits and user doesn't want to consider the
- keylength, so there are essentially no usable hash positions! */
- if (ptr == char_set && option[NOLENGTH])
- {
- fprintf (stderr, "Can't hash keyword %.*s with chosen key positions.\n",
- key_length, key);
- exit (1);
- }
- }
-
- /* Sort the KEY_SET items alphabetically. */
- set_sort (key_set, ptr - key_set);
-
- char_set = key_set;
- char_set_length = ptr - key_set;
-}
diff --git a/src/list-node.h b/src/list-node.h
deleted file mode 100644
index 3bd21b3359df..000000000000
--- a/src/list-node.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This may look like C code, but it is really -*- C++ -*- */
-
-/* Data and function members for defining values and operations of a list node.
-
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#ifndef list_node_h
-#define list_node_h 1
-
-#include "vectors.h"
-
-struct List_Node : private Vectors
-{
- List_Node *link; /* TRUE if key has an identical KEY_SET as another key. */
- List_Node *next; /* Points to next element on the list. */
- const char *key; /* Each keyword string stored here. */
- int key_length; /* Length of the key. */
- const char *rest; /* Additional information for building hash function. */
- const char *char_set; /* Set of characters to hash, specified by user. */
- int char_set_length; /* Length of char_set. */
- int hash_value; /* Hash value for the key. */
- int occurrence; /* A metric for frequency of key set occurrences. */
- int index; /* Position of this node relative to other nodes. */
-
- List_Node (const char *key, int len, const char *rest);
- static void set_sort (char *base, int len);
-};
-
-#endif
diff --git a/src/listnode.c b/src/listnode.c
deleted file mode 100644
index 2eec1a6f74f8..000000000000
--- a/src/listnode.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Creates and initializes a new list node.
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdio.h>
-#include "options.h"
-#include "listnode.h"
-#include "stderr.h"
-
-/* See comments in perfect.cc. */
-extern int occurrences[ALPHABET_SIZE];
-
-/* Sorts the key set alphabetically to speed up subsequent operations.
- Uses insertion sort since the set is probably quite small. */
-
-static void
-set_sort (base, len)
- char *base;
- int len;
-{
- int i, j;
-
- for (i = 0, j = len - 1; i < j; i++)
- {
- char curr, tmp;
-
- for (curr = i + 1, tmp = base[curr]; curr > 0 && tmp < base[curr-1]; curr--)
- base[curr] = base[curr - 1];
-
- base[curr] = tmp;
-
- }
-}
-
-/* Initializes a List_Node. This requires obtaining memory for the KEY_SET
- initializing them using the information stored in the
- KEY_POSITIONS array in Options, and checking for simple errors.
- It's important to note that KEY and REST are both pointers to
- the different offsets into the same block of dynamic memory pointed to
- by parameter K. The data member REST is used to store any additional fields
- of the input file (it is set to the "" string if Option[TYPE] is not enabled).
- This is useful if the user wishes to incorporate a lookup structure,
- rather than just an array of keys. */
-
-LIST_NODE *
-make_list_node (k, len)
- char *k;
- int len;
-{
- LIST_NODE *buffered_malloc ();
- int char_set_size = OPTION_ENABLED (option, ALLCHARS) ? len : GET_CHARSET_SIZE (option) + 1;
- LIST_NODE *temp = buffered_malloc (sizeof (LIST_NODE) + char_set_size);
- char *ptr = temp->char_set;
-
- k[len] = '\0'; /* Null terminate KEY to separate it from REST. */
- temp->key = k;
- temp->next = 0;
- temp->index = 0;
- temp->length = len;
- temp->link = 0;
- temp->rest = OPTION_ENABLED (option, TYPE) ? k + len + 1 : "";
-
- if (OPTION_ENABLED (option, ALLCHARS)) /* Use all the character position in the KEY. */
-
- for (; *k; k++, ptr++)
- ++occurrences[*ptr = *k];
-
- else /* Only use those character positions specified by the user. */
- {
- int i;
-
- /* Iterate thru the list of key_positions, initializing occurrences table
- and temp->char_set (via char * pointer ptr). */
-
- for(RESET (option); (i = GET (option)) != EOS; )
- {
- if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */
- *ptr = temp->key[len - 1];
- else if (i <= len) /* Within range of KEY length, so we'll keep it. */
- *ptr = temp->key[i - 1];
- else /* Out of range of KEY length, so we'll just skip it. */
- continue;
- ++occurrences[*ptr++];
- }
-
- if (ptr == temp->char_set) /* Didn't get any hits, i.e., no usable positions. */
- report_error ("can't hash keyword %s with chosen key positions\n%a", temp->key);
- }
-
- *ptr = '\0'; /* Terminate this bastard.... */
- /* Sort the KEY_SET items alphabetically. */
- set_sort (temp->char_set, ptr - temp->char_set);
-
- return temp;
-}
diff --git a/src/listnode.h b/src/listnode.h
deleted file mode 100644
index 3e64709f5c10..000000000000
--- a/src/listnode.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Data and function members for defining values and operations of a list node.
-
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef _listnode_h
-#define _listnode_h
-#include "prototype.h"
-
-#define ALPHABET_SIZE 128
-
-typedef struct list_node
-{
- struct list_node *link; /* TRUE if key has an identical KEY_SET as another key. */
- struct list_node *next; /* Points to next element on the list. */
- int length; /* Length of the key. */
- int hash_value; /* Hash value for the key. */
- int occurrence; /* A metric for frequency of key set occurrences. */
- int index; /* Position of this node relative to other nodes. */
- char *key; /* Key string. */
- char *rest; /* Additional information for building hash function. */
- char char_set[1]; /* Set of characters to hash, specified by user. */
-} LIST_NODE;
-
-extern LIST_NODE *make_list_node P ((char *k, int len));
-
-#endif _listnode_h
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index a54c1dfc5069..000000000000
--- a/src/main.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Driver program for the Perfect hash function generator.
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Simple driver program for the Perfect.hash function generator.
- Most of the hard work is done in class Perfect and its class methods. */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <time.h>
-#include "stderr.h"
-#include "options.h"
-#include "perfect.h"
-
-/* Calls the appropriate intialization routines for each
- ADT. Note that certain initialization routines require
- initialization *after* certain values are computed. Therefore,
- they cannot be called here. */
-
-static void
-init_all (argc, argv)
- int argc;
- char *argv[];
-{
-#ifdef RLIMIT_STACK
- /* Get rid of any avoidable limit on stack size. */
- {
- struct rlimit rlim;
-
- /* Set the stack limit huge so that alloca does not fail. */
- getrlimit (RLIMIT_STACK, &rlim);
- rlim.rlim_cur = rlim.rlim_max;
- setrlimit (RLIMIT_STACK, &rlim);
- }
-#endif /* RLIMIT_STACK */
-
- options_init (argc, argv);
- key_list_init ();
- perfect_init ();
-}
-
-/* Calls appropriate destruction routines for each ADT. These
- routines print diagnostics if the debugging option is enabled. */
-
-static void
-destroy_all ()
-{
- options_destroy ();
- key_list_destroy ();
- perfect_destroy ();
-}
-
-/* Driver for perfect hash function generation. */
-
-int
-main (argc, argv)
- int argc;
- char *argv[];
-{
- struct tm *tm;
- time_t clock;
- int status;
-
- time (&clock);
- tm = localtime (&clock);
-
- fprintf (stderr, "/* starting time is %d:%d:%d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
- /* Sets the options. */
- init_all (argc, argv);
-
- /* Generates the perfect hash table.
- Also prints generated code neatly to the output. */
- status = perfect_generate ();
- destroy_all ();
-
- time (&clock);
- tm = localtime (&clock);
- fprintf (stderr, "/* ending time is %d:%d:%d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
- return status;
-}
diff --git a/src/main.cc b/src/main.cc
index 03b6c7ea242b..577708b48bfd 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,76 +1,155 @@
-/* Driver program for the Gen_Perf hash function generator
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-/* Simple driver program for the Gen_Perf.hash function generator.
- Most of the hard work is done in class Gen_Perf and its class methods. */
-
-#include "config.h"
-#include <sys/types.h>
-#if LARGE_STACK_ARRAYS && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#endif
+/* Driver program for the hash function generator
+ Copyright (C) 1989-1998, 2000, 2002-2003 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include "options.h"
-#include "gen-perf.h"
-#include "trace.h"
+#include "input.h"
+#include "search.h"
+#include "output.h"
+
+
+/* ------------------------------------------------------------------------- */
+
+/* This Keyword factory produces KeywordExt instances. */
+
+class KeywordExt_Factory : public Keyword_Factory
+{
+virtual Keyword * create_keyword (const char *allchars, int allchars_length,
+ const char *rest);
+};
+
+Keyword *
+KeywordExt_Factory::create_keyword (const char *allchars, int allchars_length, const char *rest)
+{
+ return new KeywordExt (allchars, allchars_length, rest);
+}
+
+/* ------------------------------------------------------------------------- */
int
main (int argc, char *argv[])
{
- T (Trace t ("main");)
+ int exitcode;
+
+ /* Set the Options. Open the input file and assign stdin to it. */
+ option.parse_options (argc, argv);
+
+ /* Open the input file. */
+ if (option.get_input_file_name ())
+ if (!freopen (option.get_input_file_name (), "r", stdin))
+ {
+ fprintf (stderr, "Cannot open input file '%s'\n",
+ option.get_input_file_name ());
+ exit (1);
+ }
-#if LARGE_STACK_ARRAYS && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
- /* Get rid of any avoidable limit on stack size. */
{
- struct rlimit rlim;
- if (getrlimit (RLIMIT_STACK, &rlim) == 0)
- if (rlim.rlim_cur < rlim.rlim_max)
- {
- rlim.rlim_cur = rlim.rlim_max;
- setrlimit (RLIMIT_STACK, &rlim);
- }
- }
-#endif /* RLIMIT_STACK */
+ /* Initialize the keyword list. */
+ KeywordExt_Factory factory;
+ Input inputter (stdin, &factory);
+ inputter.read_input ();
+ /* We can cast the keyword list to KeywordExt_List* because its list
+ elements were created by KeywordExt_Factory. */
+ KeywordExt_List* list = static_cast<KeywordExt_List*>(inputter._head);
+
+ {
+ /* Search for a good hash function. */
+ Search searcher (list);
+ searcher.optimize ();
+ list = searcher._head;
+
+ /* Open the output file. */
+ if (option.get_output_file_name ())
+ if (strcmp (option.get_output_file_name (), "-") != 0)
+ if (!freopen (option.get_output_file_name (), "w", stdout))
+ {
+ fprintf (stderr, "Cannot open output file '%s'\n",
+ option.get_output_file_name ());
+ exit (1);
+ }
- /* Sets the Options. */
- option (argc, argv);
+ {
+ /* Output the hash function code. */
+ Output outputter (searcher._head,
+ inputter._struct_decl,
+ inputter._struct_decl_lineno,
+ inputter._return_type,
+ inputter._struct_tag,
+ inputter._verbatim_declarations,
+ inputter._verbatim_declarations_end,
+ inputter._verbatim_declarations_lineno,
+ inputter._verbatim_code,
+ inputter._verbatim_code_end,
+ inputter._verbatim_code_lineno,
+ inputter._charset_dependent,
+ searcher._total_keys,
+ searcher._max_key_len,
+ searcher._min_key_len,
+ searcher._key_positions,
+ searcher._alpha_inc,
+ searcher._total_duplicates,
+ searcher._alpha_size,
+ searcher._asso_values);
+ outputter.output ();
- /* Initializes the key word list. */
- Gen_Perf generate_table;
+ /* Check for write error on stdout. */
+ exitcode = 0;
+ if (fflush (stdout) || ferror (stdout))
+ {
+ fprintf (stderr, "error while writing output file\n");
+ exitcode = 1;
+ }
- /* Generates and prints the Gen_Perf hash table. */
- int status = generate_table ();
+ /* Here we run the Output destructor. */
+ }
+ /* Here we run the Search destructor. */
+ }
- /* Check for write error on stdout. */
- if (fflush (stdout) || ferror (stdout))
- status = 1;
+ /* Also delete the list that was allocated inside Input and reordered
+ inside Search. */
+ for (KeywordExt_List *ptr = list; ptr; ptr = ptr->rest())
+ {
+ KeywordExt *keyword = ptr->first();
+ do
+ {
+ KeywordExt *next_keyword = keyword->_duplicate_link;
+ delete[] const_cast<unsigned int *>(keyword->_selchars);
+ if (keyword->_rest != empty_string)
+ delete[] const_cast<char*>(keyword->_rest);
+ if (!(keyword->_allchars >= inputter._input
+ && keyword->_allchars < inputter._input_end))
+ delete[] const_cast<char*>(keyword->_allchars);
+ delete keyword;
+ keyword = next_keyword;
+ }
+ while (keyword != NULL);
+ }
+ delete_list (list);
+
+ /* Here we run the Input destructor. */
+ }
- /* Don't use exit() here, it skips the destructors. */
- return status;
+ /* Don't use exit() here, it skips the destructors. */
+ return exitcode;
}
diff --git a/src/new.cc b/src/new.cc
deleted file mode 100644
index 8c6728ec4b2a..000000000000
--- a/src/new.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Defines a buffered memory allocation abstraction that reduces calls to
- malloc.
- Copyright (C) 1989-1998 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h> /* declares malloc(), exit() */
-#include "trace.h"
-
-/* Determine default alignment. If your C++ compiler does not
- like this then try something like #define DEFAULT_ALIGNMENT 8. */
-struct fooalign {char x; double d;};
-const int ALIGNMENT = ((char *)&((struct fooalign *) 0)->d - (char *)0);
-
-/* Provide an abstraction that cuts down on the number of
- calls to NEW by buffering the memory pool from which
- strings are allocated. */
-
-void *
-operator new (size_t size)
-{
- T (Trace t ("operator new");)
- static char *buf_start = 0; /* Large array used to reduce calls to NEW. */
- static char *buf_end = 0; /* Indicates end of BUF_START. */
- static size_t buf_size = 4096; /* Size of buffer pointed to by BUF_START. */
- char *temp;
-
- /* Align this on correct boundaries, just to be safe... */
- size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
-
- /* If we are about to overflow our buffer we'll just grab another
- chunk of memory. Since we never free the original memory it
- doesn't matter that no one points to the beginning of that
- chunk. Note we use a heuristic that grows the buffer either by
- size of the request or by twice the previous size, whichever is
- larger. */
-
- if (buf_start + size >= buf_end)
- {
- buf_size *= 2;
- if (buf_size < size)
- buf_size = size;
- if ((buf_start = (char *)malloc (buf_size)) != (char *)0)
- buf_end = buf_start + buf_size;
- else
- {
- fprintf (stderr, "Virtual memory exhausted in `operator new'\n");
- exit (1);
- }
- }
-
- temp = buf_start;
- buf_start += size;
- return temp;
-}
-
-/* We need this deletion operator in order to make the linker happy.
- Because `operator new' and `operator delete' always come together. */
-
-void
-operator delete (void *ptr)
-#ifdef HAVE_THROW_DECL
- throw()
-#endif
-{
- T (Trace t ("operator delete");)
- // We cannot call free here, as it doesn't match the mallocs.
- // free ((char *) ptr);
- (void) ptr;
-}
diff --git a/src/options.c b/src/options.c
deleted file mode 100644
index 40fdf0a6588e..000000000000
--- a/src/options.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/* Handles parsing the Options provided to the user.
- Copyright (C) 1989 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
-
-This file is part of GNU GPERF.
-
-GNU GPERF 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 1, or (at your option)
-any later version.
-
-GNU GPERF 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 GPERF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdio.h>
-#include <assert.h>
-#include "options.h"
-#include "iterator.h"
-#include "stderr.h"
-
-/* Current program version. */
-extern char *version_string;
-
-/* Size to jump on a collision. */
-#define DEFAULT_JUMP_VALUE 5
-
-/* Default name for generated lookup function. */
-#define DEFAULT_NAME "in_word_set"
-
-/* Default name for the key component. */
-#define DEFAULT_KEY "name"
-
-/* Default name for generated hash function. */
-#define DEFAULT_HASH_NAME "hash"
-
-/* Globally visible OPTIONS object. */
-OPTIONS option;
-
-/* Default delimiters that separate keywords from their attributes. */
-#define DEFAULT_DELIMITERS ",\n"
-
-/* Prints program usage to standard error stream. */
-
-void
-usage ()
-{
- report_error ("usage: %n [-acCdDef[num]gGhH<hashname>i<init>jk<keys>\
-K<keyname>lnN<name>oprs<size>S<switches>tTv].\n(type %n -h for help)\n");
-}
-
-/* Sorts the key positions *IN REVERSE ORDER!!*
- This makes further routines more efficient. Especially when generating code.
- Uses a simple Insertion Sort since the set is probably ordered.
- Returns 1 if there are no duplicates, 0 otherwise. */
-
-static int
-key_sort (base, len)
- char *base;
- int len;
-{
- int i, j;
-
- for (i = 0, j = len - 1; i < j; i++)
- {
- int curr, tmp;
-
- for (curr = i + 1,tmp = base[curr]; curr > 0 && tmp >= base[curr - 1]; curr--)
- if ((base[curr] = base[curr - 1]) == tmp) /* oh no, a duplicate!!! */
- return 0;
-
- base[curr] = tmp;
- }
-
- return 1;
-}
-
-/* Dumps option status when debug is set. */
-
-void
-options_destroy ()
-{
- if (OPTION_ENABLED (option, DEBUG))
- {
- char *ptr;
-
- fprintf (stderr, "\ndumping Options:\nDEBUG is.......: %s\nORDER is.......: %s\
-\nANSI is........: %s\nTYPE is........: %s\nGNU is.........: %s\nRANDOM is......: %s\
-\nDEFAULTCHARS is: %s\nSWITCH is......: %s\nPOINTER is.....: %s\nNOLENGTH is....: %s\
-\nLENTABLE is....: %s\nDUP is.........: %s\nCOMP is........: %s\nFAST is........: %s\
-\nNOTYPE is......: %s\nGLOBAL is......: %s\nCONST is.......: %s\niterations = %d\
-\nlookup function name = %s\nhash function name = %s\nkey name = %s\
-\njump value = %d\nmax associcated value = %d\ninitial associated value = %d\
-\ndelimiters = %s\nnumber of switch statements = %d\napproximate switch statement size = %d\n",
- OPTION_ENABLED (option, DEBUG) ? "enabled" : "disabled",
- OPTION_ENABLED (option, ORDER) ? "enabled" : "disabled",
- OPTION_ENABLED (option, ANSI) ? "enabled" : "disabled",
- OPTION_ENABLED (option, TYPE) ? "enabled" : "disabled",
- OPTION_ENABLED (option, GNU) ? "enabled" : "disabled",
- OPTION_ENABLED (option, RANDOM) ? "enabled" : "disabled",
- OPTION_ENABLED (option, DEFAULTCHARS) ? "enabled" : "disabled",
- OPTION_ENABLED (option, SWITCH) ? "enabled" : "disabled",
- OPTION_ENABLED (option, POINTER) ? "enabled" : "disabled",
- OPTION_ENABLED (option, NOLENGTH) ? "enabled" : "disabled",
- OPTION_ENABLED (option, LENTABLE) ? "enabled" : "disabled",
- OPTION_ENABLED (option, DUP) ? "enabled" : "disabled",
- OPTION_ENABLED (option, COMP) ? "enabled" : "disabled",
- OPTION_ENABLED (option, FAST) ? "enabled" : "disabled",
- OPTION_ENABLED (option, NOTYPE) ? "enabled" : "disabled",
- OPTION_ENABLED (option, GLOBAL) ? "enabled" : "disabled",
- OPTION_ENABLED (option, CONST) ? "enabled" : "disabled",
- option.iterations, option.function_name, option.hash_name,
- option.key_name, option.jump, option.size - 1,
- option.initial_asso_value, option.delimiters, option.total_switches,
- keyword_list_length () / option.total_switches);
-
- if (OPTION_ENABLED (option, ALLCHARS))
- fprintf (stderr, "all characters are used in the hash function\n");
- fprintf (stderr, "maximum charset size = %d\nkey positions are: \n",
- option.total_charset_size);
-
- for (ptr = option.key_positions; *ptr != EOS; ptr++)
- if (*ptr == WORD_END)
- fprintf (stderr, "$\n");
- else
- fprintf (stderr, "%d\n", *ptr);
-
- fprintf (stderr, "finished dumping Options\n");
- }
-}
-
-/* Parses the command line Options and sets appropriate flags in option.option_word. */
-
-void
-options_init (argc, argv)
- int argc;
- char *argv[];
-{
- extern int optind;
- extern char *optarg;
- int option_char;
-
- option.key_positions[0] = WORD_START;
- option.key_positions[1] = WORD_END;
- option.key_positions[2] = EOS;
- option.total_charset_size = 2;
- option.jump = DEFAULT_JUMP_VALUE;
- option.option_word = (int) DEFAULTCHARS;
- option.function_name = DEFAULT_NAME;
- option.hash_name = DEFAULT_HASH_NAME;
- option.key_name = DEFAULT_KEY;
- option.delimiters = DEFAULT_DELIMITERS;
- option.initial_asso_value = option.size = option.iterations = 0;
- option.total_switches = 1;
- option.argument_count = argc;
- option.argument_vector = argv;
- set_program_name (argv[0]);
-
- while ((option_char = getopt (argc, argv, "adcCDe:f:gGhH:i:j:k:K:lnN:oprs:S:tTv")) != EOF)
- {
- switch (option_char)
- {
- case 'a': /* Generated coded uses the ANSI prototype format. */
- {
- SET_OPTION (option, ANSI);
- break;
- }
- case 'c': /* Generate strncmp rather than strcmp. */
- {
- SET_OPTION (option, COMP);
- break;
- }
- case 'C': /* Make the generated tables readonly (const). */
- {
- SET_OPTION (option, CONST);
- break;
- }
- case 'd': /* Enable debugging option. */
- {
- SET_OPTION (option, DEBUG);
- report_error ("starting program %n, version %s, with debuggin on.\n",
- version_string);
- break;
- }
- case 'D': /* Enable duplicate option. */
- {
- SET_OPTION (option, DUP);
- break;
- }
- case 'e': /* Allows user to provide keyword/attribute separator */
- {
- SET_DELIMITERS (option, optarg);
- break;
- }
- case 'f': /* Generate the hash table ``fast.'' */
- {
- SET_OPTION (option, FAST);
- if ((option.iterations = atoi (optarg)) < 0)
- {
- report_error ("iterations value must not be negative, assuming 0\n");
- option.iterations = 0;
- }
- break;
- }
- case 'g': /* Use the ``inline'' keyword for generated sub-routines. */
- {
- SET_OPTION (option, GNU);
- break;
- }
- case 'G': /* Make the keyword table a global variable. */
- {
- SET_OPTION (option, GLOBAL);
- break;
- }
- case 'h': /* Displays a list of helpful Options to the user. */
- {
- report_error (
-"-a\tGenerate ANSI standard C output code, i.e., function prototypes.\n\
--c\tGenerate comparison code using strncmp rather than strcmp.\n\
--C\tMake the contents of generated lookup tables constant, i.e., readonly.\n\
--d\tEnables the debugging option (produces verbose output to Std_Err).\n\
--D\tHandle keywords that hash to duplicate values. This is useful\n\
-\tfor certain highly redundant keyword sets. It enables the -S option.\n\
--e\tAllow user to provide a string containing delimiters used to separate\n\
-\tkeywords from their attributes. Default is \",\\n\"\n\
--f\tGenerate the perfect hash function ``fast.'' This decreases GPERF's\n\
-\trunning time at the cost of minimizing generated table-size.\n\
-\tThe numeric argument represents the number of times to iterate when\n\
-\tresolving a collision. `0' means ``iterate by the number of keywords''.\n\
--g\tAssume a GNU compiler, e.g., g++ or gcc. This makes all generated\n\
-\troutines use the ``inline'' keyword to remove cost of function calls.\n\
--G\tGenerate the static table of keywords as a static global variable,\n\
-\trather than hiding it inside of the lookup function (which is the\n\
-\tdefault behavior).\n\
--h\tPrints this mesage.\n");
- report_error (
-"-H\tAllow user to specify name of generated hash function. Default is `hash'.\n\
--i\tProvide an initial value for the associate values array. Default is 0.\n\
-\tSetting this value larger helps inflate the size of the final table.\n\
--j\tAffects the ``jump value,'' i.e., how far to advance the associated\n\
-\tcharacter value upon collisions. Must be an odd number, default is %d.\n\
--k\tAllows selection of the key positions used in the hash function.\n\
-\tThe allowable choices range between 1-%d, inclusive. The positions\n\
-\tare separated by commas, ranges may be used, and key positions may\n\
-\toccur in any order. Also, the meta-character '*' causes the generated\n\
-\thash function to consider ALL key positions, and $ indicates the\n\
-\t``final character'' of a key, e.g., $,1,2,4,6-10.\n\
--K\tAllow user to select name of the keyword component in the keyword structure.\n\
--l\tCompare key lengths before trying a string comparison. This helps\n\
-\tcut down on the number of string comparisons made during the lookup.\n\
--n\tDo not include the length of the keyword when computing the hash function\n\
--N\tAllow user to specify name of generated lookup function. Default\n\
-\tname is `in_word_set.'\n\
--o\tReorders input keys by frequency of occurrence of the key sets.\n\
-\tThis should decrease the search time dramatically.\n\
--p\tChanges the return value of the generated function ``in_word_set''\n\
-\tfrom its default boolean value (i.e., 0 or 1), to type ``pointer\n\
-\tto wordlist array'' This is most useful when the -t option, allowing\n\
-\tuser-defined structs, is used.\n",
- DEFAULT_JUMP_VALUE, MAX_KEY_POS - 1);
- report_error (
-"-r\tUtilizes randomness to initialize the associated values table.\n\
--s\tAffects the size of the generated hash table. The numeric argument\n\
-\tfor this option indicates ``how many times larger'' the table range\n\
-\tshould be, in relationship to the number of keys, e.g. a value of 3\n\
-\tmeans ``make the table about 3 times larger than the number of input\n\
-\tkeys.'' A larger table should decrease the time required for an\n\
-\tunsuccessful search, at the expense of extra table space. Default\n\
-\tvalue is 1. This actual table size may vary somewhat.\n\
--S\tCauses the generated C code to use a switch statement scheme, rather\n\
-\tthan an array lookup table. This can lead to a reduction in both\n\
-\ttime and space requirements for some keyfiles. The argument to\n\
-\tthis option determines how many switch statements are generated.\n\
-\tA value of 1 generates 1 switch containing all the elements, a value of 2\n\
-\tgenerates 2 tables with 1/2 the elements in each table, etc. This\n\
-\tis useful since many C compilers cannot correctly generate code for\n\
-\tlarge switch statements.\n\
-\tthe expense of longer time for each lookup. Mostly important for\n\
-\t*large* input sets, i.e., greater than around 100 items or so.\n\
--t\tAllows the user to include a structured type declaration for \n\
-\tgenerated code. Any text before %%%% is consider part of the type\n\
-\tdeclaration. Key words and additional fields may follow this, one\n\
-\tgroup of fields per line.\n\
--T\tPrevents the transfer of the type declaration to the output file.\n\
-\tUse this option if the type is already defined elsewhere.\n\
--v\tPrints out the current version number\n%e%a\n",
- usage);
- }
- case 'H': /* Sets the name for the hash function */
- {
- option.hash_name = optarg;
- break;
- }
- case 'i': /* Sets the initial value for the associated values array. */
- {
- if ((option.initial_asso_value = atoi (optarg)) < 0)
- report_error ("initial value %d must be non-zero, ignoring and continuing\n",
- option.initial_asso_value);
- if (OPTION_ENABLED (option, RANDOM))
- report_error ("warning, -r option superceeds -i, ignoring -i option and continuing\n");
- break;
- }
- case 'j': /* Sets the jump value, must be odd for later algorithms. */
- {
- if ((option.jump = atoi (optarg)) < 0)
- report_error ("jump value %d must be a positive number\n%e%a",
- option.jump, usage);
- else if (option.jump && EVEN (option.jump))
- report_error ("jump value %d should be odd, adding 1 and continuing...\n",
- option.jump++);
- break;
- }
- case 'k': /* Sets key positions used for hash function. */
- {
- int BAD_VALUE = -1;
- int value;
-
- iterator_init (optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS);
-
- if (*optarg == '*') /* Use all the characters for hashing!!!! */
- {
- UNSET_OPTION (option, DEFAULTCHARS);
- SET_OPTION (option, ALLCHARS);
- }
- else
- {
- char *key_pos;
-
- for (key_pos = option.key_positions; (value = next ()) != EOS; key_pos++)
- if (value == BAD_VALUE)
- report_error ("illegal key value or range, use 1,2,3-%d,'$' or '*'.\n%e%a",
- (MAX_KEY_POS - 1),usage);
- else
- *key_pos = value;;
-
- *key_pos = EOS;
-
- if (! (option.total_charset_size = (key_pos - option.key_positions)))
- report_error ("no keys selected\n%e%a", usage);
- else if (! key_sort (option.key_positions, option.total_charset_size))
- report_error ("duplicate keys selected\n%e%a", usage);
-
- if (option.total_charset_size != 2
- || (option.key_positions[0] != 1 || option.key_positions[1] != WORD_END))
- UNSET_OPTION (option, DEFAULTCHARS);
- }
- break;
- }
- case 'K': /* Make this the keyname for the keyword component field. */
- {
- option.key_name = optarg;
- break;
- }
- case 'l': /* Create length table to avoid extra string compares. */
- {
- SET_OPTION (option, LENTABLE);
- break;
- }
- case 'n': /* Don't include the length when computing hash function. */
- {
- SET_OPTION (option, NOLENGTH);
- break;
- }
- case 'N': /* Make generated lookup function name be optarg */
- {
- option.function_name = optarg;
- break;
- }
- case 'o': /* Order input by frequency of key set occurrence. */
- {
- SET_OPTION (option, ORDER);
- break;
- }
- case 'p': /* Generated lookup function now a pointer instead of int. */
- {
- SET_OPTION (option, POINTER);
- break;
- }
- case 'r': /* Utilize randomness to initialize the associated values table. */
- {
- SET_OPTION (option, RANDOM);
- if (option.initial_asso_value != 0)
- report_error ("warning, -r option superceeds -i, disabling -i option and continuing\n");
- break;
- }
- case 's': /* Range of associated values, determines size of final table. */
- {
- if ((option.size = atoi (optarg)) <= 0)
- report_error ("improper range argument %s\n%e%a", optarg, usage);
- else if (option.size > 50)
- report_error ("%d is excessive, did you really mean this?! (type %n -h for help)\n",
- option.size);
- break;
- }
- case 'S': /* Generate switch statement output, rather than lookup table. */
- {
- SET_OPTION (option, SWITCH);
- if ((option.total_switches = atoi (optarg)) <= 0)
- report_error ("number of switches %s must be a positive number\n%e%a", optarg, usage);
- break;
- }
- case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */
- {
- SET_OPTION (option, TYPE);
- break;
- }
- case 'T': /* Don't print structure definition. */
- {
- SET_OPTION (option, NOTYPE);
- break;
- }
- case 'v': /* Print out the version and quit. */
- report_error ("%n: version %s\n%e%a\n", version_string, usage);
- default:
- report_error ("%e%a", usage);
- }
- }
-
- if (argv[optind] && ! freopen (argv[optind], "r", stdin))
- report_error ("unable to read key word file %s\n%e%a", argv[optind], usage);
-
- if (++optind < argc)
- report_error ("extra trailing arguments to %n\n%e%a", usage);
-}
-
-/* Output command-line Options. */
-void
-print_options ()
-{
- int i;
-
- printf ("/* Command-line: ");
-
- for (i = 0; i < option.argument_count; i++)
- printf ("%s ", option.argument_vector[i]);
-
- printf (" */\n\n");
-}
-
diff --git a/src/options.cc b/src/options.cc
index d15e21cee8ce..a86432ea65ed 100644
--- a/src/options.cc
+++ b/src/options.cc
@@ -1,151 +1,192 @@
/* Handles parsing the Options provided to the user.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2000, 2002-2004, 2006-2007 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Specification. */
+#include "options.h"
#include <stdio.h>
#include <stdlib.h> /* declares atoi(), abs(), exit() */
#include <string.h> /* declares strcmp() */
+#include <ctype.h> /* declares isdigit() */
+#include <limits.h> /* defines CHAR_MAX */
#include "getopt.h"
-#include "options.h"
-#include "iterator.h"
-#include "trace.h"
-#include "vectors.h"
#include "version.h"
-/* Global option coordinator for the entire program. */
+/* Global option coordinator for the entire program. */
Options option;
-/* Records the program name. */
+/* Records the program name. */
const char *program_name;
-/* Size to jump on a collision. */
+/* Size to jump on a collision. */
static const int DEFAULT_JUMP_VALUE = 5;
-/* Default name for generated lookup function. */
-static const char *const DEFAULT_NAME = "in_word_set";
+/* Default name for generated lookup function. */
+static const char *const DEFAULT_FUNCTION_NAME = "in_word_set";
-/* Default name for the key component. */
-static const char *const DEFAULT_KEY = "name";
+/* Default name for the key component. */
+static const char *const DEFAULT_SLOT_NAME = "name";
-/* Default struct initializer suffix. */
+/* Default struct initializer suffix. */
static const char *const DEFAULT_INITIALIZER_SUFFIX = "";
-/* Default name for the generated class. */
+/* Default name for the generated class. */
static const char *const DEFAULT_CLASS_NAME = "Perfect_Hash";
-/* Default name for generated hash function. */
+/* Default name for generated hash function. */
static const char *const DEFAULT_HASH_NAME = "hash";
-/* Default name for generated hash table array. */
+/* Default name for generated hash table array. */
static const char *const DEFAULT_WORDLIST_NAME = "wordlist";
-/* Default delimiters that separate keywords from their attributes. */
-static const char *const DEFAULT_DELIMITERS = ",\n";
-
-int Options::option_word;
-int Options::total_switches;
-int Options::total_keysig_size;
-int Options::size;
-int Options::key_pos;
-int Options::jump;
-int Options::initial_asso_value;
-int Options::argument_count;
-int Options::iterations;
-char **Options::argument_vector;
-const char *Options::function_name;
-const char *Options::key_name;
-const char *Options::initializer_suffix;
-const char *Options::class_name;
-const char *Options::hash_name;
-const char *Options::wordlist_name;
-const char *Options::delimiters;
-char Options::key_positions[MAX_KEY_POS];
-
-/* Prints program usage to given stream. */
+/* Default name for generated length table array. */
+static const char *const DEFAULT_LENGTHTABLE_NAME = "lengthtable";
+
+/* Default name for string pool. */
+static const char *const DEFAULT_STRINGPOOL_NAME = "stringpool";
+
+/* Default delimiters that separate keywords from their attributes. */
+static const char *const DEFAULT_DELIMITERS = ",";
+
+/* Prints program usage to given stream. */
void
-Options::short_usage (FILE * strm)
+Options::short_usage (FILE * stream)
{
- T (Trace t ("Options::short_usage");)
- fprintf (strm, "Usage: %s [-cCdDef[num]F<initializers>GhH<hashname>i<init>Ijk<keys>K<keyname>lL<language>nN<function name>ors<size>S<switches>tTvW<wordlistname>Z<class name>7] [input-file]\n"
- "Try `%s --help' for more information.\n",
- program_name, program_name);
+ fprintf (stream,
+ "Try '%s --help' for more information.\n", program_name);
}
void
-Options::long_usage (FILE * strm)
+Options::long_usage (FILE * stream)
{
- T (Trace t ("Options::long_usage");)
- fprintf (strm,
- "GNU `gperf' generates perfect hash functions.\n"
- "\n"
- "Usage: %s [OPTION]... [INPUT-FILE]\n"
- "\n"
+ fprintf (stream,
+ "GNU 'gperf' generates perfect hash functions.\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
+ "Usage: %s [OPTION]... [INPUT-FILE]\n",
+ program_name);
+ fprintf (stream, "\n");
+ fprintf (stream,
"If a long option shows an argument as mandatory, then it is mandatory\n"
- "for the equivalent short option also.\n"
- "\n"
- "Input file interpretation:\n"
+ "for the equivalent short option also.\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
+ "Output file location:\n");
+ fprintf (stream,
+ " --output-file=FILE Write output to specified file.\n");
+ fprintf (stream,
+ "The results are written to standard output if no output file is specified\n"
+ "or if it is -.\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
+ "Input file interpretation:\n");
+ fprintf (stream,
" -e, --delimiters=DELIMITER-LIST\n"
" Allow user to provide a string containing delimiters\n"
" used to separate keywords from their attributes.\n"
- " Default is \",\\n\".\n"
+ " Default is \",\".\n");
+ fprintf (stream,
" -t, --struct-type Allows the user to include a structured type\n"
" declaration for generated code. Any text before %%%%\n"
" is considered part of the type declaration. Key\n"
" words and additional fields may follow this, one\n"
- " group of fields per line.\n"
- "\n"
- "Language for the output code:\n"
+ " group of fields per line.\n");
+ fprintf (stream,
+ " --ignore-case Consider upper and lower case ASCII characters as\n"
+ " equivalent. Note that locale dependent case mappings\n"
+ " are ignored.\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
+ "Language for the output code:\n");
+ fprintf (stream,
" -L, --language=LANGUAGE-NAME\n"
" Generates code in the specified language. Languages\n"
" handled are currently C++, ANSI-C, C, and KR-C. The\n"
- " default is C.\n"
- "\n"
- "Details in the output code:\n"
+ " default is C.\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
+ "Details in the output code:\n");
+ fprintf (stream,
" -K, --slot-name=NAME Select name of the keyword component in the keyword\n"
- " structure.\n"
+ " structure.\n");
+ fprintf (stream,
" -F, --initializer-suffix=INITIALIZERS\n"
" Initializers for additional components in the keyword\n"
- " structure.\n"
- " -H, --hash-fn-name=NAME\n"
+ " structure.\n");
+ fprintf (stream,
+ " -H, --hash-function-name=NAME\n"
" Specify name of generated hash function. Default is\n"
- " `hash'.\n"
- " -N, --lookup-fn-name=NAME\n"
+ " 'hash'.\n");
+ fprintf (stream,
+ " -N, --lookup-function-name=NAME\n"
" Specify name of generated lookup function. Default\n"
- " name is `in_word_set'.\n"
+ " name is 'in_word_set'.\n");
+ fprintf (stream,
" -Z, --class-name=NAME Specify name of generated C++ class. Default name is\n"
- " `Perfect_Hash'.\n"
- " -7, --seven-bit Assume 7-bit characters.\n"
+ " 'Perfect_Hash'.\n");
+ fprintf (stream,
+ " -7, --seven-bit Assume 7-bit characters.\n");
+ fprintf (stream,
+ " -l, --compare-lengths Compare key lengths before trying a string\n"
+ " comparison. This is necessary if the keywords\n"
+ " contain NUL bytes. It also helps cut down on the\n"
+ " number of string comparisons made during the lookup.\n");
+ fprintf (stream,
" -c, --compare-strncmp Generate comparison code using strncmp rather than\n"
- " strcmp.\n"
+ " strcmp.\n");
+ fprintf (stream,
" -C, --readonly-tables Make the contents of generated lookup tables\n"
- " constant, i.e., readonly.\n"
+ " constant, i.e., readonly.\n");
+ fprintf (stream,
" -E, --enum Define constant values using an enum local to the\n"
- " lookup function rather than with defines.\n"
+ " lookup function rather than with defines.\n");
+ fprintf (stream,
" -I, --includes Include the necessary system include file <string.h>\n"
- " at the beginning of the code.\n"
- " -G, --global Generate the static table of keywords as a static\n"
+ " at the beginning of the code.\n");
+ fprintf (stream,
+ " -G, --global-table Generate the static table of keywords as a static\n"
" global variable, rather than hiding it inside of the\n"
- " lookup function (which is the default behavior).\n"
+ " lookup function (which is the default behavior).\n");
+ fprintf (stream,
+ " -P, --pic Optimize the generated table for inclusion in shared\n"
+ " libraries. This reduces the startup time of programs\n"
+ " using a shared library containing the generated code.\n");
+ fprintf (stream,
+ " -Q, --string-pool-name=NAME\n"
+ " Specify name of string pool generated by option --pic.\n"
+ " Default name is 'stringpool'.\n");
+ fprintf (stream,
+ " --null-strings Use NULL strings instead of empty strings for empty\n"
+ " keyword table entries.\n");
+ fprintf (stream,
" -W, --word-array-name=NAME\n"
" Specify name of word list array. Default name is\n"
- " `wordlist'.\n"
+ " 'wordlist'.\n");
+ fprintf (stream,
+ " --length-table-name=NAME\n"
+ " Specify name of length table array. Default name is\n"
+ " 'lengthtable'.\n");
+ fprintf (stream,
" -S, --switch=COUNT Causes the generated C code to use a switch\n"
" statement scheme, rather than an array lookup table.\n"
" This can lead to a reduction in both time and space\n"
@@ -155,13 +196,16 @@ Options::long_usage (FILE * strm)
" elements, a value of 2 generates 2 tables with 1/2\n"
" the elements in each table, etc. If COUNT is very\n"
" large, say 1000000, the generated C code does a\n"
- " binary search.\n"
+ " binary search.\n");
+ fprintf (stream,
" -T, --omit-struct-type\n"
" Prevents the transfer of the type declaration to the\n"
" output file. Use this option if the type is already\n"
- " defined elsewhere.\n"
- "\n"
- "Algorithm employed by gperf:\n"
+ " defined elsewhere.\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
+ "Algorithm employed by gperf:\n");
+ fprintf (stream,
" -k, --key-positions=KEYS\n"
" Select the key positions used in the hash function.\n"
" The allowable choices range between 1-%d, inclusive.\n"
@@ -169,70 +213,70 @@ Options::long_usage (FILE * strm)
" used, and key positions may occur in any order.\n"
" Also, the meta-character '*' causes the generated\n"
" hash function to consider ALL key positions, and $\n"
- " indicates the ``final character'' of a key, e.g.,\n"
- " $,1,2,4,6-10.\n"
- " -l, --compare-strlen Compare key lengths before trying a string\n"
- " comparison. This helps cut down on the number of\n"
- " string comparisons made during the lookup.\n"
+ " indicates the \"final character\" of a key, e.g.,\n"
+ " $,1,2,4,6-10.\n",
+ Positions::MAX_KEY_POS);
+ fprintf (stream,
" -D, --duplicates Handle keywords that hash to duplicate values. This\n"
- " is useful for certain highly redundant keyword sets.\n"
- " -f, --fast=ITERATIONS Generate the gen-perf.hash function ``fast''. This\n"
- " decreases gperf's running time at the cost of\n"
- " minimizing generated table size. The numeric\n"
- " argument represents the number of times to iterate\n"
- " when resolving a collision. `0' means ``iterate by\n"
- " the number of keywords''.\n"
+ " is useful for certain highly redundant keyword sets.\n");
+ fprintf (stream,
+ " -m, --multiple-iterations=ITERATIONS\n"
+ " Perform multiple choices of the -i and -j values,\n"
+ " and choose the best results. This increases the\n"
+ " running time by a factor of ITERATIONS but does a\n"
+ " good job minimizing the generated table size.\n");
+ fprintf (stream,
" -i, --initial-asso=N Provide an initial value for the associate values\n"
" array. Default is 0. Setting this value larger helps\n"
- " inflate the size of the final table.\n"
- " -j, --jump=JUMP-VALUE Affects the ``jump value'', i.e., how far to advance\n"
+ " inflate the size of the final table.\n");
+ fprintf (stream,
+ " -j, --jump=JUMP-VALUE Affects the \"jump value\", i.e., how far to advance\n"
" the associated character value upon collisions. Must\n"
- " be an odd number, default is %d.\n"
+ " be an odd number, default is %d.\n",
+ DEFAULT_JUMP_VALUE);
+ fprintf (stream,
" -n, --no-strlen Do not include the length of the keyword when\n"
- " computing the hash function.\n"
- " -o, --occurrence-sort Reorders input keys by frequency of occurrence of\n"
- " the key sets. This should decrease the search time\n"
- " dramatically.\n"
+ " computing the hash function.\n");
+ fprintf (stream,
" -r, --random Utilizes randomness to initialize the associated\n"
- " values table.\n"
+ " values table.\n");
+ fprintf (stream,
" -s, --size-multiple=N Affects the size of the generated hash table. The\n"
- " numeric argument N indicates ``how many times larger\n"
- " or smaller'' the associated value range should be,\n"
+ " numeric argument N indicates \"how many times larger\n"
+ " or smaller\" the associated value range should be,\n"
" in relationship to the number of keys, e.g. a value\n"
- " of 3 means ``allow the maximum associated value to\n"
+ " of 3 means \"allow the maximum associated value to\n"
" be about 3 times larger than the number of input\n"
- " keys.'' Conversely, a value of -3 means ``make the\n"
+ " keys\". Conversely, a value of 1/3 means \"make the\n"
" maximum associated value about 3 times smaller than\n"
- " the number of input keys. A larger table should\n"
+ " the number of input keys\". A larger table should\n"
" decrease the time required for an unsuccessful\n"
" search, at the expense of extra table space. Default\n"
- " value is 1.\n"
- "\n"
+ " value is 1.\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
"Informative output:\n"
" -h, --help Print this message.\n"
" -v, --version Print the gperf version number.\n"
" -d, --debug Enables the debugging option (produces verbose\n"
- " output to the standard error).\n"
- "\n"
- "Report bugs to <bug-gnu-utils@gnu.org>.\n"
- , program_name, MAX_KEY_POS - 1, DEFAULT_JUMP_VALUE);
+ " output to the standard error).\n");
+ fprintf (stream, "\n");
+ fprintf (stream,
+ "Report bugs to <bug-gnu-gperf@gnu.org>.\n");
}
-/* Output command-line Options. */
+/* Prints the given options. */
void
-Options::print_options (void)
+Options::print_options () const
{
- T (Trace t ("Options::print_options");)
- int i;
-
printf ("/* Command-line: ");
- for (i = 0; i < argument_count; i++)
+ for (int i = 0; i < _argument_count; i++)
{
- const char *arg = argument_vector[i];
+ const char *arg = _argument_vector[i];
- /* Escape arg if it contains shell metacharacters. */
+ /* Escape arg if it contains shell metacharacters. */
if (*arg == '-')
{
putchar (*arg);
@@ -242,6 +286,20 @@ Options::print_options (void)
putchar (*arg);
arg++;
}
+ else if (*arg == '-')
+ {
+ do
+ {
+ putchar (*arg);
+ arg++;
+ }
+ while (*arg >= 'A' && *arg <= 'Z' || *arg >= 'a' && *arg <= 'z' || *arg == '-');
+ if (*arg == '=')
+ {
+ putchar (*arg);
+ arg++;
+ }
+ }
}
if (strpbrk (arg, "\t\n !\"#$&'()*;<>?[\\]`{|}~") != NULL)
{
@@ -250,7 +308,7 @@ Options::print_options (void)
putchar ('"');
for (; *arg; arg++)
{
- if (*arg == '\"' || *arg == '\\' || *arg == '$')
+ if (*arg == '\"' || *arg == '\\' || *arg == '$' || *arg == '`')
putchar ('\\');
putchar (*arg);
}
@@ -277,389 +335,653 @@ Options::print_options (void)
printf (" */");
}
-/* Sorts the key positions *IN REVERSE ORDER!!*
- This makes further routines more efficient. Especially when generating code.
- Uses a simple Insertion Sort since the set is probably ordered.
- Returns 1 if there are no duplicates, 0 otherwise. */
+/* ------------------------------------------------------------------------- */
-inline int
-Options::key_sort (char *base, int len)
+/* Parses a string denoting key positions. */
+
+class PositionStringParser
{
- T (Trace t ("Options::key_sort");)
- int i, j;
+public:
+ /* Initializes a key position string parser for string STR. */
+ PositionStringParser (const char *str,
+ int low_bound, int high_bound,
+ int end_word_marker, int error_value, int end_marker);
+ /* Returns the next key position from the given string. */
+ int nextPosition ();
+private:
+ /* A pointer to the string provided by the user. */
+ const char * _str;
+ /* Smallest possible value, inclusive. */
+ int const _low_bound;
+ /* Greatest possible value, inclusive. */
+ int const _high_bound;
+ /* A value marking the abstract "end of word" ( usually '$'). */
+ int const _end_word_marker;
+ /* Error value returned when input is syntactically erroneous. */
+ int const _error_value;
+ /* Value returned after last key is processed. */
+ int const _end_marker;
+ /* Intermediate state for producing a range of positions. */
+ bool _in_range; /* True while producing a range of positions. */
+ int _range_upper_bound; /* Upper bound (inclusive) of the range. */
+ int _range_curr_value; /* Last value returned. */
+};
+
+/* Initializes a key position strng parser for string STR. */
+PositionStringParser::PositionStringParser (const char *str,
+ int low_bound, int high_bound,
+ int end_word_marker, int error_value, int end_marker)
+ : _str (str),
+ _low_bound (low_bound),
+ _high_bound (high_bound),
+ _end_word_marker (end_word_marker),
+ _error_value (error_value),
+ _end_marker (end_marker),
+ _in_range (false)
+{
+}
- for (i = 0, j = len - 1; i < j; i++)
+/* Returns the next key position from the given string. */
+int
+PositionStringParser::nextPosition ()
+{
+ if (_in_range)
+ {
+ /* We are inside a range. Return the next value from the range. */
+ if (++_range_curr_value >= _range_upper_bound)
+ _in_range = false;
+ return _range_curr_value;
+ }
+ else
{
- int curr, tmp;
+ /* Continue parsing the given string. */
+ while (*_str)
+ switch (*_str)
+ {
+ case ',':
+ /* Skip the comma. */
+ _str++;
+ break;
+ case '$':
+ /* Valid key position. */
+ _str++;
+ return _end_word_marker;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ /* Valid key position. */
+ {
+ int curr_value;
+ for (curr_value = 0; isdigit (static_cast<unsigned char>(*_str)); _str++)
+ curr_value = curr_value * 10 + (*_str - '0');
- for (curr = i + 1,tmp = base[curr]; curr > 0 && tmp >= base[curr - 1]; curr--)
- if ((base[curr] = base[curr - 1]) == tmp) /* oh no, a duplicate!!! */
- return 0;
+ if (*_str == '-')
+ {
+ _str++;
+ /* Starting a range of key positions. */
+ _in_range = true;
- base[curr] = tmp;
- }
+ for (_range_upper_bound = 0;
+ isdigit (static_cast<unsigned char>(*_str));
+ _str++)
+ _range_upper_bound = _range_upper_bound * 10 + (*_str - '0');
+
+ /* Verify range's upper bound. */
+ if (!(_range_upper_bound > curr_value && _range_upper_bound <= _high_bound))
+ return _error_value;
+ _range_curr_value = curr_value;
+ }
- return 1;
+ /* Verify range's lower bound. */
+ if (!(curr_value >= _low_bound && curr_value <= _high_bound))
+ return _error_value;
+ return curr_value;
+ }
+ default:
+ /* Invalid syntax. */
+ return _error_value;
+ }
+
+ return _end_marker;
+ }
}
-/* Sets the default Options. */
+/* ------------------------------------------------------------------------- */
+
+/* Sets the default Options. */
-Options::Options (void)
+Options::Options ()
+ : _option_word (C),
+ _input_file_name (NULL),
+ _output_file_name (NULL),
+ _language (NULL),
+ _jump (DEFAULT_JUMP_VALUE),
+ _initial_asso_value (0),
+ _asso_iterations (0),
+ _total_switches (1),
+ _size_multiple (1),
+ _function_name (DEFAULT_FUNCTION_NAME),
+ _slot_name (DEFAULT_SLOT_NAME),
+ _initializer_suffix (DEFAULT_INITIALIZER_SUFFIX),
+ _class_name (DEFAULT_CLASS_NAME),
+ _hash_name (DEFAULT_HASH_NAME),
+ _wordlist_name (DEFAULT_WORDLIST_NAME),
+ _lengthtable_name (DEFAULT_LENGTHTABLE_NAME),
+ _stringpool_name (DEFAULT_STRINGPOOL_NAME),
+ _delimiters (DEFAULT_DELIMITERS),
+ _key_positions ()
{
- T (Trace t ("Options::Options");)
- key_positions[0] = WORD_START;
- key_positions[1] = WORD_END;
- key_positions[2] = EOS;
- total_keysig_size = 2;
- delimiters = DEFAULT_DELIMITERS;
- jump = DEFAULT_JUMP_VALUE;
- option_word = DEFAULTCHARS | C;
- function_name = DEFAULT_NAME;
- key_name = DEFAULT_KEY;
- initializer_suffix = DEFAULT_INITIALIZER_SUFFIX;
- hash_name = DEFAULT_HASH_NAME;
- wordlist_name = DEFAULT_WORDLIST_NAME;
- class_name = DEFAULT_CLASS_NAME;
- total_switches = size = 1;
- initial_asso_value = iterations = 0;
}
-/* Dumps option status when debug is set. */
+/* Dumps option status when debugging is enabled. */
-Options::~Options (void)
+Options::~Options ()
{
- T (Trace t ("Options::~Options");)
- if (option_word & DEBUG)
+ if (_option_word & DEBUG)
{
- char *ptr;
-
fprintf (stderr, "\ndumping Options:"
- "\nDEBUG is.......: %s"
- "\nORDER is.......: %s"
"\nTYPE is........: %s"
- "\nRANDOM is......: %s"
- "\nDEFAULTCHARS is: %s"
- "\nSWITCH is......: %s"
- "\nNOLENGTH is....: %s"
- "\nLENTABLE is....: %s"
- "\nDUP is.........: %s"
- "\nFAST is........: %s"
- "\nCOMP is........: %s"
- "\nNOTYPE is......: %s"
- "\nGLOBAL is......: %s"
- "\nCONST is.......: %s"
+ "\nUPPERLOWER is..: %s"
"\nKRC is.........: %s"
"\nC is...........: %s"
"\nANSIC is.......: %s"
"\nCPLUSPLUS is...: %s"
+ "\nSEVENBIT is....: %s"
+ "\nLENTABLE is....: %s"
+ "\nCOMP is........: %s"
+ "\nCONST is.......: %s"
"\nENUM is........: %s"
"\nINCLUDE is.....: %s"
- "\nSEVENBIT is....: %s"
- "\niterations = %d"
+ "\nGLOBAL is......: %s"
+ "\nNULLSTRINGS is.: %s"
+ "\nSHAREDLIB is...: %s"
+ "\nSWITCH is......: %s"
+ "\nNOTYPE is......: %s"
+ "\nDUP is.........: %s"
+ "\nNOLENGTH is....: %s"
+ "\nRANDOM is......: %s"
+ "\nDEBUG is.......: %s"
"\nlookup function name = %s"
"\nhash function name = %s"
"\nword list name = %s"
- "\nkey name = %s"
+ "\nlength table name = %s"
+ "\nstring pool name = %s"
+ "\nslot name = %s"
"\ninitializer suffix = %s"
+ "\nasso_values iterations = %d"
"\njump value = %d"
- "\nmax associated value = %d"
+ "\nhash table size multiplier = %g"
"\ninitial associated value = %d"
"\ndelimiters = %s"
"\nnumber of switch statements = %d\n",
- option_word & DEBUG ? "enabled" : "disabled",
- option_word & ORDER ? "enabled" : "disabled",
- option_word & TYPE ? "enabled" : "disabled",
- option_word & RANDOM ? "enabled" : "disabled",
- option_word & DEFAULTCHARS ? "enabled" : "disabled",
- option_word & SWITCH ? "enabled" : "disabled",
- option_word & NOLENGTH ? "enabled" : "disabled",
- option_word & LENTABLE ? "enabled" : "disabled",
- option_word & DUP ? "enabled" : "disabled",
- option_word & FAST ? "enabled" : "disabled",
- option_word & COMP ? "enabled" : "disabled",
- option_word & NOTYPE ? "enabled" : "disabled",
- option_word & GLOBAL ? "enabled" : "disabled",
- option_word & CONST ? "enabled" : "disabled",
- option_word & KRC ? "enabled" : "disabled",
- option_word & C ? "enabled" : "disabled",
- option_word & ANSIC ? "enabled" : "disabled",
- option_word & CPLUSPLUS ? "enabled" : "disabled",
- option_word & ENUM ? "enabled" : "disabled",
- option_word & INCLUDE ? "enabled" : "disabled",
- option_word & SEVENBIT ? "enabled" : "disabled",
- iterations,
- function_name, hash_name, wordlist_name, key_name,
- initializer_suffix, jump, size - 1, initial_asso_value,
- delimiters, total_switches);
- if (option_word & ALLCHARS)
+ _option_word & TYPE ? "enabled" : "disabled",
+ _option_word & UPPERLOWER ? "enabled" : "disabled",
+ _option_word & KRC ? "enabled" : "disabled",
+ _option_word & C ? "enabled" : "disabled",
+ _option_word & ANSIC ? "enabled" : "disabled",
+ _option_word & CPLUSPLUS ? "enabled" : "disabled",
+ _option_word & SEVENBIT ? "enabled" : "disabled",
+ _option_word & LENTABLE ? "enabled" : "disabled",
+ _option_word & COMP ? "enabled" : "disabled",
+ _option_word & CONST ? "enabled" : "disabled",
+ _option_word & ENUM ? "enabled" : "disabled",
+ _option_word & INCLUDE ? "enabled" : "disabled",
+ _option_word & GLOBAL ? "enabled" : "disabled",
+ _option_word & NULLSTRINGS ? "enabled" : "disabled",
+ _option_word & SHAREDLIB ? "enabled" : "disabled",
+ _option_word & SWITCH ? "enabled" : "disabled",
+ _option_word & NOTYPE ? "enabled" : "disabled",
+ _option_word & DUP ? "enabled" : "disabled",
+ _option_word & NOLENGTH ? "enabled" : "disabled",
+ _option_word & RANDOM ? "enabled" : "disabled",
+ _option_word & DEBUG ? "enabled" : "disabled",
+ _function_name, _hash_name, _wordlist_name, _lengthtable_name,
+ _stringpool_name, _slot_name, _initializer_suffix,
+ _asso_iterations, _jump, _size_multiple, _initial_asso_value,
+ _delimiters, _total_switches);
+ if (_key_positions.is_useall())
fprintf (stderr, "all characters are used in the hash function\n");
+ else
+ {
+ fprintf (stderr, "maximum keysig size = %d\nkey positions are: \n",
+ _key_positions.get_size());
- fprintf (stderr, "maximum keysig size = %d\nkey positions are: \n",
- total_keysig_size);
-
- for (ptr = key_positions; *ptr != EOS; ptr++)
- if (*ptr == WORD_END)
- fprintf (stderr, "$\n");
- else
- fprintf (stderr, "%d\n", *ptr);
+ PositionIterator iter = _key_positions.iterator();
+ for (int pos; (pos = iter.next()) != PositionIterator::EOS; )
+ if (pos == Positions::LASTCHAR)
+ fprintf (stderr, "$\n");
+ else
+ fprintf (stderr, "%d\n", pos + 1);
+ }
fprintf (stderr, "finished dumping Options\n");
}
}
-/* Parses the command line Options and sets appropriate flags in option_word. */
+/* Sets the output language, if not already set. */
+void
+Options::set_language (const char *language)
+{
+ if (_language == NULL)
+ {
+ _language = language;
+ _option_word &= ~(KRC | C | ANSIC | CPLUSPLUS);
+ if (!strcmp (language, "KR-C"))
+ _option_word |= KRC;
+ else if (!strcmp (language, "C"))
+ _option_word |= C;
+ else if (!strcmp (language, "ANSI-C"))
+ _option_word |= ANSIC;
+ else if (!strcmp (language, "C++"))
+ _option_word |= CPLUSPLUS;
+ else
+ {
+ fprintf (stderr, "unsupported language option %s, defaulting to C\n",
+ language);
+ _option_word |= C;
+ }
+ }
+}
+
+/* Sets the total number of switch statements, if not already set. */
+void
+Options::set_total_switches (int total_switches)
+{
+ if (!(_option_word & SWITCH))
+ {
+ _option_word |= SWITCH;
+ _total_switches = total_switches;
+ }
+}
+
+/* Sets the generated function name, if not already set. */
+void
+Options::set_function_name (const char *name)
+{
+ if (_function_name == DEFAULT_FUNCTION_NAME)
+ _function_name = name;
+}
+
+/* Sets the keyword key name, if not already set. */
+void
+Options::set_slot_name (const char *name)
+{
+ if (_slot_name == DEFAULT_SLOT_NAME)
+ _slot_name = name;
+}
+
+/* Sets the struct initializer suffix, if not already set. */
+void
+Options::set_initializer_suffix (const char *initializers)
+{
+ if (_initializer_suffix == DEFAULT_INITIALIZER_SUFFIX)
+ _initializer_suffix = initializers;
+}
+
+/* Sets the generated class name, if not already set. */
+void
+Options::set_class_name (const char *name)
+{
+ if (_class_name == DEFAULT_CLASS_NAME)
+ _class_name = name;
+}
+
+/* Sets the hash function name, if not already set. */
+void
+Options::set_hash_name (const char *name)
+{
+ if (_hash_name == DEFAULT_HASH_NAME)
+ _hash_name = name;
+}
+
+/* Sets the hash table array name, if not already set. */
+void
+Options::set_wordlist_name (const char *name)
+{
+ if (_wordlist_name == DEFAULT_WORDLIST_NAME)
+ _wordlist_name = name;
+}
+
+/* Sets the length table array name, if not already set. */
+void
+Options::set_lengthtable_name (const char *name)
+{
+ if (_lengthtable_name == DEFAULT_LENGTHTABLE_NAME)
+ _lengthtable_name = name;
+}
+
+/* Sets the string pool name, if not already set. */
+void
+Options::set_stringpool_name (const char *name)
+{
+ if (_stringpool_name == DEFAULT_STRINGPOOL_NAME)
+ _stringpool_name = name;
+}
+
+/* Sets the delimiters string, if not already set. */
+void
+Options::set_delimiters (const char *delimiters)
+{
+ if (_delimiters == DEFAULT_DELIMITERS)
+ _delimiters = delimiters;
+}
+
+
+/* Parses the command line Options and sets appropriate flags in option_word. */
static const struct option long_options[] =
{
- { "delimiters", required_argument, 0, 'e' },
- { "struct-type", no_argument, 0, 't' },
- { "language", required_argument, 0, 'L' },
- { "slot-name", required_argument, 0, 'K' },
- { "initializer-suffix", required_argument, 0, 'F' },
- { "hash-fn-name", required_argument, 0, 'H' },
- { "lookup-fn-name", required_argument, 0, 'N' },
- { "class-name", required_argument, 0, 'Z' },
- { "seven-bit", no_argument, 0, '7' },
- { "compare-strncmp", no_argument, 0, 'c' },
- { "readonly-tables", no_argument, 0, 'C' },
- { "enum", no_argument, 0, 'E' },
- { "includes", no_argument, 0, 'I' },
- { "global", no_argument, 0, 'G' },
- { "word-array-name", required_argument, 0, 'W' },
- { "switch", required_argument, 0, 'S' },
- { "omit-struct-type", no_argument, 0, 'T' },
- { "key-positions", required_argument, 0, 'k' },
- { "compare-strlen", no_argument, 0, 'l' },
- { "duplicates", no_argument, 0, 'D' },
- { "fast", required_argument, 0, 'f' },
- { "initial-asso", required_argument, 0, 'i' },
- { "jump", required_argument, 0, 'j' },
- { "no-strlen", no_argument, 0, 'n' },
- { "occurrence-sort", no_argument, 0, 'o' },
- { "random", no_argument, 0, 'r' },
- { "size-multiple", required_argument, 0, 's' },
- { "help", no_argument, 0, 'h' },
- { "version", no_argument, 0, 'v' },
- { "debug", no_argument, 0, 'd' },
- { 0, no_argument, 0, 0 }
+ { "output-file", required_argument, NULL, CHAR_MAX + 1 },
+ { "ignore-case", no_argument, NULL, CHAR_MAX + 2 },
+ { "delimiters", required_argument, NULL, 'e' },
+ { "struct-type", no_argument, NULL, 't' },
+ { "language", required_argument, NULL, 'L' },
+ { "slot-name", required_argument, NULL, 'K' },
+ { "initializer-suffix", required_argument, NULL, 'F' },
+ { "hash-fn-name", required_argument, NULL, 'H' }, /* backward compatibility */
+ { "hash-function-name", required_argument, NULL, 'H' },
+ { "lookup-fn-name", required_argument, NULL, 'N' }, /* backward compatibility */
+ { "lookup-function-name", required_argument, NULL, 'N' },
+ { "class-name", required_argument, NULL, 'Z' },
+ { "seven-bit", no_argument, NULL, '7' },
+ { "compare-strncmp", no_argument, NULL, 'c' },
+ { "readonly-tables", no_argument, NULL, 'C' },
+ { "enum", no_argument, NULL, 'E' },
+ { "includes", no_argument, NULL, 'I' },
+ { "global-table", no_argument, NULL, 'G' },
+ { "word-array-name", required_argument, NULL, 'W' },
+ { "length-table-name", required_argument, NULL, CHAR_MAX + 4 },
+ { "switch", required_argument, NULL, 'S' },
+ { "omit-struct-type", no_argument, NULL, 'T' },
+ { "key-positions", required_argument, NULL, 'k' },
+ { "compare-strlen", no_argument, NULL, 'l' }, /* backward compatibility */
+ { "compare-lengths", no_argument, NULL, 'l' },
+ { "duplicates", no_argument, NULL, 'D' },
+ { "fast", required_argument, NULL, 'f' },
+ { "initial-asso", required_argument, NULL, 'i' },
+ { "jump", required_argument, NULL, 'j' },
+ { "multiple-iterations", required_argument, NULL, 'm' },
+ { "no-strlen", no_argument, NULL, 'n' },
+ { "occurrence-sort", no_argument, NULL, 'o' },
+ { "optimized-collision-resolution", no_argument, NULL, 'O' },
+ { "pic", no_argument, NULL, 'P' },
+ { "string-pool-name", required_argument, NULL, 'Q' },
+ { "null-strings", no_argument, NULL, CHAR_MAX + 3 },
+ { "random", no_argument, NULL, 'r' },
+ { "size-multiple", required_argument, NULL, 's' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "debug", no_argument, NULL, 'd' },
+ { NULL, no_argument, NULL, 0 }
};
void
-Options::operator() (int argc, char *argv[])
+Options::parse_options (int argc, char *argv[])
{
- T (Trace t ("Options::operator()");)
- int option_char;
+ int option_char;
program_name = argv[0];
- argument_count = argc;
- argument_vector = argv;
+ _argument_count = argc;
+ _argument_vector = argv;
while ((option_char =
- getopt_long (argument_count, argument_vector,
- "adcCDe:Ef:F:gGhH:i:Ij:k:K:lL:nN:oprs:S:tTvW:Z:7",
- long_options, (int *)0))
+ getopt_long (_argument_count, _argument_vector,
+ "acCdDe:Ef:F:gGhH:i:Ij:k:K:lL:m:nN:oOpPQ:rs:S:tTvW:Z:7",
+ long_options, NULL))
!= -1)
{
switch (option_char)
{
- case 'a': /* Generated code uses the ANSI prototype format. */
- break; /* This is now the default. */
- case 'c': /* Generate strncmp rather than strcmp. */
+ case 'a': /* Generated code uses the ANSI prototype format. */
+ break; /* This is now the default. */
+ case 'c': /* Generate strncmp rather than strcmp. */
{
- option_word |= COMP;
+ _option_word |= COMP;
break;
}
- case 'C': /* Make the generated tables readonly (const). */
+ case 'C': /* Make the generated tables readonly (const). */
{
- option_word |= CONST;
+ _option_word |= CONST;
break;
}
- case 'd': /* Enable debugging option. */
+ case 'd': /* Enable debugging option. */
{
- option_word |= DEBUG;
+ _option_word |= DEBUG;
fprintf (stderr, "Starting program %s, version %s, with debugging on.\n",
program_name, version_string);
break;
}
- case 'D': /* Enable duplicate option. */
+ case 'D': /* Enable duplicate option. */
{
- option_word |= DUP;
+ _option_word |= DUP;
break;
}
- case 'e': /* Allows user to provide keyword/attribute separator */
+ case 'e': /* Specify keyword/attribute separator */
{
- option.delimiters = /*getopt*/optarg;
+ _delimiters = /*getopt*/optarg;
break;
}
case 'E':
{
- option_word |= ENUM;
- break;
- }
- case 'f': /* Generate the hash table ``fast.'' */
- {
- option_word |= FAST;
- if ((iterations = atoi (/*getopt*/optarg)) < 0)
- {
- fprintf (stderr, "iterations value must not be negative, assuming 0\n");
- iterations = 0;
- }
+ _option_word |= ENUM;
break;
}
+ case 'f': /* Generate the hash table "fast". */
+ break; /* Not needed any more. */
case 'F':
{
- initializer_suffix = /*getopt*/optarg;
+ _initializer_suffix = /*getopt*/optarg;
break;
}
- case 'g': /* Use the ``inline'' keyword for generated sub-routines, ifdef __GNUC__. */
- break; /* This is now the default. */
- case 'G': /* Make the keyword table a global variable. */
+ case 'g': /* Use the 'inline' keyword for generated sub-routines, ifdef __GNUC__. */
+ break; /* This is now the default. */
+ case 'G': /* Make the keyword table a global variable. */
{
- option_word |= GLOBAL;
+ _option_word |= GLOBAL;
break;
}
- case 'h': /* Displays a list of helpful Options to the user. */
+ case 'h': /* Displays a list of helpful Options to the user. */
{
long_usage (stdout);
exit (0);
}
- case 'H': /* Sets the name for the hash function */
+ case 'H': /* Sets the name for the hash function. */
{
- hash_name = /*getopt*/optarg;
+ _hash_name = /*getopt*/optarg;
break;
}
- case 'i': /* Sets the initial value for the associated values array. */
+ case 'i': /* Sets the initial value for the associated values array. */
{
- if ((initial_asso_value = atoi (/*getopt*/optarg)) < 0)
- fprintf (stderr, "Initial value %d should be non-zero, ignoring and continuing.\n", initial_asso_value);
+ if ((_initial_asso_value = atoi (/*getopt*/optarg)) < 0)
+ fprintf (stderr, "Initial value %d should be non-zero, ignoring and continuing.\n", _initial_asso_value);
if (option[RANDOM])
fprintf (stderr, "warning, -r option superceeds -i, ignoring -i option and continuing\n");
break;
}
- case 'I': /* Enable #include statements. */
+ case 'I': /* Enable #include statements. */
{
- option_word |= INCLUDE;
+ _option_word |= INCLUDE;
break;
}
- case 'j': /* Sets the jump value, must be odd for later algorithms. */
+ case 'j': /* Sets the jump value, must be odd for later algorithms. */
{
- if ((jump = atoi (/*getopt*/optarg)) < 0)
+ if ((_jump = atoi (/*getopt*/optarg)) < 0)
{
- fprintf (stderr, "Jump value %d must be a positive number.\n", jump);
+ fprintf (stderr, "Jump value %d must be a positive number.\n", _jump);
short_usage (stderr);
exit (1);
}
- else if (jump && ((jump % 2) == 0))
- fprintf (stderr, "Jump value %d should be odd, adding 1 and continuing...\n", jump++);
+ else if (_jump && ((_jump % 2) == 0))
+ fprintf (stderr, "Jump value %d should be odd, adding 1 and continuing...\n", _jump++);
break;
}
- case 'k': /* Sets key positions used for hash function. */
+ case 'k': /* Sets key positions used for hash function. */
{
- const int BAD_VALUE = -1;
+ _option_word |= POSITIONS;
+ const int BAD_VALUE = -3;
+ const int EOS = PositionIterator::EOS;
int value;
- Iterator expand (/*getopt*/optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS);
+ PositionStringParser sparser (/*getopt*/optarg, 1, Positions::MAX_KEY_POS, Positions::LASTCHAR, BAD_VALUE, EOS);
if (/*getopt*/optarg [0] == '*') /* Use all the characters for hashing!!!! */
- option_word = (option_word & ~DEFAULTCHARS) | ALLCHARS;
+ _key_positions.set_useall(true);
else
{
- char *key_pos;
-
- for (key_pos = key_positions; (value = expand ()) != EOS; key_pos++)
- if (value == BAD_VALUE)
- {
- fprintf (stderr, "Illegal key value or range, use 1,2,3-%d,'$' or '*'.\n",
- MAX_KEY_POS - 1);
- short_usage (stderr);
- exit (1);
- }
- else
- *key_pos = value;;
-
- *key_pos = EOS;
-
- if (! (total_keysig_size = (key_pos - key_positions)))
+ _key_positions.set_useall(false);
+ int *key_positions = _key_positions.pointer();
+ int *key_pos;
+
+ for (key_pos = key_positions; (value = sparser.nextPosition()) != EOS; key_pos++)
{
- fprintf (stderr, "No keys selected.\n");
+ if (value == BAD_VALUE)
+ {
+ fprintf (stderr, "Invalid position value or range, use 1,2,3-%d,'$' or '*'.\n",
+ Positions::MAX_KEY_POS);
+ short_usage (stderr);
+ exit (1);
+ }
+ if (key_pos - key_positions == Positions::MAX_SIZE)
+ {
+ /* More than Positions::MAX_SIZE key positions.
+ Since all key positions are in the range
+ 0..Positions::MAX_KEY_POS-1 or == Positions::LASTCHAR,
+ there must be duplicates. */
+ fprintf (stderr, "Duplicate key positions selected\n");
+ short_usage (stderr);
+ exit (1);
+ }
+ if (value != Positions::LASTCHAR)
+ /* We use 0-based indices in the class Positions. */
+ value = value - 1;
+ *key_pos = value;
+ }
+
+ unsigned int total_keysig_size = key_pos - key_positions;
+ if (total_keysig_size == 0)
+ {
+ fprintf (stderr, "No key positions selected.\n");
short_usage (stderr);
exit (1);
}
- else if (! key_sort (key_positions, total_keysig_size))
+ _key_positions.set_size (total_keysig_size);
+
+ /* Sorts the key positions *IN REVERSE ORDER!!*
+ This makes further routines more efficient. Especially
+ when generating code. */
+ if (! _key_positions.sort())
{
- fprintf (stderr, "Duplicate keys selected\n");
+ fprintf (stderr, "Duplicate key positions selected\n");
short_usage (stderr);
exit (1);
}
-
- if (total_keysig_size != 2
- || (key_positions[0] != 1 || key_positions[1] != WORD_END))
- option_word &= ~DEFAULTCHARS;
}
break;
}
- case 'K': /* Make this the keyname for the keyword component field. */
+ case 'K': /* Make this the keyname for the keyword component field. */
{
- key_name = /*getopt*/optarg;
+ _slot_name = /*getopt*/optarg;
break;
}
- case 'l': /* Create length table to avoid extra string compares. */
+ case 'l': /* Create length table to avoid extra string compares. */
{
- option_word |= LENTABLE;
+ _option_word |= LENTABLE;
break;
}
- case 'L': /* Deal with different generated languages. */
+ case 'L': /* Deal with different generated languages. */
{
- option_word &= ~(KRC | C | ANSIC | CPLUSPLUS);
- if (!strcmp (/*getopt*/optarg, "KR-C"))
- option_word |= KRC;
- else if (!strcmp (/*getopt*/optarg, "C"))
- option_word |= C;
- else if (!strcmp (/*getopt*/optarg, "ANSI-C"))
- option_word |= ANSIC;
- else if (!strcmp (/*getopt*/optarg, "C++"))
- option_word |= CPLUSPLUS;
- else
+ _language = NULL;
+ set_language (/*getopt*/optarg);
+ break;
+ }
+ case 'm': /* Multiple iterations for finding good asso_values. */
+ {
+ if ((_asso_iterations = atoi (/*getopt*/optarg)) < 0)
{
- fprintf (stderr, "unsupported language option %s, defaulting to C\n", /*getopt*/optarg);
- option_word |= C;
+ fprintf (stderr, "asso_iterations value must not be negative, assuming 0\n");
+ _asso_iterations = 0;
}
break;
}
- case 'n': /* Don't include the length when computing hash function. */
+ case 'n': /* Don't include the length when computing hash function. */
{
- option_word |= NOLENGTH;
+ _option_word |= NOLENGTH;
break;
}
- case 'N': /* Make generated lookup function name be optarg */
+ case 'N': /* Make generated lookup function name be optarg. */
{
- function_name = /*getopt*/optarg;
+ _function_name = /*getopt*/optarg;
break;
}
- case 'o': /* Order input by frequency of key set occurrence. */
+ case 'o': /* Order input by frequency of key set occurrence. */
+ break; /* Not needed any more. */
+ case 'O': /* Optimized choice during collision resolution. */
+ break; /* Not needed any more. */
+ case 'p': /* Generated lookup function a pointer instead of int. */
+ break; /* This is now the default. */
+ case 'P': /* Optimize for position-independent code. */
{
- option_word |= ORDER;
+ _option_word |= SHAREDLIB;
break;
}
- case 'p': /* Generated lookup function a pointer instead of int. */
- break; /* This is now the default. */
- case 'r': /* Utilize randomness to initialize the associated values table. */
+ case 'Q': /* Sets the name for the string pool. */
{
- option_word |= RANDOM;
- if (option.initial_asso_value != 0)
- fprintf (stderr, "warning, -r option superceeds -i, disabling -i option and continuing\n");
+ _stringpool_name = /*getopt*/optarg;
break;
}
- case 's': /* Range of associated values, determines size of final table. */
+ case 'r': /* Utilize randomness to initialize the associated values table. */
{
- if (abs (size = atoi (/*getopt*/optarg)) > 50)
- fprintf (stderr, "%d is excessive, did you really mean this?! (try `%s --help' for help)\n", size, program_name);
+ _option_word |= RANDOM;
+ if (_initial_asso_value != 0)
+ fprintf (stderr, "warning, -r option supersedes -i, disabling -i option and continuing\n");
break;
}
- case 'S': /* Generate switch statement output, rather than lookup table. */
+ case 's': /* Range of associated values, determines size of final table. */
{
- option_word |= SWITCH;
- if ((option.total_switches = atoi (/*getopt*/optarg)) <= 0)
+ float numerator;
+ float denominator = 1;
+ bool invalid = false;
+ char *endptr;
+
+ numerator = strtod (/*getopt*/optarg, &endptr);
+ if (endptr == /*getopt*/optarg)
+ invalid = true;
+ else if (*endptr != '\0')
+ {
+ if (*endptr == '/')
+ {
+ char *denomptr = endptr + 1;
+ denominator = strtod (denomptr, &endptr);
+ if (endptr == denomptr || *endptr != '\0')
+ invalid = true;
+ }
+ else
+ invalid = true;
+ }
+ if (invalid)
+ {
+ fprintf (stderr, "Invalid value for option -s.\n");
+ short_usage (stderr);
+ exit (1);
+ }
+ _size_multiple = numerator / denominator;
+ /* Backward compatibility: -3 means 1/3. */
+ if (_size_multiple < 0)
+ _size_multiple = 1 / (-_size_multiple);
+ /* Catch stupid users. */
+ if (_size_multiple == 0)
+ _size_multiple = 1;
+ /* Warnings. */
+ if (_size_multiple > 50)
+ fprintf (stderr, "Size multiple %g is excessive, did you really mean this?! (try '%s --help' for help)\n", _size_multiple, program_name);
+ else if (_size_multiple < 0.01f)
+ fprintf (stderr, "Size multiple %g is extremely small, did you really mean this?! (try '%s --help' for help)\n", _size_multiple, program_name);
+ break;
+ }
+ case 'S': /* Generate switch statement output, rather than lookup table. */
+ {
+ _option_word |= SWITCH;
+ _total_switches = atoi (/*getopt*/optarg);
+ if (_total_switches <= 0)
{
fprintf (stderr, "number of switches %s must be a positive number\n", /*getopt*/optarg);
short_usage (stderr);
@@ -667,33 +989,59 @@ Options::operator() (int argc, char *argv[])
}
break;
}
- case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */
+ case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */
{
- option_word |= TYPE;
+ _option_word |= TYPE;
break;
}
- case 'T': /* Don't print structure definition. */
+ case 'T': /* Don't print structure definition. */
{
- option_word |= NOTYPE;
+ _option_word |= NOTYPE;
break;
}
- case 'v': /* Print out the version and quit. */
+ case 'v': /* Print out the version and quit. */
fprintf (stdout, "GNU gperf %s\n", version_string);
+ fprintf (stdout, "Copyright (C) %s Free Software Foundation, Inc.\n\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+",
+ "1989-1998, 2000-2004, 2006-2007");
+ fprintf (stdout, "Written by %s and %s.\n",
+ "Douglas C. Schmidt", "Bruno Haible");
exit (0);
- case 'W': /* Sets the name for the hash table array */
+ case 'W': /* Sets the name for the hash table array. */
+ {
+ _wordlist_name = /*getopt*/optarg;
+ break;
+ }
+ case 'Z': /* Set the class name. */
{
- wordlist_name = /*getopt*/optarg;
+ _class_name = /*getopt*/optarg;
break;
}
- case 'Z': /* Set the class name. */
+ case '7': /* Assume 7-bit characters. */
{
- class_name = /*getopt*/optarg;
+ _option_word |= SEVENBIT;
break;
}
- case '7': /* Assume 7-bit characters. */
+ case CHAR_MAX + 1: /* Set the output file name. */
{
- option_word |= SEVENBIT;
- Vectors::ALPHA_SIZE = 128;
+ _output_file_name = /*getopt*/optarg;
+ break;
+ }
+ case CHAR_MAX + 2: /* Case insignificant. */
+ {
+ _option_word |= UPPERLOWER;
+ break;
+ }
+ case CHAR_MAX + 3: /* Use NULL instead of "". */
+ {
+ _option_word |= NULLSTRINGS;
+ break;
+ }
+ case CHAR_MAX + 4: /* Sets the name for the length table array. */
+ {
+ _lengthtable_name = /*getopt*/optarg;
break;
}
default:
@@ -703,14 +1051,10 @@ Options::operator() (int argc, char *argv[])
}
- if (argv[/*getopt*/optind] && ! freopen (argv[/*getopt*/optind], "r", stdin))
- {
- fprintf (stderr, "Cannot open keyword file `%s'\n", argv[/*getopt*/optind]);
- short_usage (stderr);
- exit (1);
- }
+ if (/*getopt*/optind < argc)
+ _input_file_name = argv[/*getopt*/optind++];
- if (++/*getopt*/optind < argc)
+ if (/*getopt*/optind < argc)
{
fprintf (stderr, "Extra trailing arguments to %s.\n", program_name);
short_usage (stderr);
@@ -718,6 +1062,8 @@ Options::operator() (int argc, char *argv[])
}
}
+/* ------------------------------------------------------------------------- */
+
#ifndef __OPTIMIZE__
#define INLINE /* not inline */
diff --git a/src/options.h b/src/options.h
index 9025c86f1732..bda7f0c8939c 100644
--- a/src/options.h
+++ b/src/options.h
@@ -2,154 +2,292 @@
/* Handles parsing the Options provided to the user.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2000, 2002-2004 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* This module provides a uniform interface to the various options available
- to a user of the gperf hash function generator. In addition to the
- run-time options, found in the Option_Type below, there is also the
- hash table Size and the Keys to be used in the hashing.
- The overall design of this module was an experiment in using C++
- classes as a mechanism to enhance centralization of option and
- and error handling, which tend to get out of hand in a C program. */
+ to a user of the gperf hash function generator. */
#ifndef options_h
#define options_h 1
#include <stdio.h>
+#include "positions.h"
-/* Enumerate the potential debugging Options. */
+/* Enumeration of the possible boolean options. */
enum Option_Type
{
- DEBUG = 01, /* Enable debugging (prints diagnostics to stderr). */
- ORDER = 02, /* Apply ordering heuristic to speed-up search time. */
- ALLCHARS = 04, /* Use all characters in hash function. */
- TYPE = 010, /* Handle user-defined type structured keyword input. */
- RANDOM = 020, /* Randomly initialize the associated values table. */
- DEFAULTCHARS = 040, /* Make default char positions be 1,$ (end of keyword). */
- SWITCH = 0100, /* Generate switch output to save space. */
- NOLENGTH = 0200, /* Don't include keyword length in hash computations. */
- LENTABLE = 0400, /* Generate a length table for string comparison. */
- DUP = 01000, /* Handle duplicate hash values for keywords. */
- FAST = 02000, /* Generate the hash function ``fast.'' */
- NOTYPE = 04000, /* Don't include user-defined type definition in output -- it's already defined elsewhere. */
- COMP = 010000, /* Generate strncmp rather than strcmp. */
- GLOBAL = 020000, /* Make the keyword table a global variable. */
- CONST = 040000, /* Make the generated tables readonly (const). */
- KRC = 0100000, /* Generate K&R C code: no prototypes, no const. */
- C = 0200000, /* Generate C code: no prototypes, but const (user can #define it away). */
- ANSIC = 0400000, /* Generate ISO/ANSI C code: prototypes and const, but no class. */
- CPLUSPLUS = 01000000, /* Generate C++ code: prototypes, const, class, inline, enum. */
- ENUM = 02000000, /* Use enum for constants. */
- INCLUDE = 04000000, /* Generate #include statements. */
- SEVENBIT = 010000000 /* Assume 7-bit, not 8-bit, characters. */
-};
+ /* --- Input file interpretation --- */
-/* Define some useful constants (these don't really belong here, but I'm
- not sure where else to put them!). These should be consts, but g++
- doesn't seem to do the right thing with them at the moment... ;-( */
+ /* Handle user-defined type structured keyword input. */
+ TYPE = 1 << 0,
-enum
-{
- MAX_KEY_POS = 128 - 1, /* Max size of each word's key set. */
- WORD_START = 1, /* Signals the start of a word. */
- WORD_END = 0, /* Signals the end of a word. */
- EOS = MAX_KEY_POS /* Signals end of the key list. */
+ /* Ignore case of ASCII characters. */
+ UPPERLOWER = 1 << 1,
+
+ /* --- Language for the output code --- */
+
+ /* Generate K&R C code: no prototypes, no const. */
+ KRC = 1 << 2,
+
+ /* Generate C code: no prototypes, but const (user can #define it away). */
+ C = 1 << 3,
+
+ /* Generate ISO/ANSI C code: prototypes and const, but no class. */
+ ANSIC = 1 << 4,
+
+ /* Generate C++ code: prototypes, const, class, inline, enum. */
+ CPLUSPLUS = 1 << 5,
+
+ /* --- Details in the output code --- */
+
+ /* Assume 7-bit, not 8-bit, characters. */
+ SEVENBIT = 1 << 6,
+
+ /* Generate a length table for string comparison. */
+ LENTABLE = 1 << 7,
+
+ /* Generate strncmp rather than strcmp. */
+ COMP = 1 << 8,
+
+ /* Make the generated tables readonly (const). */
+ CONST = 1 << 9,
+
+ /* Use enum for constants. */
+ ENUM = 1 << 10,
+
+ /* Generate #include statements. */
+ INCLUDE = 1 << 11,
+
+ /* Make the keyword table a global variable. */
+ GLOBAL = 1 << 12,
+
+ /* Use NULL strings instead of empty strings for empty table entries. */
+ NULLSTRINGS = 1 << 13,
+
+ /* Optimize for position-independent code. */
+ SHAREDLIB = 1 << 14,
+
+ /* Generate switch output to save space. */
+ SWITCH = 1 << 15,
+
+ /* Don't include user-defined type definition in output -- it's already
+ defined elsewhere. */
+ NOTYPE = 1 << 16,
+
+ /* --- Algorithm employed by gperf --- */
+
+ /* Use the given key positions. */
+ POSITIONS = 1 << 17,
+
+ /* Handle duplicate hash values for keywords. */
+ DUP = 1 << 18,
+
+ /* Don't include keyword length in hash computations. */
+ NOLENGTH = 1 << 19,
+
+ /* Randomly initialize the associated values table. */
+ RANDOM = 1 << 20,
+
+ /* --- Informative output --- */
+
+ /* Enable debugging (prints diagnostics to stderr). */
+ DEBUG = 1 << 21
};
-/* Class manager for gperf program Options. */
+/* Class manager for gperf program Options. */
class Options
{
public:
- Options (void);
- ~Options (void);
- int operator[] (Option_Type option);
- void operator() (int argc, char *argv[]);
- void operator= (enum Option_Type);
- void operator!= (enum Option_Type);
- static void print_options (void);
- static void set_asso_max (int r);
- static int get_asso_max (void);
- static void reset (void);
- static int get (void);
- static int get_iterations (void);
- static int get_max_keysig_size (void);
- static void set_keysig_size (int);
- static int get_jump (void);
- static int initial_value (void);
- static int get_total_switches (void);
- static const char *get_function_name (void);
- static const char *get_key_name (void);
- static const char *get_initializer_suffix (void);
- static const char *get_class_name (void);
- static const char *get_hash_name (void);
- static const char *get_wordlist_name (void);
- static const char *get_delimiter (void);
+ /* Constructor. */
+ Options ();
+
+ /* Destructor. */
+ ~Options ();
+
+ /* Parses the options given in the command-line arguments. */
+ void parse_options (int argc, char *argv[]);
+
+ /* Prints the given options. */
+ void print_options () const;
+
+ /* Accessors. */
+
+ /* Tests a given boolean option. Returns true if set, false otherwise. */
+ bool operator[] (Option_Type option) const;
+ /* Sets a given boolean option. */
+ void set (Option_Type option);
+
+ /* Returns the input file name. */
+ const char * get_input_file_name () const;
+
+ /* Returns the output file name. */
+ const char * get_output_file_name () const;
+
+ /* Sets the output language, if not already set. */
+ void set_language (const char *language);
+
+ /* Returns the jump value. */
+ int get_jump () const;
+
+ /* Returns the initial associated character value. */
+ int get_initial_asso_value () const;
+
+ /* Returns the number of iterations for finding good asso_values. */
+ int get_asso_iterations () const;
+
+ /* Returns the total number of switch statements to generate. */
+ int get_total_switches () const;
+ /* Sets the total number of switch statements, if not already set. */
+ void set_total_switches (int total_switches);
+
+ /* Returns the factor by which to multiply the generated table's size. */
+ float get_size_multiple () const;
+
+ /* Returns the generated function name. */
+ const char * get_function_name () const;
+ /* Sets the generated function name, if not already set. */
+ void set_function_name (const char *name);
+
+ /* Returns the keyword key name. */
+ const char * get_slot_name () const;
+ /* Sets the keyword key name, if not already set. */
+ void set_slot_name (const char *name);
+
+ /* Returns the struct initializer suffix. */
+ const char * get_initializer_suffix () const;
+ /* Sets the struct initializer suffix, if not already set. */
+ void set_initializer_suffix (const char *initializers);
+
+ /* Returns the generated class name. */
+ const char * get_class_name () const;
+ /* Sets the generated class name, if not already set. */
+ void set_class_name (const char *name);
+
+ /* Returns the hash function name. */
+ const char * get_hash_name () const;
+ /* Sets the hash function name, if not already set. */
+ void set_hash_name (const char *name);
+
+ /* Returns the hash table array name. */
+ const char * get_wordlist_name () const;
+ /* Sets the hash table array name, if not already set. */
+ void set_wordlist_name (const char *name);
+
+ /* Returns the length table array name. */
+ const char * get_lengthtable_name () const;
+ /* Sets the length table array name, if not already set. */
+ void set_lengthtable_name (const char *name);
+
+ /* Returns the string pool name. */
+ const char * get_stringpool_name () const;
+ /* Sets the string pool name, if not already set. */
+ void set_stringpool_name (const char *name);
+
+ /* Returns the string used to delimit keywords from other attributes. */
+ const char * get_delimiters () const;
+ /* Sets the delimiters string, if not already set. */
+ void set_delimiters (const char *delimiters);
+
+ /* Returns key positions. */
+ const Positions& get_key_positions () const;
private:
- static int option_word; /* Holds the user-specified Options. */
- static int total_switches; /* Number of switch statements to generate. */
- static int total_keysig_size; /* Total number of distinct key_positions. */
- static int size; /* Range of the hash table. */
- static int key_pos; /* Tracks current key position for Iterator. */
- static int jump; /* Jump length when trying alternative values. */
- static int initial_asso_value; /* Initial value for asso_values table. */
- static int argument_count; /* Records count of command-line arguments. */
- static int iterations; /* Amount to iterate when a collision occurs. */
- static char **argument_vector; /* Stores a pointer to command-line vector. */
- static const char *function_name; /* Names used for generated lookup function. */
- static const char *key_name; /* Name used for keyword key. */
- static const char *initializer_suffix; /* Suffix for empty struct initializers. */
- static const char *class_name; /* Name used for generated C++ class. */
- static const char *hash_name; /* Name used for generated hash function. */
- static const char *wordlist_name; /* Name used for hash table array. */
- static const char *delimiters; /* Separates keywords from other attributes. */
- static char key_positions[MAX_KEY_POS]; /* Contains user-specified key choices. */
- static int key_sort (char *base, int len); /* Sorts key positions in REVERSE order. */
- static void short_usage (FILE * strm); /* Prints proper program usage. */
- static void long_usage (FILE * strm); /* Prints proper program usage. */
-};
+ /* Prints program usage to given stream. */
+ static void short_usage (FILE * stream);
-/* Global option coordinator for the entire program. */
-extern Options option;
+ /* Prints program usage to given stream. */
+ static void long_usage (FILE * stream);
-/* Set to 1 if your want to stack-allocate some large arrays.
- This requires compiler support for variable-size arrays on the stack
- (not ANSI). */
-#ifndef LARGE_STACK_ARRAYS
-#if defined(__GNUG__) && !defined(__STRICT_ANSI__)
-#define LARGE_STACK_ARRAYS 1
-#else
-#define LARGE_STACK_ARRAYS 0
-#endif
-#endif
+ /* Records count of command-line arguments. */
+ int _argument_count;
-/* Set to 1 if the stack is large enough for holding a text line. */
-#ifndef LARGE_STACK
-#define LARGE_STACK 1
-#endif
+ /* Stores a pointer to command-line argument vector. */
+ char ** _argument_vector;
+
+ /* Holds the boolean options. */
+ int _option_word;
+
+ /* Name of input file. */
+ char * _input_file_name;
+
+ /* Name of output file. */
+ char * _output_file_name;
+
+ /* The output language. */
+ const char * _language;
+
+ /* Jump length when trying alternative values. */
+ int _jump;
+
+ /* Initial value for asso_values table. */
+ int _initial_asso_value;
+
+ /* Number of attempts at finding good asso_values. */
+ int _asso_iterations;
+
+ /* Number of switch statements to generate. */
+ int _total_switches;
+
+ /* Factor by which to multiply the generated table's size. */
+ float _size_multiple;
+
+ /* Names used for generated lookup function. */
+ const char * _function_name;
+
+ /* Name used for keyword key. */
+ const char * _slot_name;
+
+ /* Suffix for empty struct initializers. */
+ const char * _initializer_suffix;
+
+ /* Name used for generated C++ class. */
+ const char * _class_name;
+
+ /* Name used for generated hash function. */
+ const char * _hash_name;
+
+ /* Name used for hash table array. */
+ const char * _wordlist_name;
+
+ /* Name used for length table array. */
+ const char * _lengthtable_name;
+
+ /* Name used for the string pool. */
+ const char * _stringpool_name;
+
+ /* Separates keywords from other attributes. */
+ const char * _delimiters;
+
+ /* Contains user-specified key choices. */
+ Positions _key_positions;
+};
+
+/* Global option coordinator for the entire program. */
+extern Options option;
#ifdef __OPTIMIZE__
-#include "trace.h"
#define INLINE inline
#include "options.icc"
#undef INLINE
diff --git a/src/options.icc b/src/options.icc
index 82fe5375c23f..4188ddcbfd72 100644
--- a/src/options.icc
+++ b/src/options.icc
@@ -1,183 +1,157 @@
/* Inline Functions for options.{h,cc}.
- Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
- written by Douglas C. Schmidt (schmidt@ics.uci.edu)
+ Copyright (C) 1989-1998, 2000, 2002-2004 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
-This file is part of GNU GPERF.
+ This file is part of GNU GPERF.
-GNU GPERF 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 1, or (at your option)
-any later version.
+ GNU GPERF 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 GPERF 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.
+ GNU GPERF 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 GPERF; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-// This needs:
-//#include "trace.h"
+/* ----------------------------- Class Options ----------------------------- */
-/* TRUE if option enable, else FALSE. */
-INLINE int
-Options::operator[] (Option_Type option)
+/* Tests a given boolean option. Returns true if set, false otherwise. */
+INLINE bool
+Options::operator[] (Option_Type option) const
{
- T (Trace t ("Options::operator[]");)
- return option_word & option;
+ return _option_word & option;
}
-/* Enables option OPT. */
+/* Sets a given boolean option. */
INLINE void
-Options::operator = (enum Option_Type opt)
+Options::set (Option_Type option)
{
- T (Trace t ("Options::operator=");)
- option_word |= opt;
+ _option_word |= option;
}
-/* Disables option OPT. */
-INLINE void
-Options::operator != (enum Option_Type opt)
+/* Returns the input file name. */
+INLINE const char *
+Options::get_input_file_name () const
{
- T (Trace t ("Options::operator!=");)
- option_word &= ~opt;
+ return _input_file_name;
}
-/* Initializes the key Iterator. */
-INLINE void
-Options::reset (void)
+/* Returns the output file name. */
+INLINE const char *
+Options::get_output_file_name () const
{
- T (Trace t ("Options::reset");)
- key_pos = 0;
+ return _output_file_name;
}
-/* Returns current key_position and advance index. */
+/* Returns the jump value. */
INLINE int
-Options::get (void)
-{
- T (Trace t ("Options::get");)
- return key_positions[key_pos++];
-}
-
-/* Sets the size of the table size. */
-INLINE void
-Options::set_asso_max (int r)
+Options::get_jump () const
{
- T (Trace t ("Options::set_asso_max");)
- size = r;
+ return _jump;
}
-/* Returns the size of the table size. */
+/* Returns the initial associated character value. */
INLINE int
-Options::get_asso_max (void)
+Options::get_initial_asso_value () const
{
- T (Trace t ("Options::get_asso_max");)
- return size;
+ return _initial_asso_value;
}
-/* Returns total distinct key positions. */
+/* Returns the number of iterations for finding finding good asso_values. */
INLINE int
-Options::get_max_keysig_size (void)
+Options::get_asso_iterations () const
{
- T (Trace t ("Options::get_max_keysig_size");)
- return total_keysig_size;
+ return _asso_iterations;
}
-/* Sets total distinct key positions. */
-INLINE void
-Options::set_keysig_size (int size)
+/* Returns the total number of switch statements to generate. */
+INLINE int
+Options::get_total_switches () const
{
- T (Trace t ("Options::set_keysig_size");)
- total_keysig_size = size;
+ return _total_switches;
}
-/* Returns the jump value. */
-INLINE int
-Options::get_jump (void)
+/* Returns the factor by which to multiply the generated table's size. */
+INLINE float
+Options::get_size_multiple () const
{
- T (Trace t ("Options::get_jump");)
- return jump;
+ return _size_multiple;
}
-/* Returns the generated function name. */
+/* Returns the generated function name. */
INLINE const char *
-Options::get_function_name (void)
+Options::get_function_name () const
{
- T (Trace t ("Options::get_function_name");)
- return function_name;
+ return _function_name;
}
-/* Returns the keyword key name. */
+/* Returns the keyword key name. */
INLINE const char *
-Options::get_key_name (void)
+Options::get_slot_name () const
{
- T (Trace t ("Options::get_key_name");)
- return key_name;
+ return _slot_name;
}
-/* Returns the struct initializer suffix. */
+/* Returns the struct initializer suffix. */
INLINE const char *
-Options::get_initializer_suffix (void)
+Options::get_initializer_suffix () const
{
- T (Trace t ("Options::get_initializer_suffix");)
- return initializer_suffix;
+ return _initializer_suffix;
}
-/* Returns the hash function name. */
+/* Returns the generated class name. */
INLINE const char *
-Options::get_hash_name (void)
+Options::get_class_name () const
{
- T (Trace t ("Options::get_hash_name");)
- return hash_name;
+ return _class_name;
}
-/* Returns the hash table array name. */
+/* Returns the hash function name. */
INLINE const char *
-Options::get_wordlist_name (void)
+Options::get_hash_name () const
{
- T (Trace t ("Options::get_wordlist_name");)
- return wordlist_name;
+ return _hash_name;
}
-/* Returns the generated class name. */
+/* Returns the hash table array name. */
INLINE const char *
-Options::get_class_name (void)
+Options::get_wordlist_name () const
{
- T (Trace t ("Options::get_class_name");)
- return class_name;
+ return _wordlist_name;
}
-/* Returns the initial associated character value. */
-INLINE int
-Options::initial_value (void)
+/* Returns the length table array name. */
+INLINE const char *
+Options::get_lengthtable_name () const
{
- T (Trace t ("Options::initial_value");)
- return initial_asso_value;
+ return _lengthtable_name;
}
-/* Returns the iterations value. */
-INLINE int
-Options::get_iterations (void)
+/* Returns the string pool name. */
+INLINE const char *
+Options::get_stringpool_name () const
{
- T (Trace t ("Options::get_iterations");)
- return iterations;
+ return _stringpool_name;
}
-/* Returns the string used to delimit keywords from other attributes. */
+/* Returns the string used to delimit keywords from other attributes. */
INLINE const char *
-Options::get_delimiter ()
+Options::get_delimiters () const
{
- T (Trace t ("Options::get_delimiter");)
- return delimiters;
+ return _delimiters;
}
-/* Gets the total number of switch statements to generate. */
-INLINE int
-Options::get_total_switches ()
+/* Returns key positions. */
+INLINE const Positions&
+Options::get_key_positions () const
{
- T (Trace t ("Options::get_total_switches");)
- return total_switches;
+ return _key_positions;
}
diff --git a/src/output.cc b/src/output.cc
new file mode 100644
index 000000000000..c0c8e6ca38b5
--- /dev/null
+++ b/src/output.cc
@@ -0,0 +1,2100 @@
+/* Output routines.
+ Copyright (C) 1989-1998, 2000, 2002-2004, 2006-2007 Free Software Foundation, Inc.
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
+ and Bruno Haible <bruno@clisp.org>.
+
+ This file is part of GNU GPERF.
+
+ GNU GPERF 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 GPERF 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; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Specification. */
+#include "output.h"
+
+#include <stdio.h>
+#include <string.h> /* declares strncpy(), strchr() */
+#include <ctype.h> /* declares isprint() */
+#include <assert.h> /* defines assert() */
+#include <limits.h> /* defines SCHAR_MAX etc. */
+#include "options.h"
+#include "version.h"
+
+/* The "const " qualifier. */
+static const char *const_always;
+
+/* The "const " qualifier, for read-only arrays. */
+static const char *const_readonly_array;
+
+/* The "const " qualifier, for the array type. */
+static const char *const_for_struct;
+
+/* Returns the smallest unsigned C type capable of holding integers
+ up to N. */
+
+static const char *
+smallest_integral_type (int n)
+{
+ if (n <= UCHAR_MAX) return "unsigned char";
+ if (n <= USHRT_MAX) return "unsigned short";
+ return "unsigned int";
+}
+
+/* Returns the smallest signed C type capable of holding integers
+ from MIN to MAX. */
+
+static const char *
+smallest_integral_type (int min, int max)
+{
+ if (option[ANSIC] | option[CPLUSPLUS])
+ if (min >= SCHAR_MIN && max <= SCHAR_MAX) return "signed char";
+ if (min >= SHRT_MIN && max <= SHRT_MAX) return "short";
+ return "int";
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Constructor.
+ Note about the keyword list starting at head:
+ - The list is ordered by increasing _hash_value. This has been achieved
+ by Search::sort().
+ - Duplicates, i.e. keywords with the same _selchars set, are chained
+ through the _duplicate_link pointer. Only one representative per
+ duplicate equivalence class remains on the linear keyword list.
+ - Accidental duplicates, i.e. keywords for which the _asso_values[] search
+ couldn't achieve different hash values, cannot occur on the linear
+ keyword list. Search::optimize would catch this mistake.
+ */
+Output::Output (KeywordExt_List *head, const char *struct_decl,
+ unsigned int struct_decl_lineno, const char *return_type,
+ const char *struct_tag, const char *verbatim_declarations,
+ const char *verbatim_declarations_end,
+ unsigned int verbatim_declarations_lineno,
+ const char *verbatim_code, const char *verbatim_code_end,
+ unsigned int verbatim_code_lineno, bool charset_dependent,
+ int total_keys, int max_key_len, int min_key_len,
+ const Positions& positions, const unsigned int *alpha_inc,
+ int total_duplicates, unsigned int alpha_size,
+ const int *asso_values)
+ : _head (head), _struct_decl (struct_decl),
+ _struct_decl_lineno (struct_decl_lineno), _return_type (return_type),
+ _struct_tag (struct_tag),
+ _verbatim_declarations (verbatim_declarations),
+ _verbatim_declarations_end (verbatim_declarations_end),
+ _verbatim_declarations_lineno (verbatim_declarations_lineno),
+ _verbatim_code (verbatim_code),
+ _verbatim_code_end (verbatim_code_end),
+ _verbatim_code_lineno (verbatim_code_lineno),
+ _charset_dependent (charset_dependent),
+ _total_keys (total_keys),
+ _max_key_len (max_key_len), _min_key_len (min_key_len),
+ _key_positions (positions), _alpha_inc (alpha_inc),
+ _total_duplicates (total_duplicates), _alpha_size (alpha_size),
+ _asso_values (asso_values)
+{
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Computes the minimum and maximum hash values, and stores them
+ in _min_hash_value and _max_hash_value. */
+
+void
+Output::compute_min_max ()
+{
+ /* Since the list is already sorted by hash value all we need to do is
+ to look at the first and the last element of the list. */
+
+ _min_hash_value = _head->first()->_hash_value;
+
+ KeywordExt_List *temp;
+ for (temp = _head; temp->rest(); temp = temp->rest())
+ ;
+ _max_hash_value = temp->first()->_hash_value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Returns the number of different hash values. */
+
+int
+Output::num_hash_values () const
+{
+ /* Since the list is already sorted by hash value and doesn't contain
+ duplicates, we can simply count the number of keywords on the list. */
+ int count = 0;
+ for (KeywordExt_List *temp = _head; temp; temp = temp->rest())
+ count++;
+ return count;
+}
+
+/* -------------------- Output_Constants and subclasses -------------------- */
+
+/* This class outputs an enumeration defining some constants. */
+
+struct Output_Constants
+{
+ virtual void output_start () = 0;
+ virtual void output_item (const char *name, int value) = 0;
+ virtual void output_end () = 0;
+ Output_Constants () {}
+ virtual ~Output_Constants () {}
+};
+
+/* This class outputs an enumeration in #define syntax. */
+
+struct Output_Defines : public Output_Constants
+{
+ virtual void output_start ();
+ virtual void output_item (const char *name, int value);
+ virtual void output_end ();
+ Output_Defines () {}
+ virtual ~Output_Defines () {}
+};
+
+void Output_Defines::output_start ()
+{
+ printf ("\n");
+}
+
+void Output_Defines::output_item (const char *name, int value)
+{
+ printf ("#define %s %d\n", name, value);
+}
+
+void Output_Defines::output_end ()
+{
+}
+
+/* This class outputs an enumeration using 'enum'. */
+
+struct Output_Enum : public Output_Constants
+{
+ virtual void output_start ();
+ virtual void output_item (const char *name, int value);
+ virtual void output_end ();
+ Output_Enum (const char *indent)
+ : _indentation (indent) {}
+ virtual ~Output_Enum () {}
+private:
+ const char *_indentation;
+ bool _pending_comma;
+};
+
+void Output_Enum::output_start ()
+{
+ printf ("%senum\n"
+ "%s {\n",
+ _indentation, _indentation);
+ _pending_comma = false;
+}
+
+void Output_Enum::output_item (const char *name, int value)
+{
+ if (_pending_comma)
+ printf (",\n");
+ printf ("%s %s = %d", _indentation, name, value);
+ _pending_comma = true;
+}
+
+void Output_Enum::output_end ()
+{
+ if (_pending_comma)
+ printf ("\n");
+ printf ("%s };\n\n", _indentation);
+}
+
+/* Outputs the maximum and minimum hash values etc. */
+
+void
+Output::output_constants (struct Output_Constants& style) const
+{
+ style.output_start ();
+ style.output_item ("TOTAL_KEYWORDS", _total_keys);
+ style.output_item ("MIN_WORD_LENGTH", _min_key_len);
+ style.output_item ("MAX_WORD_LENGTH", _max_key_len);
+ style.output_item ("MIN_HASH_VALUE", _min_hash_value);
+ style.output_item ("MAX_HASH_VALUE", _max_hash_value);
+ style.output_end ();
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* We use a downcase table because when called repeatedly, the code
+ gperf_downcase[c]
+ is faster than
+ if (c >= 'A' && c <= 'Z')
+ c += 'a' - 'A';
+ */
+#define USE_DOWNCASE_TABLE 1
+
+#if USE_DOWNCASE_TABLE
+
+/* Output gperf's ASCII-downcase table. */
+
+static void
+output_upperlower_table ()
+{
+ unsigned int c;
+
+ printf ("#ifndef GPERF_DOWNCASE\n"
+ "#define GPERF_DOWNCASE 1\n"
+ "static unsigned char gperf_downcase[256] =\n"
+ " {");
+ for (c = 0; c < 256; c++)
+ {
+ if ((c % 15) == 0)
+ printf ("\n ");
+ printf (" %3d", c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c);
+ if (c < 255)
+ printf (",");
+ }
+ printf ("\n"
+ " };\n"
+ "#endif\n\n");
+}
+
+#endif
+
+/* Output gperf's ASCII-case insensitive strcmp replacement. */
+
+static void
+output_upperlower_strcmp ()
+{
+ printf ("#ifndef GPERF_CASE_STRCMP\n"
+ "#define GPERF_CASE_STRCMP 1\n"
+ "static int\n"
+ "gperf_case_strcmp ");
+ printf (option[KRC] ?
+ "(s1, s2)\n"
+ " register char *s1;\n"
+ " register char *s2;\n" :
+ option[C] ?
+ "(s1, s2)\n"
+ " register const char *s1;\n"
+ " register const char *s2;\n" :
+ option[ANSIC] | option[CPLUSPLUS] ?
+ "(register const char *s1, register const char *s2)\n" :
+ "");
+ #if USE_DOWNCASE_TABLE
+ printf ("{\n"
+ " for (;;)\n"
+ " {\n"
+ " unsigned char c1 = gperf_downcase[(unsigned char)*s1++];\n"
+ " unsigned char c2 = gperf_downcase[(unsigned char)*s2++];\n"
+ " if (c1 != 0 && c1 == c2)\n"
+ " continue;\n"
+ " return (int)c1 - (int)c2;\n"
+ " }\n"
+ "}\n");
+ #else
+ printf ("{\n"
+ " for (;;)\n"
+ " {\n"
+ " unsigned char c1 = *s1++;\n"
+ " unsigned char c2 = *s2++;\n"
+ " if (c1 >= 'A' && c1 <= 'Z')\n"
+ " c1 += 'a' - 'A';\n"
+ " if (c2 >= 'A' && c2 <= 'Z')\n"
+ " c2 += 'a' - 'A';\n"
+ " if (c1 != 0 && c1 == c2)\n"
+ " continue;\n"
+ " return (int)c1 - (int)c2;\n"
+ " }\n"
+ "}\n");
+ #endif
+ printf ("#endif\n\n");
+}
+
+/* Output gperf's ASCII-case insensitive strncmp replacement. */
+
+static void
+output_upperlower_strncmp ()
+{
+ printf ("#ifndef GPERF_CASE_STRNCMP\n"
+ "#define GPERF_CASE_STRNCMP 1\n"
+ "static int\n"
+ "gperf_case_strncmp ");
+ printf (option[KRC] ?
+ "(s1, s2, n)\n"
+ " register char *s1;\n"
+ " register char *s2;\n"
+ " register unsigned int n;\n" :
+ option[C] ?
+ "(s1, s2, n)\n"
+ " register const char *s1;\n"
+ " register const char *s2;\n"
+ " register unsigned int n;\n" :
+ option[ANSIC] | option[CPLUSPLUS] ?
+ "(register const char *s1, register const char *s2, register unsigned int n)\n" :
+ "");
+ #if USE_DOWNCASE_TABLE
+ printf ("{\n"
+ " for (; n > 0;)\n"
+ " {\n"
+ " unsigned char c1 = gperf_downcase[(unsigned char)*s1++];\n"
+ " unsigned char c2 = gperf_downcase[(unsigned char)*s2++];\n"
+ " if (c1 != 0 && c1 == c2)\n"
+ " {\n"
+ " n--;\n"
+ " continue;\n"
+ " }\n"
+ " return (int)c1 - (int)c2;\n"
+ " }\n"
+ " return 0;\n"
+ "}\n");
+ #else
+ printf ("{\n"
+ " for (; n > 0;)\n"
+ " {\n"
+ " unsigned char c1 = *s1++;\n"
+ " unsigned char c2 = *s2++;\n"
+ " if (c1 >= 'A' && c1 <= 'Z')\n"
+ " c1 += 'a' - 'A';\n"
+ " if (c2 >= 'A' && c2 <= 'Z')\n"
+ " c2 += 'a' - 'A';\n"
+ " if (c1 != 0 && c1 == c2)\n"
+ " {\n"
+ " n--;\n"
+ " continue;\n"
+ " }\n"
+ " return (int)c1 - (int)c2;\n"
+ " }\n"
+ " return 0;\n"
+ "}\n");
+ #endif
+ printf ("#endif\n\n");
+}
+
+/* Output gperf's ASCII-case insensitive memcmp replacement. */
+
+static void
+output_upperlower_memcmp ()
+{
+ printf ("#ifndef GPERF_CASE_MEMCMP\n"
+ "#define GPERF_CASE_MEMCMP 1\n"
+ "static int\n"
+ "gperf_case_memcmp ");
+ printf (option[KRC] ?
+ "(s1, s2, n)\n"
+ " register char *s1;\n"
+ " register char *s2;\n"
+ " register unsigned int n;\n" :
+ option[C] ?
+ "(s1, s2, n)\n"
+ " register const char *s1;\n"
+ " register const char *s2;\n"
+ " register unsigned int n;\n" :
+ option[ANSIC] | option[CPLUSPLUS] ?
+ "(register const char *s1, register const char *s2, register unsigned int n)\n" :
+ "");
+ #if USE_DOWNCASE_TABLE
+ printf ("{\n"
+ " for (; n > 0;)\n"
+ " {\n"
+ " unsigned char c1 = gperf_downcase[(unsigned char)*s1++];\n"
+ " unsigned char c2 = gperf_downcase[(unsigned char)*s2++];\n"
+ " if (c1 == c2)\n"
+ " {\n"
+ " n--;\n"
+ " continue;\n"
+ " }\n"
+ " return (int)c1 - (int)c2;\n"
+ " }\n"
+ " return 0;\n"
+ "}\n");
+ #else
+ printf ("{\n"
+ " for (; n > 0;)\n"
+ " {\n"
+ " unsigned char c1 = *s1++;\n"
+ " unsigned char c2 = *s2++;\n"
+ " if (c1 >= 'A' && c1 <= 'Z')\n"
+ " c1 += 'a' - 'A';\n"
+ " if (c2 >= 'A' && c2 <= 'Z')\n"
+ " c2 += 'a' - 'A';\n"
+ " if (c1 == c2)\n"
+ " {\n"
+ " n--;\n"
+ " continue;\n"
+ " }\n"
+ " return (int)c1 - (int)c2;\n"
+ " }\n"
+ " return 0;\n"
+ "}\n");
+ #endif
+ printf ("#endif\n\n");
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Outputs a keyword, as a string: enclosed in double quotes, escaping
+ backslashes, double quote and unprintable characters. */
+
+static void
+output_string (const char *key, int len)
+{
+ putchar ('"');
+ for (; len > 0; len--)
+ {
+ unsigned char c = static_cast<unsigned char>(*key++);
+ if (isprint (c))
+ {
+ if (c == '"' || c == '\\')
+ putchar ('\\');
+ putchar (c);
+ }
+ else
+ {
+ /* Use octal escapes, not hexadecimal escapes, because some old
+ C compilers didn't understand hexadecimal escapes, and because
+ hexadecimal escapes are not limited to 2 digits, thus needing
+ special care if the following character happens to be a digit. */
+ putchar ('\\');
+ putchar ('0' + ((c >> 6) & 7));
+ putchar ('0' + ((c >> 3) & 7));
+ putchar ('0' + (c & 7));
+ }
+ }
+ putchar ('"');
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Outputs a #line directive, referring to the given line number. */
+
+static void
+output_line_directive (unsigned int lineno)
+{
+ const char *file_name = option.get_input_file_name ();
+ if (file_name != NULL)
+ {
+ printf ("#line %u ", lineno);
+ output_string (file_name, strlen (file_name));
+ printf ("\n");
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Outputs a type and a const specifier (i.e. "const " or "").
+ The output is terminated with a space. */
+
+static void
+output_const_type (const char *const_string, const char *type_string)
+{
+ if (type_string[strlen(type_string)-1] == '*')
+ /* For pointer types, put the 'const' after the type. */
+ printf ("%s %s", type_string, const_string);
+ else
+ /* For scalar or struct types, put the 'const' before the type. */
+ printf ("%s%s ", const_string, type_string);
+}
+
+/* ----------------------- Output_Expr and subclasses ----------------------- */
+
+/* This class outputs a general expression. */
+
+struct Output_Expr
+{
+ virtual void output_expr () const = 0;
+ Output_Expr () {}
+ virtual ~Output_Expr () {}
+};
+
+/* This class outputs an expression formed by a single string. */
+
+struct Output_Expr1 : public Output_Expr
+{
+ virtual void output_expr () const;
+ Output_Expr1 (const char *piece1) : _p1 (piece1) {}
+ virtual ~Output_Expr1 () {}
+private:
+ const char *_p1;
+};
+
+void Output_Expr1::output_expr () const
+{
+ printf ("%s", _p1);
+}
+
+#if 0 /* unused */
+
+/* This class outputs an expression formed by the concatenation of two
+ strings. */
+
+struct Output_Expr2 : public Output_Expr
+{
+ virtual void output_expr () const;
+ Output_Expr2 (const char *piece1, const char *piece2)
+ : _p1 (piece1), _p2 (piece2) {}
+ virtual ~Output_Expr2 () {}
+private:
+ const char *_p1;
+ const char *_p2;
+};
+
+void Output_Expr2::output_expr () const
+{
+ printf ("%s%s", _p1, _p2);
+}
+
+#endif
+
+/* --------------------- Output_Compare and subclasses --------------------- */
+
+/* This class outputs a comparison expression. */
+
+struct Output_Compare
+{
+ /* Outputs the comparison expression.
+ expr1 outputs a simple expression of type 'const char *' referring to
+ the string being looked up. expr2 outputs a simple expression of type
+ 'const char *' referring to the constant string stored in the gperf
+ generated hash table. */
+ virtual void output_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const = 0;
+ /* Outputs the comparison expression for the first byte.
+ Returns true if the this comparison is complete. */
+ bool output_firstchar_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const;
+ Output_Compare () {}
+ virtual ~Output_Compare () {}
+};
+
+bool Output_Compare::output_firstchar_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const
+{
+ /* First, we emit a comparison of the first byte of the two strings.
+ This catches most cases where the string being looked up is not in the
+ hash table but happens to have the same hash code as an element of the
+ hash table. */
+ if (option[UPPERLOWER])
+ {
+ /* Incomplete comparison, just for speedup. */
+ printf ("(((unsigned char)*");
+ expr1.output_expr ();
+ printf (" ^ (unsigned char)*");
+ expr2.output_expr ();
+ printf (") & ~32) == 0");
+ return false;
+ }
+ else
+ {
+ /* Complete comparison. */
+ printf ("*");
+ expr1.output_expr ();
+ printf (" == *");
+ expr2.output_expr ();
+ return true;
+ }
+}
+
+/* This class outputs a comparison using strcmp. */
+
+struct Output_Compare_Strcmp : public Output_Compare
+{
+ virtual void output_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const;
+ Output_Compare_Strcmp () {}
+ virtual ~Output_Compare_Strcmp () {}
+};
+
+void Output_Compare_Strcmp::output_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const
+{
+ bool firstchar_done = output_firstchar_comparison (expr1, expr2);
+ printf (" && !");
+ if (option[UPPERLOWER])
+ printf ("gperf_case_");
+ printf ("strcmp (");
+ if (firstchar_done)
+ {
+ expr1.output_expr ();
+ printf (" + 1, ");
+ expr2.output_expr ();
+ printf (" + 1");
+ }
+ else
+ {
+ expr1.output_expr ();
+ printf (", ");
+ expr2.output_expr ();
+ }
+ printf (")");
+}
+
+/* This class outputs a comparison using strncmp.
+ Note that the length of expr1 will be available through the local variable
+ 'len'. */
+
+struct Output_Compare_Strncmp : public Output_Compare
+{
+ virtual void output_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const;
+ Output_Compare_Strncmp () {}
+ virtual ~Output_Compare_Strncmp () {}
+};
+
+void Output_Compare_Strncmp::output_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const
+{
+ bool firstchar_done = output_firstchar_comparison (expr1, expr2);
+ printf (" && !");
+ if (option[UPPERLOWER])
+ printf ("gperf_case_");
+ printf ("strncmp (");
+ if (firstchar_done)
+ {
+ expr1.output_expr ();
+ printf (" + 1, ");
+ expr2.output_expr ();
+ printf (" + 1, len - 1");
+ }
+ else
+ {
+ expr1.output_expr ();
+ printf (", ");
+ expr2.output_expr ();
+ printf (", len");
+ }
+ printf (") && ");
+ expr2.output_expr ();
+ printf ("[len] == '\\0'");
+}
+
+/* This class outputs a comparison using memcmp.
+ Note that the length of expr1 (available through the local variable 'len')
+ must be verified to be equal to the length of expr2 prior to this
+ comparison. */
+
+struct Output_Compare_Memcmp : public Output_Compare
+{
+ virtual void output_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const;
+ Output_Compare_Memcmp () {}
+ virtual ~Output_Compare_Memcmp () {}
+};
+
+void Output_Compare_Memcmp::output_comparison (const Output_Expr& expr1,
+ const Output_Expr& expr2) const
+{
+ bool firstchar_done = output_firstchar_comparison (expr1, expr2);
+ printf (" && !");
+ if (option[UPPERLOWER])
+ printf ("gperf_case_");
+ printf ("memcmp (");
+ if (firstchar_done)
+ {
+ expr1.output_expr ();
+ printf (" + 1, ");
+ expr2.output_expr ();
+ printf (" + 1, len - 1");
+ }
+ else
+ {
+ expr1.output_expr ();
+ printf (", ");
+ expr2.output_expr ();
+ printf (", len");
+ }
+ printf (")");
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Generates a C expression for an asso_values[] reference. */
+
+void
+Output::output_asso_values_ref (int pos) const
+{
+ printf ("asso_values[");
+ /* Always cast to unsigned char. This is necessary when the alpha_inc
+ is nonzero, and also avoids a gcc warning "subscript has type 'char'". */
+ printf ("(unsigned char)");
+ if (pos == Positions::LASTCHAR)
+ printf ("str[len - 1]");
+ else
+ {
+ printf ("str[%d]", pos);
+ if (_alpha_inc[pos])
+ printf ("+%u", _alpha_inc[pos]);
+ }
+ printf ("]");
+}
+
+/* Generates C code for the hash function that returns the
+ proper encoding for each keyword.
+ The hash function has the signature
+ unsigned int <hash> (const char *str, unsigned int len). */
+
+void
+Output::output_hash_function () const
+{
+ /* Output the function's head. */
+ if (option[CPLUSPLUS])
+ printf ("inline ");
+ else if (option[KRC] | option[C] | option[ANSIC])
+ printf ("#ifdef __GNUC__\n"
+ "__inline\n"
+ "#else\n"
+ "#ifdef __cplusplus\n"
+ "inline\n"
+ "#endif\n"
+ "#endif\n");
+
+ if (/* The function does not use the 'str' argument? */
+ _key_positions.get_size() == 0
+ || /* The function uses 'str', but not the 'len' argument? */
+ (option[NOLENGTH]
+ && _key_positions[0] < _min_key_len
+ && _key_positions[_key_positions.get_size() - 1] != Positions::LASTCHAR))
+ /* Pacify lint. */
+ printf ("/*ARGSUSED*/\n");
+
+ if (option[KRC] | option[C] | option[ANSIC])
+ printf ("static ");
+ printf ("unsigned int\n");
+ if (option[CPLUSPLUS])
+ printf ("%s::", option.get_class_name ());
+ printf ("%s ", option.get_hash_name ());
+ printf (option[KRC] ?
+ "(str, len)\n"
+ " register char *str;\n"
+ " register unsigned int len;\n" :
+ option[C] ?
+ "(str, len)\n"
+ " register const char *str;\n"
+ " register unsigned int len;\n" :
+ option[ANSIC] | option[CPLUSPLUS] ?
+ "(register const char *str, register unsigned int len)\n" :
+ "");
+
+ /* Note that when the hash function is called, it has already been verified
+ that min_key_len <= len <= max_key_len. */
+
+ /* Output the function's body. */
+ printf ("{\n");
+
+ /* First the asso_values array. */
+ if (_key_positions.get_size() > 0)
+ {
+ printf (" static %s%s asso_values[] =\n"
+ " {",
+ const_readonly_array,
+ smallest_integral_type (_max_hash_value + 1));
+
+ const int columns = 10;
+
+ /* Calculate maximum number of digits required for MAX_HASH_VALUE. */
+ int field_width = 2;
+ for (int trunc = _max_hash_value; (trunc /= 10) > 0;)
+ field_width++;
+
+ for (unsigned int count = 0; count < _alpha_size; count++)
+ {
+ if (count > 0)
+ printf (",");
+ if ((count % columns) == 0)
+ printf ("\n ");
+ printf ("%*d", field_width, _asso_values[count]);
+ }
+
+ printf ("\n"
+ " };\n");
+ }
+
+ if (_key_positions.get_size() == 0)
+ {
+ /* Trivial case: No key positions at all. */
+ printf (" return %s;\n",
+ option[NOLENGTH] ? "0" : "len");
+ }
+ else
+ {
+ /* Iterate through the key positions. Remember that Positions::sort()
+ has sorted them in decreasing order, with Positions::LASTCHAR coming
+ last. */
+ PositionIterator iter = _key_positions.iterator(_max_key_len);
+ int key_pos;
+
+ /* Get the highest key position. */
+ key_pos = iter.next ();
+
+ if (key_pos == Positions::LASTCHAR || key_pos < _min_key_len)
+ {
+ /* We can perform additional optimizations here:
+ Write it out as a single expression. Note that the values
+ are added as 'int's even though the asso_values array may
+ contain 'unsigned char's or 'unsigned short's. */
+
+ printf (" return %s",
+ option[NOLENGTH] ? "" : "len + ");
+
+ if (_key_positions.get_size() == 2
+ && _key_positions[0] == 0
+ && _key_positions[1] == Positions::LASTCHAR)
+ /* Optimize special case of "-k 1,$". */
+ {
+ output_asso_values_ref (Positions::LASTCHAR);
+ printf (" + ");
+ output_asso_values_ref (0);
+ }
+ else
+ {
+ for (; key_pos != Positions::LASTCHAR; )
+ {
+ output_asso_values_ref (key_pos);
+ if ((key_pos = iter.next ()) != PositionIterator::EOS)
+ printf (" + ");
+ else
+ break;
+ }
+
+ if (key_pos == Positions::LASTCHAR)
+ output_asso_values_ref (Positions::LASTCHAR);
+ }
+
+ printf (";\n");
+ }
+ else
+ {
+ /* We've got to use the correct, but brute force, technique. */
+ printf (" register int hval = %s;\n\n"
+ " switch (%s)\n"
+ " {\n"
+ " default:\n",
+ option[NOLENGTH] ? "0" : "len",
+ option[NOLENGTH] ? "len" : "hval");
+
+ while (key_pos != Positions::LASTCHAR && key_pos >= _max_key_len)
+ if ((key_pos = iter.next ()) == PositionIterator::EOS)
+ break;
+
+ if (key_pos != PositionIterator::EOS && key_pos != Positions::LASTCHAR)
+ {
+ int i = key_pos;
+ do
+ {
+ if (i > key_pos)
+ printf (" /*FALLTHROUGH*/\n"); /* Pacify lint. */
+ for ( ; i > key_pos; i--)
+ printf (" case %d:\n", i);
+
+ printf (" hval += ");
+