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

📄 database.cxx

📁 eCos1.31版
💻 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_current_package        = "::dbparser_current_package";const char*     dbparser_current_target         = "::dbparser_current_target";const char*     dbparser_component_repository   = "::component_repository";const char*     dbparser_database_name          = "::database_name";const char*     dbparser_pkgdir                 = "::pkgdir";const char*     dbparser_current_version        = "::version";const char*     dbparser_current_script         = "::script";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";CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlPackagesDatabaseBody);//}}}//{{{  Utility Tcl scripts                                      // ----------------------------------------------------------------------------// Utility scripts.//// Given a directory and a filename relative to that directory,// extract the contents of that file and store it in a variable// "script".static char* read_file_script = "                                       \n\if {[file pathtype $::database_name] != \"relative\"} {                 \n\    error \"Database name \\\"$::database_name\\\" should be relative\" \n\}                                                                       \n\set filename [file join $::component_repository $::database_name]       \n\if {0 == [file exists $filename]} {                                     \n\    error \"Component repository database $filename does not exist\"    \n\}                                                                       \n\if {0 == [file readable $filename]} {                                   \n\    error \"Component repository database $filename is not readable\"   \n\}                                                                       \n\set fd     \"\"                                                         \n\set script \"\"                                                         \n\set status [catch {                                                     \n\    set fd [open $filename r]                                           \n\    set script [read $fd]                                               \n\} message]                                                              \n\if {$fd != \"\"} {                                                      \n\    close $fd                                                           \n\}                                                                       \n\if { $status != 0 } {                                                   \n\    error $message                                                      \n\}                                                                       \n\";//}}}//{{{  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_command_prefix(CdlInterpreter, int, char**);    static int target_cflags(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) {        interp->set_result("A package definition should include name and contents");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    std::string pkg_name        = argv[1];    std::string msg             = std::string("Package ") + pkg_name + ": ";    // 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()) {        interp->set_result(msg + "a package can only be defined once");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    // Add this package to the list.    db->package_names.push_back(pkg_name);    // Also create a new package structure. This requires a default structure,    // which cannot be filled in until the body is executed.    CdlPackagesDatabaseBody::package_data tmp_struct;    db->packages[pkg_name]      = tmp_struct;    CdlPackagesDatabaseBody::package_data& package = db->packages[pkg_name];    // aliases and versions are vectors and will take care of themselves    package.description         = "";    package.directory           = "";    package.script              = "";    package.hardware            = false;    // 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                                 )    };    int i;    std::vector<CdlInterpreterCommandEntry> new_commands;    for (i = 0; 0 != commands[i].command; i++) {        new_commands.push_back(commands[i]);    }    std::vector<CdlInterpreterCommandEntry>* old_commands    = interp->push_commands(new_commands);    interp->set_variable(dbparser_current_package, pkg_name);    std::string str_result;    if (TCL_OK != interp->eval(argv[2], str_result)) {        interp->set_result(msg + str_result);        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    interp->pop_commands(old_commands);    interp->unset_variable(dbparser_current_package);    // Some of the fields are compulsory.    if ("" == package.directory) {        interp->set_result(msg + "missing directory specification");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    if ("" == package.script) {        interp->set_result(msg + "missing script specification");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    if (0 == package.aliases.size()) {        interp->set_result(msg + "at least one alias should be supplied");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    CYG_REPORT_RETVAL(TCL_OK);    return TCL_OK;}// 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);    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_package);    CYG_ASSERTC("" != name);    CYG_ASSERTC(db->packages.find(name) != db->packages.end());        CdlPackagesDatabaseBody::package_data& package = db->packages[name];    std::string msg = "Package " + name + ": ";    if (2 != argc) {        interp->set_result(msg + "the package description should be a single string");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    if ("" != package.description) {        interp->set_result(msg + "a package can have only one description");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    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);    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_package);    CYG_ASSERTC("" != name);    CYG_ASSERTC(db->packages.find(name) != db->packages.end());        CdlPackagesDatabaseBody::package_data& package = db->packages[name];    std::string msg = "Package " + name + ": ";        // The alias command should be used only once    if (0 < package.aliases.size()) {        interp->set_result(msg + "there should be only one list of aliases");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    // There should be one argument, a list of valid packages.    if (2 != argc) {        interp->set_result(msg + "alias should be followed by a list of known aliases");        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) {        interp->set_result(msg + "at least one alias should be supplied");        CYG_REPORT_RETVAL(TCL_ERROR);        return TCL_ERROR;    }    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;}// Syntax: directory <path>// The path is of course relative to the component repository.intCdlDbParser::package_directory(CdlInterpreter interp, int argc, char** argv){    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_directory", "result %d");    CYG_REPORT_FUNCARG1XV(argc);

⌨️ 快捷键说明

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