📄 config.cxx
字号:
CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo) throw(CdlInputOutputException, CdlParseException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlConfiguration::set_hardware"); CYG_REPORT_FUNCARG2XV(this, transaction); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(transaction); // Minimal consistency check before if (!database->is_known_target(target_name)) { throw CdlInputOutputException("Unknown target " + target_name); } int i; CdlConfiguration_CommitCancelHardwareName* rename_op = new CdlConfiguration_CommitCancelHardwareName(current_hardware); try { transaction->add_commit_cancel_op(rename_op); const std::vector<CdlLoadable>& loadables = this->get_loadables(); for (i = (int) loadables.size() - 1; i >= 0; i--) { CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]); if ((0 != package) && package->belongs_to_hardware()) { this->unload_package(transaction, package, limbo); } } current_hardware = ""; if ("" != target_name) { const std::vector<std::string>& packages = database->get_target_packages(target_name); std::vector<std::string>::const_iterator name_i; for (name_i = packages.begin(); name_i != packages.end(); name_i++) { // It is possible for a hardware package to have been // loaded separately, in which case there is no point in // loading it again. CYG_ASSERTC(database->is_known_package(*name_i)); if (0 == this->lookup(*name_i)) { this->load_package(transaction, *name_i, "", error_fn, warn_fn, limbo); CdlPackage package = dynamic_cast<CdlPackage>(this->lookup(*name_i)); CYG_LOOP_INVARIANT_CLASSC(package); package->loaded_for_hardware = true; } } } current_hardware = target_name; } catch(...) { // Cancel all operations up to and including the rename_op CdlTransactionCommitCancelOp* cancel_op = 0; do { cancel_op = transaction->get_last_commit_cancel_op(); CYG_LOOP_INVARIANTC(0 != cancel_op); transaction->cancel_last_commit_cancel_op(); } while(cancel_op != rename_op); throw; } // There may have been enables/disables and value data for that target // FIXME: any problems get ignored quietly. There should at least // be some warnings. if ("" != target_name) { const std::vector<std::string>& enables = database->get_target_enables(target_name); const std::vector<std::string>& disables = database->get_target_disables(target_name); const std::vector<std::pair<std::string, std::string> >& set_values = database->get_target_set_values(target_name); if ((0 != enables.size()) || (0 != disables.size()) || (0 != set_values.size())) { std::vector<std::string>::const_iterator opt_i; CdlNode node; CdlValuable valuable; CdlValueFlavor flavor; for (opt_i = enables.begin(); opt_i != enables.end(); opt_i++) { node = this->lookup(*opt_i); if (0 != node) { valuable = dynamic_cast<CdlValuable>(node); if (0 != valuable) { flavor = valuable->get_flavor(); if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) { valuable->enable(transaction, CdlValueSource_User); } } } } for (opt_i = disables.begin(); opt_i != disables.end(); opt_i++) { node = this->lookup(*opt_i); if (0 != node) { valuable = dynamic_cast<CdlValuable>(node); if (0 != valuable) { flavor = valuable->get_flavor(); if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) { valuable->disable(transaction, CdlValueSource_User); } } } } std::vector<std::pair<std::string,std::string> >::const_iterator value_i; for (value_i = set_values.begin(); value_i != set_values.end(); value_i++) { node = this->lookup(value_i->first); if (0 != node) { valuable = dynamic_cast<CdlValuable>(node); if (0 != valuable) { flavor = valuable->get_flavor(); if ((CdlValueFlavor_BoolData == flavor) || (CdlValueFlavor_Data == flavor)) { valuable->set_value(transaction, value_i->second, CdlValueSource_User); } } } } } } CYG_REPORT_RETURN();}voidCdlConfigurationBody::unload_hardware(CdlTransaction transaction, bool limbo){ CYG_REPORT_FUNCNAME("CdlConfiguration::unload_hardware"); CYG_REPORT_FUNCARG3XV(this, transaction, limbo); CYG_PRECONDITION_THISC(); CdlConfiguration_CommitCancelHardwareName* rename_op = new CdlConfiguration_CommitCancelHardwareName(current_hardware); try { transaction->add_commit_cancel_op(rename_op); } catch(...) { delete rename_op; throw; } current_hardware = ""; try { const std::vector<CdlLoadable>& loadables = this->get_loadables(); for (int i = (int) loadables.size() - 1; i >= 0; i--) { CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]); if ((0 != package) && package->belongs_to_hardware()) { this->unload_package(transaction, package, limbo); } } } catch(...) { CdlTransactionCommitCancelOp* cancel_op = 0; do { cancel_op = transaction->get_last_commit_cancel_op(); CYG_LOOP_INVARIANTC(0 != cancel_op); transaction->cancel_last_commit_cancel_op(); } while(cancel_op != rename_op); throw; } CYG_REPORT_RETURN();}//}}}//{{{ CdlConfiguration::set_template() etc // ----------------------------------------------------------------------------voidCdlConfigurationBody::set_template_file(CdlTransaction transaction, std::string filename, CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo) throw(CdlInputOutputException, CdlParseException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlConfiguration::set_template_file"); CYG_REPORT_FUNCARG3XV(this, transaction, limbo); CYG_PRECONDITION_THISC(); int i; CdlConfiguration_CommitCancelTemplateName* rename_op = new CdlConfiguration_CommitCancelTemplateName(current_template); // The hard work is done by add(), which loads in a partial savefile. // This can have undesirable side effects: changing the name, // description, or hardware settings. It must be possible to undo // these. std::string saved_name = this->get_name(); std::string saved_description = this->get_description(); std::string saved_hardware = this->get_hardware(); // New packages will end up at the end of the loadables vector. // Each new package needs to be registered as a template one. // NOTE: this may break if we start doing more interesting things // with savefiles. const std::vector<CdlLoadable>& loadables = this->get_loadables(); unsigned int load_i = loadables.size(); try { transaction->add_commit_cancel_op(rename_op); const std::vector<CdlLoadable>& loadables = this->get_loadables(); for (i = (int) loadables.size() - 1; i >= 0; i--) { CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]); if ((0 != package) && package->belongs_to_template()) { this->unload_package(transaction, package, limbo); } } current_template = ""; this->add(transaction, filename, error_fn, warn_fn); this->current_template = filename; this->set_name(saved_name); this->description = saved_description; this->current_hardware = saved_hardware; for ( ; load_i < loadables.size(); load_i++) { CdlPackage pkg = dynamic_cast<CdlPackage>(loadables[load_i]); CYG_ASSERT_CLASSC(pkg); pkg->loaded_for_template = true; } } catch(...) { this->set_name(saved_name); this->description = saved_description; this->current_hardware = saved_hardware; // Cancel all operations up to and including the rename_op CdlTransactionCommitCancelOp* cancel_op = 0; do { cancel_op = transaction->get_last_commit_cancel_op(); CYG_LOOP_INVARIANTC(0 != cancel_op); transaction->cancel_last_commit_cancel_op(); } while(cancel_op != rename_op); throw; } CYG_REPORT_RETURN();}voidCdlConfigurationBody::unload_template(CdlTransaction transaction, bool limbo){ CYG_REPORT_FUNCNAME("CdlConfiguration::unload_template"); CYG_REPORT_FUNCARG2XV(this, transaction); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(transaction); CdlConfiguration_CommitCancelTemplateName* rename_op = new CdlConfiguration_CommitCancelTemplateName(current_template); try { transaction->add_commit_cancel_op(rename_op); } catch(...) { delete rename_op; throw; } current_template = ""; try { const std::vector<CdlLoadable>& loadables = this->get_loadables(); for (int i = (int) loadables.size() - 1; i >= 0; i--) { CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]); if ((0 != package) && package->belongs_to_template()) { this->unload_package(transaction, package, limbo); } } } catch(...) { CdlTransactionCommitCancelOp* cancel_op = 0; do { cancel_op = transaction->get_last_commit_cancel_op(); CYG_LOOP_INVARIANTC(0 != cancel_op); transaction->cancel_last_commit_cancel_op(); } while(cancel_op != rename_op); throw; } CYG_REPORT_RETURN();}//}}}//{{{ Persistence support //{{{ initialize_savefile_support() // ----------------------------------------------------------------------------// Initialization. The purpose of this code is to determine all the// commands that can end up in a particular savefile. This includes// the cdl_configuration command, commands relevant to packages,// options, and components, the generic library commands, and// application-specific commands.//// This is a virtual function, it may get invoked indirectly from// e.g. CdlToplevel::add_savefile_command().voidCdlConfigurationBody::initialize_savefile_support(){ CYG_REPORT_FUNCNAME("CdlConfiguration::initialize_savefile_support"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); // Start with the generic stuff such as cdl_savefile_version and // cdl_command. this->CdlToplevelBody::initialize_savefile_support(); // Now add in the cdl_configuration command and its subcommands. this->add_savefile_command("cdl_configuration", 0, &savefile_configuration_command); this->add_savefile_subcommand("cdl_configuration", "description", 0, &savefile_description_command); this->add_savefile_subcommand("cdl_configuration", "hardware", 0, &savefile_hardware_command); this->add_savefile_subcommand("cdl_configuration", "template", 0, &savefile_template_command); this->add_savefile_subcommand("cdl_configuration", "package", 0, &savefile_package_command); CdlPackageBody::initialize_savefile_support(this); CdlComponentBody::initialize_savefile_support(this); CdlOptionBody::initialize_savefile_support(this); CdlInterfaceBody::initialize_savefile_support(this);}//}}}//{{{ CdlConfiguration::save() - internal // ----------------------------------------------------------------------------// The exported interface is CdlConfiguration::save(). This takes a single// argument, a filename. It opens the file, and then invokes various// functions that output the relevants bits of the file.//// This member function is responsible for outputting a cdl_configuration// command.voidCdlConfigurationBody::save(CdlInterpreter interp, Tcl_Channel chan, int indentation, bool minimal) throw(CdlInputOutputException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlConfiguration::save"); CYG_REPORT_FUNCARG5XV(this, interp, chan, indentation, minimal); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(interp); CYG_PRECONDITIONC(0 == indentation); std::string text = ""; if (!minimal) { text = "# This section defines the toplevel configuration object. The only\n\# values that can be changed are the name of the configuration and\n\# the description field. It is not possible to modify the target,\n\# the template or the set of packages simply by editing the lines\n\# below because these changes have wide-ranging effects. Instead\n\# the appropriate tools should be used to make such modifications.\n\\n"; } text += "cdl_configuration " + CdlInterpreterBody::quote(this->get_name()) + " {\n"; std::string config_data = this->get_description(); if (!minimal || ("" != text)) { text += " description " + CdlInterpreterBody::quote(config_data) + " ;\n"; } // Repeat the warning. if (!minimal) { text += "\n # These fields should not be modified.\n"; } config_data = this->get_hardware(); if ("" != config_data) { text += " hardware " + CdlInterpreterBody::quote(config_data) + " ;\n"; } config_data = this->get_template(); if ("" != config_data) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -