📄 build.cxx
字号:
if (("" != file) && ("system.h" == file)) { chan = system_h; } if ((CdlValueFlavor_None == flavor) || (CdlValueFlavor_Bool == flavor)) { std::string define = "#define " + symbol + " 1\n"; Tcl_Write(chan, const_cast<char*>(define.c_str()), -1); } else { std::string format = strprop->get_option("format"); if ("" == format) { std::string define = "#define " + symbol + " " + value + "\n"; Tcl_Write(chan, const_cast<char*>(define.c_str()), -1); } else { std::string cmd = "return \"#define " + symbol + " [format " + format + " " + value + "]\n\""; std::string define; if (TCL_OK != interp->eval(cmd, define)) { throw CdlInputOutputException("Internal error executing tcl fragment to process format option"); } Tcl_Write(chan, const_cast<char*>(define.c_str()), -1); } std::string tmp = symbol + "_" + value; if (Cdl::is_valid_c_preprocessor_symbol(tmp)) { tmp = "#define " + tmp + "\n"; Tcl_Write(chan, const_cast<char*>(tmp.c_str()), -1); } } } // Now check for if_define properties std::vector<CdlProperty> if_define_props; get_properties(CdlPropertyId_IfDefine, if_define_props); for (prop_i = if_define_props.begin(); prop_i != if_define_props.end(); prop_i++) { CdlProperty_StringVector strprop = dynamic_cast<CdlProperty_StringVector>(*prop_i); CYG_ASSERT_CLASSC(strprop); CYG_ASSERTC(2 == strprop->get_number_of_strings()); std::string sym1 = strprop->get_string(0); std::string sym2 = strprop->get_string(1); Tcl_Channel chan = this_hdr; std::string file = strprop->get_option("file"); if (("" != file) && ("system.h" == file)) { chan = system_h; } std::string data = "#ifdef " + sym1 + "\n# define " + sym2 + " 1\n#endif\n"; Tcl_Write(chan, const_cast<char*>(data.c_str()), -1); } // And define_proc properties std::vector<CdlProperty> define_proc_props; get_properties(CdlPropertyId_DefineProc, define_proc_props); for (prop_i = define_proc_props.begin(); prop_i != define_proc_props.end(); prop_i++) { CdlProperty_TclCode codeprop = dynamic_cast<CdlProperty_TclCode>(*prop_i); CYG_ASSERT_CLASSC(codeprop); cdl_tcl_code code = codeprop->get_code(); std::string result; if (TCL_OK != interp->eval(code, result)) { throw CdlInputOutputException("Error evaluating define_proc property for " + name + "\n" + result); } } CYG_REPORT_RETURN();}//}}}//}}}//{{{ CdlDefineLoadableBody //{{{ Basics // ----------------------------------------------------------------------------CdlDefineLoadableBody::CdlDefineLoadableBody(){ CYG_REPORT_FUNCNAME("CdlDefineLoadable:: default constructor"); CYG_REPORT_FUNCARG1XV(this); cdldefineloadablebody_cookie = CdlDefineLoadableBody_Magic; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}CdlDefineLoadableBody::~CdlDefineLoadableBody(){ CYG_REPORT_FUNCNAME("CdlDefineLoadable:: destructor"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); cdldefineloadablebody_cookie = CdlDefineLoadableBody_Invalid; CYGDBG_MEMLEAK_DESTRUCTOR(); CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------std::stringCdlDefineLoadableBody::get_class_name() const{ CYG_REPORT_FUNCNAME("CdlDefineLoadable::get_class_name"); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return "define_loadable";}// ----------------------------------------------------------------------------boolCdlDefineLoadableBody::check_this(cyg_assert_class_zeal zeal) const{ if (CdlDefineLoadableBody_Magic != cdldefineloadablebody_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); return CdlLoadableBody::check_this(zeal) && CdlNodeBody::check_this(zeal);}//}}}//{{{ Property parsing // ----------------------------------------------------------------------------voidCdlDefineLoadableBody::add_property_parsers(std::vector<CdlInterpreterCommandEntry>& parsers){ CYG_REPORT_FUNCNAME("CdlDefineLoadable::add_property_parsers"); static CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("define_header", &parse_define_header), CdlInterpreterCommandEntry("", 0 ) }; for (int i = 0; commands[i].command != 0; i++) { std::vector<CdlInterpreterCommandEntry>::const_iterator j; for (j = parsers.begin(); j != parsers.end(); j++) { if (commands[i].name == j->name) { if (commands[i].command != j->command) { CYG_FAIL("Property names are being re-used"); } break; } } if (j == parsers.end()) { parsers.push_back(commands[i]); } } CdlNodeBody::add_property_parsers(parsers); CYG_REPORT_RETURN();}voidCdlDefineLoadableBody::check_properties(CdlInterpreter interp){ CYG_REPORT_FUNCNAME("CdlDefineLoadable::check_properties"); CYG_REPORT_FUNCARG2XV(this, interp); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(interp); // There should be at most one define_header property int count = count_properties(CdlPropertyId_DefineHeader); if (count> 1) { CdlParse::report_error(interp, "There should be at most one define_header property."); } // FIXME: filename validation CdlNodeBody::check_properties(interp); CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// syntax: define_header <header file name>intCdlDefineLoadableBody::parse_define_header(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_define_header", "result %d"); int result = CdlParse::parse_string_property(interp, argc, argv, CdlPropertyId_DefineHeader, 0, 0); CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ generate_config_header() // ----------------------------------------------------------------------------voidCdlDefineLoadableBody::generate_config_header(Tcl_Channel this_hdr, Tcl_Channel system_h) const throw(CdlInputOutputException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlDefineLoadable::generate_config_header"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CdlInterpreter interp = get_interpreter(); Tcl_RegisterChannel(interp->get_tcl_interpreter(), this_hdr); Tcl_RegisterChannel(interp->get_tcl_interpreter(), system_h); try { interp->set_variable("::cdl_header", Tcl_GetChannelName(this_hdr)); interp->set_variable("::cdl_system_header", Tcl_GetChannelName(system_h)); const std::vector<CdlNode>& contents = get_owned(); std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { CdlDefinable definable = dynamic_cast<CdlDefinable>(*node_i); if (0 == definable) { continue; } if (!definable->is_active()) { continue; } definable->generate_config_header(this_hdr, system_h); } interp->unset_variable("::cdl_header"); interp->unset_variable("::cdl_system_header"); } catch(...) { Tcl_UnregisterChannel(interp->get_tcl_interpreter(), this_hdr); Tcl_UnregisterChannel(interp->get_tcl_interpreter(), system_h); throw; } Tcl_UnregisterChannel(interp->get_tcl_interpreter(), this_hdr); Tcl_UnregisterChannel(interp->get_tcl_interpreter(), system_h); CYG_REPORT_RETURN();}//}}}//{{{ get_config_headers() // ----------------------------------------------------------------------------// What header file should be generated for this loadable?//// If there is a define_header property then this should be used.// Otherwise a filename is constructed from the loadable's name.std::stringCdlDefineLoadableBody::get_config_header() const{ CYG_REPORT_FUNCNAME("CdlDefineLoadable::get_config_headers"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); std::string result = ""; CdlProperty prop = get_property(CdlPropertyId_DefineHeader); if (0 != prop) { CdlProperty_String string_prop = dynamic_cast<CdlProperty_String>(prop); CYG_ASSERT_CLASSC(string_prop); result = string_prop->get_string(); } else { std::string tmp = get_name(); result = Cdl::get_short_form(tmp); result += ".h"; } CYG_REPORT_RETURN(); return result;}//}}}//}}}//{{{ CdlToplevel //{{{ CdlToplevel::get_build_info() // ----------------------------------------------------------------------------// Essentially this code involves iterating over the loadables vector,// looking for BuildLoadables and invoking their update_build_info()// member function. In addition, if there is currently some data in// the build_info vector (probably from a previous call) then that// must be cleared.voidCdlToplevelBody::get_build_info(CdlBuildInfo& build_info){ CYG_REPORT_FUNCNAME("CdlToplevel::get_build_info"); CYG_REPORT_FUNCARG2XV(this, &build_info); CYG_PRECONDITION_THISC(); if (0 != build_info.entries.size()) { build_info.entries.clear(); } const std::vector<CdlLoadable>& loadables = get_loadables(); std::vector<CdlLoadable>::const_iterator load_i; for (load_i = loadables.begin(); load_i != loadables.end(); load_i++) { CdlConstBuildLoadable bl = dynamic_cast<CdlConstBuildLoadable>(*load_i); if (0 != bl) { bl->update_build_info(build_info); } } CYG_REPORT_RETURN();}//}}}//{{{ CdlToplevel::get_all_build_info() // ----------------------------------------------------------------------------// This is just like get_build_info(), but calls a different// BuildLoadable member.voidCdlToplevelBody::get_all_build_info(CdlBuildInfo& build_info){ CYG_REPORT_FUNCNAME("CdlToplevel::get_all_build_info"); CYG_REPORT_FUNCARG2XV(this, &build_info); CYG_PRECONDITION_THISC(); if (0 != build_info.entries.size()) { build_info.entries.clear(); } const std::vector<CdlLoadable>& loadables = get_loadables(); std::vector<CdlLoadable>::const_iterator load_i; for (load_i = loadables.begin(); load_i != loadables.end(); load_i++) { CdlConstBuildLoadable bl = dynamic_cast<CdlConstBuildLoadable>(*load_i); if (0 != bl) { bl->update_all_build_info(build_info); } } CYG_REPORT_RETURN();}//}}}//{{{ CdlToplevel::generate_config_headers() // ----------------------------------------------------------------------------// Generating the config headers. This involves the following steps://// 1) for every DefineLoadable, find out what header file should// be generated. Note that some loadables may share a header file.//// 2) create a temporary version of system.h. Note that it is not// a good idea to just overwrite an existing system.h, chances// are pretty good that the file will not have changed, and// updating it unnecessarily will result in unnecessary rebuilds// due to header file dependencies.//// 3) for each file that should be generated, create a temporary// version and allow all applicable loadables to update it.// A utility to compare two files and do the right thing.// This requires some simple Tcl code.static voidcompare_and_copy(CdlInterpreter interp, std::string file1, std::string file2){ CYG_REPORT_FUNCNAME("compare_and_copy"); CYG_PRECONDITION_CLASSC(interp); CYG_PRECONDITIONC("" != file1); CYG_PRECONDITIONC("" != file2); CYG_PRECONDITIONC(file1 != file2); static char compare_and_copy_script[] = "\if {[file exists \"$::cdl_compare_and_copy_file2\"] =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -