📄 database.cxx
字号:
// There should be one argument, a list of valid flags. if (2 != argc) { CdlParse::report_error(interp, diag_target + name, "`disable' should be followed by a list of CDL options."); } else { 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)) { CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp)); } else { 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); std::string name = interp->get_variable(dbparser_targetname); CYG_ASSERTC("" != name); CdlPackagesDatabaseBody::target_data* target = static_cast<CdlPackagesDatabaseBody::target_data*>(interp->get_assoc_data(dbparser_targetdata)); // There should be one argument, a list of valid flags. if (3 != argc) { CdlParse::report_error(interp, diag_target + name, "`set_value' should be followed by an option name and its value."); } else { 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, CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn){ 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, error_fn, warn_fn); CYG_REPORT_RETVAL(result); return result;}// ----------------------------------------------------------------------------CdlPackagesDatabaseBody::CdlPackagesDatabaseBody(std::string repo, CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn){ 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. // // No attempt is made at this stage to use a safe interpreter. // Some file I/O operations are needed while processing the data, // for example to check that a package is actually installed. // Additional file I/O may prove useful in future, e.g. to create // some or all of a database on the fly. Obviously some // restrictions are desirable (no modify access to the repository, // no network capabilities, and so on.) These have to be added // in future. CdlInterpreter interp = CdlInterpreterBody::make(); try { CdlInterpreterBody::ContextSupport context(interp, database_name); CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("package", &CdlDbParser::new_package ), CdlInterpreterCommandEntry("target", &CdlDbParser::new_target ), CdlInterpreterCommandEntry("", 0 ) }; CdlInterpreterBody::CommandSupport cmds(interp, commands); CdlInterpreterBody::DiagSupport diag(interp, error_fn, warn_fn); CdlInterpreterBody::AssocSupport assoc(interp, dbparser_database_key, static_cast<ClientData>(this)); CdlInterpreterBody::VariableSupport var(interp, dbparser_component_repository, repo); interp->add_command("unknown", &CdlParse::unknown_command); CdlParse::clear_error_count(interp); // Ignore errors at this stage, instead check error count at the end. (void) interp->eval_file(component_repository + "/" + database_name); // Now start looking for templates. These should reside in the // templates subdirectory of the component repository. Each template // should be in its own directory, and inside each directory should // be versioned template files with a .ect extension. std::string templates_dir = repo + "/" + "templates"; std::vector<std::string> subdirs; interp->locate_subdirs(templates_dir, subdirs); unsigned int i; for (i = 0; i < subdirs.size(); i++) { // Do not add the template to the known ones until we are sure there is // at least one valid template. std::vector<std::string> files; interp->locate_files(templates_dir + "/" + subdirs[i], files); unsigned int j; for (j = 0; j < files.size(); j++) { if ((4 < files[j].size()) && (".ect" == files[j].substr(files[j].size() - 4))) { break; } } if (j != files.size()) { this->template_names.push_back(subdirs[i]); for ( ; j < files.size(); j++) { if ((4 < files[j].size()) && (".ect" == files[j].substr(files[j].size() - 4))) { this->templates[subdirs[i]].versions.push_back(files[j].substr(0, files[j].size() - 4)); } } } } // Consistency checks. All target-specific packages should // have the hardware attribute. Also, all the packages should // exist. Problems only result in warnings, to allow for // somewhat inconsistent repositories e.g. an anoncvs tree. std::vector<std::string>::const_iterator name_i; std::vector<std::string>::const_iterator name_j; for (name_i = target_names.begin(); name_i != target_names.end(); name_i++) { for (name_j = targets[*name_i].packages.begin(); name_j != targets[*name_i].packages.end(); name_j++) { if (std::find(package_names.begin(), package_names.end(), *name_j) == package_names.end()) { CdlParse::report_warning(interp, diag_target + *name_i, std::string("This target refers to an unknown package `") + *name_j + "'."); } if (!packages[*name_j].hardware) { CdlParse::report_warning(interp, diag_target + *name_i, std::string("This target refers to a package `") + *name_j + "' that is not hardware-specific."); } } } // Now, were there any errors while reading in the database? // If so it is necessary to throw an exception here, to make sure // that things get cleaned up properly. int error_count = CdlParse::get_error_count(interp); if (0 != error_count) { throw CdlInputOutputException("Invalid package database."); } } catch(...) { // Something has gone wrong. Clear out all of the data accumulated so far, as well // as the interpreter. delete interp; package_names.clear(); target_names.clear(); template_names.clear(); packages.clear(); targets.clear(); templates.clear(); throw; } delete interp; CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_REPORT_RETURN();}//}}}//{{{ CdlPackagesDatabase:: destructor // ----------------------------------------------------------------------------CdlPackagesDatabaseBody::~CdlPackagesDatabaseBody(){ CYG_REPORT_FUNCNAME("CdlPackagesDatabase:: default destructor"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); cdlpackagesdatabasebody_cookie = CdlPackagesDatabaseBody_Invalid; component_repository = ""; package_names.clear(); target_names.clear(); template_names.clear(); packages.clear(); targets.clear(); templates.clear(); CYGDBG_MEMLEAK_DESTRUCTOR(); CYG_REPORT_RETURN();}//}}}//{{{ CdlPackagesDatabase:: check_this() // ----------------------------------------------------------------------------boolCdlPackagesDatabaseBody::check_this(cyg_assert_class_zeal zeal) const{ if (CdlPackagesDatabaseBody_Magic != cdlpackagesdatabasebody_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); switch(zeal) { case cyg_system_test : case cyg_extreme : { std::vector<std::string>::const_iterator names_i; std::map<std::string,package_data>::const_iterator pkgs_i; // Every entry in the names vector should have an entry in the packages vector. for (names_i = package_names.begin(); names_i != package_names.end(); names_i++) { if (packages.find(*names_i) == packages.end()) { return false; } } // The inverse should be true as well for (pkgs_i = packages.begin(); pkgs_i != packages.end(); pkgs_i++) { if (std::find(package_names.begin(), package_names.end(), pkgs_i->first) == package_names.end()) { return false; } } // Repeat for targets. std::map<std::string,target_data>::const_iterator targets_i; for (names_i = target_names.begin(); names_i != target_names.end(); names_i++) { if (targets.find(*names_i) == targets.end()) { return false; } } for (targets_i = targets.begin(); targets_i != targets.end(); targets_i++) { if (std::find(target_names.begin(), target_names.end(), targets_i->first) == target_names.end()) { return false; } } // And for templates std::map<std::string,template_data>::const_iterator templates_i; for (names_i = template_names.begin(); names_i != template_names.end(); names_i++) { if (templates.find(*names_i) == templates.end()) { return false; } } // The inverse should be true as well for (templates_i = templates.begin(); templates_i != templates.end(); templates_i++) { if (std::find(template_names.begin(), template_names.end(), templates_i->first) == template_names.end()) { return false; } } // Possibly the package directories should be validated as // well, not to mention the various version subdirectories, // but doing file I/O inside an assertion is excessive. } case cyg_thorough : case cyg_quick: if ("" == component_repository) { return false; } case cyg_trivial: case cyg_none : break; } return true;}//}}}//{{{ CdlPackagesDatabase:: misc // ----------------------------------------------------------------------------std::stringCdlPackagesDatabaseBody::get_component_repository() const{ CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_component_repository"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -