[prev in list] [next in list] [prev in thread] [next in thread]
List: aspell-user
Subject: [aspell] Re: Draft Interface for command Spell Checker API
From: Kevin Atkinson <kevinatk () home ! com>
Date: 2000-02-05 12:00:43
Message-ID: Pine.LNX.4.10.10002050659340.11116-200000 () kevins-linux
[Download RAW message or body]
On Sat, 5 Feb 2000, Kevin Atkinson wrote:
>
> Well the LyX developers managed to convince me to use C++ for my common
> C++ abi. What I decided to do is to have my ABI me portable enough to
> satisfy the major points of the mozilla portability guide lines
> (http://www.mozilla.org/hacking/portable-cpp.html, they have some really
> strange ones which I don't think apply any more. It also has not been
> updated in over a year and a half.) However, I will also provide a
> number of template classes to increase type safely and the ability to use
> exceptions.
>
> I have attached a draft of my proposed abi. Have fun riping it apart
> ;)
>
>
> PS: Please contunue to CC the aspell-user mailing list.
Oops. I forgot to attach the file. Here it is
---
Kevin Atkinson
kevinatk@home.com
http://metalab.unc.edu/kevina/
["interface.cc" (TEXT/PLAIN)]
// these will all be prefixed by the name of my portable library or an
// abbreviation of it.
class Object {
virtual Object * clone() const = 0;
// if the two objects are not of the exact same type
// the assign method is undefined.
virtual void assign(const Object *) = 0;
virtual void error_num() {return 0;}
virtaul const char * error_message() {return "";}
~Object() {}
}
// An emulation is an efficient way to iterate through elements much
// like a forward iterator. The at_end method is a convince method and
// as emulations will return a null pointer when they are at the end.
// Unlike an iterator iterating through x elements on a list can be
// done in x function calls while an iterator will require 3*x.
// function calls.
// Example of emulator usage
// const char * word;
// while ( (word = elements->next()) != 0) { // one function call
// cout << word << endl;
// }
// And an iterator
// iterator i = container->begin();
// iterator end = container->end();
// while (i != end) { // comparison, one function call
// cout << *i << endl; // deref, total of two function calls
// ++i; // increment, total of three function calls.
// }
// Normally all three calls are inline so it doesn't really matter
// but when the container type is not visible there are not inline
// and probably even virtual.
// If you really love iterators you can very easily wrap an emulation
// in a forward iterator.
class StringEmulation : public Object {
public:
virtual const char * next() = 0;
virtual bool at_end() const = 0;
};
class StringPair {
const char * first;
const char * second;
}
class StringPairEmulation : public Object {
public:
virtual StringPair next() = 0;
virtual bool at_end() const = 0;
virtual ~StringPairEmulation() {}
};
// Used by the Config class below...
class MutableContainer {
public:
virtual void insert(const char *) = 0;
virtual void remove(const char *) = 0;
virtual void clear() = 0;
virtual ~MutableContainer();
};
enum AddAction {Insert, Replace};
// A string map is a simple hash table where the key and values
// are strings. It also has the ability to write and read data
// files of a standard format.
// It is perfect for storing word pairs for "Replace All".
class StringMap : public MutableContainer, virtual public Object {
public:
PairEmulation * elements() const;
// allocated with new
virtual void insert(const char * key, const char * value) = 0;
// note: insert will NOT overwrite an existing entry
virtual void replace(const char * key, const char * value) = 0;
virtual void remove(const char * key) = 0;
virtual const char * lookup(const char * key) const = 0;
virtual bool have(const char * key) const = 0;
virtual void clear() = 0;
virtual void merge(const StringMap & other);
virtual void read_in_stream(istream &, char delim = '\n',
AddAction a = Replace);
virtual void read_in_file(const char *, AddAction a = Replace);
virtual void read_in_string(const char *, AddAction a = Replace);
virtual void write_to_stream(ostream &) const;
virtual void write_to_file(const char *) const;
};
struct KeyInfo {
const char * name;
enum Type {Bool, String, Int, List};
Type type;
const char * def;
const char * desc; // null if internal value
};
class KeyInfoEmulation {
...
};
// The Config class is used to hold configuration information.
// it has a set of keys which it will except. Inserting are even
// trying to look at a key that it does not know will produce
// an error. Extra accepted keys can be added with the set_extra
// method.
class Config : public StringMap {
public:
private:
void set_extra(const KeyInfo * begin, const KeyInfo * end);
virtual const KeyInfo * keyinfo(const char * key) const = 0
virtual KeyInfoEmulation * possible_elements(bool include_extra = true) const = 0;
// allocates with new
virtual string get_default(const char * key) const = 0;
// these unlike lookup will
// a) return the default if the value is not set
// b) give an error if the key is not requested as known
// c) give an error if the value is not in the right format
virtual string retrieve (const char * key) const = 0;
virtual string retrieve_list (const char * key) const = 0;
virtual void retrieve_list (const char * key, MutableContainer &) const = 0;
virtual bool retrieve_bool(const char * key) const = 0;
virtual int retrieve_int(const char * key) const = 0;
// This will read in the configuration from a set of files and
// environmental variables specific to the particular spell checker
// used.
void read_in();
};
// This class is responsible for keeping track of the dictionaries
// coming up with suggestions and the like
// Its methods are NOT meant to be used my multiple threads and/or
// documents.
// Most all if the manipulation of options is done via the Config
// class, thus this class has precious few methods
class Manager : public Object {
virtual Config & config() = 0;
virtual const Config & config () const = 0;
virtual const char * lang_name() const = 0;
bool check(const char * word) const;
void add_to_personal(const char *);
void add_to_session(const char *);
void save_all_wls();
void clear_session();
SuggestionList & suggest(const char * word);
// the suggestion list and the elements in it are only
// valid until the next call to suggest.
void store_repl(const char * mis, const char * cor);
};
class SuggestionList : public Object {
public:
virtual bool empty() const = 0;
virtual int size() const = 0;
virtual StringEmulation * elements() const = 0;
};
// these will also be some classes for checking a document which will
// be about like it was in my original plan but I have not worked the
// details of those classes out yet.
// There will also be a bunch of functions that will return various
// of the above classes allocated with new.
// Stuff like sharing dictionaries between different Managers and the
// like will be handles by these functions and by setting parameters in
// the Config class.
// Should I provide classes to directly access the individual word lists?
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic