⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdlcore.hxx

📁 eCos1.31版
💻 HXX
📖 第 1 页 / 共 5 页
字号:
// bidirectional: if a "requires" property in option A references// option B then it would be useful to have a link back to A from B;// that way, if the value of B changes it is a lot easier to keep// things up to date.//// Terminology: the entity which contains the reference, e.g. a// "requires" property, is the source. The relevant property is the// "source property". The entity pointed at is the destination.//// Unfortunately there may be connections between CDL entities outside// the tree hierarchy. In particular any property can contain one or// more references to packages, components, options, wizards, or// whatever. Often these references will be to options etc. within the// same package, but some references will go to other packages. There// may even be references to other configurations: for example a board// may contain both an ordinary processor and a DSP; these two need// their own configurations; however a package running on the DSP may// need to interact with a package running on the processor, and vice// versa.//// Also, a reference may occur inside an object that is not in the// hierarchy. For example CDL expressions may get evaluated inside Tcl// code rather than as part of a property. Such expressions may still// contain references to entities in the current configuration.//// References may not be resolved. When reading in a CDL script there// may be forward references. A reference may involve another package// that has not yet been loaded, which is a conflict.//// Using simple pointers to store these connections is a bad idea. It// makes it a lot harder to figure out what is connected to what, and// it introduces horrible consistency problems when packages get// loaded and unloaded. Instead libCDL provides a CdlReference class.// Whenever a CdlProperty contains a reference to some other CDL// entity there should be a CdlReference object corresponding to this.// The reverse direction is handled via a CdlReferrer object.//// A CdlReference object can be either bound or unbound. By default it// is unbound, containing only a string. It can then be bound via a// member function, examined, and unbound again as required. Creating// a binding automatically creates a CdlReferrer entry in the target// object, thus avoiding any risk of inconsistencies.//// The CdlReference class should not be used outside the hierarchy,// since every bound reference must have a referrer object pointing// back, and this link back can only be valid within the hierarchy.// Temporary CdlReference objects are useful during the construction// of properties.//// It is possible that a given property (e.g. a complicated "requires"// expression) has multiple references to another entity. Each of// these involves a separate CdlReference/CdlReferrer pair.// ----------------------------------------------------------------------------// The actual CdlReference class.class CdlReference {    friend class        CdlTest;    // CdlReferrer must be a friend so that when a package gets unloaded    // it can clean up all references to it.    friend class        CdlReferrer;      public:    // The default constructor should not normally be used, instead    // a string should be supplied. However there are vectors of    // reference objects...    CdlReference();        // The main constructor supplies the name of the referenced    // entity. The resulting object will be unbound.    CdlReference(const std::string);    // The copy constructor is legal for unbound objects only.    CdlReference(const CdlReference&);    // The assignment operator is needed for STL operations.    // Again it only makes sense of unbound objects.    CdlReference& operator=(const CdlReference&);        // The destructor is only valid for unbound objects. All references    // should be unbound before an entity can be destroyed.    ~CdlReference();        // Access the various fields.    void               set_destination_name(const std::string);    const std::string& get_destination_name() const;    CdlNode            get_destination() const;    // Binding a reference. Obviously this can only be used when the    // reference is still unbound. When doing the binding it is    // necessary to know:    //   (1) the object containing the reference.    //   (2) the specific property that contains the reference.    //   (3) the object being referred to.    // Binding a reference results in a new referrer entry in the    // destination.    void bind(CdlNode, CdlProperty, CdlNode);    // Unbinding a reference. Typically this only happens when the    // destination is unloaded. The arguments provide the source and    // the source property.    void unbind(CdlNode, CdlProperty);    // This is used by the ASSERT_CLASS() and ASSERT_THIS() macros.    bool check_this(cyg_assert_class_zeal cyg_quick) const;    CYGDBG_DECLARE_MEMLEAK_COUNTER();      protected:  private:        // The data fields. The name is usually filled in by the    // constructor. The destination defaults to zero for an unbound    // object and gets filled in by the bind() operation.    std::string dest_name;    CdlNode     dest;    enum {        CdlReference_Invalid = 0,        CdlReference_Magic   = 0x3f908608    } cdlreference_cookie;};// ----------------------------------------------------------------------------// The CdlNode class (and hence just about everything) contains a// vector of CdlReferrer objects. This keeps track of all entities// that refer to this one, so if the value associated with this// changes it is possible to work out the impact of this on all// entities that rely on this value.//// Arguably this should work in terms of CdlValuable objects rather// than CdlNode objects. However it is convenient to use references// for the connection between e.g. an option and a dialog, where// there is no value involved. The reverse connection is of little// use in this circumstance.//// CdlReferrer objects are rarely accessed directly. Instead they will// be filled in during a CdlReference::bind() operation and erased// during a CdlReference::unbind() operation. The only operations that// should be public allow access to the contained data.class CdlReferrer {    friend class        CdlTest;    // CdlReference::bind() and unbind() have direct access to the    // members, since these two functions are really responsible for    // creating and destroying referrer objects.    friend class        CdlReference;      public:    // The default constructor, copy constructor and assignment    // operator are all public to avoid problems with having vectors    // of referrer objects. Similarly the destructor is public.    // In practice updates actually happen as a consequence of    // CdlReference::bind() and CdlReference::unbind().    CdlReferrer();    CdlReferrer(const CdlReferrer&);    CdlReferrer& operator=(const CdlReferrer&);    ~CdlReferrer();    CdlNode     get_source() const;    CdlProperty get_source_property() const;    void        update(CdlTransaction, CdlNode, CdlUpdate);    bool        check_this(cyg_assert_class_zeal=cyg_quick) const;    CYGDBG_DECLARE_MEMLEAK_COUNTER();      private:    CdlNode     source;    CdlProperty source_property;        enum {        CdlReferrer_Invalid = 0,        CdlReferrer_Magic   = 0x70e1fc37    } cdlreferrer_cookie;};//}}}//{{{  Value and Expression  classes                    //{{{  CdlEvalContext                   // ----------------------------------------------------------------------------// Expression evaluation always happens within a certain context.// This may involve a transaction. Usually it involves a node and// a property within that node, although it is possible to evaluate// expressions from inside Tcl code.//// To avoid passing too many arguments around the various// evaluation-related routines, a utility class is provided.class CdlEvalContext {        friend class CdlTest;      public:    CdlTransaction      transaction;    CdlNode             node;    CdlProperty         property;    CdlToplevel         toplevel;    CdlEvalContext(CdlTransaction, CdlNode, CdlProperty, CdlToplevel = 0);    ~CdlEvalContext();        bool                check_this(cyg_assert_class_zeal = cyg_quick) const;    CYGDBG_DECLARE_MEMLEAK_COUNTER();      protected:  private:    // Illegal operation, the three fields must always be supplied,    // although they may be zero.    CdlEvalContext();    enum {        CdlEvalContext_Invalid  = 0,        CdlEvalContext_Magic    = 0x03434be9    } cdlevalcontext_cookie;    };//}}}//{{{  CdlSimpleValue                   // ----------------------------------------------------------------------------// Expression evaluation happens in terms of CdlSimpleValue objects.// In CDL all values are strings, but for the purposes of arithmetic// these strings sometimes have to be interpreted as integers or as// double precision numbers. Sometimes there is a choice, for example// the equality operator == can mean numerical or string comparison.// The basic rules that get applied are:////    1) if the current value has an integer representation then//       use this by preference. This means that an expression//       of the form (CYGNUM_XXX != 0x100) will do a integer//       comparison if possible.////    2) otherwise if the current value can be interpreted as a//       double precision number, use that representation.//       All integers can be interpreted as doubles (at the risk//       of some loss of precision), so the representation as//       a double should only be used if the integer representation//       is inappropriate.////    3) otherwise interpret the value as a string.//// The default value is 0.class CdlSimpleValue {        friend class CdlTest;  public:    CdlSimpleValue();    CdlSimpleValue(std::string);    CdlSimpleValue(cdl_int);    CdlSimpleValue(double);    CdlSimpleValue(const CdlSimpleValue&);    CdlSimpleValue(bool);    ~CdlSimpleValue();    CdlSimpleValue&     operator=(const CdlSimpleValue&);    CdlSimpleValue&     operator=(std::string);    CdlSimpleValue&     operator=(cdl_int);    CdlSimpleValue&     operator=(double);        CdlSimpleValue&     operator=(bool);        bool                operator==(const CdlSimpleValue&) const;    bool                operator!=(const CdlSimpleValue&) const;    bool                operator==(std::string arg) const    {        CdlSimpleValue val(arg);        return *this == val;    }    bool                operator==(cdl_int arg) const    {        CdlSimpleValue val(arg);        return *this == val;    }    bool                operator==(double arg) const    {        CdlSimpleValue val(arg);        return *this == val;    }    bool                operator!=(std::string arg) const    {        CdlSimpleValue val(arg);        return *this != val;    }    bool                operator!=(cdl_int arg) const    {        CdlSimpleValue val(arg);        return *this != val;    }    bool                operator!=(double arg) const    {        CdlSimpleValue val(arg);        return *this != val;    }        void                set_value(std::s

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -