1
0
mirror of https://git.savannah.gnu.org/git/gperf.git synced 2025-12-02 13:09:22 +00:00

Class PositionStringParser replaces class Iterator.

This commit is contained in:
Bruno Haible
2002-11-06 13:28:32 +00:00
parent 5de859e402
commit 4c0ed264be
5 changed files with 84 additions and 150 deletions

View File

@@ -1,5 +1,13 @@
2002-10-03 Bruno Haible <bruno@clisp.org>
* src/iterator.h: Remove file.
* src/iterator.cc: Remove file.
* src/options.cc: (PositionStringParser): New class, taken from old
iterator.cc.
* src/Makefile.in (OBJECTS): Remove iterator.o.
(ITERATOR_H): Remove variable.
(iterator.o): Remove rule.
* src/keyword-list.h: New file.
* src/keyword-list.cc: New file.
* src/list-node.h: Remove file.

View File

@@ -59,7 +59,7 @@ SHELL = /bin/sh
VPATH = $(srcdir)
OBJECTS = options.o iterator.o main.o gen-perf.o key-list.o \
OBJECTS = options.o main.o gen-perf.o key-list.o \
hash-table.o bool-array.o read-line.o vectors.o version.o \
keyword.o keyword-list.o
LIBS = ../lib/libgp.a @GPERF_LIBM@
@@ -88,7 +88,6 @@ VECTORS_H = vectors.h
READ_LINE_H = read-line.h read-line.icc
OPTIONS_H = options.h options.icc
KEY_LIST_H = key-list.h $(VECTORS_H) $(READ_LINE_H)
ITERATOR_H = iterator.h
HASH_TABLE_H = hash-table.h
BOOL_ARRAY_H = bool-array.h bool-array.icc $(OPTIONS_H)
GEN_PERF_H = gen-perf.h $(KEY_LIST_H) $(BOOL_ARRAY_H)
@@ -99,13 +98,11 @@ gen-perf.o : gen-perf.cc $(GEN_PERF_H) $(OPTIONS_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/gen-perf.cc
hash-table.o : hash-table.cc $(HASH_TABLE_H) $(OPTIONS_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/hash-table.cc
iterator.o : iterator.cc $(ITERATOR_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/iterator.cc
key-list.o : key-list.cc $(KEY_LIST_H) $(OPTIONS_H) $(READ_LINE_H) $(HASH_TABLE_H) $(VERSION_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/key-list.cc
main.o : main.cc $(OPTIONS_H) $(GEN_PERF_H) $(CONFIG_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/main.cc
options.o : options.cc $(OPTIONS_H) $(ITERATOR_H) $(VECTORS_H) $(VERSION_H)
options.o : options.cc $(OPTIONS_H) $(VECTORS_H) $(VERSION_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/options.cc
read-line.o : read-line.cc $(READ_LINE_H) $(OPTIONS_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/read-line.cc

View File

@@ -1,84 +0,0 @@
/* Provides an Iterator for keyword characters.
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.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include "iterator.h"
#include <ctype.h>
/* Constructor for Iterator. */
Iterator::Iterator (const char *s, int lo, int hi, int word_end, int bad_val, int key_end)
{
end = key_end;
error_value = bad_val;
end_word = word_end;
str = s;
hi_bound = hi;
lo_bound = lo;
}
/* Provide an Iterator, returning the ``next'' value from
the list of valid values given in the constructor. */
int
Iterator::operator() (void)
{
/* Variables to record the Iterator's status when handling ranges, e.g., 3-12. */
static int size;
static int curr_value;
static int upper_bound;
if (size)
{
if (++curr_value >= upper_bound)
size = 0;
return curr_value;
}
else
{
while (*str)
switch (*str)
{
default: return error_value;
case ',': str++; break;
case '$': str++; return end_word;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
for (curr_value = 0; isdigit ((unsigned char)(*str)); str++)
curr_value = curr_value * 10 + (*str - '0');
if (*str == '-')
{
for (size = 1, upper_bound = 0;
isdigit ((unsigned char)(*++str));
upper_bound = upper_bound * 10 + (*str - '0'));
if (upper_bound <= curr_value || upper_bound > hi_bound)
return error_value;
}
return curr_value >= lo_bound && curr_value <= hi_bound
? curr_value : error_value;
}
return end;
}
}

View File

@@ -1,51 +0,0 @@
/* This may look like C code, but it is really -*- C++ -*- */
/* Provides an Iterator for keyword characters.
Copyright (C) 1989-1998 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
GNU GPERF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU GPERF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU GPERF; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Provides an Iterator that expands and decodes a control string containing digits
and ranges, returning an integer every time the generator function is called.
This is used to decode the user's key position requests. For example:
"-k 1,2,5-10,$" will return 1, 2, 5, 6, 7, 8, 9, 10, and 0 ( representing
the abstract ``last character of the key'' on successive calls to the
member function operator ().
No errors are handled in these routines, they are passed back to the
calling routines via a user-supplied Error_Value */
#ifndef iterator_h
#define iterator_h 1
class Iterator
{
private:
const char *str; /* A pointer to the string provided by the user. */
int end; /* Value returned after last key is processed. */
int end_word; /* A value marking the abstract ``end of word'' ( usually '$'). */
int error_value; /* Error value returned when input is syntactically erroneous. */
int hi_bound; /* Greatest possible value, inclusive. */
int lo_bound; /* Smallest possible value, inclusive. */
public:
Iterator (const char *s, int lo, int hi, int word_end, int bad_val, int key_end);
int operator () (void);
};
#endif

View File

@@ -21,9 +21,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include <stdio.h>
#include <stdlib.h> /* declares atoi(), abs(), exit() */
#include <string.h> /* declares strcmp() */
#include <ctype.h> /* declares isdigit() */
#include "getopt.h"
#include "options.h"
#include "iterator.h"
#include "vectors.h"
#include "version.h"
@@ -273,6 +273,70 @@ Options::print_options (void)
printf (" */");
}
/* Parses a string denoting key positions. */
class PositionStringParser
{
public:
PositionStringParser (const char *s, int lo, int hi, int word_end, int bad_val, int key_end);
int nextPosition ();
private:
const char *str; /* A pointer to the string provided by the user. */
int end; /* Value returned after last key is processed. */
int end_word; /* A value marking the abstract ``end of word'' ( usually '$'). */
int error_value; /* Error value returned when input is syntactically erroneous. */
int hi_bound; /* Greatest possible value, inclusive. */
int lo_bound; /* Smallest possible value, inclusive. */
int size;
int curr_value;
int upper_bound;
};
PositionStringParser::PositionStringParser (const char *s, int lo, int hi, int word_end, int bad_val, int key_end)
: str (s), end (key_end), end_word (word_end), error_value (bad_val), hi_bound (hi), lo_bound (lo),
size (0), curr_value (0), upper_bound (0)
{
}
int PositionStringParser::nextPosition ()
{
if (size)
{
if (++curr_value >= upper_bound)
size = 0;
return curr_value;
}
else
{
while (*str)
switch (*str)
{
default: return error_value;
case ',': str++; break;
case '$': str++; return end_word;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
for (curr_value = 0; isdigit ((unsigned char)(*str)); str++)
curr_value = curr_value * 10 + (*str - '0');
if (*str == '-')
{
for (size = 1, upper_bound = 0;
isdigit ((unsigned char)(*++str));
upper_bound = upper_bound * 10 + (*str - '0'));
if (upper_bound <= curr_value || upper_bound > hi_bound)
return error_value;
}
return curr_value >= lo_bound && curr_value <= hi_bound
? curr_value : error_value;
}
return end;
}
}
/* 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.
@@ -281,17 +345,17 @@ Options::print_options (void)
inline int
Options::key_sort (char *base, int len)
{
int i, j;
for (i = 0, j = len - 1; i < j; i++)
/* Bubble sort. */
for (int i = 1; i < len; i++)
{
int curr, tmp;
int j;
int 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!!! */
for (j = i, tmp = base[j]; j > 0 && tmp >= base[j - 1]; j--)
if ((base[j] = base[j - 1]) == tmp) /* oh no, a duplicate!!! */
return 0;
base[curr] = tmp;
base[j] = tmp;
}
return 1;
@@ -550,7 +614,7 @@ Options::operator() (int argc, char *argv[])
{
const int BAD_VALUE = -1;
int value;
Iterator expand (/*getopt*/optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS);
PositionStringParser sparser (/*getopt*/optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS);
if (/*getopt*/optarg [0] == '*') /* Use all the characters for hashing!!!! */
option_word = (option_word & ~DEFAULTCHARS) | ALLCHARS;
@@ -558,7 +622,7 @@ Options::operator() (int argc, char *argv[])
{
char *key_pos;
for (key_pos = key_positions; (value = expand ()) != EOS; key_pos++)
for (key_pos = key_positions; (value = sparser.nextPosition()) != EOS; key_pos++)
if (value == BAD_VALUE)
{
fprintf (stderr, "Illegal key value or range, use 1,2,3-%d,'$' or '*'.\n",