📄 database.cxx
字号:
CdlPackagesDatabase db = static_cast<CdlPackagesDatabaseBody*>(interp->get_assoc_data(dbparser_database_key)); CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); std::string name = interp->get_variable(dbparser_current_target); CYG_ASSERTC("" != name); CYG_ASSERTC(db->targets.find(name) != db->targets.end()); CdlPackagesDatabaseBody::target_data& target = db->targets[name]; std::string msg = "Target " + name + ": "; // The command_prefix command should be used only once if ("" != target.command_prefix) { interp->set_result(msg + "a target can have only one command_prefix string"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } // And there should be exactly one argument. if (2 != argc) { interp->set_result(msg + "only one command_prefix can be specified"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } target.command_prefix = argv[1]; CYG_REPORT_RETVAL(TCL_OK); return TCL_OK;}// Syntax: cflags <list of pairs> ...// For example: cflags { ERRFLAGS "-Wall" DBGFLAGS "-g" }intCdlDbParser::target_cflags(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_cflags", "result %d"); CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); CdlPackagesDatabase db = static_cast<CdlPackagesDatabase>(interp->get_assoc_data(dbparser_database_key)); CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); std::string name = interp->get_variable(dbparser_current_target); CYG_ASSERTC("" != name); CYG_ASSERTC(db->targets.find(name) != db->targets.end()); CdlPackagesDatabaseBody::target_data& target = db->targets[name]; std::string msg = "Target " + name + ": "; // The cflags command should be used only once if (0 < target.cflags.size()) { interp->set_result(msg + "there should be only one set of compiler flags"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } // There should be one argument, a list of valid flags. if (2 != argc) { interp->set_result(msg + "cflags should be followed by a list of compiler flag/value pairs"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } int list_count = 0; char** list_entries = 0; Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } if (0 != (list_count % 2)) { interp->set_result(msg + "compiler flags and values must occur in pairs"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } int i; const std::vector<std::string>& valid_cflags = CdlPackagesDatabaseBody::get_valid_cflags(); for (i = 0; i < list_count; i+= 2) { std::vector<std::string>::const_iterator j; for (j = valid_cflags.begin(); j != valid_cflags.end(); j++) { if (*j == list_entries[i]) { break; } if (j == valid_cflags.end()) { interp->set_result(msg + "invalid cflag name " + list_entries[i]); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } } } // NOTE: do the quote marks have to be removed explicitly or is that done // by splitlist? for (i = 0; i < list_count; i+= 2) { target.cflags.push_back(std::make_pair(list_entries[i], list_entries[i+1])); } Tcl_Free((char*)list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK;}// Syntax: enable { opt1 opt2 ... }// For example: enable { CYGPKG_HAL_ARM_CL7xxx_7211 }intCdlDbParser::target_enable(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_enable", "result %d"); CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); CdlPackagesDatabase db = static_cast<CdlPackagesDatabase>(interp->get_assoc_data(dbparser_database_key)); CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); std::string name = interp->get_variable(dbparser_current_target); CYG_ASSERTC("" != name); CYG_ASSERTC(db->targets.find(name) != db->targets.end()); CdlPackagesDatabaseBody::target_data& target = db->targets[name]; std::string msg = "Target " + name + ": "; // There should be one argument, a list of valid flags. if (2 != argc) { interp->set_result(msg + "enable should be followed by a list of CDL options"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } int list_count = 0; char** list_entries = 0; Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } for (int i = 0; i < list_count; i++) { target.enable.push_back(list_entries[i]); } Tcl_Free((char *) list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK;} // Syntax: disable { opt1 opt2 ... }// For example: disable { CYGPKG_HAL_ARM_CL7xxx_7111 }intCdlDbParser::target_disable(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_disable", "result %d"); CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); CdlPackagesDatabase db = static_cast<CdlPackagesDatabase>(interp->get_assoc_data(dbparser_database_key)); CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); std::string name = interp->get_variable(dbparser_current_target); CYG_ASSERTC("" != name); CYG_ASSERTC(db->targets.find(name) != db->targets.end()); CdlPackagesDatabaseBody::target_data& target = db->targets[name]; std::string msg = "Target " + name + ": "; // There should be one argument, a list of valid flags. if (2 != argc) { interp->set_result(msg + "disable should be followed by a list of CDL options"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } int list_count = 0; char** list_entries = 0; Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } for (int i = 0; i < list_count; i++) { target.disable.push_back(list_entries[i]); } Tcl_Free((char *) list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK;}// Syntax: set_value <option> <value>// For example: set_value CYGHWR_MEMSIZE 0x100000intCdlDbParser::target_set_value(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_set_value", "result %d"); CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); CdlPackagesDatabase db = static_cast<CdlPackagesDatabase>(interp->get_assoc_data(dbparser_database_key)); CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); std::string name = interp->get_variable(dbparser_current_target); CYG_ASSERTC("" != name); CYG_ASSERTC(db->targets.find(name) != db->targets.end()); CdlPackagesDatabaseBody::target_data& target = db->targets[name]; std::string msg = "Target " + name + ": "; // There should be one argument, a list of valid flags. if (3 != argc) { interp->set_result(msg + "set_value command should be followed by an option name and its value"); CYG_REPORT_RETVAL(TCL_ERROR); return TCL_ERROR; } target.set_values.push_back(std::make_pair(std::string(argv[1]), std::string(argv[2]))); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK;}//}}}//}}}//{{{ CdlPackagesDatabase:: creation // ----------------------------------------------------------------------------// The exported interface is make(). The hard work is done inside the// constructor.CdlPackagesDatabaseCdlPackagesDatabaseBody::make(std::string repo) throw(CdlInputOutputException, std::bad_alloc){ CYG_REPORT_FUNCNAMETYPE("CdlPackagesDatabase::make", "database %p"); // Where is the component repository? The location may come from the // parent or from an environment variable ECOS_REPOSITORY if ("" == repo) { char *env = getenv("ECOS_REPOSITORY"); if (0 == env) { throw CdlInputOutputException(std::string("No component repository specified and no ") + std::string("ECOS_REPOSITORY environment variable")); } else { repo = env; } } // 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 < repo.size(); i++) { if ('\\' == repo[i]) { repo[i] = '/'; } } CdlPackagesDatabase result = new CdlPackagesDatabaseBody(repo); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------CdlPackagesDatabaseBody::CdlPackagesDatabaseBody(std::string repo) throw(CdlInputOutputException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlPackagesDatabase:: constructor"); CYG_PRECONDITIONC("" != repo); // There will be calls to check_this() while the database is evaluated, // so make sure that the database is valid first. component_repository = repo; cdlpackagesdatabasebody_cookie = CdlPackagesDatabaseBody_Magic; // We want to read in the entire packages file. Portability problems // can be largely eliminated by using a Tcl interpreter for this, but // under Windows there is a problem if the pathname is a cygwin one. // For now it is assumed that the supplied pathname is acceptable to // Tcl. // // A Tcl interpreter can be used to read in the file. It must not start // off as a safe interpreter because file I/O is needed. However it has // to be turned into a safe interpreter before the packages script is // actually executed. // No need for a try/catch here, there are no resources to free yet. CdlInterpreter interp = CdlInterpreterBody::make(); try { interp->set_variable(dbparser_component_repository, repo); interp->set_variable(dbparser_database_name, database_name); } catch(std::bad_alloc) { delete interp; throw; } std::string str_result; if (TCL_OK != interp->eval(read_file_script, str_result)) { delete interp; throw CdlInputOutputException(str_result); } // We have the script. It comes from a source that is not completely // trusted so it can only be executed in a safe interpreter. However // after the script is read it will still be necessary to perform // glob commands afterwards to locate version subdirectories // and to check for the existence of the script files. try { CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("package", &CdlDbParser::new_package ), CdlInterpreterCommandEntry("target", &CdlDbParser::new_target ), CdlInterpreterCommandEntry("", 0 ) }; unsigned int i; std::vector<CdlInterpreterCommandEntry> new_commands; for (i = 0; 0 != commands[i].command; i++) { new_commands.push_back(commands[i]); } interp->set_assoc_data(dbparser_database_key, static_cast<ClientData>(this)); interp->push_commands(new_commands); if (TCL_OK != interp->eval(" \n\ set parser [interp create -safe] \n\ $parser alias package ::package \n\ $parser alias target ::target \n\ $parser eval $script \n\ ", str_result)) { throw CdlInputOutputException(str_result); } // There should be at least one package and target. if (0 == package_names.size()) { throw CdlInputOutputException("There are no packages in the database."); } if (0 == target_names.size()) { throw CdlInputOutputException("There are no targets in the database."); } // All of the package names should be valid CDL names. std::vector<std::string>::const_iterator name_i; std::vector<std::string>::const_iterator name_j; for (name_i = package_names.begin(); name_i != package_names.end(); name_i++) { if (!Cdl::is_valid_cdl_name(*name_i)) { throw CdlInputOutputException("Package " + *name_i + ", this is not a valid CDL name."); } } // The ecos.db data has been read in. For each package, find // the subdirectories and list them as versions. Each package
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -