// This file is part of The New Aspell // Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license // version 2.0 or 2.1. You should have received a copy of the LGPL // license along with this library if you did not you can find // it at http://www.gnu.org/. #ifndef ASPELL_CONFIG___HPP #define ASPELL_CONFIG___HPP #include "can_have_error.hpp" #include "key_info.hpp" #include "posib_err.hpp" #include "string.hpp" #include "vector.hpp" namespace acommon { class OStream; class KeyInfoEnumeration; class StringPairEnumeration; class MutableContainer; class Cacheable; struct Conv; // The Config class is used to hold configuration information. // it has a set of keys which it will except. Inserting or 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. // Keys taged with KEYINFO_UTF8 are expected to be in UTF-8 format. // Keys with file/dir names may contain 8-bit characters and must // remain untranslated // All other keys are expected to only contain ASCII characters. class Config; struct ConfigModule { const char * name; const char * file; // path of shared object or dll const char * desc; // description of module const KeyInfo * begin; const KeyInfo * end; }; class Notifier { public: // returns a copy if a copy should be made otherwise returns null virtual Notifier * clone(Config *) const {return 0;} virtual ~Notifier() {} virtual PosibErr item_updated(const KeyInfo *, bool) {return no_err;} virtual PosibErr item_updated(const KeyInfo *, int) {return no_err;} virtual PosibErr item_updated(const KeyInfo *, ParmStr) {return no_err;} virtual PosibErr list_updated(const KeyInfo *) {return no_err;} }; class PossibleElementsEmul; class NotifierEnumeration; class GetLine; class MDInfoListofLists; static const bool REPLACE = true; static const bool INSERT = false; // prefixes // // reset - resets a value to the default // // enable - sets a boolean value to true // dont, disable - sets a boolean value to false // -- setting a boolean value to an empty string is the same as setting // it to true // // lset - sets a list, items seperated by ':' // rem, remove - removes item from a list // add - add an item to a list // clear - removes all items from a list // -- setting a list item directly, ie with out a prefix, is the same as // setting it to a single value class Config : public CanHaveError { // copy and destructor provided friend class MDInfoListofLists; public: enum Action {NoOp, Set, Reset, Enable, Disable, ListSet, ListAdd, ListRemove, ListClear}; struct Entry { Entry * next; String key; String value; String file; unsigned line_num; Action action; bool need_conv; short place_holder; Entry() : line_num(0), action(NoOp), need_conv(false), place_holder(-1) {} }; private: static const int num_parms_[9]; public: static inline bool list_action(Action a) {return (int)a >= (int)ListAdd; } static inline int num_parms(Action a) {return num_parms_[a];} private: String name_; Entry * first_; Entry * * insert_point_; Entry * others_; bool committed_; bool attached_; // if attached can't copy Vector notifier_list; friend class PossibleElementsEmul; const KeyInfo * keyinfo_begin; const KeyInfo * keyinfo_end; const KeyInfo * extra_begin; const KeyInfo * extra_end; int md_info_list_index; void copy(const Config & other); void del(); PosibErr commit(Entry * entry, Conv * conv = 0); bool settings_read_in_; public: // the first // if the second parameter is set than flaged options will be // converted to utf-8 if needed PosibErr commit_all(Vector * = 0, const char * codeset = 0); PosibErr replace(ParmStr, ParmStr); PosibErr remove(ParmStr); bool empty() const {return !first_;} PosibErr merge(const Config & other); void lang_config_merge(const Config & other, int which, ParmStr codeset); bool settings_read_in() {return settings_read_in_;} PosibErr set_committed_state(bool val); const Entry * lookup(const char * key) const; void lookup_list(const KeyInfo * ki, MutableContainer & m, bool include_default) const; String temp_str; PosibErr (* load_filter_hook)(Config * config, ParmStr value); Notifier * filter_mode_notifier; Vector filter_modules; Vector filter_modules_ptrs; Config(ParmStr name, const KeyInfo * mainbegin, const KeyInfo * mainend); Config(const Config &); ~Config(); Config & operator= (const Config &); bool get_attached() const {return attached_;} void set_attached(bool a) {attached_ = a;} Config * clone() const; void assign(const Config * other); const char * name() const {return name_.c_str();} NotifierEnumeration * notifiers() const; bool add_notifier ( Notifier *); bool remove_notifier (const Notifier *); bool replace_notifier(const Notifier *, Notifier *); void set_extra(const KeyInfo * begin, const KeyInfo * end); void set_filter_modules(const ConfigModule * modbegin, const ConfigModule * modend); static const char * base_name(const char * name, Action * action = 0); PosibErr keyinfo(ParmStr key) const; KeyInfoEnumeration * possible_elements(bool include_extra = true, bool include_modules = true) const; StringPairEnumeration * elements() {return 0;} // FIXME String get_default(const KeyInfo * ki) const; PosibErr get_default(ParmStr) const; PosibErr retrieve(ParmStr key) const; // will also retrive a list, with one value per line PosibErr retrieve_any(ParmStr key) const; bool have (ParmStr key) const; PosibErr retrieve_list (ParmStr key, MutableContainer *) const; PosibErr retrieve_bool (ParmStr key) const; PosibErr retrieve_int (ParmStr key) const; // will take ownership of entry, even if there is an error PosibErr set(Entry * entry, bool do_unescape = false); void replace_internal (ParmStr, ParmStr); void write_to_stream(OStream & out, bool include_extra = false); PosibErr read_in_settings(const Config * = 0); PosibErr read_in(IStream & in, ParmStr id = ""); PosibErr read_in_file(ParmStr file); PosibErr read_in_string(ParmStr str, const char * what = ""); }; Config * new_config(); Config * new_basic_config(); // config which doesn't require any // external symbols class NotifierEnumeration { // no copy and destructor needed Vector::const_iterator i; Vector::const_iterator end; public: NotifierEnumeration(const Vector & b) : i(b.begin()), end(b.end()) {} const Notifier * next() { const Notifier * temp = *i; if (i != end) ++i; return temp; } bool at_end() const {return i == end;} }; class KeyInfoEnumeration { public: typedef const KeyInfo * Value; virtual KeyInfoEnumeration * clone() const = 0; virtual void assign(const KeyInfoEnumeration *) = 0; virtual bool at_end() const = 0; virtual const KeyInfo * next() = 0; virtual const char * active_filter_module_name(void) = 0; virtual const char * active_filter_module_desc(void) = 0; virtual bool active_filter_module_changed(void) = 0; virtual ~KeyInfoEnumeration() {} }; static const unsigned KEYINFO_MAY_CHANGE = 1 << 0; static const unsigned KEYINFO_UTF8 = 1 << 1; static const unsigned KEYINFO_HIDDEN = 1 << 2; static const unsigned KEYINFO_COMMON = 1 << 4; class AddableContainer; class StringList; void separate_list(ParmStr value, AddableContainer & out, bool do_unescape = true); void combine_list(String & res, const StringList &); } #endif