1
0
mirror of https://git.savannah.gnu.org/git/gperf.git synced 2025-12-02 21:19:24 +00:00

Change the positions to be 0-based, instead of 1-based.

This commit is contained in:
Bruno Haible
2003-04-04 10:04:24 +00:00
parent 68f03b3ea7
commit ec3d1127fa
15 changed files with 100 additions and 72 deletions

View File

@@ -1,3 +1,31 @@
2002-12-11 Bruno Haible <bruno@clisp.org>
Change the positions to be 0-based, instead of 1-based.
* src/positions.h (Positions::LASTCHAR): Set to -1.
(Positions::MAX_SIZE): New constant.
(Positions::pointer): Change return type.
(Positions::_positions): Change element type.
(PositionIterator::EOS, PositionReverseIterator::EOS): Set to -2.
* src/positions.icc (Positions::pointer): Change return type.
(Positions::sort): Update.
* src/positions.cc (Positions::contains, Positions::add,
Positions::remove): Update.
(Positions::print): Update. Fix off-by-one bug.
* src/options.cc (Options::~Options): Update.
(Options::parse_options): Set BAD_VALUE to -3. Update.
* src/keyword.cc (KeywordExt::init_selchars_low): Update.
* src/search.cc (Search::find_positions, Search::compute_alpha_unify,
Search::find_alpha_inc): Update.
* src/output.cc (Output::output_hash_function): Update. Don't emit
a 'case' statement right after 'default:'.
* tests/c-parse.exp: Regenerated.
* tests/charsets.exp: Regenerated.
* tests/cplusplus.exp: Regenerated.
* tests/java.exp: Regenerated.
* tests/languages.exp: Regenerated.
* tests/modula2.exp: Regenerated.
* tests/objc.exp: Regenerated.
2002-12-10 Bruno Haible <bruno@clisp.org> 2002-12-10 Bruno Haible <bruno@clisp.org>
* src/options.h: Reorder enum values. * src/options.h: Reorder enum values.

View File

@@ -91,12 +91,12 @@ KeywordExt::init_selchars_low (bool use_all_chars, const Positions& positions, c
if (i == Positions::LASTCHAR) if (i == Positions::LASTCHAR)
/* Special notation for last KEY position, i.e. '$'. */ /* Special notation for last KEY position, i.e. '$'. */
c = static_cast<unsigned char>(_allchars[_allchars_length - 1]); c = static_cast<unsigned char>(_allchars[_allchars_length - 1]);
else if (i <= _allchars_length) else if (i < _allchars_length)
{ {
/* Within range of KEY length, so we'll keep it. */ /* Within range of KEY length, so we'll keep it. */
c = static_cast<unsigned char>(_allchars[i - 1]); c = static_cast<unsigned char>(_allchars[i]);
if (alpha_inc) if (alpha_inc)
c += alpha_inc[i - 1]; c += alpha_inc[i];
} }
else else
/* Out of range of KEY length, so we'll just skip it. */ /* Out of range of KEY length, so we'll just skip it. */

View File

@@ -526,7 +526,7 @@ Options::~Options ()
if (pos == Positions::LASTCHAR) if (pos == Positions::LASTCHAR)
fprintf (stderr, "$\n"); fprintf (stderr, "$\n");
else else
fprintf (stderr, "%d\n", pos); fprintf (stderr, "%d\n", pos + 1);
} }
fprintf (stderr, "finished dumping Options\n"); fprintf (stderr, "finished dumping Options\n");
@@ -767,7 +767,7 @@ Options::parse_options (int argc, char *argv[])
case 'k': /* Sets key positions used for hash function. */ case 'k': /* Sets key positions used for hash function. */
{ {
_option_word |= POSITIONS; _option_word |= POSITIONS;
const int BAD_VALUE = -2; const int BAD_VALUE = -3;
const int EOS = PositionIterator::EOS; const int EOS = PositionIterator::EOS;
int value; int value;
PositionStringParser sparser (/*getopt*/optarg, 1, Positions::MAX_KEY_POS, Positions::LASTCHAR, BAD_VALUE, EOS); PositionStringParser sparser (/*getopt*/optarg, 1, Positions::MAX_KEY_POS, Positions::LASTCHAR, BAD_VALUE, EOS);
@@ -776,8 +776,8 @@ Options::parse_options (int argc, char *argv[])
_option_word |= ALLCHARS; _option_word |= ALLCHARS;
else else
{ {
unsigned char *key_positions = _key_positions.pointer(); int *key_positions = _key_positions.pointer();
unsigned char *key_pos; int *key_pos;
for (key_pos = key_positions; (value = sparser.nextPosition()) != EOS; key_pos++) for (key_pos = key_positions; (value = sparser.nextPosition()) != EOS; key_pos++)
{ {
@@ -788,16 +788,19 @@ Options::parse_options (int argc, char *argv[])
short_usage (stderr); short_usage (stderr);
exit (1); exit (1);
} }
if (key_pos - key_positions == Positions::MAX_KEY_POS + 1) if (key_pos - key_positions == Positions::MAX_SIZE)
{ {
/* More than Positions::MAX_KEY_POS + 1 key positions. /* More than Positions::MAX_SIZE key positions.
Since all key positions are in the range Since all key positions are in the range
1..Positions::MAX_KEY_POS or == Positions::LASTCHAR, 0..Positions::MAX_KEY_POS-1 or == Positions::LASTCHAR,
there must be duplicates. */ there must be duplicates. */
fprintf (stderr, "Duplicate key positions selected\n"); fprintf (stderr, "Duplicate key positions selected\n");
short_usage (stderr); short_usage (stderr);
exit (1); exit (1);
} }
if (value != Positions::LASTCHAR)
/* We use 0-based indices in the class Positions. */
value = value - 1;
*key_pos = value; *key_pos = value;
} }

View File

@@ -674,7 +674,7 @@ Output::output_hash_function () const
/* Get the highest key position. */ /* Get the highest key position. */
key_pos = iter.next (); key_pos = iter.next ();
if (key_pos == Positions::LASTCHAR || key_pos <= _min_key_len) if (key_pos == Positions::LASTCHAR || key_pos < _min_key_len)
{ {
/* We can perform additional optimizations here: /* We can perform additional optimizations here:
Write it out as a single expression. Note that the values Write it out as a single expression. Note that the values
@@ -685,7 +685,7 @@ Output::output_hash_function () const
option[NOLENGTH] ? "" : "len + "); option[NOLENGTH] ? "" : "len + ");
if (_key_positions.get_size() == 2 if (_key_positions.get_size() == 2
&& _key_positions[0] == 1 && _key_positions[0] == 0
&& _key_positions[1] == Positions::LASTCHAR) && _key_positions[1] == Positions::LASTCHAR)
/* Optimize special case of "-k 1,$". */ /* Optimize special case of "-k 1,$". */
{ {
@@ -699,9 +699,9 @@ Output::output_hash_function () const
{ {
for (; key_pos != Positions::LASTCHAR; ) for (; key_pos != Positions::LASTCHAR; )
{ {
printf ("asso_values[%sstr[%d]", char_to_index, key_pos - 1); printf ("asso_values[%sstr[%d]", char_to_index, key_pos);
if (_alpha_inc[key_pos - 1]) if (_alpha_inc[key_pos])
printf ("+%u", _alpha_inc[key_pos - 1]); printf ("+%u", _alpha_inc[key_pos]);
printf ("]"); printf ("]");
if ((key_pos = iter.next ()) != PositionIterator::EOS) if ((key_pos = iter.next ()) != PositionIterator::EOS)
printf (" + "); printf (" + ");
@@ -725,7 +725,7 @@ Output::output_hash_function () const
option[NOLENGTH] ? "0" : "len", option[NOLENGTH] ? "0" : "len",
option[NOLENGTH] ? "len" : "hval"); option[NOLENGTH] ? "len" : "hval");
while (key_pos != Positions::LASTCHAR && key_pos > _max_key_len) while (key_pos != Positions::LASTCHAR && key_pos >= _max_key_len)
if ((key_pos = iter.next ()) == PositionIterator::EOS) if ((key_pos = iter.next ()) == PositionIterator::EOS)
break; break;
@@ -734,13 +734,13 @@ Output::output_hash_function () const
int i = key_pos; int i = key_pos;
do do
{ {
for ( ; i >= key_pos; i--) for ( ; i > key_pos; i--)
printf (" case %d:\n", i); printf (" case %d:\n", i);
printf (" hval += asso_values[%sstr[%d]", printf (" hval += asso_values[%sstr[%d]",
char_to_index, key_pos - 1); char_to_index, key_pos);
if (_alpha_inc[key_pos - 1]) if (_alpha_inc[key_pos])
printf ("+%u", _alpha_inc[key_pos - 1]); printf ("+%u", _alpha_inc[key_pos]);
printf ("];\n"); printf ("];\n");
key_pos = iter.next (); key_pos = iter.next ();

View File

@@ -35,7 +35,7 @@ bool
Positions::contains (int pos) const Positions::contains (int pos) const
{ {
unsigned int count = _size; unsigned int count = _size;
const unsigned char *p = _positions + _size - 1; const int *p = _positions + _size - 1;
for (; count > 0; p--, count--) for (; count > 0; p--, count--)
{ {
@@ -52,13 +52,13 @@ Positions::add (int pos)
{ {
unsigned int count = _size; unsigned int count = _size;
if (count == MAX_KEY_POS + 1) if (count == MAX_SIZE)
{ {
fprintf (stderr, "Positions::add internal error: overflow\n"); fprintf (stderr, "Positions::add internal error: overflow\n");
exit (1); exit (1);
} }
unsigned char *p = _positions + _size - 1; int *p = _positions + _size - 1;
for (; count > 0; p--, count--) for (; count > 0; p--, count--)
{ {
@@ -81,7 +81,7 @@ Positions::remove (int pos)
unsigned int count = _size; unsigned int count = _size;
if (count > 0) if (count > 0)
{ {
unsigned char *p = _positions + _size - 1; int *p = _positions + _size - 1;
if (*p == pos) if (*p == pos)
{ {
@@ -90,7 +90,7 @@ Positions::remove (int pos)
} }
if (*p < pos) if (*p < pos)
{ {
unsigned char prev = *p; int prev = *p;
for (;;) for (;;)
{ {
@@ -106,7 +106,7 @@ Positions::remove (int pos)
} }
if (*p > pos) if (*p > pos)
break; break;
unsigned char curr = *p; int curr = *p;
*p = prev; *p = prev;
prev = curr; prev = curr;
} }
@@ -123,17 +123,18 @@ Positions::print () const
bool first = true; bool first = true;
bool seen_LASTCHAR = false; bool seen_LASTCHAR = false;
unsigned int count = _size; unsigned int count = _size;
const unsigned char *p = _positions + _size - 1; const int *p = _positions + _size - 1;
for (; count > 0; p--, count--) for (; count > 0; p--)
{ {
count--;
if (*p == LASTCHAR) if (*p == LASTCHAR)
seen_LASTCHAR = true; seen_LASTCHAR = true;
else else
{ {
if (!first) if (!first)
printf (","); printf (",");
printf ("%d", *p); printf ("%d", *p + 1);
if (count > 0 && p[-1] == *p + 1) if (count > 0 && p[-1] == *p + 1)
{ {
printf ("-"); printf ("-");
@@ -143,7 +144,7 @@ Positions::print () const
count--; count--;
} }
while (count > 0 && p[-1] == *p + 1); while (count > 0 && p[-1] == *p + 1);
printf ("%d", *p); printf ("%d", *p + 1);
} }
first = false; first = false;
} }

View File

@@ -34,12 +34,17 @@ class Positions
friend class PositionReverseIterator; friend class PositionReverseIterator;
public: public:
/* Denotes the last char of a keyword, depending on the keyword's length. */ /* Denotes the last char of a keyword, depending on the keyword's length. */
enum { LASTCHAR = 0 }; enum { LASTCHAR = -1 };
/* Maximum key position specifiable by the user. /* Maximum key position specifiable by the user, 1-based.
Note that this must fit into the element type of _positions[], below. */ Note that MAX_KEY_POS-1 must fit into the element type of _positions[],
below. */
enum { MAX_KEY_POS = 255 }; enum { MAX_KEY_POS = 255 };
/* Maximum possible size. Since duplicates are eliminated and the possible
0-based positions are -1 .. MAX_KEY_POS-1, this is: */
enum { MAX_SIZE = MAX_KEY_POS + 1 };
/* Constructors. */ /* Constructors. */
Positions (); Positions ();
Positions (int pos1); Positions (int pos1);
@@ -56,7 +61,7 @@ public:
unsigned int get_size () const; unsigned int get_size () const;
/* Write access. */ /* Write access. */
unsigned char * pointer (); int * pointer ();
void set_size (unsigned int size); void set_size (unsigned int size);
/* Sorts the array in reverse order. /* Sorts the array in reverse order.
@@ -74,11 +79,9 @@ public:
private: private:
/* Number of positions. */ /* Number of positions. */
unsigned int _size; unsigned int _size;
/* Array of positions. 1 for the first char, 2 for the second char etc., /* Array of positions. 0 for the first char, 1 for the second char etc.,
LASTCHAR for the last char. LASTCHAR for the last char. */
Note that since duplicates are eliminated, the maximum possible size int _positions[MAX_SIZE];
is MAX_KEY_POS + 1. */
unsigned char _positions[MAX_KEY_POS + 1];
}; };
/* This class denotes an iterator through a set of byte positions. */ /* This class denotes an iterator through a set of byte positions. */
@@ -90,7 +93,7 @@ public:
PositionIterator (Positions const& positions); PositionIterator (Positions const& positions);
/* End of iteration marker. */ /* End of iteration marker. */
enum { EOS = -1 }; enum { EOS = -2 };
/* Retrieves the next position, or EOS past the end. */ /* Retrieves the next position, or EOS past the end. */
int next (); int next ();
@@ -110,7 +113,7 @@ public:
PositionReverseIterator (Positions const& positions); PositionReverseIterator (Positions const& positions);
/* End of iteration marker. */ /* End of iteration marker. */
enum { EOS = -1 }; enum { EOS = -2 };
/* Retrieves the next position, or EOS past the end. */ /* Retrieves the next position, or EOS past the end. */
int next (); int next ();

View File

@@ -84,7 +84,7 @@ Positions::get_size () const
/* Write access. */ /* Write access. */
INLINE unsigned char * INLINE int *
Positions::pointer () Positions::pointer ()
{ {
return _positions; return _positions;
@@ -103,7 +103,7 @@ Positions::sort ()
{ {
/* Bubble sort. */ /* Bubble sort. */
bool duplicate_free = true; bool duplicate_free = true;
unsigned char *base = _positions; int *base = _positions;
unsigned int len = _size; unsigned int len = _size;
for (unsigned int i = 1; i < len; i++) for (unsigned int i = 1; i < len; i++)

View File

@@ -251,10 +251,10 @@ Search::find_positions ()
{ {
int n = keyword1->_allchars_length; int n = keyword1->_allchars_length;
int i; int i;
for (i = 1; i < n; i++) for (i = 0; i < n - 1; i++)
{ {
unsigned char c1 = keyword1->_allchars[i-1]; unsigned char c1 = keyword1->_allchars[i];
unsigned char c2 = keyword2->_allchars[i-1]; unsigned char c2 = keyword2->_allchars[i];
if (option[UPPERLOWER]) if (option[UPPERLOWER])
{ {
if (c1 >= 'A' && c1 <= 'Z') if (c1 >= 'A' && c1 <= 'Z')
@@ -265,13 +265,13 @@ Search::find_positions ()
if (c1 != c2) if (c1 != c2)
break; break;
} }
if (i < n) if (i < n - 1)
{ {
int j; int j;
for (j = i + 1; j <= n; j++) for (j = i + 1; j < n; j++)
{ {
unsigned char c1 = keyword1->_allchars[j-1]; unsigned char c1 = keyword1->_allchars[j];
unsigned char c2 = keyword2->_allchars[j-1]; unsigned char c2 = keyword2->_allchars[j];
if (option[UPPERLOWER]) if (option[UPPERLOWER])
{ {
if (c1 >= 'A' && c1 <= 'Z') if (c1 >= 'A' && c1 <= 'Z')
@@ -282,7 +282,7 @@ Search::find_positions ()
if (c1 != c2) if (c1 != c2)
break; break;
} }
if (j > n) if (j >= n)
{ {
/* Position i is mandatory. */ /* Position i is mandatory. */
if (!mandatory.contains (i)) if (!mandatory.contains (i))
@@ -295,8 +295,8 @@ Search::find_positions ()
} }
/* 2. Add positions, as long as this decreases the duplicates count. */ /* 2. Add positions, as long as this decreases the duplicates count. */
int imax = (_max_key_len < Positions::MAX_KEY_POS int imax = (_max_key_len - 1 < Positions::MAX_KEY_POS - 1
? _max_key_len : Positions::MAX_KEY_POS); ? _max_key_len - 1 : Positions::MAX_KEY_POS - 1);
Positions current = mandatory; Positions current = mandatory;
unsigned int current_duplicates_count = count_duplicates_tuple (current); unsigned int current_duplicates_count = count_duplicates_tuple (current);
for (;;) for (;;)
@@ -304,7 +304,7 @@ Search::find_positions ()
Positions best; Positions best;
unsigned int best_duplicates_count = UINT_MAX; unsigned int best_duplicates_count = UINT_MAX;
for (int i = imax; i >= 0; i--) for (int i = imax; i >= -1; i--)
if (!current.contains (i)) if (!current.contains (i))
{ {
Positions tryal = current; Positions tryal = current;
@@ -315,7 +315,7 @@ Search::find_positions ()
or if it produces the same number of duplicates but with or if it produces the same number of duplicates but with
a more efficient hash function. */ a more efficient hash function. */
if (try_duplicates_count < best_duplicates_count if (try_duplicates_count < best_duplicates_count
|| (try_duplicates_count == best_duplicates_count && i > 0)) || (try_duplicates_count == best_duplicates_count && i >= 0))
{ {
best = tryal; best = tryal;
best_duplicates_count = try_duplicates_count; best_duplicates_count = try_duplicates_count;
@@ -337,7 +337,7 @@ Search::find_positions ()
Positions best; Positions best;
unsigned int best_duplicates_count = UINT_MAX; unsigned int best_duplicates_count = UINT_MAX;
for (int i = imax; i >= 0; i--) for (int i = imax; i >= -1; i--)
if (current.contains (i) && !mandatory.contains (i)) if (current.contains (i) && !mandatory.contains (i))
{ {
Positions tryal = current; Positions tryal = current;
@@ -348,7 +348,7 @@ Search::find_positions ()
or if it produces the same number of duplicates but with or if it produces the same number of duplicates but with
a more efficient hash function. */ a more efficient hash function. */
if (try_duplicates_count < best_duplicates_count if (try_duplicates_count < best_duplicates_count
|| (try_duplicates_count == best_duplicates_count && i == 0)) || (try_duplicates_count == best_duplicates_count && i == -1))
{ {
best = tryal; best = tryal;
best_duplicates_count = try_duplicates_count; best_duplicates_count = try_duplicates_count;
@@ -370,9 +370,9 @@ Search::find_positions ()
Positions best; Positions best;
unsigned int best_duplicates_count = UINT_MAX; unsigned int best_duplicates_count = UINT_MAX;
for (int i1 = imax; i1 >= 0; i1--) for (int i1 = imax; i1 >= -1; i1--)
if (current.contains (i1) && !mandatory.contains (i1)) if (current.contains (i1) && !mandatory.contains (i1))
for (int i2 = imax; i2 >= 0; i2--) for (int i2 = imax; i2 >= -1; i2--)
if (current.contains (i2) && !mandatory.contains (i2) && i2 != i1) if (current.contains (i2) && !mandatory.contains (i2) && i2 != i1)
for (int i3 = imax; i3 >= 0; i3--) for (int i3 = imax; i3 >= 0; i3--)
if (!current.contains (i3)) if (!current.contains (i3))
@@ -389,7 +389,7 @@ Search::find_positions ()
a more efficient hash function. */ a more efficient hash function. */
if (try_duplicates_count < best_duplicates_count if (try_duplicates_count < best_duplicates_count
|| (try_duplicates_count == best_duplicates_count || (try_duplicates_count == best_duplicates_count
&& (i1 == 0 || i2 == 0 || i3 > 0))) && (i1 == -1 || i2 == -1 || i3 >= 0)))
{ {
best = tryal; best = tryal;
best_duplicates_count = try_duplicates_count; best_duplicates_count = try_duplicates_count;
@@ -422,7 +422,7 @@ Search::find_positions ()
seen_lastchar = true; seen_lastchar = true;
else else
{ {
fprintf (stderr, "%d", i); fprintf (stderr, "%d", i + 1);
first = false; first = false;
} }
} }
@@ -509,8 +509,8 @@ Search::compute_alpha_unify (const Positions& positions, const unsigned int *alp
unsigned int c; unsigned int c;
if (i == Positions::LASTCHAR) if (i == Positions::LASTCHAR)
c = static_cast<unsigned char>(keyword->_allchars[keyword->_allchars_length - 1]); c = static_cast<unsigned char>(keyword->_allchars[keyword->_allchars_length - 1]);
else if (i <= keyword->_allchars_length) else if (i < keyword->_allchars_length)
c = static_cast<unsigned char>(keyword->_allchars[i - 1]); c = static_cast<unsigned char>(keyword->_allchars[i]);
else else
continue; continue;
if (c >= 'A' && c <= 'Z') if (c >= 'A' && c <= 'Z')
@@ -518,7 +518,7 @@ Search::compute_alpha_unify (const Positions& positions, const unsigned int *alp
if (c >= 'a' && c <= 'z') if (c >= 'a' && c <= 'z')
{ {
if (i != Positions::LASTCHAR) if (i != Positions::LASTCHAR)
c += alpha_inc[i - 1]; c += alpha_inc[i];
/* Unify c with c - ('a'-'A'). */ /* Unify c with c - ('a'-'A'). */
unsigned int d = alpha_unify[c]; unsigned int d = alpha_unify[c];
unsigned int b = c - ('a'-'A'); unsigned int b = c - ('a'-'A');
@@ -622,7 +622,7 @@ Search::find_alpha_inc ()
if (key_pos == PositionIterator::EOS if (key_pos == PositionIterator::EOS
|| key_pos == Positions::LASTCHAR) || key_pos == Positions::LASTCHAR)
abort (); abort ();
indices[j] = key_pos - 1; indices[j] = key_pos;
} }
} }

View File

@@ -57,7 +57,6 @@ hash (str, len)
switch (hval) switch (hval)
{ {
default: default:
case 3:
hval += asso_values[(unsigned char)str[2]]; hval += asso_values[(unsigned char)str[2]];
case 2: case 2:
case 1: case 1:

View File

@@ -66,7 +66,6 @@ hash (str, len)
switch (hval) switch (hval)
{ {
default: default:
case 22:
hval += asso_values[(unsigned char)str[21]]; hval += asso_values[(unsigned char)str[21]];
case 21: case 21:
case 20: case 20:

View File

@@ -57,7 +57,6 @@ hash (str, len)
switch (hval) switch (hval)
{ {
default: default:
case 7:
hval += asso_values[(unsigned char)str[6]]; hval += asso_values[(unsigned char)str[6]];
case 6: case 6:
case 5: case 5:

View File

@@ -81,7 +81,6 @@ hash (str, len)
switch (hval) switch (hval)
{ {
default: default:
case 3:
hval += asso_values[(unsigned char)str[2]]; hval += asso_values[(unsigned char)str[2]];
case 2: case 2:
case 1: case 1:

View File

@@ -70,7 +70,6 @@ hash (str, len)
switch (hval) switch (hval)
{ {
default: default:
case 5:
hval += asso_values[(unsigned char)str[4]+1]; hval += asso_values[(unsigned char)str[4]+1];
case 4: case 4:
case 3: case 3:

View File

@@ -54,7 +54,6 @@ hash (str, len)
switch (len) switch (len)
{ {
default: default:
case 8:
hval += asso_values[(unsigned char)str[7]]; hval += asso_values[(unsigned char)str[7]];
case 7: case 7:
hval += asso_values[(unsigned char)str[6]]; hval += asso_values[(unsigned char)str[6]];

View File

@@ -57,7 +57,6 @@ hash (str, len)
switch (hval) switch (hval)
{ {
default: default:
case 3:
hval += asso_values[(unsigned char)str[2]]; hval += asso_values[(unsigned char)str[2]];
case 2: case 2:
case 1: case 1: