[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