diff --git a/ChangeLog b/ChangeLog index b6ba96f..279e3af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2002-10-03 Bruno Haible + * 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 hash table using 'new'. (Key_List::output_lookup_array): Allocate the memory for the duplicates diff --git a/src/Makefile.in b/src/Makefile.in index 4a792d3..bee850d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -60,7 +60,8 @@ SHELL = /bin/sh VPATH = $(srcdir) 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@ CPPFLAGS = -I. -I$(srcdir)/../lib @@ -115,6 +116,8 @@ vectors.o : vectors.cc $(VECTORS_H) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/vectors.cc version.o : version.cc $(VERSION_H) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/version.cc +keyword.o : keyword.cc keyword.h + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/keyword.cc install : all force $(MKINSTALLDIRS) $(DESTDIR)$(bindir) diff --git a/src/gen-perf.cc b/src/gen-perf.cc index 6d84b21..c2285b9 100644 --- a/src/gen-perf.cc +++ b/src/gen-perf.cc @@ -150,7 +150,7 @@ Gen_Perf::sort_set (char *union_set, int len) inline int 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; 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", num_done, - prior->key_length, prior->key, - curr->key_length, curr->key, + prior->allchars_length, prior->allchars, + curr->allchars_length, curr->allchars, curr->hash_value); fflush (stderr); } diff --git a/src/hash-table.cc b/src/hash-table.cc index 25c5e6b..67575fe 100644 --- a/src/hash-table.cc +++ b/src/hash-table.cc @@ -58,7 +58,7 @@ Hash_Table::~Hash_Table (void) fprintf (stderr, "%8d, %*.*s, %.*s\n", i, field_width, table[i]->char_set_length, table[i]->char_set, - table[i]->key_length, table[i]->key); + table[i]->allchars_length, table[i]->allchars); 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); 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]) { if (table[probe]->char_set_length == item->char_set_length && memcmp (table[probe]->char_set, item->char_set, item->char_set_length) == 0 - && (ignore_length || table[probe]->key_length == item->key_length)) + && (ignore_length || table[probe]->allchars_length == item->allchars_length)) return table[probe]; collisions++; diff --git a/src/key-list.cc b/src/key-list.cc index f2fb7a2..1f6046b 100644 --- a/src/key-list.cc +++ b/src/key-list.cc @@ -411,18 +411,18 @@ Key_List::read_keys (void) /* Complain if user hasn't enabled the duplicate option. */ if (!option[DUP] || option[DEBUG]) fprintf (stderr, "Key link: \"%.*s\" = \"%.*s\", with key set \"%.*s\".\n", - temp->key_length, temp->key, - ptr->key_length, ptr->key, + temp->allchars_length, temp->allchars, + ptr->allchars_length, ptr->allchars, temp->char_set_length, temp->char_set); } else trail = temp; /* Update minimum and maximum keyword length, if needed. */ - if (max_key_len < temp->key_length) - max_key_len = temp->key_length; - if (min_key_len > temp->key_length) - min_key_len = temp->key_length; + if (max_key_len < temp->allchars_length) + max_key_len = temp->allchars_length; + if (min_key_len > temp->allchars_length) + min_key_len = temp->allchars_length; } delete[] table; @@ -1169,7 +1169,7 @@ Key_List::output_keylength_table (void) printf (","); if ((column++ % columns) == 0) printf("\n%s ", indent); - printf ("%3d", temp->key_length); + printf ("%3d", temp->allchars_length); /* Deal with links specially. */ if (temp->link) // implies option[DUP] @@ -1179,7 +1179,7 @@ Key_List::output_keylength_table (void) printf (","); if ((column++ % columns) == 0) printf("\n%s ", indent); - printf ("%3d", links->key_length); + printf ("%3d", links->allchars_length); } index++; @@ -1198,7 +1198,7 @@ output_keyword_entry (List_Node *temp, const char *indent) printf ("%s ", indent); if (option[TYPE]) printf ("{"); - output_string (temp->key, temp->key_length); + output_string (temp->allchars, temp->allchars_length); if (option[TYPE]) { if (strlen (temp->rest) > 0) @@ -1342,7 +1342,7 @@ Key_List::output_lookup_array (void) lookup_array[hash_value] = temp->index; if (option[DEBUG]) fprintf (stderr, "keyword = %.*s, index = %d\n", - temp->key_length, temp->key, temp->index); + temp->allchars_length, temp->allchars, temp->index); if (temp->link || (temp->next && hash_value == temp->next->hash_value)) { @@ -1359,7 +1359,7 @@ Key_List::output_lookup_array (void) if (option[DEBUG]) fprintf (stderr, "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)) @@ -1370,7 +1370,7 @@ Key_List::output_lookup_array (void) dup_ptr->count++; if (option[DEBUG]) 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); dup_ptr++; @@ -1502,7 +1502,7 @@ output_switch_case (List_Node *list, int indent, int *jumps_away) { if (option[DEBUG]) 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] && (list->link @@ -1535,7 +1535,7 @@ output_switch_case (List_Node *list, int indent, int *jumps_away) { printf ("%*sif (len == %d)\n" "%*s {\n", - indent, "", list->key_length, + indent, "", list->allchars_length, indent, ""); indent += 4; } @@ -1544,7 +1544,7 @@ output_switch_case (List_Node *list, int indent, int *jumps_away) if (option[TYPE]) printf ("&%s[%d]", option.get_wordlist_name (), list->index); else - output_string (list->key, list->key_length); + output_string (list->allchars, list->allchars_length); printf (";\n"); printf ("%*sgoto compare;\n", indent, ""); @@ -2068,9 +2068,9 @@ Key_List::dump () for (List_Node *ptr = head; ptr; ptr = ptr->next) fprintf (stderr, "%11d,%11d,%6d, %*.*s, %.*s\n", - ptr->hash_value, ptr->key_length, ptr->index, + ptr->hash_value, ptr->allchars_length, ptr->index, field_width, ptr->char_set_length, ptr->char_set, - ptr->key_length, ptr->key); + ptr->allchars_length, ptr->allchars); } /* Simple-minded constructor action here... */ diff --git a/src/keyword.cc b/src/keyword.cc new file mode 100644 index 0000000..3047dda --- /dev/null +++ b/src/keyword.cc @@ -0,0 +1,35 @@ +/* Keyword data. + Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. + Written by Bruno Haible . + +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 () {} diff --git a/src/keyword.h b/src/keyword.h new file mode 100644 index 0000000..aa2ebfc --- /dev/null +++ b/src/keyword.h @@ -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 . + +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 diff --git a/src/list-node.cc b/src/list-node.cc index 479d43c..26c3919 100644 --- a/src/list-node.cc +++ b/src/list-node.cc @@ -56,7 +56,7 @@ List_Node::set_sort (char *base, int len) the INDEX field to some useful value. */ List_Node::List_Node (const char *k, int len, const char *r): - link (0), next (0), key (k), key_length (len), rest (r), index (0) + Keyword (k, len, r), link (0), next (0), index (0) { char *key_set = new char[(option[ALLCHARS] ? len : option.get_max_keysig_size ())]; 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; ) { 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. */ - *ptr = key[i - 1]; + *ptr = allchars[i - 1]; else /* Out of range of KEY length, so we'll just skip it. */ continue; ++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]) { fprintf (stderr, "Can't hash keyword %.*s with chosen key positions.\n", - key_length, key); + allchars_length, allchars); exit (1); } } diff --git a/src/list-node.h b/src/list-node.h index 3bd21b3..ce5d8a9 100644 --- a/src/list-node.h +++ b/src/list-node.h @@ -2,7 +2,7 @@ /* 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) 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 #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 *next; /* Points to next element on the list. */ - const char *key; /* Each keyword string stored here. */ - int key_length; /* Length of the key. */ - const char *rest; /* Additional information for building hash function. */ const char *char_set; /* Set of characters to hash, specified by user. */ int char_set_length; /* Length of char_set. */ int hash_value; /* Hash value for the key. */