📄 refer.cxx
字号:
//{{{ Banner //============================================================================//// refer.cxx//// Implementation of the CdlReference and CdlReferrer classes.////============================================================================//####COPYRIGHTBEGIN####// // ----------------------------------------------------------------------------// Copyright (C) 1999, 2000 Red Hat, Inc.//// This file is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// ----------------------------------------------------------------------------// //####COPYRIGHTEND####//============================================================================//#####DESCRIPTIONBEGIN####//// Author(s): bartv// Contact(s): bartv// Date: 1999/02/01// Version: 0.02////####DESCRIPTIONEND####//============================================================================//}}}//{{{ #include's // ----------------------------------------------------------------------------#include "cdlconfig.h"// Get the infrastructure types, assertions, tracing and similar// facilities.#include <cyg/infra/cyg_ass.h>#include <cyg/infra/cyg_trac.h>// <cdlcore.hxx> defines everything implemented in this module.// It implicitly supplies <string>, <vector> and <map> because// the class definitions rely on these headers.#include <cdlcore.hxx>//}}}//{{{ Statics // ----------------------------------------------------------------------------CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlReference);CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlReferrer);//}}}//{{{ CdlReference class // ----------------------------------------------------------------------------// The default constructor. This should not normally get invoked, instead// a string argument should be supplied. However it is occasionally useful// to construct a reference and then set the name later.CdlReference::CdlReference(){ CYG_REPORT_FUNCNAME("CdlReference:: default constructor"); CYG_REPORT_FUNCARG1XV(this); dest_name = ""; dest = 0; cdlreference_cookie = CdlReference_Magic; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}// This constructor typically gets used when parsing a property.// The object may be created either on the stack or in the heap,// depending on the requirements of the property. During a later// phase in the parsing process the object may get bound.CdlReference::CdlReference(const std::string dest_arg){ CYG_REPORT_FUNCNAME("CdlReference:: constructor"); CYG_REPORT_FUNCARG1("this %p", this); CYG_PRECONDITIONC("" != dest_arg); dest_name = dest_arg; dest = 0; cdlreference_cookie = CdlReference_Magic; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}// For some properties, notably LocalReference ones, it is convenient// to create a temporary reference object on the stack and then// derive the property from the temporary. This requires the// copy constructor. When this operation is used the object// should still be unbound.CdlReference::CdlReference(const CdlReference& orig){ CYG_REPORT_FUNCNAME("CdlReference:: copy constructor"); CYG_REPORT_FUNCARG2("this %p, orig %p", this, &orig); CYG_INVARIANT_CLASSC(CdlReference, orig); CYG_PRECONDITIONC(0 == orig.dest); dest_name = orig.dest_name; dest = 0; cdlreference_cookie = CdlReference_Magic; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}// The assignment operator may be needed for similar reasons.CdlReference&CdlReference::operator=(const CdlReference& orig){ CYG_REPORT_FUNCNAME("CdlReference:: assignment operator"); CYG_REPORT_FUNCARG2("this %p, orig %p", this, &orig); CYG_INVARIANT_CLASSC(CdlReference, orig); CYG_PRECONDITIONC(0 == orig.dest); if (this != &orig) { dest_name = orig.dest_name; dest = 0; cdlreference_cookie = CdlReference_Magic; } CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN(); return *this;} // The destructor should only get invoked when a package is unloaded.// All appropriate clean-ups should have happened already, in particular// the reference should not currently be bound.CdlReference::~CdlReference(){ CYG_REPORT_FUNCNAME("CdlReference:: destructor"); CYG_REPORT_FUNCARG1("this %p", this); CYG_PRECONDITION_THISC(); CYG_PRECONDITIONC(0 == dest); cdlreference_cookie = CdlReference_Invalid; dest_name = ""; CYGDBG_MEMLEAK_DESTRUCTOR(); CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// Accessing the fields.voidCdlReference::set_destination_name(const std::string name){ CYG_REPORT_FUNCNAME("CdlReference::set_destination_name"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CYG_PRECONDITIONC((0 == dest) && ("" == dest_name)); dest_name = name; CYG_REPORT_RETURN();}const std::string&CdlReference::get_destination_name(void) const{ CYG_REPORT_FUNCNAME("CdlReference::get_destination_name"); CYG_REPORT_FUNCARG1("this %p", this); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return dest_name;}CdlNodeCdlReference::get_destination() const{ CYG_REPORT_FUNCNAMETYPE("CdlReference::get_destination", "result %p"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CdlNode result = dest; CYG_REPORT_RETVAL(result); return result;}boolCdlReference::check_this(cyg_assert_class_zeal zeal) const{ if (CdlReference_Magic != cdlreference_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); switch(zeal) { case cyg_system_test: case cyg_extreme: // There is not enough information in the reference // object itself to allow for a check for a corresponding // referrer object. If more debugability is needed // then extra data will have to be stored. // // However, it is possible to do a basic check of dest itself. if (0 != dest) { if (!dest->check_this(cyg_quick)) { return false; } } case cyg_thorough: if (0 != dest) { if (dest_name != dest->get_name()) { return false; } } case cyg_quick: case cyg_trivial: case cyg_none : default : break; } return true;}// ----------------------------------------------------------------------------// Binding. This is simply a case of filling in some fields in the reference// object and pushing a new referrer object. Binding generally happens as// a result of calling reference update handlers when a package gets loaded.voidCdlReference::bind(CdlNode src_arg, CdlProperty src_prop_arg, CdlNode dest_arg){ CYG_REPORT_FUNCNAME("CdlReference::bind"); CYG_REPORT_FUNCARG4XV(this, src_arg, src_prop_arg, dest_arg); CYG_INVARIANT_THISC(CdlReference); CYG_PRECONDITION_CLASSC(src_arg); CYG_PRECONDITION_CLASSC(src_prop_arg); CYG_PRECONDITION_CLASSC(dest_arg); CYG_ASSERTC(dest_name == dest_arg->get_name()); CdlReferrer local_copy; local_copy.source = src_arg; local_copy.source_property = src_prop_arg; dest_arg->referrers.push_back(local_copy); dest = dest_arg; CYG_REPORT_RETURN();}// Unbinding involves finding and removing the appropriate referrer object (there// may be several, but each will result in a separate unbind() call.)voidCdlReference::unbind(CdlNode src_arg, CdlProperty src_prop_arg){ CYG_REPORT_FUNCNAME("CdlReference::unbind"); CYG_REPORT_FUNCARG3XV(this, src_arg, src_prop_arg); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(src_arg); CYG_PRECONDITION_CLASSC(src_prop_arg); if (0 != dest) { std::vector<CdlReferrer>::iterator ref_i; for (ref_i = dest->referrers.begin(); ref_i != dest->referrers.end(); ref_i++) { if ((ref_i->source == src_arg) && (ref_i->source_property == src_prop_arg)) { dest->referrers.erase(ref_i); break; } } } dest = 0; CYG_REPORT_RETURN();}//}}}//{{{ CdlReferrer class // ----------------------------------------------------------------------------// The constructors etc. should only get invoked from// CdlReference::bind() and unbind(). However because Referrer objects// get held in STL vectors/lists/whatever it is hard to know exactly// what will happen when, so assertions are a bit thin on the ground.CdlReferrer::CdlReferrer(){ CYG_REPORT_FUNCNAME("CdlReferrer:: default constructor"); CYG_REPORT_FUNCARG1XV(this); source = 0; source_property = 0; cdlreferrer_cookie = CdlReferrer_Magic; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}CdlReferrer::CdlReferrer(const CdlReferrer& original){ CYG_REPORT_FUNCNAME("CdlReferrer:: copy constructor"); CYG_REPORT_FUNCARG2XV(this, &original); CYG_PRECONDITION_CLASSOC(original); source = original.source; source_property = original.source_property; cdlreferrer_cookie = CdlReferrer_Magic; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}CdlReferrer&CdlReferrer::operator=(const CdlReferrer& original){ CYG_REPORT_FUNCNAME("CdlReferrer:: assignment operator"); CYG_REPORT_FUNCARG2XV(this, &original); CYG_PRECONDITION_CLASSOC(original); if (this != &original) { source = original.source; source_property = original.source_property; cdlreferrer_cookie = CdlReferrer_Magic; } CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN(); return *this;}CdlReferrer::~CdlReferrer(){ CYG_REPORT_FUNCNAME("CdlReferrer:: destructor"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); cdlreferrer_cookie = CdlReferrer_Magic; source = 0; source_property = 0; CYGDBG_MEMLEAK_DESTRUCTOR(); CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// This routine is the main reason for having reference and referrer// objects around in the first place. It allows changes to an entity// to be propagated back to anything else interested in the entity.voidCdlReferrer::update(CdlTransaction transact, CdlNode dest_arg, CdlUpdate change){ CYG_REPORT_FUNCNAME("CdlReferrer::update"); CYG_REPORT_FUNCARG4XV(this, transact, dest_arg, change); CYG_PRECONDITION_THISC(); source_property->update(transact, source, dest_arg, change); CYG_REPORT_RETURN();}CdlNodeCdlReferrer::get_source() const{ CYG_REPORT_FUNCNAMETYPE("CdlReferrer::get_source", "result %p"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CdlNode result = source; CYG_REPORT_RETVAL(result); return result;}CdlPropertyCdlReferrer::get_source_property() const{ CYG_REPORT_FUNCNAMETYPE("CdlReferrer::get_source_property", "result %p"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CdlProperty result = source_property; CYG_REPORT_RETVAL(result); return result;}boolCdlReferrer::check_this(cyg_assert_class_zeal zeal) const{ if (CdlReferrer_Magic != cdlreferrer_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); switch(zeal) { case cyg_system_test : case cyg_extreme: case cyg_thorough: if (0 != source) { if (!source->check_this(cyg_quick)) { return false; } } if (0 != source_property) { if (!source_property->check_this(cyg_quick)) { return false; } } case cyg_quick: case cyg_trivial: case cyg_none: break; } return true;}//}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -