📄 build.cxx
字号:
//}}}//}}}//{{{ CdlDefinableBody //{{{ Basics // ----------------------------------------------------------------------------CdlDefinableBody::CdlDefinableBody(){ CYG_REPORT_FUNCNAME("CdlDefinable:: default constructor"); CYG_REPORT_FUNCARG1XV(this); // There is no data to initialize cdldefinablebody_cookie = CdlDefinableBody_Magic; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}CdlDefinableBody::~CdlDefinableBody(){ CYG_REPORT_FUNCNAME("CdlDefinable:: destructor"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); cdldefinablebody_cookie = CdlDefinableBody_Invalid; CYGDBG_MEMLEAK_DESTRUCTOR(); CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------std::stringCdlDefinableBody::get_class_name() const{ CYG_REPORT_FUNCNAME("CdlDefinable::get_class_name"); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return "definable";}// ----------------------------------------------------------------------------boolCdlDefinableBody::check_this(cyg_assert_class_zeal zeal) const{ if (CdlDefinableBody_Magic != cdldefinablebody_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); return CdlNodeBody::check_this(zeal);}//}}}//{{{ add_property_parser() and check_properties() // ----------------------------------------------------------------------------voidCdlDefinableBody::add_property_parsers(std::vector<CdlInterpreterCommandEntry>& parsers){ CYG_REPORT_FUNCNAME("CdlDefinable::add_property_parsers"); static CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("no_define", &parse_no_define ), CdlInterpreterCommandEntry("define", &parse_define ), CdlInterpreterCommandEntry("define_format", &parse_define_format ), CdlInterpreterCommandEntry("define_proc", &parse_define_proc ), CdlInterpreterCommandEntry("if_define", &parse_if_define ), 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();}voidCdlDefinableBody::check_properties(CdlInterpreter interp){ CYG_REPORT_FUNCNAME("CdlDefinable::check_properties"); CYG_REPORT_FUNCARG2XV(this, interp); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(interp); // There should be at most one each of no_define and define_format. if (count_properties(CdlPropertyId_NoDefine) > 1) { CdlParse::report_error(interp, "There should be at most one no_define property."); } if (count_properties(CdlPropertyId_DefineFormat) > 1) { CdlParse::report_error(interp, "There should be at most one define_format property."); } if (has_property(CdlPropertyId_NoDefine) && has_property(CdlPropertyId_DefineFormat)) { CdlParse::report_error(interp, "The no_define and define_format properties are mutually exclusive."); } // FIXME: the define_format property only makes sense for certain // flavors. However the flavor property may not have been processed yet. CdlNodeBody::check_properties(interp); CYG_REPORT_RETURN();}//}}}//{{{ Definable properties // ----------------------------------------------------------------------------// Syntax: no_defineintCdlDefinableBody::parse_no_define(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_no_define", "result %d"); int result = CdlParse::parse_minimal_property(interp, argc, argv, CdlPropertyId_NoDefine, 0, 0); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// syntax: define <symbol>// The argument to "define" should be a valid C preprocessor symbol.static voidparse_define_final_check(CdlInterpreter interp, CdlProperty_String prop){ CYG_REPORT_FUNCNAME("parse_define_final_check"); CYG_PRECONDITION_CLASSC(prop); CYG_PRECONDITION_CLASSC(interp); const std::string& str = prop->get_string(); if (!Cdl::is_valid_c_preprocessor_symbol(str)) { CdlParse::report_property_parse_error(interp, prop, str + " is not a valid C preprocessor symbol"); } // There may be a file option. At this stage the only valid filename // that can be used here is system.h std::string file_option = prop->get_option("file"); if (("" != file_option) && ("system.h" != file_option)) { CdlParse::report_property_parse_error(interp, prop, "Invalid -file option " + file_option); } // FIXME: validate the format string CYG_REPORT_RETURN();}intCdlDefinableBody::parse_define(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_define", "result %d"); static char* options[] = { "file:", "format:", 0 }; int result = CdlParse::parse_string_property(interp, argc, argv, CdlPropertyId_Define, options, &parse_define_final_check); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// syntax: define_format <string>//// FIXME: it is possible to apply some checks to the string, e.g. that there// is only one conversion operation.//// FIXME: also check that the flavor is sensible, define_format has no effect// for none or bool//// FIXME: enforce mutual exclusion with no_defineintCdlDefinableBody::parse_define_format(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_format", "result %d"); int result = CdlParse::parse_string_property(interp, argc, argv, CdlPropertyId_DefineFormat, 0, 0); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// syntax: define_proc <tclcode>intCdlDefinableBody::parse_define_proc(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_define_proc", "result %d"); int result = CdlParse::parse_tclcode_property(interp, argc, argv, CdlPropertyId_DefineProc, 0, 0); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------// Syntax: if_define sym1 sym2static voidparse_if_define_final_check(CdlInterpreter interp, CdlProperty_StringVector prop){ CYG_REPORT_FUNCNAME("parse_if_define_final_check"); CYG_PRECONDITION_CLASSC(interp); CYG_PRECONDITION_CLASSC(prop); // There should be exactly two entries in the vector, and both of them should be // valid preprocessor symbols. const std::vector<std::string>& strings = prop->get_strings(); if (2 != strings.size()) { CdlParse::report_property_parse_error(interp, prop, "There should be exactly two arguments."); } if (!Cdl::is_valid_c_preprocessor_symbol(strings[0])) { CdlParse::report_property_parse_error(interp, prop, strings[0] + " is not a valid C preprocessor symbol."); } if (!Cdl::is_valid_c_preprocessor_symbol(strings[1])) { CdlParse::report_property_parse_error(interp, prop, strings[1] + " is not a valid C preprocessor symbol."); } // There may be a file option. At this stage the only valid filename // that can be used here is system.h std::string file_option = prop->get_option("file"); if (("" != file_option) && ("system.h" != file_option)) { CdlParse::report_property_parse_error(interp, prop, "Invalid -file option " + file_option); }}intCdlDefinableBody::parse_if_define(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("parse_if_define", "result %d"); char* options[] = { "file:", 0 }; int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_IfDefine, options, &parse_if_define_final_check); CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ generate_config_header() // ----------------------------------------------------------------------------// This code needs to allow for the following properties.//// 1) no_define. This suppresses the default #define generation. //// 2) define_format <format_string.//// 3) define [-file <filename>][-format <format_string>] symbol//// 4) define_proc//// 5) if_definevoidCdlDefinableBody::generate_config_header(Tcl_Channel this_hdr, Tcl_Channel system_h) const throw(CdlInputOutputException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlDefinable::generate_config_header"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CdlLoadable loadable = get_owner(); CdlInterpreter interp = loadable->get_interpreter(); // This definable is known to be active. However it may or may not be enabled. CYG_PRECONDITIONC(is_active()); std::string name = get_name(); CdlValueFlavor flavor = CdlValueFlavor_Bool; std::string value = "1"; CdlConstValuable valuable = dynamic_cast<CdlConstValuable>(this); if (0 != valuable) { // It is always possible to check the enabled() flag. if (!valuable->is_enabled()) { CYG_REPORT_RETURN(); return; } // The value is only valid for BoolData and Data flavors, and may // not have been provided. If there is no value then this option // should not generate a #define flavor = valuable->get_flavor(); if ((CdlValueFlavor_BoolData == flavor) || (CdlValueFlavor_Data == flavor)) { value = valuable->get_value(); } } // Flavor and value are now both set to sensible strings. // First, check the no_define property. If this is present then the default // #define generation should be suppressed. if (!has_property(CdlPropertyId_NoDefine)) { // OK, it is necessary to generate at least one #define. // If this node is actually a loadable then the #define should go // into system.h, otherwise into the current header Tcl_Channel chan = this_hdr; if (dynamic_cast<CdlConstLoadable>((CdlConstNode)this) == loadable) { chan = system_h; } // For flavors None and Bool, there should be just one #define if ((CdlValueFlavor_None == flavor) || (CdlValueFlavor_Bool == flavor)) { std::string define = "#define " + name + " 1\n"; Tcl_Write(chan, const_cast<char*>(define.c_str()), -1); } else { // If there is a format string then that controls the default // value display. if (!has_property(CdlPropertyId_DefineFormat)) { std::string define = "#define " + name + " " + value + "\n"; Tcl_Write(chan, const_cast<char*>(define.c_str()), -1); } else { CdlProperty_String strprop = dynamic_cast<CdlProperty_String>(get_property(CdlPropertyId_DefineFormat)); CYG_ASSERT_CLASSC(strprop); std::string format = strprop->get_string(); std::string cmd = "return \"#define " + name + " [format " + format + " " + value + "]\n\""; std::string define; if (TCL_OK != interp->eval(cmd, define)) { throw CdlInputOutputException("Internal error executing tcl fragment to process define_format property"); } Tcl_Write(chan, const_cast<char*>(define.c_str()), -1); } // There may also be a separate #define of the form <name>_<value>, // if that is a valid preprocessor symbol. std::string tmp = name + "_" + value; if (Cdl::is_valid_c_preprocessor_symbol(tmp)) { tmp = "#define "+ tmp + "\n"; Tcl_Write(chan, const_cast<char*>(tmp.c_str()), -1); } } } // Next, check for any additional define properties std::vector<CdlProperty> define_props; get_properties(CdlPropertyId_Define, define_props); std::vector<CdlProperty>::const_iterator prop_i; for (prop_i = define_props.begin(); prop_i != define_props.end(); prop_i++) { CdlProperty_String strprop = dynamic_cast<CdlProperty_String>(*prop_i); CYG_ASSERT_CLASSC(strprop); std::string symbol = strprop->get_string(); std::string file = strprop->get_option("file"); Tcl_Channel chan = this_hdr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -