mirror of
https://git.savannah.gnu.org/git/gperf.git
synced 2025-12-02 21:19:24 +00:00
New class Keyword.
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -1,5 +1,15 @@
|
|||||||
2002-10-03 Bruno Haible <bruno@clisp.org>
|
2002-10-03 Bruno Haible <bruno@clisp.org>
|
||||||
|
|
||||||
|
* src/keyword.h: New file.
|
||||||
|
* src/keyword.cc: New file.
|
||||||
|
* src/list-node.h (List_Node): Extend Keyword.
|
||||||
|
* src/list-node.cc: Update.
|
||||||
|
* src/gen-perf.cc: Update.
|
||||||
|
* src/hash-table.cc: Update.
|
||||||
|
* src/key-list.cc: Update.
|
||||||
|
* src/Makefile.in (OBJECTS): Add keyword.o.
|
||||||
|
(keyword.o): New rule.
|
||||||
|
|
||||||
* src/key-list.cc (Key_List::read_keys): Allocate the memory for the
|
* src/key-list.cc (Key_List::read_keys): Allocate the memory for the
|
||||||
hash table using 'new'.
|
hash table using 'new'.
|
||||||
(Key_List::output_lookup_array): Allocate the memory for the duplicates
|
(Key_List::output_lookup_array): Allocate the memory for the duplicates
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ SHELL = /bin/sh
|
|||||||
VPATH = $(srcdir)
|
VPATH = $(srcdir)
|
||||||
|
|
||||||
OBJECTS = options.o iterator.o main.o gen-perf.o key-list.o list-node.o \
|
OBJECTS = options.o iterator.o main.o gen-perf.o key-list.o list-node.o \
|
||||||
hash-table.o bool-array.o read-line.o vectors.o version.o
|
hash-table.o bool-array.o read-line.o vectors.o version.o \
|
||||||
|
keyword.o
|
||||||
LIBS = ../lib/libgp.a @GPERF_LIBM@
|
LIBS = ../lib/libgp.a @GPERF_LIBM@
|
||||||
CPPFLAGS = -I. -I$(srcdir)/../lib
|
CPPFLAGS = -I. -I$(srcdir)/../lib
|
||||||
|
|
||||||
@@ -115,6 +116,8 @@ vectors.o : vectors.cc $(VECTORS_H)
|
|||||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/vectors.cc
|
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/vectors.cc
|
||||||
version.o : version.cc $(VERSION_H)
|
version.o : version.cc $(VERSION_H)
|
||||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/version.cc
|
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/version.cc
|
||||||
|
keyword.o : keyword.cc keyword.h
|
||||||
|
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/keyword.cc
|
||||||
|
|
||||||
install : all force
|
install : all force
|
||||||
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ Gen_Perf::sort_set (char *union_set, int len)
|
|||||||
inline int
|
inline int
|
||||||
Gen_Perf::hash (List_Node *key_node)
|
Gen_Perf::hash (List_Node *key_node)
|
||||||
{
|
{
|
||||||
int sum = option[NOLENGTH] ? 0 : key_node->key_length;
|
int sum = option[NOLENGTH] ? 0 : key_node->allchars_length;
|
||||||
|
|
||||||
const char *p = key_node->char_set;
|
const char *p = key_node->char_set;
|
||||||
int i = key_node->char_set_length;
|
int i = key_node->char_set_length;
|
||||||
@@ -222,8 +222,8 @@ Gen_Perf::change (List_Node *prior, List_Node *curr)
|
|||||||
{
|
{
|
||||||
fprintf (stderr, "collision on keyword #%d, prior = \"%.*s\", curr = \"%.*s\" hash = %d\n",
|
fprintf (stderr, "collision on keyword #%d, prior = \"%.*s\", curr = \"%.*s\" hash = %d\n",
|
||||||
num_done,
|
num_done,
|
||||||
prior->key_length, prior->key,
|
prior->allchars_length, prior->allchars,
|
||||||
curr->key_length, curr->key,
|
curr->allchars_length, curr->allchars,
|
||||||
curr->hash_value);
|
curr->hash_value);
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Hash_Table::~Hash_Table (void)
|
|||||||
fprintf (stderr, "%8d, %*.*s, %.*s\n",
|
fprintf (stderr, "%8d, %*.*s, %.*s\n",
|
||||||
i,
|
i,
|
||||||
field_width, table[i]->char_set_length, table[i]->char_set,
|
field_width, table[i]->char_set_length, table[i]->char_set,
|
||||||
table[i]->key_length, table[i]->key);
|
table[i]->allchars_length, table[i]->allchars);
|
||||||
|
|
||||||
fprintf (stderr, "\nend dumping hash table\n\n");
|
fprintf (stderr, "\nend dumping hash table\n\n");
|
||||||
}
|
}
|
||||||
@@ -73,13 +73,13 @@ Hash_Table::insert (List_Node *item)
|
|||||||
{
|
{
|
||||||
unsigned hash_val = hashpjw (item->char_set, item->char_set_length);
|
unsigned hash_val = hashpjw (item->char_set, item->char_set_length);
|
||||||
int probe = hash_val & (size - 1);
|
int probe = hash_val & (size - 1);
|
||||||
int increment = ((hash_val ^ item->key_length) | 1) & (size - 1);
|
int increment = ((hash_val ^ item->allchars_length) | 1) & (size - 1);
|
||||||
|
|
||||||
while (table[probe])
|
while (table[probe])
|
||||||
{
|
{
|
||||||
if (table[probe]->char_set_length == item->char_set_length
|
if (table[probe]->char_set_length == item->char_set_length
|
||||||
&& memcmp (table[probe]->char_set, item->char_set, item->char_set_length) == 0
|
&& memcmp (table[probe]->char_set, item->char_set, item->char_set_length) == 0
|
||||||
&& (ignore_length || table[probe]->key_length == item->key_length))
|
&& (ignore_length || table[probe]->allchars_length == item->allchars_length))
|
||||||
return table[probe];
|
return table[probe];
|
||||||
|
|
||||||
collisions++;
|
collisions++;
|
||||||
|
|||||||
@@ -411,18 +411,18 @@ Key_List::read_keys (void)
|
|||||||
/* Complain if user hasn't enabled the duplicate option. */
|
/* Complain if user hasn't enabled the duplicate option. */
|
||||||
if (!option[DUP] || option[DEBUG])
|
if (!option[DUP] || option[DEBUG])
|
||||||
fprintf (stderr, "Key link: \"%.*s\" = \"%.*s\", with key set \"%.*s\".\n",
|
fprintf (stderr, "Key link: \"%.*s\" = \"%.*s\", with key set \"%.*s\".\n",
|
||||||
temp->key_length, temp->key,
|
temp->allchars_length, temp->allchars,
|
||||||
ptr->key_length, ptr->key,
|
ptr->allchars_length, ptr->allchars,
|
||||||
temp->char_set_length, temp->char_set);
|
temp->char_set_length, temp->char_set);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
trail = temp;
|
trail = temp;
|
||||||
|
|
||||||
/* Update minimum and maximum keyword length, if needed. */
|
/* Update minimum and maximum keyword length, if needed. */
|
||||||
if (max_key_len < temp->key_length)
|
if (max_key_len < temp->allchars_length)
|
||||||
max_key_len = temp->key_length;
|
max_key_len = temp->allchars_length;
|
||||||
if (min_key_len > temp->key_length)
|
if (min_key_len > temp->allchars_length)
|
||||||
min_key_len = temp->key_length;
|
min_key_len = temp->allchars_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] table;
|
delete[] table;
|
||||||
@@ -1169,7 +1169,7 @@ Key_List::output_keylength_table (void)
|
|||||||
printf (",");
|
printf (",");
|
||||||
if ((column++ % columns) == 0)
|
if ((column++ % columns) == 0)
|
||||||
printf("\n%s ", indent);
|
printf("\n%s ", indent);
|
||||||
printf ("%3d", temp->key_length);
|
printf ("%3d", temp->allchars_length);
|
||||||
|
|
||||||
/* Deal with links specially. */
|
/* Deal with links specially. */
|
||||||
if (temp->link) // implies option[DUP]
|
if (temp->link) // implies option[DUP]
|
||||||
@@ -1179,7 +1179,7 @@ Key_List::output_keylength_table (void)
|
|||||||
printf (",");
|
printf (",");
|
||||||
if ((column++ % columns) == 0)
|
if ((column++ % columns) == 0)
|
||||||
printf("\n%s ", indent);
|
printf("\n%s ", indent);
|
||||||
printf ("%3d", links->key_length);
|
printf ("%3d", links->allchars_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
@@ -1198,7 +1198,7 @@ output_keyword_entry (List_Node *temp, const char *indent)
|
|||||||
printf ("%s ", indent);
|
printf ("%s ", indent);
|
||||||
if (option[TYPE])
|
if (option[TYPE])
|
||||||
printf ("{");
|
printf ("{");
|
||||||
output_string (temp->key, temp->key_length);
|
output_string (temp->allchars, temp->allchars_length);
|
||||||
if (option[TYPE])
|
if (option[TYPE])
|
||||||
{
|
{
|
||||||
if (strlen (temp->rest) > 0)
|
if (strlen (temp->rest) > 0)
|
||||||
@@ -1342,7 +1342,7 @@ Key_List::output_lookup_array (void)
|
|||||||
lookup_array[hash_value] = temp->index;
|
lookup_array[hash_value] = temp->index;
|
||||||
if (option[DEBUG])
|
if (option[DEBUG])
|
||||||
fprintf (stderr, "keyword = %.*s, index = %d\n",
|
fprintf (stderr, "keyword = %.*s, index = %d\n",
|
||||||
temp->key_length, temp->key, temp->index);
|
temp->allchars_length, temp->allchars, temp->index);
|
||||||
if (temp->link
|
if (temp->link
|
||||||
|| (temp->next && hash_value == temp->next->hash_value))
|
|| (temp->next && hash_value == temp->next->hash_value))
|
||||||
{
|
{
|
||||||
@@ -1359,7 +1359,7 @@ Key_List::output_lookup_array (void)
|
|||||||
if (option[DEBUG])
|
if (option[DEBUG])
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"static linked keyword = %.*s, index = %d\n",
|
"static linked keyword = %.*s, index = %d\n",
|
||||||
ptr->key_length, ptr->key, ptr->index);
|
ptr->allchars_length, ptr->allchars, ptr->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(temp->next && hash_value == temp->next->hash_value))
|
if (!(temp->next && hash_value == temp->next->hash_value))
|
||||||
@@ -1370,7 +1370,7 @@ Key_List::output_lookup_array (void)
|
|||||||
dup_ptr->count++;
|
dup_ptr->count++;
|
||||||
if (option[DEBUG])
|
if (option[DEBUG])
|
||||||
fprintf (stderr, "dynamic linked keyword = %.*s, index = %d\n",
|
fprintf (stderr, "dynamic linked keyword = %.*s, index = %d\n",
|
||||||
temp->key_length, temp->key, temp->index);
|
temp->allchars_length, temp->allchars, temp->index);
|
||||||
}
|
}
|
||||||
assert (dup_ptr->count >= 2);
|
assert (dup_ptr->count >= 2);
|
||||||
dup_ptr++;
|
dup_ptr++;
|
||||||
@@ -1502,7 +1502,7 @@ output_switch_case (List_Node *list, int indent, int *jumps_away)
|
|||||||
{
|
{
|
||||||
if (option[DEBUG])
|
if (option[DEBUG])
|
||||||
printf ("%*s/* hash value = %4d, keyword = \"%.*s\" */\n",
|
printf ("%*s/* hash value = %4d, keyword = \"%.*s\" */\n",
|
||||||
indent, "", list->hash_value, list->key_length, list->key);
|
indent, "", list->hash_value, list->allchars_length, list->allchars);
|
||||||
|
|
||||||
if (option[DUP]
|
if (option[DUP]
|
||||||
&& (list->link
|
&& (list->link
|
||||||
@@ -1535,7 +1535,7 @@ output_switch_case (List_Node *list, int indent, int *jumps_away)
|
|||||||
{
|
{
|
||||||
printf ("%*sif (len == %d)\n"
|
printf ("%*sif (len == %d)\n"
|
||||||
"%*s {\n",
|
"%*s {\n",
|
||||||
indent, "", list->key_length,
|
indent, "", list->allchars_length,
|
||||||
indent, "");
|
indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
}
|
}
|
||||||
@@ -1544,7 +1544,7 @@ output_switch_case (List_Node *list, int indent, int *jumps_away)
|
|||||||
if (option[TYPE])
|
if (option[TYPE])
|
||||||
printf ("&%s[%d]", option.get_wordlist_name (), list->index);
|
printf ("&%s[%d]", option.get_wordlist_name (), list->index);
|
||||||
else
|
else
|
||||||
output_string (list->key, list->key_length);
|
output_string (list->allchars, list->allchars_length);
|
||||||
printf (";\n");
|
printf (";\n");
|
||||||
printf ("%*sgoto compare;\n",
|
printf ("%*sgoto compare;\n",
|
||||||
indent, "");
|
indent, "");
|
||||||
@@ -2068,9 +2068,9 @@ Key_List::dump ()
|
|||||||
|
|
||||||
for (List_Node *ptr = head; ptr; ptr = ptr->next)
|
for (List_Node *ptr = head; ptr; ptr = ptr->next)
|
||||||
fprintf (stderr, "%11d,%11d,%6d, %*.*s, %.*s\n",
|
fprintf (stderr, "%11d,%11d,%6d, %*.*s, %.*s\n",
|
||||||
ptr->hash_value, ptr->key_length, ptr->index,
|
ptr->hash_value, ptr->allchars_length, ptr->index,
|
||||||
field_width, ptr->char_set_length, ptr->char_set,
|
field_width, ptr->char_set_length, ptr->char_set,
|
||||||
ptr->key_length, ptr->key);
|
ptr->allchars_length, ptr->allchars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simple-minded constructor action here... */
|
/* Simple-minded constructor action here... */
|
||||||
|
|||||||
35
src/keyword.cc
Normal file
35
src/keyword.cc
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* Keyword data.
|
||||||
|
Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
|
||||||
|
Written by Bruno Haible <bruno@clisp.org>.
|
||||||
|
|
||||||
|
This file is part of GNU GPERF.
|
||||||
|
|
||||||
|
GNU GPERF is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 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 "keyword.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword class. */
|
||||||
|
|
||||||
|
Keyword::Keyword (const char *s, int s_len, const char *r)
|
||||||
|
: allchars (s), allchars_length (s_len), rest (r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword_Factory class. */
|
||||||
|
|
||||||
|
Keyword_Factory::Keyword_Factory () {}
|
||||||
|
|
||||||
|
Keyword_Factory::~Keyword_Factory () {}
|
||||||
52
src/keyword.h
Normal file
52
src/keyword.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* This may look like C code, but it is really -*- C++ -*- */
|
||||||
|
|
||||||
|
/* Keyword data.
|
||||||
|
|
||||||
|
Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
|
||||||
|
Written by Bruno Haible <bruno@clisp.org>.
|
||||||
|
|
||||||
|
This file is part of GNU GPERF.
|
||||||
|
|
||||||
|
GNU GPERF is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
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 keyword_h
|
||||||
|
#define keyword_h 1
|
||||||
|
|
||||||
|
/* An instance of this class is a keyword, as specified in the input file. */
|
||||||
|
struct Keyword
|
||||||
|
{
|
||||||
|
/* Constructor. */
|
||||||
|
Keyword (const char *allchars, int allchars_length, const char *rest);
|
||||||
|
|
||||||
|
/* Data members. */
|
||||||
|
/* The keyword as a string, possibly containing NUL bytes. */
|
||||||
|
const char *const allchars;
|
||||||
|
const int allchars_length;
|
||||||
|
/* Additional stuff seen on the same line of the input file. */
|
||||||
|
const char *const rest;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A factory for creating Keyword instances. */
|
||||||
|
class Keyword_Factory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Keyword_Factory ();
|
||||||
|
virtual ~Keyword_Factory ();
|
||||||
|
/* Creates a new Keyword. */
|
||||||
|
virtual Keyword create_keyword (const char *allchars, int allchars_length,
|
||||||
|
const char *rest) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -56,7 +56,7 @@ List_Node::set_sort (char *base, int len)
|
|||||||
the INDEX field to some useful value. */
|
the INDEX field to some useful value. */
|
||||||
|
|
||||||
List_Node::List_Node (const char *k, int len, const char *r):
|
List_Node::List_Node (const char *k, int len, const char *r):
|
||||||
link (0), next (0), key (k), key_length (len), rest (r), index (0)
|
Keyword (k, len, r), link (0), next (0), index (0)
|
||||||
{
|
{
|
||||||
char *key_set = new char[(option[ALLCHARS] ? len : option.get_max_keysig_size ())];
|
char *key_set = new char[(option[ALLCHARS] ? len : option.get_max_keysig_size ())];
|
||||||
char *ptr = key_set;
|
char *ptr = key_set;
|
||||||
@@ -73,9 +73,9 @@ List_Node::List_Node (const char *k, int len, const char *r):
|
|||||||
for (option.reset (); (i = option.get ()) != EOS; )
|
for (option.reset (); (i = option.get ()) != EOS; )
|
||||||
{
|
{
|
||||||
if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */
|
if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */
|
||||||
*ptr = key[len - 1];
|
*ptr = allchars[len - 1];
|
||||||
else if (i <= len) /* Within range of KEY length, so we'll keep it. */
|
else if (i <= len) /* Within range of KEY length, so we'll keep it. */
|
||||||
*ptr = key[i - 1];
|
*ptr = allchars[i - 1];
|
||||||
else /* Out of range of KEY length, so we'll just skip it. */
|
else /* Out of range of KEY length, so we'll just skip it. */
|
||||||
continue;
|
continue;
|
||||||
++occurrences[(unsigned char)(*ptr++)];
|
++occurrences[(unsigned char)(*ptr++)];
|
||||||
@@ -86,7 +86,7 @@ List_Node::List_Node (const char *k, int len, const char *r):
|
|||||||
if (ptr == char_set && option[NOLENGTH])
|
if (ptr == char_set && option[NOLENGTH])
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Can't hash keyword %.*s with chosen key positions.\n",
|
fprintf (stderr, "Can't hash keyword %.*s with chosen key positions.\n",
|
||||||
key_length, key);
|
allchars_length, allchars);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/* Data and function members for defining values and operations of a list node.
|
/* Data and function members for defining values and operations of a list node.
|
||||||
|
|
||||||
Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
|
Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
|
||||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||||
|
|
||||||
This file is part of GNU GPERF.
|
This file is part of GNU GPERF.
|
||||||
@@ -25,14 +25,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
|
|||||||
#define list_node_h 1
|
#define list_node_h 1
|
||||||
|
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
|
#include "keyword.h"
|
||||||
|
|
||||||
struct List_Node : private Vectors
|
struct List_Node : public Keyword, private Vectors
|
||||||
{
|
{
|
||||||
List_Node *link; /* TRUE if key has an identical KEY_SET as another key. */
|
List_Node *link; /* TRUE if key has an identical KEY_SET as another key. */
|
||||||
List_Node *next; /* Points to next element on the list. */
|
List_Node *next; /* Points to next element on the list. */
|
||||||
const char *key; /* Each keyword string stored here. */
|
|
||||||
int key_length; /* Length of the key. */
|
|
||||||
const char *rest; /* Additional information for building hash function. */
|
|
||||||
const char *char_set; /* Set of characters to hash, specified by user. */
|
const char *char_set; /* Set of characters to hash, specified by user. */
|
||||||
int char_set_length; /* Length of char_set. */
|
int char_set_length; /* Length of char_set. */
|
||||||
int hash_value; /* Hash value for the key. */
|
int hash_value; /* Hash value for the key. */
|
||||||
|
|||||||
Reference in New Issue
Block a user