📄 component.cxx
字号:
// Even if there were errors, they were not fatal. There may // now be a number of properties for this component, and some // validation should take place. Start with the base classes. new_component->CdlNodeBody::check_properties(interp); new_component->CdlUserVisibleBody::check_properties(interp); new_component->CdlValuableBody::check_properties(interp); new_component->CdlParentableBody::check_properties(interp); new_component->CdlBuildableBody::check_properties(interp); new_component->CdlDefinableBody::check_properties(interp); // There should be at most one each of wizard and script. if (new_component->count_properties(CdlPropertyId_Wizard) > 1) { CdlParse::report_error(interp, "A component should have at most one `wizard' property."); } if (new_component->count_properties(CdlPropertyId_Script) > 1) { CdlParse::report_error(interp, "A component should have at most one `script' property."); } // If there is a script property, life gets more interesting. if (new_component->has_property(CdlPropertyId_Script)) { CdlProperty_String prop = dynamic_cast<CdlProperty_String>(new_component->get_property(CdlPropertyId_Script)); CYG_PRECONDITION_CLASSC(prop); std::string script_name = prop->get_string(); // Try to locate this script. std::string script_filename = package->find_absolute_file(script_name, "cdl", false); if ("" == script_filename) { CdlParse::report_error(interp, "Unable to find script " + script_name); } else { // The script exists, so we need to try and execute it. // The current container is still set correctly, but we need // to change the filename and install a different set // of commands. old_filename = interp->push_filename(script_filename); new_commands.clear(); for (i = 0; 0 != script_commands[i].command; i++) { new_commands.push_back(script_commands[i]); } old_commands = interp->push_commands(new_commands); result = interp->eval_file(script_filename, tcl_result); interp->pop_commands(old_commands); interp->pop_filename(old_filename); } } done2: // Dummy command just to keep the compiler happy filename = ""; } catch (std::bad_alloc e) { // Errors at this stage should be reported via Tcl, not via C++. // However there is no point in continuing with the parsing operation, // just give up. interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); result = TCL_ERROR; } catch (CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); result = TCL_ERROR; } // Restore the interpreter to its prior state. interp->pop_node(old_node); interp->pop_container(old_container); if (0 != old_commands) { interp->pop_commands(old_commands); } CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// Syntax: script <filename>intCdlComponentBody::parse_script(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_script", "result %d"); int result = CdlParse::parse_string_property(interp, argc, argv, CdlPropertyId_Script, 0, 0); CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ Propagation support // ----------------------------------------------------------------------------voidCdlComponentBody::update(CdlTransaction transaction, CdlUpdate update){ CYG_REPORT_FUNCNAME("CdlComponent::update"); this->CdlValuableBody::update(transaction, update); this->CdlContainerBody::update(transaction, update); CYG_REPORT_RETURN();}//}}}//{{{ Persistence support // ----------------------------------------------------------------------------voidCdlComponentBody::initialize_savefile_support(CdlToplevel toplevel){ CYG_REPORT_FUNCNAME("CdlComponent::initialize_savefile_support"); toplevel->add_savefile_command("cdl_component", 0, &savefile_component_command); CdlValuableBody::initialize_savefile_support(toplevel, "cdl_component"); CYG_REPORT_RETURN();}voidCdlComponentBody::save(CdlInterpreter interp, Tcl_Channel chan, int indentation, bool minimal) throw(CdlInputOutputException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlComponent::save"); CYG_REPORT_FUNCARG5XV(this, interp, chan, indentation, minimal); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(interp); if (!minimal || this->has_additional_savefile_information() || this->value_savefile_entry_needed()) { // Start with the UserVisible data, which will result in a suitable set // of comments before the package definition itself. this->CdlUserVisibleBody::save(interp, chan, indentation, minimal); // Now output the line "cdl_component <name> {" // The name is guaranteed to be a valid C preprocessor symbol, so it // is not going to need any quoting. std::string data = std::string(indentation, ' ') + "cdl_component " + get_name() + " {\n"; interp->write_data(chan, data); // Deal with the value bool modifiable = !(CdlValueFlavor_None == this->get_flavor()) && !this->has_property(CdlPropertyId_Calculated); this->CdlValuableBody::save(interp, chan, indentation + 4, modifiable, minimal); // And with any unrecognised data this->CdlNodeBody::save(interp, chan, indentation + 4, minimal); // Close the cdl_component body. A blank line is added here. interp->write_data(chan, "};\n\n"); } // Packages are containers, so dump the contents as well. this->CdlContainerBody::save(interp, chan, indentation, minimal); CYG_REPORT_RETURN();}intCdlComponentBody::savefile_component_command(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("CdlComponent::savefile_component_command", "result %d"); CYG_PRECONDITION_CLASSC(interp); int result = TCL_OK; CdlToplevel toplevel = interp->get_toplevel(); CYG_ASSERT_CLASSC(toplevel); CdlConfiguration config = dynamic_cast<CdlConfiguration>(toplevel); CYG_ASSERT_CLASSC(config); std::vector<CdlInterpreterCommandEntry> subcommands; std::vector<CdlInterpreterCommandEntry>* toplevel_commands = 0; CdlNode old_node = 0; try { if (3 != argc) { CdlParse::report_error(interp, "Invalid cdl_component command in savefile, expecting two arguments."); } else { CdlNode current_node = config->lookup(argv[1]); if (0 == current_node) { // FIXME: save value in limbo CdlParse::report_error(interp, std::string("The savefile contains a cdl_component command for an unknown component `") + argv[1] + "'"); } else { config->get_savefile_subcommands("cdl_component", subcommands); toplevel_commands = interp->push_commands(subcommands); old_node = interp->push_node(current_node); std::string tcl_result; result = interp->eval(argv[2], tcl_result); interp->pop_commands(toplevel_commands); toplevel_commands = 0; interp->pop_node(old_node); old_node = 0; } } } catch(...) { if (0 != old_node) { interp->pop_node(old_node); } if (0 != toplevel_commands) { interp->pop_commands(toplevel_commands); } throw; } CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ check_this() // ----------------------------------------------------------------------------boolCdlComponentBody::check_this(cyg_assert_class_zeal zeal) const{ if (CdlComponentBody_Magic != cdlcomponentbody_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); return CdlNodeBody::check_this(zeal) && CdlContainerBody::check_this(zeal) && CdlUserVisibleBody::check_this(zeal) && CdlParentableBody::check_this(zeal) && CdlValuableBody::check_this(zeal) && CdlBuildableBody::check_this(zeal) && CdlDefinableBody::check_this(zeal);}//}}}//{{{ Misc // ----------------------------------------------------------------------------std::stringCdlComponentBody::get_class_name() const{ CYG_REPORT_FUNCNAME("CdlComponent::get_class_name"); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return "component";}//}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -