mirror of
https://git.savannah.gnu.org/git/gperf.git
synced 2025-12-02 13:09:22 +00:00
Initial revision
This commit is contained in:
143
src/Makefile.in
Normal file
143
src/Makefile.in
Normal file
@@ -0,0 +1,143 @@
|
||||
# Makefile for gperf/src
|
||||
|
||||
# Copyright (C) 1989, 1992, 1993, 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.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
# Directories used by "make":
|
||||
srcdir = @srcdir@
|
||||
|
||||
# Directories used by "make install":
|
||||
prefix = @prefix@
|
||||
local_prefix = /usr/local
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
|
||||
# Programs used by "make":
|
||||
# C compiler
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
# C++ compiler
|
||||
CXX = @CXX@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CXXCPP = @CXXCPP@
|
||||
# Other
|
||||
MV = mv
|
||||
LN = ln
|
||||
RM = rm -f
|
||||
@SET_MAKE@
|
||||
|
||||
# Programs used by "make install":
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
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
|
||||
CPPFLAGS = -I. -I$(srcdir)/../lib
|
||||
|
||||
TARGETPROG = gperf
|
||||
|
||||
all : $(TARGETPROG)
|
||||
|
||||
$(TARGETPROG): $(OBJECTS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS)
|
||||
|
||||
# Don't use implicit rules, since AIX "make" and OSF/1 "make" don't always
|
||||
# expand $< correctly in this context.
|
||||
#
|
||||
#%.o : %.c
|
||||
# $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
#
|
||||
#%.o : %.cc
|
||||
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
# 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)
|
||||
$(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)
|
||||
$(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)
|
||||
$(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
|
||||
if [ ! -d $(bindir) ] ; then mkdir $(bindir) ; fi
|
||||
$(INSTALL_PROGRAM) $(TARGETPROG) $(bindir)/$(TARGETPROG)
|
||||
|
||||
installdirs : force
|
||||
if [ ! -d $(bindir) ] ; then mkdir $(bindir) ; fi
|
||||
|
||||
uninstall : force
|
||||
$(RM) $(bindir)/$(TARGETPROG)
|
||||
|
||||
check : all
|
||||
|
||||
mostlyclean : clean
|
||||
|
||||
clean : force
|
||||
$(RM) *~ *.s *.o *.a $(TARGETPROG) core
|
||||
|
||||
distclean : clean
|
||||
$(RM) config.status config.log config.cache Makefile config.h
|
||||
|
||||
maintainer-clean : distclean
|
||||
|
||||
force :
|
||||
49
src/bool-array.cc
Normal file
49
src/bool-array.cc
Normal file
@@ -0,0 +1,49 @@
|
||||
/* 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)
|
||||
|
||||
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 "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)
|
||||
{
|
||||
T (Trace t ("Bool_Array::~Bool_Array");)
|
||||
if (option[DEBUG])
|
||||
fprintf (stderr, "\ndumping boolean array information\n"
|
||||
"size = %d\niteration number = %d\nend of array dump\n",
|
||||
size, iteration_number);
|
||||
}
|
||||
|
||||
#ifndef __OPTIMIZE__
|
||||
|
||||
#define INLINE /* not inline */
|
||||
#include "bool-array.icc"
|
||||
#undef INLINE
|
||||
|
||||
#endif /* not defined __OPTIMIZE__ */
|
||||
66
src/bool-array.h
Normal file
66
src/bool-array.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* This may look like C code, but it is really -*- C++ -*- */
|
||||
|
||||
/* 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)
|
||||
|
||||
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. */
|
||||
|
||||
/* Define and implement a simple boolean array abstraction,
|
||||
uses an Iteration Numbering implementation to save on initialization time. */
|
||||
|
||||
#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
|
||||
|
||||
class Bool_Array
|
||||
{
|
||||
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. */
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
#ifdef __OPTIMIZE__ /* efficiency hack! */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "options.h"
|
||||
#define INLINE inline
|
||||
#include "bool-array.icc"
|
||||
#undef INLINE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
85
src/bool-array.icc
Normal file
85
src/bool-array.icc
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Inline Functions for bool-array.{h,cc}.
|
||||
|
||||
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. */
|
||||
|
||||
// This needs:
|
||||
//#include <stdio.h>
|
||||
//#include <string.h>
|
||||
//#include "options.h"
|
||||
//#include "trace.h"
|
||||
|
||||
INLINE
|
||||
Bool_Array::Bool_Array (void)
|
||||
{
|
||||
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));
|
||||
if (option[DEBUG])
|
||||
fprintf (stderr, "\nbool array size = %d, total bytes = %d\n",
|
||||
size, (unsigned int) (size * sizeof (*storage_array)));
|
||||
}
|
||||
|
||||
INLINE int
|
||||
Bool_Array::find (int index)
|
||||
{
|
||||
T (Trace t ("Bool_Array::find");)
|
||||
if (storage_array[index] == iteration_number)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
storage_array[index] = iteration_number;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void
|
||||
Bool_Array::reset (void)
|
||||
{
|
||||
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! */
|
||||
|
||||
if (++iteration_number == 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");
|
||||
fflush (stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/config.h.in
Normal file
19
src/config.h.in
Normal file
@@ -0,0 +1,19 @@
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if the C++ compiler supports "throw ()" declarations. */
|
||||
#undef HAVE_THROW_DECL
|
||||
|
||||
/* Define if you have the getrlimit function. */
|
||||
#undef HAVE_GETRLIMIT
|
||||
|
||||
/* Define if you have the setrlimit function. */
|
||||
#undef HAVE_SETRLIMIT
|
||||
|
||||
/* Define if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
1573
src/configure
vendored
Executable file
1573
src/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
71
src/configure.in
Normal file
71
src/configure.in
Normal file
@@ -0,0 +1,71 @@
|
||||
dnl autoconf configuration for gperf/src
|
||||
|
||||
dnl Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
dnl written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
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 any later version.
|
||||
dnl
|
||||
dnl GNU GPERF is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
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.
|
||||
|
||||
AC_INIT(gen-perf.cc)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PROG_MAKE_SET
|
||||
dnl
|
||||
dnl checks for programs
|
||||
dnl
|
||||
AC_PROG_CC
|
||||
dnl sets variable CC
|
||||
AC_PROG_CPP
|
||||
dnl sets variable CPP
|
||||
AC_PROG_CXX
|
||||
dnl sets variable CXX
|
||||
AC_PROG_CXXCPP
|
||||
dnl sets variable CXXCPP
|
||||
CL_PROG_INSTALL
|
||||
dnl sets variables INSTALL, INSTALL_DATA, INSTALL_PROGRAM
|
||||
dnl
|
||||
dnl checks for compiler characteristics
|
||||
dnl
|
||||
AC_MSG_CHECKING([for working throw()])
|
||||
AC_CACHE_VAL(gp_cxx_throw_decl,[
|
||||
AC_LANG_SAVE()
|
||||
AC_LANG_CPLUSPLUS()
|
||||
AC_TRY_COMPILE([#include <stdlib.h>
|
||||
void operator delete (void* ptr) throw() {}], [],
|
||||
gp_cxx_throw_decl=yes, gp_cxx_throw_decl=no)
|
||||
AC_LANG_RESTORE()
|
||||
])
|
||||
AC_MSG_RESULT([$]gp_cxx_throw_decl)
|
||||
if test [$]gp_cxx_throw_decl = yes; then
|
||||
AC_DEFINE(HAVE_THROW_DECL)
|
||||
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 That's it.
|
||||
dnl
|
||||
AC_OUTPUT(Makefile)
|
||||
342
src/gen-perf.cc
Normal file
342
src/gen-perf.cc
Normal file
@@ -0,0 +1,342 @@
|
||||
/* Provides high-level routines to manipulate the keywork list
|
||||
structures the code generation output.
|
||||
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 <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, const char *set_2, char *set_3)
|
||||
{
|
||||
T (Trace t ("Gen_Perf::compute_disjoint_union");)
|
||||
char *base = set_3;
|
||||
|
||||
while (*set_1 && *set_2)
|
||||
if (*set_1 == *set_2)
|
||||
set_1++, set_2++;
|
||||
else
|
||||
{
|
||||
*set_3 = *set_1 < *set_2 ? *set_1++ : *set_2++;
|
||||
if (set_3 == base || *set_3 != *(set_3-1)) set_3++;
|
||||
}
|
||||
|
||||
while (*set_1)
|
||||
{
|
||||
*set_3 = *set_1++;
|
||||
if (set_3 == base || *set_3 != *(set_3-1)) set_3++;
|
||||
}
|
||||
|
||||
while (*set_2)
|
||||
{
|
||||
*set_3 = *set_2++;
|
||||
if (set_3 == base || *set_3 != *(set_3-1)) set_3++;
|
||||
}
|
||||
*set_3 = '\0';
|
||||
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->length;
|
||||
|
||||
for (const char *ptr = key_node->char_set; *ptr; ptr++)
|
||||
sum += asso_values[(unsigned char)(*ptr)];
|
||||
|
||||
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;
|
||||
|
||||
if (!union_set)
|
||||
union_set = new char [2 * option.get_max_keysig_size () + 1];
|
||||
|
||||
if (option[DEBUG])
|
||||
{
|
||||
fprintf (stderr, "collision on keyword #%d, prior = \"%s\", curr = \"%s\" hash = %d\n",
|
||||
num_done, prior->key, curr->key, curr->hash_value);
|
||||
fflush (stderr);
|
||||
}
|
||||
sort_set (union_set, compute_disjoint_union (prior->char_set, curr->char_set, union_set));
|
||||
|
||||
/* Try changing some values, if change doesn't alter other values continue normal action. */
|
||||
fewest_collisions++;
|
||||
|
||||
for (char *temp = union_set; *temp; temp++)
|
||||
if (!affects_prev (*temp, curr))
|
||||
{
|
||||
if (option[DEBUG])
|
||||
{
|
||||
fprintf (stderr, " by changing asso_value['%c'] (char #%d) to %d\n",
|
||||
*temp, temp - union_set + 1, asso_values[(unsigned char)(*temp)]);
|
||||
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");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
50
src/gen-perf.h
Normal file
50
src/gen-perf.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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 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, const char *set_2, char *set_3);
|
||||
static void sort_set (char *union_set, int len);
|
||||
|
||||
public:
|
||||
Gen_Perf (void);
|
||||
~Gen_Perf (void);
|
||||
int operator () (void);
|
||||
};
|
||||
|
||||
#endif
|
||||
91
src/hash-table.cc
Normal file
91
src/hash-table.cc
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Hash table for checking keyword links. Implemented using double hashing.
|
||||
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 "hash-table.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* declares memset(), strcmp() */
|
||||
#include <hash.h>
|
||||
#include "options.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define NIL(TYPE) (TYPE *)0
|
||||
|
||||
/* 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):
|
||||
table (table_ptr), size (s), collisions (0)
|
||||
{
|
||||
T (Trace t ("Hash_Table::Hash_Table");)
|
||||
memset ((char *) table, 0, size * sizeof (*table));
|
||||
}
|
||||
|
||||
Hash_Table::~Hash_Table (void)
|
||||
{
|
||||
T (Trace t ("Hash_Table::~Hash_Table");)
|
||||
if (option[DEBUG])
|
||||
{
|
||||
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, table[i]->key);
|
||||
|
||||
fprintf (stderr, "\nend 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 *
|
||||
Hash_Table::operator() (List_Node *item, int ignore_length)
|
||||
{
|
||||
T (Trace t ("Hash_Table::operator()");)
|
||||
unsigned hash_val = hashpjw (item->char_set);
|
||||
int probe = hash_val & size - 1;
|
||||
int increment = (hash_val ^ item->length | 1) & size - 1;
|
||||
|
||||
while (table[probe]
|
||||
&& (strcmp (table[probe]->char_set, item->char_set)
|
||||
|| (!ignore_length && table[probe]->length != item->length)))
|
||||
{
|
||||
collisions++;
|
||||
probe = probe + increment & size - 1;
|
||||
}
|
||||
|
||||
return table[probe] ? table[probe] : (table[probe] = item, NIL (List_Node));
|
||||
}
|
||||
42
src/hash-table.h
Normal file
42
src/hash-table.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* This may look like C code, but it is really -*- C++ -*- */
|
||||
|
||||
/* Hash table used to check for duplicate keyword entries.
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef hash_table_h
|
||||
#define hash_table_h 1
|
||||
|
||||
#include "list-node.h"
|
||||
|
||||
class Hash_Table
|
||||
{
|
||||
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! */
|
||||
|
||||
public:
|
||||
Hash_Table (List_Node **t, int s);
|
||||
~Hash_Table (void);
|
||||
List_Node *operator () (List_Node *item, int ignore_length);
|
||||
};
|
||||
|
||||
#endif
|
||||
88
src/iterator.cc
Normal file
88
src/iterator.cc
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 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, USA. */
|
||||
|
||||
#include "iterator.h"
|
||||
|
||||
#include <stream.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;
|
||||
}
|
||||
}
|
||||
51
src/iterator.h
Normal file
51
src/iterator.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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
|
||||
1957
src/key-list.cc
Normal file
1957
src/key-list.cc
Normal file
File diff suppressed because it is too large
Load Diff
96
src/key-list.h
Normal file
96
src/key-list.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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
|
||||
101
src/list-node.cc
Normal file
101
src/list-node.cc
Normal file
@@ -0,0 +1,101 @@
|
||||
/* Creates and initializes a new list node.
|
||||
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 "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 (char *k, int len): link (0), next (0),
|
||||
key (k), rest (option[TYPE] ? k + len + 1 : ""), length (len), index (0)
|
||||
{
|
||||
T (Trace t ("List_Node::List_Node");)
|
||||
char *ptr = new char[(option[ALLCHARS] ? len : option.get_max_keysig_size ()) + 1];
|
||||
char *key_set = ptr;
|
||||
k[len] = '\0'; /* Null terminate KEY to separate it from REST. */
|
||||
|
||||
if (option[ALLCHARS]) /* Use all the character position in the KEY. */
|
||||
for (; *k; k++, ptr++)
|
||||
++occurrences[(unsigned char)(*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 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);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
*ptr = '\0'; /* Terminate this bastard.... */
|
||||
/* Sort the KEY_SET items alphabetically. */
|
||||
set_sort (key_set, ptr - key_set);
|
||||
char_set = key_set;
|
||||
}
|
||||
45
src/list-node.h
Normal file
45
src/list-node.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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 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. */
|
||||
const char *rest; /* Additional information for building hash function. */
|
||||
const char *char_set; /* Set of characters to hash, specified by user. */
|
||||
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. */
|
||||
|
||||
List_Node (char *key, int len);
|
||||
static void set_sort (char *base, int len);
|
||||
};
|
||||
|
||||
#endif
|
||||
72
src/main.cc
Normal file
72
src/main.cc
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Driver program for the Gen_Perf hash function generator
|
||||
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. */
|
||||
|
||||
/* 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
|
||||
|
||||
#include <stdio.h>
|
||||
#include "options.h"
|
||||
#include "gen-perf.h"
|
||||
#include "trace.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
T (Trace t ("main");)
|
||||
|
||||
#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 */
|
||||
|
||||
/* Sets the Options. */
|
||||
option (argc, argv);
|
||||
|
||||
/* Initializes the key word list. */
|
||||
Gen_Perf generate_table;
|
||||
|
||||
/* Generates and prints the Gen_Perf hash table. */
|
||||
int status = generate_table ();
|
||||
|
||||
/* Don't use exit() here, it skips the destructors. */
|
||||
return status;
|
||||
}
|
||||
87
src/new.cc
Normal file
87
src/new.cc
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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;
|
||||
}
|
||||
668
src/options.cc
Normal file
668
src/options.cc
Normal file
@@ -0,0 +1,668 @@
|
||||
/* Handles parsing the Options provided to the user.
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h> /* declares atoi(), abs(), exit() */
|
||||
#include <string.h> /* declares strcmp() */
|
||||
#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. */
|
||||
Options option;
|
||||
|
||||
/* Records the program name. */
|
||||
const char *program_name;
|
||||
|
||||
/* 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 the key component. */
|
||||
static const char *const DEFAULT_KEY = "name";
|
||||
|
||||
/* Default name for the generated class. */
|
||||
static const char *const DEFAULT_CLASS_NAME = "Perfect_Hash";
|
||||
|
||||
/* Default name for generated hash function. */
|
||||
static const char *const DEFAULT_HASH_NAME = "hash";
|
||||
|
||||
/* 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::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. */
|
||||
|
||||
void
|
||||
Options::short_usage (FILE * strm)
|
||||
{
|
||||
T (Trace t ("Options::short_usage");)
|
||||
fprintf (strm, "Usage: %s [-cCdDef[num]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);
|
||||
}
|
||||
|
||||
void
|
||||
Options::long_usage (FILE * strm)
|
||||
{
|
||||
T (Trace t ("Options::long_usage");)
|
||||
fprintf (strm,
|
||||
"GNU `gperf' generates perfect hash functions.\n"
|
||||
"\n"
|
||||
"Usage: %s [OPTION]... [INPUT-FILE]\n"
|
||||
"\n"
|
||||
"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"
|
||||
" -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"
|
||||
" -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"
|
||||
" -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"
|
||||
" -K, --slot-name=NAME Select name of the keyword component in the keyword\n"
|
||||
" structure.\n"
|
||||
" -H, --hash-fn-name=NAME\n"
|
||||
" Specify name of generated hash function. Default is\n"
|
||||
" `hash'.\n"
|
||||
" -N, --lookup-fn-name=NAME\n"
|
||||
" Specify name of generated lookup function. Default\n"
|
||||
" name is `in_word_set'.\n"
|
||||
" -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"
|
||||
" -c, --compare-strncmp Generate comparison code using strncmp rather than\n"
|
||||
" strcmp.\n"
|
||||
" -C, --readonly-tables Make the contents of generated lookup tables\n"
|
||||
" constant, i.e., readonly.\n"
|
||||
" -E, --enum Define constant values using an enum local to the\n"
|
||||
" lookup function rather than with defines.\n"
|
||||
" -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"
|
||||
" global variable, rather than hiding it inside of the\n"
|
||||
" lookup function (which is the default behavior).\n"
|
||||
" -W, --word-array-name=NAME\n"
|
||||
" Specify name of word list array. Default name is\n"
|
||||
" `wordlist'.\n"
|
||||
" -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"
|
||||
" requirements for some keyfiles. The COUNT argument\n"
|
||||
" determines how many switch statements are generated.\n"
|
||||
" A value of 1 generates 1 switch containing all the\n"
|
||||
" 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"
|
||||
" -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"
|
||||
" -k, --key-positions=KEYS\n"
|
||||
" Select the key positions used in the hash function.\n"
|
||||
" The allowable choices range between 1-%d, inclusive.\n"
|
||||
" The positions are separated by commas, ranges may be\n"
|
||||
" 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"
|
||||
" -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"
|
||||
" -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"
|
||||
" the associated character value upon collisions. Must\n"
|
||||
" be an odd number, default is %d.\n"
|
||||
" -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"
|
||||
" -r, --random Utilizes randomness to initialize the associated\n"
|
||||
" values table.\n"
|
||||
" -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"
|
||||
" in relationship to the number of keys, e.g. a value\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"
|
||||
" maximum associated value about 3 times smaller than\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"
|
||||
"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 command-line Options. */
|
||||
|
||||
void
|
||||
Options::print_options (void)
|
||||
{
|
||||
T (Trace t ("Options::print_options");)
|
||||
int i;
|
||||
|
||||
printf ("/* Command-line: ");
|
||||
|
||||
for (i = 0; i < argument_count; i++)
|
||||
printf ("%s ", argument_vector[i]);
|
||||
|
||||
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)
|
||||
{
|
||||
T (Trace t ("Options::key_sort");)
|
||||
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;
|
||||
}
|
||||
|
||||
/* Sets the default Options. */
|
||||
|
||||
Options::Options (void)
|
||||
{
|
||||
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;
|
||||
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. */
|
||||
|
||||
Options::~Options (void)
|
||||
{
|
||||
T (Trace t ("Options::~Options");)
|
||||
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"
|
||||
"\nKRC is.........: %s"
|
||||
"\nC is...........: %s"
|
||||
"\nANSIC is.......: %s"
|
||||
"\nCPLUSPLUS is...: %s"
|
||||
"\nENUM is........: %s"
|
||||
"\nINCLUDE is.....: %s"
|
||||
"\nSEVENBIT is....: %s"
|
||||
"\niterations = %d"
|
||||
"\nlookup function name = %s"
|
||||
"\nhash function name = %s"
|
||||
"\nword list name = %s"
|
||||
"\nkey name = %s"
|
||||
"\njump value = %d"
|
||||
"\nmax associated value = %d"
|
||||
"\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,
|
||||
jump, size - 1, initial_asso_value, delimiters, total_switches);
|
||||
if (option_word & ALLCHARS)
|
||||
fprintf (stderr, "all characters are used in the hash function\n");
|
||||
|
||||
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);
|
||||
|
||||
fprintf (stderr, "finished dumping Options\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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' },
|
||||
{ "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 }
|
||||
};
|
||||
|
||||
void
|
||||
Options::operator() (int argc, char *argv[])
|
||||
{
|
||||
T (Trace t ("Options::operator()");)
|
||||
int option_char;
|
||||
|
||||
program_name = argv[0];
|
||||
argument_count = argc;
|
||||
argument_vector = argv;
|
||||
|
||||
while ((option_char =
|
||||
getopt_long (argument_count, argument_vector,
|
||||
"adcCDe:Ef:gGhH:i:Ij:k:K:lL:nN:oprs:S:tTvW:Z:7",
|
||||
long_options, (int *)0))
|
||||
!= -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. */
|
||||
{
|
||||
option_word |= COMP;
|
||||
break;
|
||||
}
|
||||
case 'C': /* Make the generated tables readonly (const). */
|
||||
{
|
||||
option_word |= CONST;
|
||||
break;
|
||||
}
|
||||
case 'd': /* Enable debugging option. */
|
||||
{
|
||||
option_word |= DEBUG;
|
||||
fprintf (stderr, "Starting program %s, version %s, with debugging on.\n",
|
||||
program_name, version_string);
|
||||
break;
|
||||
}
|
||||
case 'D': /* Enable duplicate option. */
|
||||
{
|
||||
option_word |= DUP;
|
||||
break;
|
||||
}
|
||||
case 'e': /* Allows user to provide keyword/attribute separator */
|
||||
{
|
||||
option.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;
|
||||
}
|
||||
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. */
|
||||
{
|
||||
option_word |= GLOBAL;
|
||||
break;
|
||||
}
|
||||
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 */
|
||||
{
|
||||
hash_name = /*getopt*/optarg;
|
||||
break;
|
||||
}
|
||||
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 (option[RANDOM])
|
||||
fprintf (stderr, "warning, -r option superceeds -i, ignoring -i option and continuing\n");
|
||||
break;
|
||||
}
|
||||
case 'I': /* Enable #include statements. */
|
||||
{
|
||||
option_word |= INCLUDE;
|
||||
break;
|
||||
}
|
||||
case 'j': /* Sets the jump value, must be odd for later algorithms. */
|
||||
{
|
||||
if ((jump = atoi (/*getopt*/optarg)) < 0)
|
||||
{
|
||||
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++);
|
||||
break;
|
||||
}
|
||||
case 'k': /* Sets key positions used for hash function. */
|
||||
{
|
||||
const int BAD_VALUE = -1;
|
||||
int value;
|
||||
Iterator expand (/*getopt*/optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS);
|
||||
|
||||
if (/*getopt*/optarg [0] == '*') /* Use all the characters for hashing!!!! */
|
||||
option_word = (option_word & ~DEFAULTCHARS) | ALLCHARS;
|
||||
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)))
|
||||
{
|
||||
fprintf (stderr, "No keys selected.\n");
|
||||
short_usage (stderr);
|
||||
exit (1);
|
||||
}
|
||||
else if (! key_sort (key_positions, total_keysig_size))
|
||||
{
|
||||
fprintf (stderr, "Duplicate keys 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. */
|
||||
{
|
||||
key_name = /*getopt*/optarg;
|
||||
break;
|
||||
}
|
||||
case 'l': /* Create length table to avoid extra string compares. */
|
||||
{
|
||||
option_word |= LENTABLE;
|
||||
break;
|
||||
}
|
||||
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
|
||||
{
|
||||
fprintf (stderr, "unsupported language option %s, defaulting to C\n", /*getopt*/optarg);
|
||||
option_word |= C;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'n': /* Don't include the length when computing hash function. */
|
||||
{
|
||||
option_word |= NOLENGTH;
|
||||
break;
|
||||
}
|
||||
case 'N': /* Make generated lookup function name be optarg */
|
||||
{
|
||||
function_name = /*getopt*/optarg;
|
||||
break;
|
||||
}
|
||||
case 'o': /* Order input by frequency of key set occurrence. */
|
||||
{
|
||||
option_word |= ORDER;
|
||||
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. */
|
||||
{
|
||||
option_word |= RANDOM;
|
||||
if (option.initial_asso_value != 0)
|
||||
fprintf (stderr, "warning, -r option superceeds -i, disabling -i option and continuing\n");
|
||||
break;
|
||||
}
|
||||
case 's': /* Range of associated values, determines size of final 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);
|
||||
break;
|
||||
}
|
||||
case 'S': /* Generate switch statement output, rather than lookup table. */
|
||||
{
|
||||
option_word |= SWITCH;
|
||||
if ((option.total_switches = atoi (/*getopt*/optarg)) <= 0)
|
||||
{
|
||||
fprintf (stderr, "number of switches %s must be a positive number\n", /*getopt*/optarg);
|
||||
short_usage (stderr);
|
||||
exit (1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */
|
||||
{
|
||||
option_word |= TYPE;
|
||||
break;
|
||||
}
|
||||
case 'T': /* Don't print structure definition. */
|
||||
{
|
||||
option_word |= NOTYPE;
|
||||
break;
|
||||
}
|
||||
case 'v': /* Print out the version and quit. */
|
||||
fprintf (stdout, "GNU gperf %s\n", version_string);
|
||||
exit (0);
|
||||
case 'W': /* Sets the name for the hash table array */
|
||||
{
|
||||
wordlist_name = /*getopt*/optarg;
|
||||
break;
|
||||
}
|
||||
case 'Z': /* Set the class name. */
|
||||
{
|
||||
class_name = /*getopt*/optarg;
|
||||
break;
|
||||
}
|
||||
case '7': /* Assume 7-bit characters. */
|
||||
{
|
||||
option_word |= SEVENBIT;
|
||||
Vectors::ALPHA_SIZE = 128;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
short_usage (stderr);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
fprintf (stderr, "Extra trailing arguments to %s.\n", program_name);
|
||||
short_usage (stderr);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __OPTIMIZE__
|
||||
|
||||
#define INLINE /* not inline */
|
||||
#include "options.icc"
|
||||
#undef INLINE
|
||||
|
||||
#endif /* not defined __OPTIMIZE__ */
|
||||
157
src/options.h
Normal file
157
src/options.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/* This may look like C code, but it is really -*- C++ -*- */
|
||||
|
||||
/* Handles parsing the Options provided to the user.
|
||||
|
||||
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. */
|
||||
|
||||
/* 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. */
|
||||
|
||||
#ifndef options_h
|
||||
#define options_h 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Enumerate the potential debugging 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. */
|
||||
};
|
||||
|
||||
/* 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... ;-( */
|
||||
|
||||
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. */
|
||||
};
|
||||
|
||||
/* 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_class_name (void);
|
||||
static const char *get_hash_name (void);
|
||||
static const char *get_wordlist_name (void);
|
||||
static const char *get_delimiter (void);
|
||||
|
||||
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 *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. */
|
||||
};
|
||||
|
||||
/* Global option coordinator for the entire program. */
|
||||
extern Options option;
|
||||
|
||||
/* 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
|
||||
|
||||
/* Set to 1 if the stack is large enough for holding a text line. */
|
||||
#ifndef LARGE_STACK
|
||||
#define LARGE_STACK 1
|
||||
#endif
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
|
||||
#include "trace.h"
|
||||
#define INLINE inline
|
||||
#include "options.icc"
|
||||
#undef INLINE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
175
src/options.icc
Normal file
175
src/options.icc
Normal file
@@ -0,0 +1,175 @@
|
||||
/* Inline Functions for options.{h,cc}.
|
||||
|
||||
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. */
|
||||
|
||||
// This needs:
|
||||
//#include "trace.h"
|
||||
|
||||
/* TRUE if option enable, else FALSE. */
|
||||
INLINE int
|
||||
Options::operator[] (Option_Type option)
|
||||
{
|
||||
T (Trace t ("Options::operator[]");)
|
||||
return option_word & option;
|
||||
}
|
||||
|
||||
/* Enables option OPT. */
|
||||
INLINE void
|
||||
Options::operator = (enum Option_Type opt)
|
||||
{
|
||||
T (Trace t ("Options::operator=");)
|
||||
option_word |= opt;
|
||||
}
|
||||
|
||||
/* Disables option OPT. */
|
||||
INLINE void
|
||||
Options::operator != (enum Option_Type opt)
|
||||
{
|
||||
T (Trace t ("Options::operator!=");)
|
||||
option_word &= ~opt;
|
||||
}
|
||||
|
||||
/* Initializes the key Iterator. */
|
||||
INLINE void
|
||||
Options::reset (void)
|
||||
{
|
||||
T (Trace t ("Options::reset");)
|
||||
key_pos = 0;
|
||||
}
|
||||
|
||||
/* Returns current key_position and advance index. */
|
||||
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)
|
||||
{
|
||||
T (Trace t ("Options::set_asso_max");)
|
||||
size = r;
|
||||
}
|
||||
|
||||
/* Returns the size of the table size. */
|
||||
INLINE int
|
||||
Options::get_asso_max (void)
|
||||
{
|
||||
T (Trace t ("Options::get_asso_max");)
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Returns total distinct key positions. */
|
||||
INLINE int
|
||||
Options::get_max_keysig_size (void)
|
||||
{
|
||||
T (Trace t ("Options::get_max_keysig_size");)
|
||||
return total_keysig_size;
|
||||
}
|
||||
|
||||
/* Sets total distinct key positions. */
|
||||
INLINE void
|
||||
Options::set_keysig_size (int size)
|
||||
{
|
||||
T (Trace t ("Options::set_keysig_size");)
|
||||
total_keysig_size = size;
|
||||
}
|
||||
|
||||
/* Returns the jump value. */
|
||||
INLINE int
|
||||
Options::get_jump (void)
|
||||
{
|
||||
T (Trace t ("Options::get_jump");)
|
||||
return jump;
|
||||
}
|
||||
|
||||
/* Returns the generated function name. */
|
||||
INLINE const char *
|
||||
Options::get_function_name (void)
|
||||
{
|
||||
T (Trace t ("Options::get_function_name");)
|
||||
return function_name;
|
||||
}
|
||||
|
||||
/* Returns the keyword key name. */
|
||||
INLINE const char *
|
||||
Options::get_key_name (void)
|
||||
{
|
||||
T (Trace t ("Options::get_key_name");)
|
||||
return key_name;
|
||||
}
|
||||
|
||||
/* Returns the hash function name. */
|
||||
INLINE const char *
|
||||
Options::get_hash_name (void)
|
||||
{
|
||||
T (Trace t ("Options::get_hash_name");)
|
||||
return hash_name;
|
||||
}
|
||||
|
||||
/* Returns the hash table array name. */
|
||||
INLINE const char *
|
||||
Options::get_wordlist_name (void)
|
||||
{
|
||||
T (Trace t ("Options::get_wordlist_name");)
|
||||
return wordlist_name;
|
||||
}
|
||||
|
||||
/* Returns the generated class name. */
|
||||
INLINE const char *
|
||||
Options::get_class_name (void)
|
||||
{
|
||||
T (Trace t ("Options::get_class_name");)
|
||||
return class_name;
|
||||
}
|
||||
|
||||
/* Returns the initial associated character value. */
|
||||
INLINE int
|
||||
Options::initial_value (void)
|
||||
{
|
||||
T (Trace t ("Options::initial_value");)
|
||||
return initial_asso_value;
|
||||
}
|
||||
|
||||
/* Returns the iterations value. */
|
||||
INLINE int
|
||||
Options::get_iterations (void)
|
||||
{
|
||||
T (Trace t ("Options::get_iterations");)
|
||||
return iterations;
|
||||
}
|
||||
|
||||
/* Returns the string used to delimit keywords from other attributes. */
|
||||
INLINE const char *
|
||||
Options::get_delimiter ()
|
||||
{
|
||||
T (Trace t ("Options::get_delimiter");)
|
||||
return delimiters;
|
||||
}
|
||||
|
||||
/* Gets the total number of switch statements to generate. */
|
||||
INLINE int
|
||||
Options::get_total_switches ()
|
||||
{
|
||||
T (Trace t ("Options::get_total_switches");)
|
||||
return total_switches;
|
||||
}
|
||||
97
src/read-line.cc
Normal file
97
src/read-line.cc
Normal file
@@ -0,0 +1,97 @@
|
||||
/* Correctly reads an arbitrarily size string.
|
||||
|
||||
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 "read-line.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* declares memcpy() */
|
||||
#include "options.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Recursively fills up the buffer. */
|
||||
|
||||
#define CHUNK_SIZE 4096
|
||||
|
||||
/* CHUNKS is the number of chunks (each of size CHUNK_SIZE) which have
|
||||
already been read and which are temporarily stored on the stack.
|
||||
This function reads the remainder of the line, allocates a buffer
|
||||
for the entire line, fills the part beyond &buffer[chunks*CHUNK_SIZE],
|
||||
and returns &buffer[chunks*CHUNK_SIZE]. */
|
||||
|
||||
char *
|
||||
Read_Line::readln_aux (int chunks)
|
||||
{
|
||||
T (Trace t ("Read_Line::readln_aux");)
|
||||
#if LARGE_STACK
|
||||
char buf[CHUNK_SIZE];
|
||||
#else
|
||||
// Note: we don't use new, because that invokes a custom operator new.
|
||||
char *buf = (char*)malloc(CHUNK_SIZE);
|
||||
if (buf == NULL)
|
||||
abort ();
|
||||
#endif
|
||||
char *bufptr = buf;
|
||||
char *ptr;
|
||||
int c;
|
||||
|
||||
while (c = getc (fp), c != EOF && c != '\n') /* fill the current buffer */
|
||||
{
|
||||
*bufptr++ = c;
|
||||
if (bufptr - buf == CHUNK_SIZE)
|
||||
{
|
||||
if ((ptr = readln_aux (chunks + 1)) != NULL)
|
||||
|
||||
/* prepend remainder to ptr buffer */
|
||||
{
|
||||
ptr -= CHUNK_SIZE;
|
||||
memcpy (ptr, buf, CHUNK_SIZE);
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (c == EOF && bufptr == buf && chunks == 0)
|
||||
ptr = NULL;
|
||||
else
|
||||
{
|
||||
size_t s1 = chunks * CHUNK_SIZE;
|
||||
size_t s2 = bufptr - buf;
|
||||
|
||||
ptr = new char[s1+s2+1];
|
||||
ptr += s1;
|
||||
ptr[s2] = '\0';
|
||||
memcpy (ptr, buf, s2);
|
||||
}
|
||||
done:
|
||||
#if !LARGE_STACK
|
||||
free (buf);
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#ifndef __OPTIMIZE__
|
||||
|
||||
#define INLINE /* not inline */
|
||||
#include "read-line.icc"
|
||||
#undef INLINE
|
||||
|
||||
#endif /* not defined __OPTIMIZE__ */
|
||||
53
src/read-line.h
Normal file
53
src/read-line.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* This may look like C code, but it is really -*- C++ -*- */
|
||||
|
||||
/* Reads arbitrarily long string from input file, returning it as a
|
||||
dynamically allocated buffer.
|
||||
|
||||
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. */
|
||||
|
||||
/* Returns a pointer to an arbitrary length string. Returns NULL on error or EOF
|
||||
The storage for the string is dynamically allocated by new. */
|
||||
|
||||
#ifndef read_line_h
|
||||
#define read_line_h 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class Read_Line
|
||||
{
|
||||
private:
|
||||
char *readln_aux (int chunks);
|
||||
FILE *fp; /* FILE pointer to the input stream. */
|
||||
|
||||
public:
|
||||
Read_Line (FILE *stream = stdin) : fp (stream) {}
|
||||
char *get_line (void);
|
||||
};
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
|
||||
#include "trace.h"
|
||||
#define INLINE inline
|
||||
#include "read-line.icc"
|
||||
#undef INLINE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
src/read-line.icc
Normal file
47
src/read-line.icc
Normal file
@@ -0,0 +1,47 @@
|
||||
/* Inline Functions for read-line.{h,cc}.
|
||||
|
||||
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. */
|
||||
|
||||
// This needs:
|
||||
//#include <stdio.h>
|
||||
//#include "trace.h"
|
||||
|
||||
/* Returns the ``next'' line, ignoring comments beginning with '#'. */
|
||||
INLINE char *
|
||||
Read_Line::get_line (void)
|
||||
{
|
||||
T (Trace t ("Read_Line::get_line");)
|
||||
int c;
|
||||
|
||||
while ((c = getc (fp)) == '#')
|
||||
{
|
||||
while (c = getc (fp), c != EOF && c != '\n')
|
||||
;
|
||||
|
||||
if (c == EOF)
|
||||
return (char *)0;
|
||||
}
|
||||
|
||||
if (c == EOF)
|
||||
return (char *)0;
|
||||
|
||||
ungetc (c, stdin);
|
||||
return readln_aux (0);
|
||||
}
|
||||
35
src/trace.cc
Normal file
35
src/trace.cc
Normal file
@@ -0,0 +1,35 @@
|
||||
/* Tracing function calls.
|
||||
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 "trace.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int Trace::nesting = 0;
|
||||
|
||||
Trace::Trace (const char *n)
|
||||
{
|
||||
fprintf (stderr, "%*scalling %s\n", 3 * nesting++, "", name = n);
|
||||
}
|
||||
|
||||
Trace::~Trace (void)
|
||||
{
|
||||
fprintf (stderr, "%*sleaving %s\n", 3 * --nesting, "", name);
|
||||
}
|
||||
40
src/trace.h
Normal file
40
src/trace.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* Tracing function calls.
|
||||
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. */
|
||||
|
||||
#ifndef trace_h
|
||||
#define trace_h 1
|
||||
|
||||
#ifdef TRACE
|
||||
#define T(X) X
|
||||
#else
|
||||
#define T(X)
|
||||
#endif
|
||||
|
||||
class Trace
|
||||
{
|
||||
private:
|
||||
static int nesting;
|
||||
const char *name;
|
||||
public:
|
||||
Trace (const char *n);
|
||||
~Trace (void);
|
||||
};
|
||||
|
||||
#endif
|
||||
25
src/vectors.cc
Normal file
25
src/vectors.cc
Normal file
@@ -0,0 +1,25 @@
|
||||
/* Static class data members that are shared between several classes.
|
||||
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 "vectors.h"
|
||||
|
||||
int Vectors::ALPHA_SIZE = MAX_ALPHA_SIZE;
|
||||
int Vectors::occurrences[MAX_ALPHA_SIZE];
|
||||
int Vectors::asso_values[MAX_ALPHA_SIZE];
|
||||
37
src/vectors.h
Normal file
37
src/vectors.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* This may look like C code, but it is really -*- C++ -*- */
|
||||
|
||||
/* Static class data members that are shared between several classes via
|
||||
inheritance.
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef vectors_h
|
||||
#define vectors_h 1
|
||||
|
||||
static const int MAX_ALPHA_SIZE = 256;
|
||||
|
||||
struct Vectors
|
||||
{
|
||||
static int ALPHA_SIZE; /* Size of alphabet. */
|
||||
static int occurrences[MAX_ALPHA_SIZE]; /* Counts occurrences of each key set character. */
|
||||
static int asso_values[MAX_ALPHA_SIZE]; /* Value associated with each character. */
|
||||
};
|
||||
|
||||
#endif
|
||||
22
src/version.cc
Normal file
22
src/version.cc
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Current program version number.
|
||||
|
||||
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. */
|
||||
|
||||
const char *version_string = "2.7";
|
||||
23
src/version.h
Normal file
23
src/version.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Current program version number.
|
||||
|
||||
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. */
|
||||
|
||||
/* Current release version. */
|
||||
extern const char *version_string;
|
||||
Reference in New Issue
Block a user