⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 database.cxx

📁 移植到WLIT项目的redboot源代码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//{{{  Banner                                                   //============================================================================////      database.cxx////      Temporary implementation of the CdlPackagesDatabase class//      Implementations of the temporary CdlTargetsDatabase and//      CdlTemplatesDatabase classes.////============================================================================//####COPYRIGHTBEGIN####//                                                                          // ----------------------------------------------------------------------------// Copyright (C) 1999, 2000 Red Hat, Inc.//// This file is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.//// ----------------------------------------------------------------------------//                                                                          //####COPYRIGHTEND####//============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   bartv// Contact(s):  bartv// Date:        1999/01/21// Version:     0.02////####DESCRIPTIONEND####//============================================================================//}}}//{{{  #include's                                               // ----------------------------------------------------------------------------#include "cdlconfig.h"// Get the infrastructure types, assertions, tracing and similar// facilities.#include <cyg/infra/cyg_ass.h>#include <cyg/infra/cyg_trac.h>// <cdl.hxx> defines everything implemented in this module.// It implicitly supplies <string>, <vector> and <map> because// the class definitions rely on these headers.#include <cdl.hxx>// strcmp() is useful when dealing with Tcl strings.#include <cstring>//}}}//{{{  Statics                                                  // ----------------------------------------------------------------------------// Some test cases may want to read in a file other than// "ecos.db", e.g. to facilitate testing the error conditions.char*CdlPackagesDatabaseBody::database_name = "ecos.db";// The new_package etc. commands need to store the name of the// current package so that subsequent commands can do the right thing.// Using constant strings as the key avoids typo problems.const char*     dbparser_pkgname                = "::dbparser_pkgname";const char*     dbparser_pkgdata                = "__cdl_dbparser_pkgdata";const char*     dbparser_targetname             = "::dbparser_targetname";const char*     dbparser_targetdata             = "__cdl_dbparser_targetdata";const char*     dbparser_component_repository   = "::component_repository";const char*     dbparser_database_key           = "__dbparser_key";       // for assoc dataconst char*     template_description_key        = "__cdl_extract_template_description"; // dittoconst char*     template_packages_key           = "__cdl_extract_template_packages";// These are useful for generating diagnostics.static std::string diag_package = std::string("package ");static std::string diag_target  = std::string("target ");CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlPackagesDatabaseBody);//}}}//{{{  Tcl commands for the parser                              //{{{  CdlDbParser class                                // ----------------------------------------------------------------------------// Commands that get invoked from inside the Tcl interpreter. These// need access to the internals of the database objects, which can be// achieved by making them static members of a CdlDbParser class.class CdlDbParser {  public:    static int new_package(CdlInterpreter, int, char**);    static int package_description(CdlInterpreter, int, char**);    static int package_alias(CdlInterpreter, int, char**);    static int package_directory(CdlInterpreter, int, char**);    static int package_script(CdlInterpreter, int, char**);    static int package_hardware(CdlInterpreter, int, char**);    static int new_target(CdlInterpreter, int, char**);    static int target_description(CdlInterpreter, int, char**);    static int target_alias(CdlInterpreter, int, char**);    static int target_packages(CdlInterpreter, int, char**);    static int target_enable(CdlInterpreter, int, char**);    static int target_disable(CdlInterpreter, int, char**);    static int target_set_value(CdlInterpreter, int, char**);};//}}}//{{{  CdlDbParser::package-related                     // ----------------------------------------------------------------------------// package <name> <body>intCdlDbParser::new_package(CdlInterpreter interp, int argc, char** argv){    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::new_package", "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);        if (3 != argc) {        if (argc < 2) {            CdlParse::report_error(interp, "", "Invalid package command, missing name and contents.");        } else if (argc == 2) {            CdlParse::report_error(interp, diag_package + argv[1], "Invalid package command, missing body.");        } else {            CdlParse::report_error(interp, diag_package + argv[1],                                   "Invalid package command, expecting just name and body.");        }        CYG_REPORT_RETVAL(TCL_OK);        return TCL_OK;    }    std::string pkg_name        = argv[1];    // Better make sure that this is not a duplicate definition.    if (std::find(db->package_names.begin(), db->package_names.end(), pkg_name) != db->package_names.end()) {        CdlParse::report_warning(interp, diag_package + pkg_name, "Duplicate package entry, ignoring second occurence.");        CYG_REPORT_RETVAL(TCL_OK);        return TCL_OK;    }        // The package data is constructed locally. It only gets added to    // the database in the absence of errors.    bool package_ok      = true;    int  old_error_count = CdlParse::get_error_count(interp);            CdlPackagesDatabaseBody::package_data package;    package.description = "";    package.directory   = "";    package.script      = "";    package.hardware    = false;        // aliases and versions are vectors and will take care of themselves    // And the name had better be valid as well.    if (!Cdl::is_valid_cdl_name(pkg_name)) {        CdlParse::report_error(interp, diag_package + pkg_name, "This is not a valid CDL name.");    }        // Sort out the commands, then invoke the script in argv[2]. There is    // no need to worry about error recovery here, any errors will be    // fatal anyway.    CdlInterpreterCommandEntry commands[] = {        CdlInterpreterCommandEntry("description", &CdlDbParser::package_description ),        CdlInterpreterCommandEntry("alias",       &CdlDbParser::package_alias       ),        CdlInterpreterCommandEntry("directory",   &CdlDbParser::package_directory   ),        CdlInterpreterCommandEntry("script",      &CdlDbParser::package_script      ),        CdlInterpreterCommandEntry("hardware",    &CdlDbParser::package_hardware    ),        CdlInterpreterCommandEntry("",            0                                 )    };    CdlInterpreterBody::CommandSupport  cmds(interp, commands);    CdlInterpreterBody::VariableSupport interp_name(interp, dbparser_pkgname, pkg_name);    CdlInterpreterBody::AssocSupport    interp_data(interp, dbparser_pkgdata, static_cast<ClientData>(&package));    int result = interp->eval(argv[2]);    if (TCL_OK == result) {                // The body has been parsed OK. Check that it is valid.        if ("" == package.directory) {            CdlParse::report_error(interp, diag_package + pkg_name, "Missing directory specification.");        }        if ("" == package.script) {            CdlParse::report_error(interp, diag_package + pkg_name, "Missing script specification.");        }        if (0 == package.aliases.size()) {            CdlParse::report_error(interp, diag_package + pkg_name, "At least one alias should be supplied.");        }        // Additional checks. Is the package directory actually present.        if ("" != package.directory) {            std::string repo = interp->get_variable(dbparser_component_repository);            CYG_ASSERTC("" != repo);            std::string pkgdir = repo + "/" + package.directory;            if (!interp->is_directory(pkgdir)) {                CdlParse::report_warning(interp, diag_package + pkg_name,                        std::string("This package is not present in the component repository.\nThere is no directory `")                                    + pkgdir + "'.");                package_ok = false;            } else {                                // Now look for version subdirectories. There should be at least one.                std::vector<std::string> subdirs;                unsigned int i;                interp->locate_subdirs(pkgdir, subdirs);                std::sort(subdirs.begin(), subdirs.end(), Cdl::version_cmp());                                for (i = 0; i < subdirs.size(); i++) {                    if ("CVS" == subdirs[i]) {                        continue;                    }                    if ("" != package.script) {                        if (!(interp->is_file(pkgdir + "/" + subdirs[i] + "/cdl/" + package.script) ||                              interp->is_file(pkgdir + "/" + subdirs[i] + "/" + package.script))) {                            CdlParse::report_warning(interp, diag_package + pkg_name,                                                     std::string("Version subdirectory `") + subdirs[i] +                                                     "' does not have a CDL script `" + package.script + "'.");                            continue;                        }                    }                    package.versions.push_back(subdirs[i]);                }                if (0 == package.versions.size()) {                    CdlParse::report_warning(interp, diag_package + pkg_name,                                             "This package does not have any valid version subdirectories.");                    package_ok = false;                }            }        }    }    // If the package is still ok, now is the time to add it to the database.    if (package_ok && (old_error_count == CdlParse::get_error_count(interp))) {        db->package_names.push_back(pkg_name);        db->packages[pkg_name] = package;    }    CYG_REPORT_RETVAL(result);    return result;}// Syntax: description <text>intCdlDbParser::package_description(CdlInterpreter interp, int argc, char** argv){    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_description", "result %d");    CYG_REPORT_FUNCARG1XV(argc);    CYG_PRECONDITION_CLASSC(interp);    std::string name = interp->get_variable(dbparser_pkgname);    CYG_ASSERTC("" != name);    CdlPackagesDatabaseBody::package_data* package =        static_cast<CdlPackagesDatabaseBody::package_data*>(interp->get_assoc_data(dbparser_pkgdata));    if (2 != argc) {        CdlParse::report_error(interp, diag_package + name, "Invalid description, expecting a single string.");    } else if ("" != package->description) {        CdlParse::report_warning(interp, diag_package + name, "A package should have only one description.");    } else {        package->description = argv[1];    }        CYG_REPORT_RETVAL(TCL_OK);    return TCL_OK;}// Syntax: alias <list>// For example: alias { "This is an alias" another_alias dummy_name }intCdlDbParser::package_alias(CdlInterpreter interp, int argc, char** argv){    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_alias", "result %d");    CYG_REPORT_FUNCARG1XV(argc);    CYG_PRECONDITION_CLASSC(interp);    std::string name = interp->get_variable(dbparser_pkgname);    CYG_ASSERTC("" != name);    CdlPackagesDatabaseBody::package_data* package =        static_cast<CdlPackagesDatabaseBody::package_data*>(interp->get_assoc_data(dbparser_pkgdata));    // There should be one argument, a list of valid packages.    // Also, the alias command should be used only once    if (2 != argc) {        CdlParse::report_error(interp, diag_package + name,                               "The alias command should be followed by a list of known aliases.");    } else if (0 < package->aliases.size()) {        CdlParse::report_warning(interp, diag_package + name, "There should be only one list of aliases.");    } 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_package + name, Tcl_GetStringResult(tcl_interp));        } else {            if (0 == list_count) {                CdlParse::report_error(interp, diag_package + name, "At least one alias should be supplied.");            } else {                for (int i = 0; i < list_count; i++) {                    package->aliases.push_back(list_entries[i]);                }            }            Tcl_Free((char*)list_entries);        }    }        CYG_REPORT_RETVAL(TCL_OK);    return TCL_OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -