Zap old files no longer included in gperf 2.7

This commit is contained in:
Kris Kennaway 2000-03-25 08:25:58 +00:00
parent 99fee5f91c
commit 3f8f00575d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=58555
29 changed files with 0 additions and 4779 deletions

View File

@ -1,41 +0,0 @@
# Copyright (C) 1989 Free Software Foundation, Inc.
# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
#
# This file is part of GNU GPERF.
#
# GNU GPERF is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 1, or (at your option)
# any later version.
#
# GNU GPERF is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU GPERF; see the file COPYING. If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
GPERF = ../src/gperf
all: gperf tests
gperf:
(cd src; $(MAKE))
tests: gperf
(cd tests; $(MAKE) GPERF=$(GPERF))
distrib:
(cd ..; rm -f cperf.tar.Z; tar cvf cperf.tar cperf; compress cperf.tar; uuencode cperf.tar.Z < cperf.tar.Z > CSHAR)
clean:
(cd src; $(MAKE) clean)
(cd tests; $(MAKE) clean)
realclean:
(cd src; $(MAKE) realclean)
(cd tests; $(MAKE) clean)
-rm -f gperf.info* gperf.?? gperf.??s gperf.log gperf.toc \
gperf.*aux *inset.c *out gperf

View File

@ -1,8 +0,0 @@
Note: Just for clarification, this version of `gperf' is written in
portable K&R C. The `gperf' supplied in the top-level libg++ directory on
this distribution tape is written in C++. Either will generate output for
C or C++, so which one to compile is up to you.
--Noah Friedman, GNU tape distribution maintainer.
friedman@prep.ai.mit.edu
December 24, 1991

View File

@ -1,23 +0,0 @@
.TH GPERF 1 "December 16, 1988
.UC 4
.SH NAME
gperf \- generate a perfect hash function from a key set
.SH SYNOPSIS
.B gperf
[
.B \-adghijklnoprsStv
] [
.I keyfile
]
.SH DESCRIPTION
\fIgperf\fP reads a set of ``keys'' from \fIkeyfile\fP (or, by
default, from the standard input) and attempts to find a non-minimal
perfect hashing function that recognizes a member of the key set in
constant, i.e., O(1), time. If such a function is found the program
generates a pair of \fIC\fP source code routines that perform the
hashing and table lookup. All generated code is directed to the
standard output.
Please refer to the \fIgperf.texinfo\fP file for more information.
This file is distributed with \fIgperf\fP release.

File diff suppressed because it is too large Load Diff

View File

@ -1,77 +0,0 @@
# Copyright (C) 1989 Free Software Foundation, Inc.
# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
#
# This file is part of GNU GPERF.
#
# GNU GPERF is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 1, or (at your option)
# any later version.
#
# GNU GPERF is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU GPERF; see the file COPYING. If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
CC = gcc
DFLAGS= -DLO_CAL -DGATHER_STATISTICS #-DRLIMIT_STACK
OFLAGS= -O -p -g -fstrength-reduce -fomit-frame-pointer -fdelayed-branch -finline-functions # gcc options
CFLAGS= $(DFLAGS) $(OFLAGS)
OBJS = options.o iterator.o main.o perfect.o keylist.o listnode.o xmalloc.o \
hashtable.o boolarray.o readline.o stderr.o version.o getopt.o
SOURCES = options.c iterator.c main.c perfect.c keylist.c listnode.c xmalloc.c \
hashtable.c boolarray.c readline.c stderr.c version.c getopt.c
all: gperf
gperf: $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
clean:
-rm -f *.o core *~ #*#
realclean: clean
-rm -f gperf
# dependencies
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
boolarray.o: boolarray.c /usr/include/stdio.h boolarray.h prototype.h options.h
boolarray.o: /usr/include/stdio.h prototype.h
getopt.o: getopt.c /usr/include/stdio.h
hashtable.o: hashtable.c /usr/include/stdio.h hashtable.h keylist.h
hashtable.o: /usr/include/stdio.h listnode.h prototype.h prototype.h options.h
hashtable.o: /usr/include/stdio.h prototype.h
iterator.o: iterator.c /usr/include/stdio.h /usr/include/ctype.h iterator.h
iterator.o: prototype.h
keylist.o: keylist.c /usr/include/assert.h /usr/include/stdio.h options.h
keylist.o: /usr/include/stdio.h prototype.h readline.h prototype.h keylist.h
keylist.o: /usr/include/stdio.h listnode.h prototype.h hashtable.h keylist.h
keylist.o: prototype.h stderr.h prototype.h /usr/include/varargs.h
listnode.o: listnode.c /usr/include/stdio.h options.h /usr/include/stdio.h
listnode.o: prototype.h listnode.h prototype.h stderr.h prototype.h
listnode.o: /usr/include/varargs.h
main.o: main.c /usr/include/stdio.h stderr.h prototype.h /usr/include/varargs.h
main.o: options.h /usr/include/stdio.h prototype.h perfect.h prototype.h
main.o: keylist.h /usr/include/stdio.h listnode.h prototype.h boolarray.h
main.o: prototype.h
options.o: options.c /usr/include/stdio.h /usr/include/assert.h options.h
options.o: /usr/include/stdio.h prototype.h iterator.h prototype.h stderr.h
options.o: prototype.h /usr/include/varargs.h
perfect.o: perfect.c /usr/include/stdio.h /usr/include/assert.h
perfect.o: /usr/include/ctype.h options.h /usr/include/stdio.h prototype.h
perfect.o: perfect.h prototype.h keylist.h /usr/include/stdio.h listnode.h
perfect.o: prototype.h boolarray.h prototype.h stderr.h prototype.h
perfect.o: /usr/include/varargs.h
readline.o: readline.c /usr/include/stdio.h readline.h prototype.h
stderr.o: stderr.c /usr/include/stdio.h stderr.h prototype.h
stderr.o: /usr/include/varargs.h
version.o: version.c
xmalloc.o: xmalloc.c /usr/include/stdio.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY

View File

@ -1,90 +0,0 @@
/* Fast lookup table abstraction implemented as a Guilmette Array
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "boolarray.h"
#include "options.h"
/* Locally visible BOOL_ARRAY object. */
static BOOL_ARRAY bool_array;
/* Prints out debugging diagnostics. */
void
bool_array_destroy ()
{
if (OPTION_ENABLED (option, DEBUG))
fprintf (stderr, "\ndumping boolean array information\niteration number = %d\nend of array dump\n",
bool_array.iteration_number);
free ((char *) bool_array.storage_array);
}
void
bool_array_init (size)
int size;
{
STORAGE_TYPE *xmalloc ();
bool_array.iteration_number = 1;
bool_array.size = size;
bool_array.storage_array = xmalloc (size * sizeof *bool_array.storage_array);
bzero (bool_array.storage_array, size * sizeof *bool_array.storage_array);
if (OPTION_ENABLED (option, DEBUG))
fprintf (stderr, "\nbool array size = %d, total bytes = %d\n",
bool_array.size, bool_array.size * sizeof *bool_array.storage_array);
}
bool
lookup (index)
int index;
{
if (bool_array.storage_array[index] == bool_array.iteration_number)
return 1;
else
{
bool_array.storage_array[index] = bool_array.iteration_number;
return 0;
}
}
/* Simple enough to reset, eh?! */
void
bool_array_reset ()
{
/* If we wrap around it's time to zero things out again! */
if (++bool_array.iteration_number == 0)
{
if (OPTION_ENABLED (option, DEBUG))
{
fprintf (stderr, "(re-initializing bool_array)...");
fflush (stderr);
}
bool_array.iteration_number = 1;
bzero (bool_array.storage_array, bool_array.size * sizeof *bool_array.storage_array);
if (OPTION_ENABLED (option, DEBUG))
{
fprintf (stderr, "done\n");
fflush (stderr);
}
}
}

View File

@ -1,48 +0,0 @@
/* Simple lookup table abstraction implemented as a Guilmette Array.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Define and implement a simple boolean array abstraction,
uses a Guilmette array implementation to save on initialization time. */
#ifndef _boolarray_h
#define _boolarray_h
#include "prototype.h"
#ifdef LO_CAL
/* If we are on a memory diet then we'll only make these use a limited
amount of storage space. */
typedef unsigned short STORAGE_TYPE;
#else
typedef int STORAGE_TYPE;
#endif
typedef struct bool_array
{
STORAGE_TYPE *storage_array; /* Initialization of the index space. */
STORAGE_TYPE iteration_number; /* Keep track of the current iteration. */
int size; /* Size of the entire array (dynamically initialized). */
} BOOL_ARRAY;
extern void bool_array_init P ((int size));
extern void bool_array_destroy P ((void));
extern bool lookup P ((int hash_value));
extern void bool_array_reset P ((void));
#endif /* _boolarray_h */

View File

@ -1,413 +0,0 @@
/* Getopt for GNU.
Copyright (C) 1987, 1989 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As `getopt' works, it permutes the elements of `argv' so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include <stdio.h>
#ifdef sparc
#include <alloca.h>
#endif
#ifdef USG
#define bcopy(s, d, l) memcpy((d), (s), (l))
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg = 0;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
int optind = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int opterr = 1;
/* Describe how to deal with options that follow non-option ARGV-elements.
UNSPECIFIED means the caller did not specify anything;
the default is then REQUIRE_ORDER if the environment variable
_OPTIONS_FIRST is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options.
Stop option processing when the first non-option is seen.
This is what Unix does.
PERMUTE is the default. We permute the contents of `argv' as we scan,
so that eventually all the options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code zero.
Using `-' as the first character of the list of option characters
requests this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void
exchange (argv)
char **argv;
{
int nonopts_size
= (last_nonopt - first_nonopt) * sizeof (char *);
char **temp = (char **) alloca (nonopts_size);
/* Interchange the two blocks of data in argv. */
bcopy (&argv[first_nonopt], temp, nonopts_size);
bcopy (&argv[last_nonopt], &argv[first_nonopt],
(optind - last_nonopt) * sizeof (char *));
bcopy (temp, &argv[first_nonopt + optind - last_nonopt],
nonopts_size);
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of theoption characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns `EOF'.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
A colon in OPTSTRING means that the previous character is an option
that wants an argument. The argument is taken from the rest of the
current ARGV-element, or from the following ARGV-element,
and returned in `optarg'.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg'.
If OPTSTRING starts with `-', it requests a different method of handling the
non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
int
getopt (argc, argv, optstring)
int argc;
char **argv;
char *optstring;
{
/* Initialize the internal data when the first call is made.
Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
if (optind == 0)
{
first_nonopt = last_nonopt = optind = 1;
nextchar = 0;
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
ordering = RETURN_IN_ORDER;
else if (getenv ("_POSIX_OPTION_ORDER") != 0)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
}
if (nextchar == 0 || *nextchar == 0)
{
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange (argv);
else if (last_nonopt != optind)
first_nonopt = optind;
/* Now skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc
&& (argv[optind][0] != '-'
|| argv[optind][1] == 0))
optind++;
last_nonopt = optind;
}
/* Special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange (argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return EOF;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if (argv[optind][0] != '-' || argv[optind][1] == 0)
{
if (ordering == REQUIRE_ORDER)
return EOF;
optarg = argv[optind++];
return 0;
}
/* We have found another option-ARGV-element.
Start decoding its characters. */
nextchar = argv[optind] + 1;
}
/* Look at and handle the next option-character. */
{
char c = *nextchar++;
char *temp = (char *) index (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == 0)
optind++;
if (temp == 0 || c == ':')
{
if (opterr != 0)
{
if (c < 040 || c >= 0177)
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
argv[0], c);
else
fprintf (stderr, "%s: unrecognized option `-%c'\n",
argv[0], c);
}
return '?';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != 0)
{
optarg = nextchar;
optind++;
}
else
optarg = 0;
nextchar = 0;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != 0)
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr != 0)
fprintf (stderr, "%s: no argument for `-%c' option\n",
argv[0], c);
c = '?';
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = 0;
}
}
return c;
}
}
#ifdef TEST
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
int
main (argc, argv)
int argc;
char **argv;
{
char c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind;
if ((c = getopt (argc, argv, "abc:d:0123456789")) == EOF)
break;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
return 0;
}
#endif /* TEST */

View File

@ -1,22 +0,0 @@
1. provide output diagnostics that explain how many input keys total,
how many after dealing with static links, and finally, after the
algorithm is complete, how many dynamic duplicates do we now
have.
2. fix up GATHER_STATISTICS for all instrumentation.
3. Useful idea:
a. Generate the wordlist as a contiguous block of keywords, as before.
This wordlist *must* be sorted by hash value.
b. generate the lookup_array, which are an array of signed {chars,shorts,ints},
which ever allows full coverage of the wordlist dimensions. If the
value v, where v = lookup_array[hash(str,len)], is >= 0, then we
simply use this result as a direct access into wordlist to snag
the keyword for comparison.
c. Otherwise, if v is < 0 this is an indication that we'll need to
search through some number of duplicates hash values. Using a
hash linking scheme we'd then index into a duplicate_address
table that would provide the starting index and total length of
the duplicate entries to consider sequentially.

View File

@ -1,132 +0,0 @@
/* Hash table for checking keyword links. Implemented using double hashing.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "hashtable.h"
#include "options.h"
#ifdef GATHER_STATISTICS
/* Find out how well our double hashing is working! */
static collisions = 0;
#endif
/* Locally visible hash table. */
static HASH_TABLE hash_table;
/* Basically the algorithm from the Dragon book. */
static unsigned
hash_pjw (str)
char *str;
{
char *temp;
unsigned g, h = 0;
for (temp = str; *temp; temp++)
{
h = (h << 4) + (*temp * 13);
if (g = h & 0xf0000000)
{
h ^= (g >> 24);
h ^= g;
}
}
return h;
}
/* The size of the hash table is always the smallest power of 2 >= the size
indicated by the user. This allows several optimizations, including
the use of double hashing and elimination of the mod instruction.
Note that the size had better be larger than the number of items
in the hash table, else there's trouble!!! Note that the memory
for the hash table is allocated *outside* the intialization routine.
This compromises information hiding somewhat, but greatly reduces
memory fragmentation, since we can now use alloca! */
void
hash_table_init (table, s)
LIST_NODE **table;
int s;
{
hash_table.size = s;
hash_table.table = table;
bzero ((char *) hash_table.table, hash_table.size * sizeof *hash_table.table);
}
/* Frees the dynamically allocated table. Note that since we don't
really need this space anymore, and since it is potentially quite
big it is best to return it when we are done. */
void
hash_table_destroy ()
{
if (OPTION_ENABLED (option, DEBUG))
{
int i;
fprintf (stderr, "\ndumping the hash table\ntotal elements = %d, bytes = %d\n",
hash_table.size, hash_table.size * sizeof *hash_table.table);
for (i = hash_table.size - 1; i >= 0; i--)
if (hash_table.table[i])
fprintf (stderr, "location[%d] has charset \"%s\" and keyword \"%s\"\n",
i, hash_table.table[i]->char_set, hash_table.table[i]->key);
#ifdef GATHER_STATISTICS
fprintf (stderr, "\ntotal collisions during hashing = %d\n", collisions);
#endif
fprintf (stderr, "end dumping hash table\n\n");
}
}
/* If the ITEM is already in the hash table return the item found
in the table. Otherwise inserts the ITEM, and returns FALSE.
Uses double hashing. */
LIST_NODE *
retrieve (item, ignore_length)
LIST_NODE *item;
int ignore_length;
{
unsigned hash_val = hash_pjw (item->char_set);
int probe = hash_val & hash_table.size - 1;
int increment = (hash_val ^ item->length | 1) & hash_table.size - 1;
while (hash_table.table[probe]
&& (strcmp (hash_table.table[probe]->char_set, item->char_set)
|| (!ignore_length && hash_table.table[probe]->length != item->length)))
{
#ifdef GATHER_STATISTICS
collisions++;
#endif
probe = probe + increment & hash_table.size - 1;
}
if (hash_table.table[probe])
return hash_table.table[probe];
else
{
hash_table.table[probe] = item;
return 0;
}
}

View File

@ -1,37 +0,0 @@
/* Hash table used to check for duplicate keyword entries.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _hashtable_h
#define _hashtable_h
#include "keylist.h"
#include "prototype.h"
typedef struct hash_table
{
LIST_NODE **table; /* Vector of pointers to linked lists of List_Node's. */
int size; /* Size of the vector. */
} HASH_TABLE;
extern void hash_table_init P ((LIST_NODE **table, int size));
extern void hash_table_destroy P ((void));
extern LIST_NODE *retrieve P ((LIST_NODE *item, int ignore_length));
#endif /* _hashtable_h */

View File

@ -1,106 +0,0 @@
/* Provides an Iterator for keyword characters.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <ctype.h>
#include "iterator.h"
/* Locally visible ITERATOR object. */
ITERATOR iterator;
/* Constructor for ITERATOR. */
void
iterator_init (s, lo, hi, word_end, bad_val, key_end)
char *s;
int lo;
int hi;
int word_end;
int bad_val;
int key_end;
{
iterator.end = key_end;
iterator.error_value = bad_val;
iterator.end_word = word_end;
iterator.str = s;
iterator.hi_bound = hi;
iterator.lo_bound = lo;
}
/* Define several useful macros to clarify subsequent code. */
#define ISPOSDIGIT(X) ((X)<='9'&&(X)>'0')
#define TODIGIT(X) ((X)-'0')
/* Provide an Iterator, returning the ``next'' value from
the list of valid values given in the constructor. */
int
next ()
{
/* Variables to record the Iterator's status when handling ranges, e.g., 3-12. */
static int size;
static int curr_value;
static int upper_bound;
if (size)
{
if (++curr_value >= upper_bound)
size = 0;
return curr_value;
}
else
{
while (*iterator.str)
{
if (*iterator.str == ',')
iterator.str++;
else if (*iterator.str == '$')
{
iterator.str++;
return iterator.end_word;
}
else if (ISPOSDIGIT (*iterator.str))
{
for (curr_value = 0; isdigit (*iterator.str); iterator.str++)
curr_value = curr_value * 10 + *iterator.str - '0';
if (*iterator.str == '-')
{
for (size = 1, upper_bound = 0;
isdigit (*++iterator.str);
upper_bound = upper_bound * 10 + *iterator.str - '0');
if (upper_bound <= curr_value || upper_bound > iterator.hi_bound)
return iterator.error_value;
}
return curr_value >= iterator.lo_bound && curr_value <= iterator.hi_bound
? curr_value : iterator.error_value;
}
else
return iterator.error_value;
}
return iterator.end;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +0,0 @@
/* Data and function member declarations for the keyword list class.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* The key word list is a useful abstraction that keeps track of
various pieces of information that enable that fast generation
of the Perfect.hash function. A Key_List is a singly-linked
list of List_Nodes. */
#ifndef _keylist_h
#define _keylist_h
#include <stdio.h>
#include "listnode.h"
typedef struct key_list
{
LIST_NODE *head; /* Points to the head of the linked list. */
char *array_type; /* Pointer to the type for word list. */
char *return_type; /* Pointer to return type for lookup function. */
char *struct_tag; /* Shorthand for user-defined struct tag type. */
char *include_src; /* C source code to be included verbatim. */
int list_len; /* Length of head's Key_List, not counting duplicates. */
int total_keys; /* Total number of keys, counting duplicates. */
int max_key_len; /* Maximum length of the longest keyword. */
int min_key_len; /* Minimum length of the shortest keyword. */
bool occurrence_sort; /* True if sorting by occurrence. */
bool hash_sort; /* True if sorting by hash value. */
bool additional_code; /* True if any additional C code is included. */
} KEY_LIST;
extern void key_list_init P ((void));
extern void key_list_destroy P ((void));
extern void print_output P ((void));
extern int keyword_list_length P ((void));
extern int max_key_length P ((void));
extern KEY_LIST key_list;
#endif /* _keylist_h */

View File

@ -1,111 +0,0 @@
/* Creates and initializes a new list node.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "options.h"
#include "listnode.h"
#include "stderr.h"
/* See comments in perfect.cc. */
extern int occurrences[ALPHABET_SIZE];
/* Sorts the key set alphabetically to speed up subsequent operations.
Uses insertion sort since the set is probably quite small. */
static void
set_sort (base, len)
char *base;
int len;
{
int i, j;
for (i = 0, j = len - 1; i < j; i++)
{
char curr, tmp;
for (curr = i + 1, tmp = base[curr]; curr > 0 && tmp < base[curr-1]; curr--)
base[curr] = base[curr - 1];
base[curr] = tmp;
}
}
/* Initializes a List_Node. This requires obtaining memory for the KEY_SET
initializing them using the information stored in the
KEY_POSITIONS array in Options, and checking for simple errors.
It's important to note that KEY and REST are both pointers to
the different offsets into the same block of dynamic memory pointed to
by parameter K. The data member REST is used to store any additional fields
of the input file (it is set to the "" string if Option[TYPE] is not enabled).
This is useful if the user wishes to incorporate a lookup structure,
rather than just an array of keys. */
LIST_NODE *
make_list_node (k, len)
char *k;
int len;
{
LIST_NODE *buffered_malloc ();
int char_set_size = OPTION_ENABLED (option, ALLCHARS) ? len : GET_CHARSET_SIZE (option) + 1;
LIST_NODE *temp = buffered_malloc (sizeof (LIST_NODE) + char_set_size);
char *ptr = temp->char_set;
k[len] = '\0'; /* Null terminate KEY to separate it from REST. */
temp->key = k;
temp->next = 0;
temp->index = 0;
temp->length = len;
temp->link = 0;
temp->rest = OPTION_ENABLED (option, TYPE) ? k + len + 1 : "";
if (OPTION_ENABLED (option, ALLCHARS)) /* Use all the character position in the KEY. */
for (; *k; k++, ptr++)
++occurrences[*ptr = *k];
else /* Only use those character positions specified by the user. */
{
int i;
/* Iterate thru the list of key_positions, initializing occurrences table
and temp->char_set (via char * pointer ptr). */
for(RESET (option); (i = GET (option)) != EOS; )
{
if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */
*ptr = temp->key[len - 1];
else if (i <= len) /* Within range of KEY length, so we'll keep it. */
*ptr = temp->key[i - 1];
else /* Out of range of KEY length, so we'll just skip it. */
continue;
++occurrences[*ptr++];
}
if (ptr == temp->char_set) /* Didn't get any hits, i.e., no usable positions. */
report_error ("can't hash keyword %s with chosen key positions\n%a", temp->key);
}
*ptr = '\0'; /* Terminate this bastard.... */
/* Sort the KEY_SET items alphabetically. */
set_sort (temp->char_set, ptr - temp->char_set);
return temp;
}

View File

@ -1,43 +0,0 @@
/* Data and function members for defining values and operations of a list node.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _listnode_h
#define _listnode_h
#include "prototype.h"
#define ALPHABET_SIZE 128
typedef struct list_node
{
struct list_node *link; /* TRUE if key has an identical KEY_SET as another key. */
struct list_node *next; /* Points to next element on the list. */
int length; /* Length of the key. */
int hash_value; /* Hash value for the key. */
int occurrence; /* A metric for frequency of key set occurrences. */
int index; /* Position of this node relative to other nodes. */
char *key; /* Key string. */
char *rest; /* Additional information for building hash function. */
char char_set[1]; /* Set of characters to hash, specified by user. */
} LIST_NODE;
extern LIST_NODE *make_list_node P ((char *k, int len));
#endif _listnode_h

View File

@ -1,96 +0,0 @@
/* Driver program for the Perfect hash function generator.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Simple driver program for the Perfect.hash function generator.
Most of the hard work is done in class Perfect and its class methods. */
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include "stderr.h"
#include "options.h"
#include "perfect.h"
/* Calls the appropriate intialization routines for each
ADT. Note that certain initialization routines require
initialization *after* certain values are computed. Therefore,
they cannot be called here. */
static void
init_all (argc, argv)
int argc;
char *argv[];
{
#ifdef RLIMIT_STACK
/* Get rid of any avoidable limit on stack size. */
{
struct rlimit rlim;
/* Set the stack limit huge so that alloca does not fail. */
getrlimit (RLIMIT_STACK, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit (RLIMIT_STACK, &rlim);
}
#endif /* RLIMIT_STACK */
options_init (argc, argv);
key_list_init ();
perfect_init ();
}
/* Calls appropriate destruction routines for each ADT. These
routines print diagnostics if the debugging option is enabled. */
static void
destroy_all ()
{
options_destroy ();
key_list_destroy ();
perfect_destroy ();
}
/* Driver for perfect hash function generation. */
int
main (argc, argv)
int argc;
char *argv[];
{
struct tm *tm;
time_t clock;
int status;
time (&clock);
tm = localtime (&clock);
fprintf (stderr, "/* starting time is %d:%d:%d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
/* Sets the options. */
init_all (argc, argv);
/* Generates the perfect hash table.
Also prints generated code neatly to the output. */
status = perfect_generate ();
destroy_all ();
time (&clock);
tm = localtime (&clock);
fprintf (stderr, "/* ending time is %d:%d:%d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
return status;
}

View File

@ -1,444 +0,0 @@
/* Handles parsing the Options provided to the user.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <assert.h>
#include "options.h"
#include "iterator.h"
#include "stderr.h"
/* Current program version. */
extern char *version_string;
/* Size to jump on a collision. */
#define DEFAULT_JUMP_VALUE 5
/* Default name for generated lookup function. */
#define DEFAULT_NAME "in_word_set"
/* Default name for the key component. */
#define DEFAULT_KEY "name"
/* Default name for generated hash function. */
#define DEFAULT_HASH_NAME "hash"
/* Globally visible OPTIONS object. */
OPTIONS option;
/* Default delimiters that separate keywords from their attributes. */
#define DEFAULT_DELIMITERS ",\n"
/* Prints program usage to standard error stream. */
void
usage ()
{
report_error ("usage: %n [-acCdDef[num]gGhH<hashname>i<init>jk<keys>\
K<keyname>lnN<name>oprs<size>S<switches>tTv].\n(type %n -h for help)\n");
}
/* Sorts the key positions *IN REVERSE ORDER!!*
This makes further routines more efficient. Especially when generating code.
Uses a simple Insertion Sort since the set is probably ordered.
Returns 1 if there are no duplicates, 0 otherwise. */
static int
key_sort (base, len)
char *base;
int len;
{
int i, j;
for (i = 0, j = len - 1; i < j; i++)
{
int curr, tmp;
for (curr = i + 1,tmp = base[curr]; curr > 0 && tmp >= base[curr - 1]; curr--)
if ((base[curr] = base[curr - 1]) == tmp) /* oh no, a duplicate!!! */
return 0;
base[curr] = tmp;
}
return 1;
}
/* Dumps option status when debug is set. */
void
options_destroy ()
{
if (OPTION_ENABLED (option, DEBUG))
{
char *ptr;
fprintf (stderr, "\ndumping Options:\nDEBUG is.......: %s\nORDER is.......: %s\
\nANSI is........: %s\nTYPE is........: %s\nGNU is.........: %s\nRANDOM is......: %s\
\nDEFAULTCHARS is: %s\nSWITCH is......: %s\nPOINTER is.....: %s\nNOLENGTH is....: %s\
\nLENTABLE is....: %s\nDUP is.........: %s\nCOMP is........: %s\nFAST is........: %s\
\nNOTYPE is......: %s\nGLOBAL is......: %s\nCONST is.......: %s\niterations = %d\
\nlookup function name = %s\nhash function name = %s\nkey name = %s\
\njump value = %d\nmax associcated value = %d\ninitial associated value = %d\
\ndelimiters = %s\nnumber of switch statements = %d\napproximate switch statement size = %d\n",
OPTION_ENABLED (option, DEBUG) ? "enabled" : "disabled",
OPTION_ENABLED (option, ORDER) ? "enabled" : "disabled",
OPTION_ENABLED (option, ANSI) ? "enabled" : "disabled",
OPTION_ENABLED (option, TYPE) ? "enabled" : "disabled",
OPTION_ENABLED (option, GNU) ? "enabled" : "disabled",
OPTION_ENABLED (option, RANDOM) ? "enabled" : "disabled",
OPTION_ENABLED (option, DEFAULTCHARS) ? "enabled" : "disabled",
OPTION_ENABLED (option, SWITCH) ? "enabled" : "disabled",
OPTION_ENABLED (option, POINTER) ? "enabled" : "disabled",
OPTION_ENABLED (option, NOLENGTH) ? "enabled" : "disabled",
OPTION_ENABLED (option, LENTABLE) ? "enabled" : "disabled",
OPTION_ENABLED (option, DUP) ? "enabled" : "disabled",
OPTION_ENABLED (option, COMP) ? "enabled" : "disabled",
OPTION_ENABLED (option, FAST) ? "enabled" : "disabled",
OPTION_ENABLED (option, NOTYPE) ? "enabled" : "disabled",
OPTION_ENABLED (option, GLOBAL) ? "enabled" : "disabled",
OPTION_ENABLED (option, CONST) ? "enabled" : "disabled",
option.iterations, option.function_name, option.hash_name,
option.key_name, option.jump, option.size - 1,
option.initial_asso_value, option.delimiters, option.total_switches,
keyword_list_length () / option.total_switches);
if (OPTION_ENABLED (option, ALLCHARS))
fprintf (stderr, "all characters are used in the hash function\n");
fprintf (stderr, "maximum charset size = %d\nkey positions are: \n",
option.total_charset_size);
for (ptr = option.key_positions; *ptr != EOS; ptr++)
if (*ptr == WORD_END)
fprintf (stderr, "$\n");
else
fprintf (stderr, "%d\n", *ptr);
fprintf (stderr, "finished dumping Options\n");
}
}
/* Parses the command line Options and sets appropriate flags in option.option_word. */
void
options_init (argc, argv)
int argc;
char *argv[];
{
extern int optind;
extern char *optarg;
int option_char;
option.key_positions[0] = WORD_START;
option.key_positions[1] = WORD_END;
option.key_positions[2] = EOS;
option.total_charset_size = 2;
option.jump = DEFAULT_JUMP_VALUE;
option.option_word = (int) DEFAULTCHARS;
option.function_name = DEFAULT_NAME;
option.hash_name = DEFAULT_HASH_NAME;
option.key_name = DEFAULT_KEY;
option.delimiters = DEFAULT_DELIMITERS;
option.initial_asso_value = option.size = option.iterations = 0;
option.total_switches = 1;
option.argument_count = argc;
option.argument_vector = argv;
set_program_name (argv[0]);
while ((option_char = getopt (argc, argv, "adcCDe:f:gGhH:i:j:k:K:lnN:oprs:S:tTv")) != EOF)
{
switch (option_char)
{
case 'a': /* Generated coded uses the ANSI prototype format. */
{
SET_OPTION (option, ANSI);
break;
}
case 'c': /* Generate strncmp rather than strcmp. */
{
SET_OPTION (option, COMP);
break;
}
case 'C': /* Make the generated tables readonly (const). */
{
SET_OPTION (option, CONST);
break;
}
case 'd': /* Enable debugging option. */
{
SET_OPTION (option, DEBUG);
report_error ("starting program %n, version %s, with debuggin on.\n",
version_string);
break;
}
case 'D': /* Enable duplicate option. */
{
SET_OPTION (option, DUP);
break;
}
case 'e': /* Allows user to provide keyword/attribute separator */
{
SET_DELIMITERS (option, optarg);
break;
}
case 'f': /* Generate the hash table ``fast.'' */
{
SET_OPTION (option, FAST);
if ((option.iterations = atoi (optarg)) < 0)
{
report_error ("iterations value must not be negative, assuming 0\n");
option.iterations = 0;
}
break;
}
case 'g': /* Use the ``inline'' keyword for generated sub-routines. */
{
SET_OPTION (option, GNU);
break;
}
case 'G': /* Make the keyword table a global variable. */
{
SET_OPTION (option, GLOBAL);
break;
}
case 'h': /* Displays a list of helpful Options to the user. */
{
report_error (
"-a\tGenerate ANSI standard C output code, i.e., function prototypes.\n\
-c\tGenerate comparison code using strncmp rather than strcmp.\n\
-C\tMake the contents of generated lookup tables constant, i.e., readonly.\n\
-d\tEnables the debugging option (produces verbose output to Std_Err).\n\
-D\tHandle keywords that hash to duplicate values. This is useful\n\
\tfor certain highly redundant keyword sets. It enables the -S option.\n\
-e\tAllow user to provide a string containing delimiters used to separate\n\
\tkeywords from their attributes. Default is \",\\n\"\n\
-f\tGenerate the perfect hash function ``fast.'' This decreases GPERF's\n\
\trunning time at the cost of minimizing generated table-size.\n\
\tThe numeric argument represents the number of times to iterate when\n\
\tresolving a collision. `0' means ``iterate by the number of keywords''.\n\
-g\tAssume a GNU compiler, e.g., g++ or gcc. This makes all generated\n\
\troutines use the ``inline'' keyword to remove cost of function calls.\n\
-G\tGenerate the static table of keywords as a static global variable,\n\
\trather than hiding it inside of the lookup function (which is the\n\
\tdefault behavior).\n\
-h\tPrints this mesage.\n");
report_error (
"-H\tAllow user to specify name of generated hash function. Default is `hash'.\n\
-i\tProvide an initial value for the associate values array. Default is 0.\n\
\tSetting this value larger helps inflate the size of the final table.\n\
-j\tAffects the ``jump value,'' i.e., how far to advance the associated\n\
\tcharacter value upon collisions. Must be an odd number, default is %d.\n\
-k\tAllows selection of the key positions used in the hash function.\n\
\tThe allowable choices range between 1-%d, inclusive. The positions\n\
\tare separated by commas, ranges may be used, and key positions may\n\
\toccur in any order. Also, the meta-character '*' causes the generated\n\
\thash function to consider ALL key positions, and $ indicates the\n\
\t``final character'' of a key, e.g., $,1,2,4,6-10.\n\
-K\tAllow user to select name of the keyword component in the keyword structure.\n\
-l\tCompare key lengths before trying a string comparison. This helps\n\
\tcut down on the number of string comparisons made during the lookup.\n\
-n\tDo not include the length of the keyword when computing the hash function\n\
-N\tAllow user to specify name of generated lookup function. Default\n\
\tname is `in_word_set.'\n\
-o\tReorders input keys by frequency of occurrence of the key sets.\n\
\tThis should decrease the search time dramatically.\n\
-p\tChanges the return value of the generated function ``in_word_set''\n\
\tfrom its default boolean value (i.e., 0 or 1), to type ``pointer\n\
\tto wordlist array'' This is most useful when the -t option, allowing\n\
\tuser-defined structs, is used.\n",
DEFAULT_JUMP_VALUE, MAX_KEY_POS - 1);
report_error (
"-r\tUtilizes randomness to initialize the associated values table.\n\
-s\tAffects the size of the generated hash table. The numeric argument\n\
\tfor this option indicates ``how many times larger'' the table range\n\
\tshould be, in relationship to the number of keys, e.g. a value of 3\n\
\tmeans ``make the table about 3 times larger than the number of input\n\
\tkeys.'' A larger table should decrease the time required for an\n\
\tunsuccessful search, at the expense of extra table space. Default\n\
\tvalue is 1. This actual table size may vary somewhat.\n\
-S\tCauses the generated C code to use a switch statement scheme, rather\n\
\tthan an array lookup table. This can lead to a reduction in both\n\
\ttime and space requirements for some keyfiles. The argument to\n\
\tthis option determines how many switch statements are generated.\n\
\tA value of 1 generates 1 switch containing all the elements, a value of 2\n\
\tgenerates 2 tables with 1/2 the elements in each table, etc. This\n\
\tis useful since many C compilers cannot correctly generate code for\n\
\tlarge switch statements.\n\
\tthe expense of longer time for each lookup. Mostly important for\n\
\t*large* input sets, i.e., greater than around 100 items or so.\n\
-t\tAllows the user to include a structured type declaration for \n\
\tgenerated code. Any text before %%%% is consider part of the type\n\
\tdeclaration. Key words and additional fields may follow this, one\n\
\tgroup of fields per line.\n\
-T\tPrevents the transfer of the type declaration to the output file.\n\
\tUse this option if the type is already defined elsewhere.\n\
-v\tPrints out the current version number\n%e%a\n",
usage);
}
case 'H': /* Sets the name for the hash function */
{
option.hash_name = optarg;
break;
}
case 'i': /* Sets the initial value for the associated values array. */
{
if ((option.initial_asso_value = atoi (optarg)) < 0)
report_error ("initial value %d must be non-zero, ignoring and continuing\n",
option.initial_asso_value);
if (OPTION_ENABLED (option, RANDOM))
report_error ("warning, -r option superceeds -i, ignoring -i option and continuing\n");
break;
}
case 'j': /* Sets the jump value, must be odd for later algorithms. */
{
if ((option.jump = atoi (optarg)) < 0)
report_error ("jump value %d must be a positive number\n%e%a",
option.jump, usage);
else if (option.jump && EVEN (option.jump))
report_error ("jump value %d should be odd, adding 1 and continuing...\n",
option.jump++);
break;
}
case 'k': /* Sets key positions used for hash function. */
{
int BAD_VALUE = -1;
int value;
iterator_init (optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS);
if (*optarg == '*') /* Use all the characters for hashing!!!! */
{
UNSET_OPTION (option, DEFAULTCHARS);
SET_OPTION (option, ALLCHARS);
}
else
{
char *key_pos;
for (key_pos = option.key_positions; (value = next ()) != EOS; key_pos++)
if (value == BAD_VALUE)
report_error ("illegal key value or range, use 1,2,3-%d,'$' or '*'.\n%e%a",
(MAX_KEY_POS - 1),usage);
else
*key_pos = value;;
*key_pos = EOS;
if (! (option.total_charset_size = (key_pos - option.key_positions)))
report_error ("no keys selected\n%e%a", usage);
else if (! key_sort (option.key_positions, option.total_charset_size))
report_error ("duplicate keys selected\n%e%a", usage);
if (option.total_charset_size != 2
|| (option.key_positions[0] != 1 || option.key_positions[1] != WORD_END))
UNSET_OPTION (option, DEFAULTCHARS);
}
break;
}
case 'K': /* Make this the keyname for the keyword component field. */
{
option.key_name = optarg;
break;
}
case 'l': /* Create length table to avoid extra string compares. */
{
SET_OPTION (option, LENTABLE);
break;
}
case 'n': /* Don't include the length when computing hash function. */
{
SET_OPTION (option, NOLENGTH);
break;
}
case 'N': /* Make generated lookup function name be optarg */
{
option.function_name = optarg;
break;
}
case 'o': /* Order input by frequency of key set occurrence. */
{
SET_OPTION (option, ORDER);
break;
}
case 'p': /* Generated lookup function now a pointer instead of int. */
{
SET_OPTION (option, POINTER);
break;
}
case 'r': /* Utilize randomness to initialize the associated values table. */
{
SET_OPTION (option, RANDOM);
if (option.initial_asso_value != 0)
report_error ("warning, -r option superceeds -i, disabling -i option and continuing\n");
break;
}
case 's': /* Range of associated values, determines size of final table. */
{
if ((option.size = atoi (optarg)) <= 0)
report_error ("improper range argument %s\n%e%a", optarg, usage);
else if (option.size > 50)
report_error ("%d is excessive, did you really mean this?! (type %n -h for help)\n",
option.size);
break;
}
case 'S': /* Generate switch statement output, rather than lookup table. */
{
SET_OPTION (option, SWITCH);
if ((option.total_switches = atoi (optarg)) <= 0)
report_error ("number of switches %s must be a positive number\n%e%a", optarg, usage);
break;
}
case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */
{
SET_OPTION (option, TYPE);
break;
}
case 'T': /* Don't print structure definition. */
{
SET_OPTION (option, NOTYPE);
break;
}
case 'v': /* Print out the version and quit. */
report_error ("%n: version %s\n%e%a\n", version_string, usage);
default:
report_error ("%e%a", usage);
}
}
if (argv[optind] && ! freopen (argv[optind], "r", stdin))
report_error ("unable to read key word file %s\n%e%a", argv[optind], usage);
if (++optind < argc)
report_error ("extra trailing arguments to %n\n%e%a", usage);
}
/* Output command-line Options. */
void
print_options ()
{
int i;
printf ("/* Command-line: ");
for (i = 0; i < option.argument_count; i++)
printf ("%s ", option.argument_vector[i]);
printf (" */\n\n");
}

View File

@ -1,350 +0,0 @@
/* Provides high-level routines to manipulate the keywork list
structures the code generation output.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include "options.h"
#include "perfect.h"
#include "stderr.h"
/* Current release version. */
extern char *version_string;
/* Counts occurrences of each key set character. */
int occurrences[ALPHABET_SIZE];
/* Value associated with each character. */
int asso_values[ALPHABET_SIZE];
/* Locally visible PERFECT object. */
PERFECT perfect;
/* 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! */
void
perfect_init ()
{
int asso_value_max;
int len;
perfect.num_done = 1;
perfect.fewest_collisions = 0;
read_keys ();
if (OPTION_ENABLED (option, ORDER))
reorder ();
asso_value_max = GET_ASSO_MAX (option);
len = keyword_list_length ();
asso_value_max = (asso_value_max ? asso_value_max * len : len);
SET_ASSO_MAX (option, POW (asso_value_max));
if (OPTION_ENABLED (option, RANDOM))
{
int i;
srandom (time (0));
for (i = 0; i < ALPHABET_SIZE; i++)
asso_values[i] = (random () & asso_value_max - 1);
}
else
{
int asso_value = INITIAL_VALUE (option);
if (asso_value) /* Initialize array if user requests non-zero default. */
{
int i;
for (i = ALPHABET_SIZE - 1; i >= 0; i--)
asso_values[i] = asso_value & GET_ASSO_MAX (option) - 1;
}
}
perfect.max_hash_value = max_key_length () + GET_ASSO_MAX (option) *
GET_CHARSET_SIZE (option);
printf ("/* C code produced by gperf version %s */\n", version_string);
print_options ();
if (OPTION_ENABLED (option, DEBUG))
{
int i;
fprintf (stderr, "\nnumber of keys = %d\nmaximum associated value is %d\
\nmaximum possible size of generated hash table is %d\n",
len, asso_value_max, perfect.max_hash_value);
}
}
/* Merge two 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. */
static int
compute_disjoint_union (set_1, set_2, set_3)
char *set_1;
char *set_2;
char *set_3;
{
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. */
static void
sort_set (union_set, len)
char *union_set;
int len;
{
int i, j;
for (i = 0, j = len - 1; i < j; i++)
{
char curr, tmp;
for (curr = i+1, tmp = union_set[curr];
curr > 0 && occurrences[tmp] < occurrences[union_set[curr-1]];
curr--)
union_set[curr] = union_set[curr - 1];
union_set[curr] = tmp;
}
}
/* Generate a key set's hash value. */
static int
hash (key_node)
LIST_NODE *key_node;
{
int sum = OPTION_ENABLED (option, NOLENGTH) ? 0 : key_node->length;
char *ptr;
for (ptr = key_node->char_set; *ptr; ptr++)
sum += asso_values[*ptr];
return key_node->hash_value = sum;
}
/* Find out how associated value changes affect successfully hashed items.
Returns FALSE if no other hash values are affected, else returns TRUE.
Note that because GET_ASSO_MAX (option) is a power of two we can guarantee
that all legal ASSO_VALUES are visited without repetition since
GET_JUMP (option) was forced to be an odd value! */
static bool
affects_prev (c, curr)
char c;
LIST_NODE *curr;
{
int original_char = asso_values[c];
int i = !OPTION_ENABLED (option, FAST) ? GET_ASSO_MAX (option) :
GET_ITERATIONS (option) == 0 ? key_list.list_len : GET_ITERATIONS (option);
/* Try all asso_values. */
while (--i >= 0)
{
int collisions = 0;
LIST_NODE *ptr;
asso_values[c] = asso_values[c] + (GET_JUMP (option) ? GET_JUMP (option) : random ())
& GET_ASSO_MAX (option) - 1;
bool_array_reset ();
/* See how this asso_value change affects previous keywords. If
it does better than before we'll take it! */
for (ptr = key_list.head;
!lookup (hash (ptr)) || ++collisions < perfect.fewest_collisions;
ptr = ptr->next)
if (ptr == curr)
{
perfect.fewest_collisions = collisions;
return FALSE;
}
}
asso_values[c] = original_char; /* Restore original values, no more tries. */
return TRUE; /* If we're this far it's time to try the next character.... */
}
/* Change a character value, try least-used characters first. */
static void
change (prior, curr)
LIST_NODE *prior;
LIST_NODE *curr;
{
char *xmalloc ();
static char *union_set = 0;
char *temp;
LIST_NODE *ptr;
if (!union_set)
union_set = xmalloc (2 * GET_CHARSET_SIZE (option) + 1);
if (OPTION_ENABLED (option, DEBUG)) /* Very useful for debugging. */
{
fprintf (stderr, "collision on keyword #%d, prior=\"%s\", curr=\"%s\", hash=%d\n",
perfect.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. */
perfect.fewest_collisions++;
for (temp = union_set; *temp; temp++)
if (!affects_prev (*temp, curr))
{
if (OPTION_ENABLED (option, DEBUG))
{
fprintf (stderr, "- resolved by changing asso_value['%c'] (char #%d) to %d\n",
*temp, temp - union_set + 1, asso_values[*temp]);
fflush (stderr);
}
return; /* Good, doesn't affect previous hash values, we'll take it. */
}
for (ptr = key_list.head; ptr != curr; ptr = ptr->next)
hash (ptr);
hash (curr);
if (OPTION_ENABLED (option, DEBUG))
{
fprintf (stderr, "** collision not resolved, %d duplicates remain, continuing...\n",
perfect.fewest_collisions);
fflush (stderr);
}
}
/* Does the hard stuff....
Initializes the Iteration Number boolean array, and then trys 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
perfect_generate ()
{
LIST_NODE *curr;
bool_array_init (perfect.max_hash_value);
for (curr = key_list.head; curr; curr = curr->next)
{
LIST_NODE *ptr;
hash (curr);
for (ptr = key_list.head; ptr != curr; ptr = ptr->next)
if (ptr->hash_value == curr->hash_value)
{
change (ptr, curr);
break;
}
perfect.num_done++;
}
/* Make one final check, just to make sure nothing weird happened.... */
bool_array_reset ();
for (curr = key_list.head; curr; curr = curr->next)
if (lookup (hash (curr)))
if (OPTION_ENABLED (option, DUP)) /* We'll try to deal with this later..... */
break;
else /* Yow, big problems. we're outta here! */
{
report_error ("\nInternal error, duplicate value %d:\n\
try options -D or -r, or use new key positions.\n\n",
hash (curr));
return 1;
}
bool_array_destroy ();
/* First sorts the key word list by hash value, and the outputs the
list to the proper ostream. The generated hash table code is only
output if the early stage of processing turned out O.K. */
sort ();
print_output ();
return 0;
}
/* Prints out some diagnostics upon completion. */
void
perfect_destroy ()
{
if (OPTION_ENABLED (option, DEBUG))
{
int i;
fprintf (stderr, "\ndumping occurrence and associated values tables\n");
for (i = 0; i < ALPHABET_SIZE; i++)
if (occurrences[i])
fprintf (stderr, "asso_values[%c] = %3d, occurrences[%c] = %3d\n",
i, asso_values[i], i, occurrences[i]);
fprintf (stderr, "end table dumping\n");
}
}

View File

@ -1,45 +0,0 @@
/* Provides high-level routines to manipulate the keyword list
structures the code generation output.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _perfect_h
#define _perfect_h
#include "prototype.h"
#include "keylist.h"
#include "boolarray.h"
typedef struct perfect
{
KEY_LIST list; /* List of key words provided by the user. */
BOOL_ARRAY duplicate; /* Speeds up check for redundant hash values. */
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. */
} PERFECT;
extern void perfect_init P ((void));
extern void perfect_destroy P ((void));
extern int perfect_generate P ((void));
extern void perfect_print P ((void));
#endif /* _perfect_h */

View File

@ -1,15 +0,0 @@
#ifndef _prototype_h
#define _prototype_h
#ifdef __STDC__
#define P(X) X
#else
#define P(X) ()
#endif
typedef char bool;
#define FALSE 0
#define TRUE 1
#define ODD(X) ((X) & 1)
#define EVEN(X) (!((X) & 1))
#endif /* _prototype_h */

View File

@ -1,87 +0,0 @@
/* Correctly reads an arbitrarily size string.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "readline.h"
/* Size of each chunk. */
#define CHUNK_SIZE BUFSIZ
/* Recursively fills up the buffer. */
static char *
readln_aux (chunks)
int chunks;
{
char *buffered_malloc ();
char buf[CHUNK_SIZE];
register char *bufptr = buf;
register char *ptr;
int c;
while ((c = getchar ()) != EOF && c != '\n') /* fill the current buffer */
{
*bufptr++ = c;
if (bufptr - buf >= CHUNK_SIZE) /* prepend remainder to ptr buffer */
{
if (ptr = readln_aux (chunks + 1))
for (; bufptr != buf; *--ptr = *--bufptr);
return ptr;
}
}
if (c == EOF && bufptr == buf)
return NULL;
c = (chunks * CHUNK_SIZE + bufptr - buf) + 1;
if (ptr = buffered_malloc (c))
{
for (*(ptr += (c - 1)) = '\0'; bufptr != buf; *--ptr = *--bufptr)
;
return ptr;
}
else
return NULL;
}
/* Returns the ``next'' line, ignoring comments beginning with '#'. */
char *read_line ()
{
int c;
if ((c = getchar ()) == '#')
{
while ((c = getchar ()) != '\n' && c != EOF)
;
return c != EOF ? read_line () : NULL;
}
else
{
ungetc (c, stdin);
return readln_aux (0);
}
}

View File

@ -1,31 +0,0 @@
/* Reads arbitrarily long string from input file, returning it as a dynamic buffer.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* 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 _readline_h
#define _readline_h
#include "prototype.h"
extern char *read_line P ((void));
#endif /* _readline_h */

View File

@ -1,96 +0,0 @@
/* Provides a useful variable-length argument error handling abstraction.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <errno.h>
#ifdef _HAVE_PARAM_H
#include <sys/param.h>
#endif
#include "stderr.h"
/* Holds the name of the currently active program. */
static char *program_name;
/* Sets name of program. */
void
set_program_name (prog_name)
char *prog_name;
{
program_name = prog_name;
}
/* Valid Options (prefixed by '%', as in printf format strings) include:
'a': exit the program at this point
'c': print a character
'd': print a decimal number
'e': call the function pointed to by the corresponding argument
'f','g': print a double
'n': print the name of the program (NULL if not set in constructor or elsewhere)
'p': print out the appropriate errno value from sys_errlist
's': print out a character string
'%': print out a single percent sign, '%' */
void
report_error (va_alist)
va_dcl
{
extern int errno, sys_nerr;
#if (! defined(BSD) || (BSD < 199103))
extern char *sys_errlist[];
#endif /* not 4.3 Net2 based */
typedef void (*PTF)();
typedef char *CHARP;
va_list argp;
int abort_flag = 0;
char *format;
va_start (argp);
for (format = va_arg (argp, char *); *format; format++)
{
if (*format != '%')
putc (*format, stderr);
else
{
switch(*++format)
{
case '%' : putc ('%', stderr); break;
case 'a' : abort_flag = 1; break;
case 'c' : putc (va_arg (argp, int), stderr); break;
case 'd' : fprintf (stderr, "%d", va_arg (argp, int)); break;
case 'e' : (*va_arg (argp, PTF))(); break;
case 'f' : fprintf (stderr, "%g", va_arg (argp, double)); break;
case 'n' : fputs (program_name ? program_name : "error", stderr); break;
case 'p' :
if (errno < sys_nerr)
fprintf (stderr, "%s: %s", va_arg (argp, CHARP), sys_errlist[errno]);
else
fprintf (stderr, "<unknown error> %d", errno);
break;
case 's' : fputs (va_arg (argp, CHARP), stderr); break;
}
}
if (abort_flag)
exit (1);
}
va_end (argp);
}

View File

@ -1,29 +0,0 @@
/* Provides a useful variable-length argument error handling abstraction.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _stderr_h
#define _stderr_h
#include "prototype.h"
#include <varargs.h>
extern void set_program_name P ((char *prog_name));
extern void report_error ();
#endif /* _stderr_h */

View File

@ -1,22 +0,0 @@
/* Current program version number.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
char *version_string = "2.1 (K&R C version)";

View File

@ -1,78 +0,0 @@
/* Provide a useful malloc sanity checker and an efficient buffered memory
allocator that reduces calls to malloc.
Copyright (C) 1989 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
/* Grabs SIZE bytes of dynamic memory or dies trying! */
char *
xmalloc (size)
int size;
{
char *malloc ();
char *temp = malloc (size);
if (temp == 0)
{
fprintf (stderr, "out of virtual memory\n");
exit (1);
}
return temp;
}
/* 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;};
#define ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
/* Provide an abstraction that cuts down on the number of
calls to MALLOC by buffering the memory pool from which
items are allocated. */
char *
buffered_malloc (size)
int size;
{
char *temp;
static char *buf_start = 0; /* Large array used to reduce calls to NEW. */
static char *buf_end = 0; /* Indicates end of BUF_START. */
static int buf_size = 4 * BUFSIZ; /* Size of buffer pointed to by BUF_START. */
/* 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. Furthermore, as a heuristic, we double the
size of the new buffer! */
if (buf_start + size >= buf_end)
{
buf_size = buf_size * 2 > size ? buf_size * 2 : size;
buf_start = xmalloc (buf_size);
buf_end = buf_start + buf_size;
}
temp = buf_start;
buf_start += size;
return temp;
}

View File

@ -1,65 +0,0 @@
# Copyright (C) 1989 Free Software Foundation, Inc.
# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
#
# This file is part of GNU GPERF.
#
# GNU GPERF is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 1, or (at your option)
# any later version.
#
# GNU GPERF is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU GPERF; see the file COPYING. If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
GPERF = gperf
CC = gcc
all: test
test:
@echo "performing some tests of the perfect hash generator"
$(CC) -c -O test.c
$(GPERF) -p -c -l -S1 -C -o c.gperf > cinset.c
$(CC) -O -o cout cinset.c test.o
@echo "testing ANSI C reserved words, all items should be found in the set"
./cout -v < c.gperf
$(GPERF) -k1,4,'$$' ada.gperf > adainset.c
# double '$$' is only there since make gets confused; program wants only 1 '$'
$(CC) -O -o aout adainset.c test.o
@echo "testing Ada reserved words,all items should be found in the set"
./aout -v < ada.gperf
$(GPERF) -p -D -S1 -k1,'$$' -s 2 -o adapredefined.gperf > preinset.c
$(CC) -O -o preout preinset.c test.o
@echo "testing Ada predefined words, all items should be found in the set"
./preout -v < adapredefined.gperf
$(GPERF) -k1,2,'$$' -o modula3.gperf > m3inset.c
$(CC) -O -o m3out m3inset.c test.o
@echo "testing Modula3 reserved words, all items should be found in the set"
./m3out -v < modula3.gperf
$(GPERF) -o -S1 -p < pascal.gperf > pinset.c
$(CC) -O -o pout pinset.c test.o
@echo "testing Pascal reserved words, all items should be found in the set"
./pout -v < pascal.gperf
$(GPERF) -o -S2 -j1 -D -p -t < c++.gperf > c++inset.c
$(CC) -O -o c++out c++inset.c test.o
@echo "testing C++ reserved words, all items should be found in the set"
tail -47 c++.gperf | ./c++out -v
# these next 5 are demos that show off the generated code
$(GPERF) -p -j1 -g -o -t -N is_reserved_word -k1,3,'$$' c-parse.gperf
$(GPERF) -n -k1-8 -l modula2.gperf
$(GPERF) -p -j 1 -o -a -g -t -k1,4,$$ gplus.gperf
$(GPERF) -D -p -t < c-parse.gperf
$(GPERF) -g -o -j1 -t -p -N is_reserved_word gpc.gperf
# prints out the help message
-$(GPERF) -h
@echo "only if, do, for, case, goto, else, while, and return should be found "
./aout -v < c.gperf
clean:
-rm -f *.o core *~ *inset.c *out #*#

View File

@ -1,54 +0,0 @@
boolean
character
constraint_error
false
float
integer
natural
numeric_error
positive
program_error
storage_error
string
tasking_error
true
address
aft
base
callable
constrained
count
delta
digits
emax
epsilon
first
firstbit
fore
image
large
last
lastbit
length
machine_emax
machine_emin
machine_mantissa
machine_overflows
machine_radix
machine_rounds
mantissa
pos
position
pred
range
safe_emax
safe_large
safe_small
size
small
storage_size
succ
terminated
val
value
width