home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-03-05 | 14.1 KB | 421 lines | [TEXT/ALFA] |
- // This may look like C code, but it is really -*- C++ -*-
- /*
- ************************************************************************
- *
- * Vocabulary service
- *
- * Multilevel/interrelated vocabularies with named slots are at the
- * center of everything
- *
- * Vocabularies are polymorphic: a vocabulary slot may contain a simple
- * data type (int, double, or a string, that is, const char *), a reference
- * to another vocabulary, or just a (sub)vocabulary. Homogeneous vocabulary
- * are those whose slots have exactly the same structure, which is reinforced
- * when new entries are added.
- * Vocabulary of vocabularies contains all full-fledged vocabularies: that
- * is, each vocabulary is inserted in some other (parent) vocabulary,
- * which in many cases is the Vocabulary of vocabularies (note, a
- * vocabulary can be referenced from many vocabulary slots).
- * A vocabulary path is a list of vocabularies to search for a named slot
- * in, in order of appearance in the path.
- *
- * Vocabularies can be referred to from within other vocabularies by
- * special vocabulary items, vocabulary references. A reference either
- * points to a vocabulary (when it's completely "resolved") or just
- * keeps the name of the referred vocabulary, which is to be looked up
- * when needed (lazy reference). The reference may also contain a file
- * name, from which the vocabulary would be loaded when it failed to
- * be located otherwise. If the file name is relative (that is, does
- * not start with '/'), it's prepended by dir names specified in
- * the special env variable VOCPATH.
- *
- * A vocabulary supports the main basic functions: lookup, insert, delete,
- * traverse. Looking up a slot (or a slot value) is the main function,
- * and exists in many varieties.
- * There is a function to look up a slot in the current dictionary,
- * in all dictionaries in the path (the top dictionary in the path
- * is searched first, the dictionary underneath is search only if the
- * lookup in the top dictionary failed, etc).
- *
- * Path search provides something like system-wide and specific
- * environments/databases (a hierarchy of system/local environments).
- * Previous incarnation of this pacakage was so-called task_env service
- *
- * Note, vocabulary objects and their slots are non-standard C++ objects.
- * There is no public constructor/destructor available for them.
- * When one creates a vocabulary, it is always inserted into the vocabulary
- * of vocabularies, and, at the same time, put at the top of the vocabulary
- * path (which makes it the current vocabulary). When an item is created, its
- * memory is allocated dynamically, and it is inserted automatically into
- * the current vocabulary. So, an item or a vocabulary cannot exist
- * by itself, not being a part of some vocabulary. Therefore, a user
- * is never given a vocabulary or slot object themselves, only references
- * to them.
- *
- * Note, a vocabulary can contain another vocabulary (or a reference to
- * another vocabulary). Subvocabularies are usually treated differently:
- * they are not inserted into the Vocabulary of vocabularies, rather they
- * are present only in the parent vocabulary (and die with it).
- *
- * $Id: voc.h,v 1.2 1997/03/04 21:02:18 oleg Exp oleg $
- *
- ************************************************************************
- */
-
- #ifndef __GNUC__
- #pragma once
- #endif
-
- #ifndef _voc_h
- #define _voc_h 1
-
- #ifdef __GNUC__
- #pragma interface
- #endif
-
- #include "myenv.h"
-
- //------------------------------------------------------------------------
- // Data structures that represent the vocabulary
- // Note the only operation one can do on Voc Items is to create them
- // through a special (non-standard) creator that always creates an
- // object on heap and places an item into the current vocabulary.
- // So a vocabulary item cannot exist by itself, it can only be in
- // some vocabulary
-
- #ifndef MSIPL_IOSTREAM_H
- class ostream; // Opaque i/o classes
- class istream;
- #endif
-
- class Voc; // Forward decl of the Vocabulary
- class VocRefItem; // Forward decl of the Vocabulary
- class VocPathPrivate;
-
- // This is an abstract class that describes
- // the most generic item
- class GenericVocItem
- {
- friend class Voc;
- friend class VocRefItem;
- friend class VocPathPrivate;
-
- public:
- enum Type { Int, Double, String, Vocab, VocRef, Last }; // Type of voc value
- union TypeSet // Union of all voc types
- { int _int; double _double; const char * _str; Voc * _voc; };
-
- private:
- GenericVocItem * next; // Ptr to the next element or 0
-
- // The following aren't implemented. But
- // since they are private, this makes any
- // (explicit or implicit) assignment impossible
- // GenericVocItem(const GenericVocItem& another);
- // GenericVocItem& operator=(const GenericVocItem& another);
-
- protected:
- char name[33]; // Name of the item, should not
- // contain "=" or non-ascii chars
- const enum Type val_type;
- // Item value would follow in the
- // derived classes
-
- // The derived classes must redefine the
- // following functions
- virtual TypeSet get_value(void) const = 0;
- virtual void write_down(ostream& outs) const;
-
- // Don't allow laymen to construct the item
- // or destroy it
- GenericVocItem(const char * _name, const Type type);
- virtual ~GenericVocItem(void) { assert( next == 0 ); }
-
- void catalog(void); // Add this item to the current vocabulary
-
- // Read in and parse val_type & name, create
- // and return an item of an appropriate
- // type
- static GenericVocItem * read_in(istream& ins);
-
- public:
- const char * q_name(void) const { return name; }
- enum Type q_type(void) const { return val_type; }
- virtual void print(const char * title) const;
- };
-
- // Some elementary voc items
- class IntVocItem : public GenericVocItem
- {
- friend class GenericVocItem;
-
- int value;
-
- IntVocItem(const char * _name, const int _val) :
- GenericVocItem(_name,GenericVocItem::Int), value(_val) {}
- IntVocItem(const char * _name, istream& ins); // read the value in
-
- // Standard interface
- virtual TypeSet get_value(void) const
- { TypeSet tset; tset._int = value; return tset; }
- virtual void write_down(ostream& outs) const;
-
- public:
- friend const IntVocItem & new_IntVocItem(const char * _name, const int _val)
- { IntVocItem& item = * new IntVocItem(_name,_val); item.catalog();
- return item; }
- // friend const IntVocItem & new_IntVocItem(const char * _name, istream& ins);
- virtual void print(const char * title) const;
- };
-
- class DoubleVocItem : public GenericVocItem
- {
- friend class GenericVocItem;
-
- double value;
-
- DoubleVocItem(const char * _name, const double _val) :
- GenericVocItem(_name,GenericVocItem::Double), value(_val) {}
- DoubleVocItem(const char * _name, istream& ins); // read the value in
-
- // Standard interface
- virtual TypeSet get_value(void) const
- { TypeSet tset; tset._double = value; return tset; }
- virtual void write_down(ostream& outs) const;
-
- public:
- friend const DoubleVocItem & new_DoubleVocItem(const char * _name,
- const double _val)
- { DoubleVocItem& item = * new DoubleVocItem(_name,_val);
- item.catalog(); return item; }
- // friend const DoubleVocItem & new_DoubleVocItem(const char * _name,
- // istream& ins);
- virtual void print(const char * title) const;
- };
-
- // String voc item
- class StrVocItem : public GenericVocItem
- {
- friend class GenericVocItem;
-
- const char * value;
-
- StrVocItem(const char * _name, const char * _val);
- StrVocItem(const char * _name, istream& ins); // read the value in
- ~StrVocItem(void);
-
- // Standard interface
- virtual TypeSet get_value(void) const
- { TypeSet tset; tset._str = value; return tset; }
- virtual void write_down(ostream& outs) const;
-
- public:
- friend const StrVocItem& new_StrVocItem(const char * _name,
- const char * _val)
- { StrVocItem& item = * new StrVocItem(_name,_val); item.catalog();
- return item; }
- const StrVocItem& new_StrVocItem(const char * _name, istream& ins);
- virtual void print(const char * title) const;
- };
-
-
- // Vocabulary: a collection of VocItem's
- class Voc : public GenericVocItem
- {
- friend class GenericVocItem;
- friend class VocRefItem;
- friend class VocPathPrivate;
-
- GenericVocItem * first;
- GenericVocItem * last;
-
- const char * comment;
-
- void ok_to_modify(void); // Make sure it's ok to modify; set
- // the dirty bit if so
-
- // if the dictionary is homogeneous
- void homogenity_checking(GenericVocItem& item);
- // and non-empty, the item being added
- // should be structurally equivalent
- // to the item on the top of the
- // dictionary
-
-
- void VocOfVoc_catalog(void); // Add this Voc to the VocOfVoc
- void make_current(void); // Make this vocabulary current
-
- // Find a slot with the specified name and
- // type. Return 0 if not found
- virtual GenericVocItem * find(const char * _name, const Type type) const;
-
- protected:
- enum Option { ReadOnly = 1, Homogeneous = 2, Dirty = 8 } options;
- int check_option(const Option opt) const { return options & opt; }
- void set_option(const Option opt) { (int&)options |= opt; }
- void reset_option(const Option opt) { (int&)options &= ~opt; }
-
- Voc(const char * name, const char * comment);
- ~Voc(void);
-
- Voc(istream& ins); // Load from the istream
- static Voc& load(const char * file_name); // Load from the file (using
- // VOCPATH) & catalog
-
- virtual TypeSet get_value(void) const
- { TypeSet tset; tset._voc = (Voc *)this; return tset; }
- virtual void write_down(ostream& outs) const;
-
- void operator += (GenericVocItem& item); // Add an item at the top
- GenericVocItem& remove_top(void); // Remove the item at the top
-
- public:
- // Create an empty dictionary and make it
- // current
- friend Voc& new_Voc(const char * _name, const char * _comment)
- { Voc& voc = * new Voc(_name,_comment);
- voc.VocOfVoc_catalog(); voc.make_current(); return voc; }
-
- // Read in a dictionary and make it
- // current
- friend Voc& new_Voc(istream& ins)
- { Voc& voc = * new Voc(ins);
- voc.VocOfVoc_catalog(); voc.make_current(); return voc; }
-
- // Create an empty dictionary and insert it
- // into the current vocabulary
- friend Voc& new_subVoc(const char * _name, const char * _comment)
- { Voc& voc = * new Voc(_name,_comment);
- voc.catalog(); return voc; }
-
-
- void info(void) const; // Just give brief info about the voc
-
- // Deep vocabulary printing
- virtual void print(const char * title) const;
-
- friend ostream& operator << (ostream& outs, const Voc& voc)
- { voc.write_down(outs); return outs; }
-
- int q_empty(void) const { return first == 0; }
- const GenericVocItem& top(void) const;
- const GenericVocItem& bottom(void) const;
- int count(void) const; // How many items in a dictionary
-
-
- // Retrieving functions, raise an exception if
- // the slot is not found
- const char * find_str(const char * name) const;
- int find_int(const char * name) const;
- double find_double(const char * name) const;
- Voc& find_voc(const char * name) const;
-
- // Retrieving functions with a default value
- // (which is returned if the slot is not found)
- const char * find_with_default(const char * name,
- const char * default_val) const;
- int find_with_default(const char * name,
- const int default_val) const;
- double find_with_default(const char * name,
- const double default_val) const;
- Voc& find_with_default(const char * name,
- Voc& default_val) const;
- };
-
- // Voc reference item - reference to another
- // vocabulary. The vocabulary may already
- // exist, or it can be represented by its
- // file name. It would be loaded when this
- // VocRefItem gets "dereferenced"
- class VocRefItem : public GenericVocItem
- {
- friend class Voc;
- friend class GenericVocItem;
- friend class VocPathPrivate;
-
- Voc * value;
- const char * voc_file_name;
-
- VocRefItem(const Voc& _voc) : // Refer to an existing vocabulary
- GenericVocItem(_voc.q_name(),GenericVocItem::VocRef),
- value((Voc *)&_voc), voc_file_name(0) {}
- VocRefItem(const char * name); // Look up the named vocabulary
- // and take its reference
-
- // Create a proxy
- VocRefItem(const char * name, const char * file_name);
-
- ~VocRefItem(void);
-
- // Standard interface
- virtual TypeSet get_value(void) const; // Loads when necessary
- virtual void write_down(ostream& outs) const;
-
- public:
- friend const VocRefItem& new_VocRefItem(Voc& _val)
- { VocRefItem& item = * new VocRefItem(_val); item.catalog();
- return item; }
- friend const VocRefItem& new_VocRefItem(const char * voc_name)
- { VocRefItem& item = * new VocRefItem(voc_name); item.catalog();
- return item; }
- friend const VocRefItem& new_VocProxy(const char * voc_name,
- const char * voc_file_name)
- { VocRefItem& item = * new VocRefItem(voc_name,voc_file_name);
- item.catalog(); return item; }
- virtual void print(const char * title) const;
- };
-
- void print_all_vocabularies(void);
-
- extern Voc& Dummy_Voc;
-
- class VocPathPrivate;
- // Path of current vocabularies
- // Note the current class provides only access
- // to the path, the path (data) are allocated
- // beforehand and stay this way
- class VocPath
- {
- friend class VocPathPrivate;
-
- public:
- static void print(void);
-
- // Retrieving functions, raise an exception if
- // the slot is not found
- static const char * find_str(const char * name);
- static int find_int(const char * name);
- static double find_double(const char * name);
- static Voc& find_voc(const char * name);
-
- // Retrieving functions with a default value
- // (which is returned if the slot is not found)
- static const char * find_with_default(const char * name,
- const char * default_val);
- static int find_with_default(const char * name,
- const int default_val);
- static double find_with_default(const char * name,
- const double default_val);
- static Voc& find_with_default(const char * name,
- Voc& default_val);
-
- // Find a vocabulary with a specified name
- static void push(const char * name);
- // (in all the vocab in the path) and put it
- // at the top of the stack
- static void pop(void); // Remove the top (current) vocabulary
-
- };
-
- // Mark the current state of the VocPath stack
- class VocPathMark
- {
- const int vocpath_count;
- public:
- void back_off(void) const; // Back off to the marked state of VPath
- VocPathMark(void); // Note the current state of VocPath
- ~VocPathMark(void) { back_off(); }
- };
-
- #endif
-