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

📄 base.cxx

📁 eCos1.31版
💻 CXX
📖 第 1 页 / 共 5 页
字号:
CdlLoadableBody::get_directory() const{    CYG_REPORT_FUNCNAME("CdlLoadable::get_directory");    CYG_REPORT_FUNCARG1XV(this);    CYG_PRECONDITION_THISC();    CYG_REPORT_RETURN();    return directory;}//}}}//{{{  Bind/unbind support                      // ----------------------------------------------------------------------------// Binding a loadable. This involves checking every property of every node// in the loadable, which the properties do themselves by a suitable// update() virtual function. Next, there may be properties in the// existing configuration which could not previously be bound: there// will be structural conflicts for all of these. Once all the pointers// go to the right places it is possible to calculate the default values// and generally process the properties. Finally each node's active// state is checked - the default inactive state will be inappropriate// in many cases.//// FIXME: error recovery?voidCdlLoadableBody::bind(CdlTransaction transaction){    CYG_REPORT_FUNCNAME("CdlLoadable::bind");    CYG_REPORT_FUNCARG2XV(this, transaction);    CYG_INVARIANT_THISC(CdlLoadableBody);    CYG_INVARIANT_CLASSC(CdlTransactionBody, transaction);    // The loadable must already be part of the hierarchy.    CdlToplevel toplevel = this->get_toplevel();    CYG_ASSERT_CLASSC(toplevel);            // As a first step, bind all references in this loadable.    // This is achieved via a Loaded update.    const std::vector<CdlNode>& nodes = this->get_owned();    std::vector<CdlNode>::const_iterator node_i;    for (node_i = nodes.begin(); node_i != nodes.end(); node_i++) {        const std::vector<CdlProperty>& properties = (*node_i)->get_properties();        std::vector<CdlProperty>::const_iterator prop_i;        for (prop_i = properties.begin(); prop_i != properties.end(); prop_i++) {            (*prop_i)->update(transaction, *node_i, 0, CdlUpdate_Loaded);        }    }    // Next, look for all structural conflicts which are unresolved    // references and which can now be resolved. It is necessary    // to check per-transaction structural conflicts, plus those    // in any parent transactions, plus the global ones.    std::list<CdlConflict>::const_iterator conf_i;    CdlTransaction current_transaction = transaction;    do {        CYG_ASSERT_CLASSC(current_transaction);        const std::list<CdlConflict>& new_structural_conflicts = current_transaction->get_new_structural_conflicts();                for (conf_i = new_structural_conflicts.begin(); conf_i != new_structural_conflicts.end(); ) {                        CdlConflict conflict = *conf_i++;            CYG_LOOP_INVARIANT_CLASSC(conflict);                        CdlConflict_Unresolved unresolved_conflict = dynamic_cast<CdlConflict_Unresolved>(conflict);            if ((0 != unresolved_conflict) && !transaction->has_conflict_been_cleared(conflict)) {                CdlNode dest = toplevel->lookup(unresolved_conflict->get_target_name());                if (0 != dest) {                    CdlNode     node = unresolved_conflict->get_node();                    CdlProperty prop = unresolved_conflict->get_property();                    prop->update(transaction, node, dest, CdlUpdate_Created);                }                                }        }        current_transaction = current_transaction->get_parent();    } while (0 != current_transaction);    const std::list<CdlConflict>& structural_conflicts = toplevel->get_all_structural_conflicts();    for (conf_i = structural_conflicts.begin(); conf_i != structural_conflicts.end(); ) {                CdlConflict conflict = *conf_i++;        CYG_LOOP_INVARIANT_CLASSC(conflict);                    CdlConflict_Unresolved this_conflict = dynamic_cast<CdlConflict_Unresolved>(conflict);        if ((0 != this_conflict) && !transaction->has_conflict_been_cleared(conflict)) {            CdlNode dest = toplevel->lookup(this_conflict->get_target_name());            if (0 != dest) {                CdlNode     node = this_conflict->get_node();                CdlProperty prop = this_conflict->get_property();                prop->update(transaction, node, dest, CdlUpdate_Created);            }        }    }    // Conflict resolution has happened. Next it is time    // to evaluate default_value expressions and the like    // in the new loadable.    for (node_i = nodes.begin(); node_i != nodes.end(); node_i++) {        const std::vector<CdlProperty>& properties = (*node_i)->get_properties();        std::vector<CdlProperty>::const_iterator prop_i;        for (prop_i = properties.begin(); prop_i != properties.end(); prop_i++) {            (*prop_i)->update(transaction, *node_i, 0, CdlUpdate_Init);        }    }    // Nodes start of inactive. Check each one whether or not it    // should be active.    // NOTE: possibly this should be done via a per-node init    // update instead.    for (node_i = nodes.begin(); node_i != nodes.end(); node_i++) {        bool current_state = transaction->is_active(*node_i);        bool new_state     = (*node_i)->test_active(transaction);        if (current_state != new_state) {            transaction->set_active(*node_i, new_state);        }    }    CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------voidCdlLoadableBody::unbind(CdlTransaction transaction){    CYG_REPORT_FUNCNAME("CdlLoadable::unbind");    CYG_REPORT_FUNCARG2XV(this, transaction);    CYG_PRECONDITION_THISC();    CYG_PRECONDITION_CLASSC(transaction);        // First take care of all references to nodes in the loadable    // that is disappearing. This involves a Destroyed update.    const std::vector<CdlNode>& nodes = this->get_owned();    std::vector<CdlNode>::const_iterator node_i;    for (node_i = nodes.begin(); node_i != nodes.end(); node_i++) {        // The update will remove referrer objects, so it is best        // to work from the back.        std::vector<CdlReferrer>& referrers = (*node_i)->referrers;        std::vector<CdlReferrer>::reverse_iterator ref_i;        for (ref_i = referrers.rbegin(); ref_i != referrers.rend(); ref_i = referrers.rbegin()) {            ref_i->update(transaction, *node_i, CdlUpdate_Destroyed);            CYG_LOOP_INVARIANT(ref_i != referrers.rbegin(), "the vector should have shrunk");        }    }    // Now repeat the loop, but unbind references from the unloaded objects    // to ones which are going to stay loaded. This will not cause    // the properties to disappear.    for (node_i = nodes.begin(); node_i != nodes.end(); node_i++) {        const std::vector<CdlProperty>& properties = (*node_i)->get_properties();        std::vector<CdlProperty>::const_iterator prop_i;        for (prop_i = properties.begin(); prop_i != properties.end(); prop_i++) {            (*prop_i)->update(transaction, *node_i, 0, CdlUpdate_Unloading);        }    }    // Eliminate any conflicts that belong to this loadable.    // FIXME: why is his necessary? Should these conflicts not get    // eliminated by the above property iterations?    std::list<CdlConflict>::const_iterator conf_i;    const std::list<CdlConflict>& global_conflicts = toplevel->get_all_conflicts();    for (conf_i = global_conflicts.begin(); conf_i != global_conflicts.end(); ) {        CdlConflict conflict = *conf_i++;        CYG_LOOP_INVARIANT_CLASSC(conflict);        CdlNode     node     = conflict->get_node();        if ((node->get_owner() == this) && !transaction->has_conflict_been_cleared(conflict)) {            transaction->clear_conflict(conflict);        }    }    const std::list<CdlConflict>& global_structural_conflicts = toplevel->get_all_structural_conflicts();    for (conf_i = global_structural_conflicts.begin(); conf_i != global_structural_conflicts.end(); ) {        CdlConflict conflict = *conf_i++;        CYG_LOOP_INVARIANT_CLASSC(conflict);        CdlNode     node     = conflict->get_node();        if ((node->get_owner() == this) && !transaction->has_conflict_been_cleared(conflict)) {            transaction->clear_conflict(conflict);        }    }    const std::list<CdlConflict>& transaction_conflicts = transaction->get_new_conflicts();    for (conf_i = transaction_conflicts.begin(); conf_i != transaction_conflicts.end(); ) {        CdlConflict conflict = *conf_i++;        CYG_LOOP_INVARIANT_CLASSC(conflict);        CdlNode     node     = conflict->get_node();        if (node->get_owner() == this) {            transaction->clear_conflict(conflict);        }    }    const std::list<CdlConflict>& transaction_structural_conflicts = transaction->get_new_structural_conflicts();    for (conf_i = transaction_structural_conflicts.begin(); conf_i != transaction_structural_conflicts.end(); ) {        CdlConflict conflict = *conf_i++;        CYG_LOOP_INVARIANT_CLASSC(conflict);        CdlNode     node     = conflict->get_node();        if (node->get_owner() == this) {            transaction->clear_conflict(conflict);        }    }    // FIXME: how about cleanup_orphans()        CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// These members are invoked for load and unload operations.//// Committing a load does not require anything, the loadable has// already been fully bound and all propagation has happened.voidCdlLoadableBody::transaction_commit_load(CdlTransaction transaction, CdlLoadable loadable){    CYG_REPORT_FUNCNAME("CdlLoadable::transaction_commit_load");    CYG_REPORT_FUNCARG2XV(transaction, loadable);    CYG_PRECONDITION_CLASSC(transaction);    CYG_PRECONDITION_CLASSC(loadable);    CYG_UNUSED_PARAM(CdlTransaction, transaction);    CYG_UNUSED_PARAM(CdlLoadable, loadable);        CYG_REPORT_RETURN();}// Cancelling a load is more difficult. The loadable has to be// unbound, removed from the toplevel, and deleted. If any of// this fails then we are in trouble, there is no easy way to// recover.voidCdlLoadableBody::transaction_cancel_load(CdlTransaction transaction, CdlLoadable loadable){    CYG_REPORT_FUNCNAME("CdlLoadable::transaction_cancel_load");    CYG_REPORT_FUNCARG2XV(transaction, loadable);    CYG_PRECONDITION_CLASSC(transaction);    CYG_PRECONDITION_CLASSC(loadable);    CdlToplevel toplevel = transaction->get_toplevel();    CYG_PRECONDITION_CLASSC(toplevel);    CYG_ASSERTC(toplevel == loadable->get_toplevel());    loadable->unbind(transaction);    toplevel->remove_loadable_from_toplevel(loadable);    delete loadable;        CYG_REPORT_RETURN();}// Committing an unload means that the loadable can now be deleted.// It should already be unbound and removed from the toplevel.voidCdlLoadableBody::transaction_commit_unload(CdlTransaction transaction, CdlLoadable loadable){    CYG_REPORT_FUNCNAME("CdlLoadable::transaction_commit_unload");    CYG_REPORT_FUNCARG2XV(transaction, loadable);    CYG_PRECONDITION_CLASSC(transaction);    CYG_PRECONDITION_CLASSC(loadable);    CYG_UNUSED_PARAM(CdlTransaction, transaction);    delete loadable;    CYG_REPORT_RETURN();}// Cancelling an unload means that the loadable has to be re-added// to the hierarchy and then rebound. This implies that value// propagation needs to happen. However, since all value changes// since the very start of the transaction are held inside the// transaction and will be eliminated, the original state will// be restored anyway so the propagation is not actually required.voidCdlLoadableBody::transaction_cancel_unload(CdlTransaction transaction, CdlLoadable loadable){    CYG_REPORT_FUNCNAME("CdlLoadable::transaction_cancel_unload");    CYG_REPORT_FUNCARG2XV(transaction, loadable);    CYG_PRECONDITION_CLASSC(transaction);    CYG_PRECONDITION_CLASSC(loadable);    CdlToplevel toplevel = transaction->get_toplevel();    CYG_PRECONDITION_CLASSC(toplevel);    toplevel->add_loadable_to_toplevel(loadable);    CYG_ASSERT_CLASSC(loadable);    loadable->bind(transaction);        CYG_REPORT_RETURN();}//}}}//{{{  File search facilities                   // ----------------------------------------------------------------------------// File search facilities. Given a file name such as hello.cxx from a compile// property, or doc.html from a doc property, find the corresponding filename,// for example /usr/local/eCos/kernel/v1_3/doc/threads.html#create//// The second argument (default value "") indicates a preferred directory// where searching should begin. This would be src for a source file,// doc for a URL, etc.//// For some properties the data may refer to a URL rather than to a local// filename. This is controlled by the third argument, allow_urls.// If false then only local filenames will be considered. allow_urls// also controls whether or not anchor processing is performed.//// RFC1807: a URL consists of <scheme>:<rest>, where <scheme> can be// any sequence of lower-case letters, digits, plus, dot or hyphen. It// is recommended that upper-case letters should be accepted as well.//// RFC1807: an anchor is everything after the first # in the URL.static char find_absolute_file_script[] = "                                     \n\set cdl_anchor \"\"                                                             \n\if {$::cdl_allow_urls} {                                                        \n\  if { [regexp -- {^[a-zA-Z+.-]*:.*$} $::cdl_target] } {                        \n\      return $::cdl_target                                                      \n\  }                                                                             \n\  set tmp \"\"                                                                  \n\  set non_anchor \"\"                                                           \n\  if { [regexp -- {^([^#])(#.*$)} $::cdl_target tmp non_anchor cdl_anchor] } {  \n\      set ::cdl_target $non_anchor                                              \n\  }                                                                             \n\}                                                                               \n\if {$::cdl_prefdir != \"\"} {                                                   \n\    set filename [file join $::cdl_topdir $::cdl_pkgdir $::cdl_prefdir $::cdl_target]         \n\    if {[file exists $filename]} {                                              \n\        return \"[set filename][set cdl_anchor]\"                               \n\    }                                                                           \n\}                                                                               \n\set filename [file join $::cdl_topdir $::cdl_pkgdir $::cdl_target]              \n\if {[file exists $filename]} {                                                  \n\    return \"[set filename][set cdl_anchor]\"                                   \n\}                                                                               \n\return -error \"\"                                                              \n\";std::stringCdlLoadableBody::find_absolute_file(std::string filename, std::string dirname, bool allow_urls) const{    CYG_REPORT_FUNCNAME("CdlLoadable::find_absolute_file");    CYG_REPORT_FUNCARG1XV(this);    CYG_PRECONDITION_THISC();    CYG_PRECONDITIONC("" != filename);    // These variable names should be kept in step with CdlBuildable::update_all_build_info()    interp->set_variable("::cdl_topdir",  get_toplevel()->get_directory());    interp->set_variable("::cdl_pkgdir",  directory);    interp->set_variable("::cdl_prefdir", dirname);    interp->set_variable("::cdl_target",  filename);    interp->set_variable("::cdl_allow_urls", allow_urls ? "1" : "0");    std::string result;    int tmp = interp->eval(find_absolute_file_script, result);    if (tmp != TCL_OK) {        result = "";    }        // Replace any backslashes in the repository with forward slashes.    // The latter are used throughout the library    // NOTE: this is not i18n-friendly.    for (unsigned int i = 0; i < result.size(); i++) {        if ('\\' == result[i]) {            result[i] = '/';        }    }    CYG_REPORT_RETURN();    return result;}static char find_relative_file_script[] = "                                     \n\if {$::cdl_prefdir != \"\"} {                                                   \n\    set filename [file join $::cdl_prefdir $::cdl_target]                       \n\    if {[file exists [file join $::cdl_topdir $::cdl_pkgdir $filename]]} {      \n\        return $filename                                                        \n\    }                                                                           \n\}                                                                               \n\set filename $::cdl_target                                                      \n\if {[file exists [file join $::cdl_topdir $::cdl_pkgdir $filename]]} {          \n\    return \"[set filename][set cdl_anchor]\"                                   \n\}                                                                               \n\return -error \"\"                                                              \n\";

⌨️ 快捷键说明

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