-//{{{ Banner
+//{{{ Banner
//============================================================================
//
//
//============================================================================
//####COPYRIGHTBEGIN####
-//
+//
// ----------------------------------------------------------------------------
// Copyright (C) 2002 Bart Veer
// 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)
+// 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
+//
+// 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.,
+// this program; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// ----------------------------------------------------------------------------
-//
+//
//####COPYRIGHTEND####
//============================================================================
//#####DESCRIPTIONBEGIN####
//============================================================================
//}}}
-//{{{ #include's
+//{{{ #include's
// ----------------------------------------------------------------------------
#include "cdlconfig.h"
//}}}
-//{{{ CdlConfiguration constants and statics
+//{{{ CdlConfiguration constants and statics
// ----------------------------------------------------------------------------
CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConfigurationBody);
//}}}
-//{{{ CdlConfiguration:: creation
+//{{{ CdlConfiguration:: creation
// ----------------------------------------------------------------------------
// The toplevel class will take care of just about everything.
database = db;
save_file = "";
description = "";
-
+
cdlconfigurationbody_cookie = CdlConfigurationBody_Magic;
CYGDBG_MEMLEAK_CONSTRUCTOR();
-
+
CYG_POSTCONDITION_THISC();
CYG_REPORT_RETURN();
}
}
//}}}
-//{{{ CdlConfiguration:: destructor
+//{{{ CdlConfiguration:: destructor
// ----------------------------------------------------------------------------
CdlConfigurationBody::~CdlConfigurationBody()
CdlLocalTransaction transaction(this);
const std::vector<CdlLoadable>& loadables = this->get_loadables();
for (int i = loadables.size() - 1; i >= 0; i--) {
- CdlPackage pkg = dynamic_cast<CdlPackage>(loadables[i]);
- if (0 != pkg) {
- this->unload_package(transaction.get(), pkg);
- }
+ CdlPackage pkg = dynamic_cast<CdlPackage>(loadables[i]);
+ if (0 != pkg) {
+ this->unload_package(transaction.get(), pkg);
+ }
}
transaction.propagate();
transaction.commit();
-
+
cdlconfigurationbody_cookie = CdlConfigurationBody_Invalid;
current_hardware = "";
current_template = "";
database = 0;
save_file = "";
-
+
CYGDBG_MEMLEAK_DESTRUCTOR();
-
+
CYG_REPORT_RETURN();
}
//}}}
-//{{{ CdlConfiguration::check_this()
+//{{{ CdlConfiguration::check_this()
// ----------------------------------------------------------------------------
// There is very little information associated with a configuration.
CdlConfigurationBody::check_this(cyg_assert_class_zeal zeal) const
{
if (CdlConfigurationBody_Magic != cdlconfigurationbody_cookie) {
- return false;
+ return false;
}
CYGDBG_MEMLEAK_CHECKTHIS();
switch(zeal) {
case cyg_system_test :
case cyg_extreme :
- if ((0 == database) || !database->check_this(cyg_quick)) {
- return false;
- }
+ if ((0 == database) || !database->check_this(cyg_quick)) {
+ return false;
+ }
case cyg_thorough :
- if (("" != current_hardware) && !database->is_known_target(current_hardware)) {
- return false;
- }
- if (("" != current_template) && !database->is_known_template(current_template)) {
- return false;
- }
+ if (("" != current_hardware) && !database->is_known_target(current_hardware)) {
+ return false;
+ }
+ if (("" != current_template) && !database->is_known_template(current_template)) {
+ return false;
+ }
case cyg_quick :
- if (0 == database) {
- return false;
- }
+ if (0 == database) {
+ return false;
+ }
case cyg_trivial :
case cyg_none :
default :
- break;
+ break;
}
return CdlNodeBody::check_this(zeal) && CdlContainerBody::check_this(zeal) && CdlToplevelBody::check_this(zeal);
}
//}}}
-//{{{ CdlConfiguration:: basic info
+//{{{ CdlConfiguration:: basic info
// ----------------------------------------------------------------------------
// Provide ready access to configuration-specific data.
CYG_PRECONDITION_THISC();
current_hardware = new_name;
-
+
CYG_REPORT_RETURN();
}
CYG_PRECONDITION_THISC();
current_template = new_name;
-
+
CYG_REPORT_RETURN();
}
}
//}}}
-//{{{ Load and unload operations - wrappers
+//{{{ Load and unload operations - wrappers
// ----------------------------------------------------------------------------
// These members are basically wrappers for the functions that do the
void
CdlConfigurationBody::load_package(std::string name, std::string version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::load_package");
CYG_REPORT_FUNCARG1XV(this);
void
CdlConfigurationBody::change_package_version(std::string name, std::string version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::change_package_version");
CYG_REPORT_FUNCARG1XV(this);
void
CdlConfigurationBody::change_package_version(CdlPackage package, std::string version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::change_package_version");
CYG_REPORT_FUNCARG1XV(this);
void
CdlConfigurationBody::change_package_version(CdlTransaction transaction, std::string name, std::string new_version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::change_package_version");
CYG_REPORT_FUNCARG2XV(this, transaction);
CdlPackage package = 0;
CdlNode node = this->lookup(name);
if (0 != node) {
- package = dynamic_cast<CdlPackage>(node);
+ package = dynamic_cast<CdlPackage>(node);
}
// For now it is illegal to change the version of package that has
// not been loaded yet
if (0 == package) {
- throw CdlInputOutputException(std::string("Cannot change version of \"") + name + "\" , this package is not loaded");
+ throw CdlInputOutputException(std::string("Cannot change version of \"") + name + "\" , this package is not loaded");
}
CYG_ASSERT_CLASSC(package);
-
+
this->change_package_version(transaction, package, new_version, error_fn, warn_fn, limbo);
CYG_REPORT_RETURN();
void
CdlConfigurationBody::add(std::string filename,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::add");
CYG_REPORT_FUNCARG1XV(this);
void
CdlConfigurationBody::set_template(std::string name, std::string version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::set_template");
CYG_REPORT_FUNCARG1XV(this);
void
CdlConfigurationBody::set_template_file(std::string filename,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::set_template_file");
CYG_REPORT_FUNCARG1XV(this);
void
CdlConfigurationBody::set_template(CdlTransaction transaction, std::string template_name, std::string version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::set_template");
CYG_REPORT_FUNCARG2XV(this, transaction);
// Some consistency checks before doing anything damaging
if (!this->database->is_known_template(template_name)) {
- throw CdlInputOutputException("Unknown template " + template_name);
+ throw CdlInputOutputException("Unknown template " + template_name);
}
std::string template_filename = this->database->get_template_filename(template_name, version);
if ("" == template_filename) {
- if ("" == version) {
- throw CdlInputOutputException("There is no template file corresponding to " + template_name);
- } else {
- throw CdlInputOutputException("There is no temmplate file corresponding to version "
- + version + " of " + template_name);
- }
+ if ("" == version) {
+ throw CdlInputOutputException("There is no template file corresponding to " + template_name);
+ } else {
+ throw CdlInputOutputException("There is no temmplate file corresponding to version "
+ + version + " of " + template_name);
+ }
}
// Now use set_template_file() to do the hard work.
void
CdlConfigurationBody::set_hardware(std::string name,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::set_hardware");
CYG_REPORT_FUNCARG1XV(this);
}
//}}}
-//{{{ Load and unload - transaction support
+//{{{ Load and unload - transaction support
// ----------------------------------------------------------------------------
// A number of commit/cancel auxiliary classes are needed to allow the
public:
CdlConfiguration_CommitCancelLoad(CdlPackage package_arg)
- : CdlTransactionCommitCancelOp()
+ : CdlTransactionCommitCancelOp()
{
- CYG_ASSERT_CLASSC(package_arg);
- package = package_arg;
+ CYG_ASSERT_CLASSC(package_arg);
+ package = package_arg;
}
~CdlConfiguration_CommitCancelLoad()
{
- package = 0;
+ package = 0;
}
void commit(CdlTransaction transaction)
{
- CYG_ASSERT_CLASSC(package);
- CdlLoadableBody::transaction_commit_load(transaction, package);
- package = 0;
+ CYG_ASSERT_CLASSC(package);
+ CdlLoadableBody::transaction_commit_load(transaction, package);
+ package = 0;
}
void cancel(CdlTransaction transaction)
{
- CYG_ASSERT_CLASSC(package);
- CdlLoadableBody::transaction_cancel_load(transaction, package);
- package = 0;
+ CYG_ASSERT_CLASSC(package);
+ CdlLoadableBody::transaction_cancel_load(transaction, package);
+ package = 0;
}
-
+
protected:
-
+
private:
CdlConfiguration_CommitCancelLoad()
{
public:
CdlConfiguration_CommitCancelUnload(CdlPackage package_arg)
- : CdlTransactionCommitCancelOp()
+ : CdlTransactionCommitCancelOp()
{
- CYG_ASSERT_CLASSC(package_arg);
- package = package_arg;
+ CYG_ASSERT_CLASSC(package_arg);
+ package = package_arg;
}
~CdlConfiguration_CommitCancelUnload()
{
- package = 0;
+ package = 0;
}
void commit(CdlTransaction transaction)
{
- CYG_PRECONDITION_CLASSC(package);
- CdlLoadableBody::transaction_commit_unload(transaction, package);
- package = 0;
+ CYG_PRECONDITION_CLASSC(package);
+ CdlLoadableBody::transaction_commit_unload(transaction, package);
+ package = 0;
}
void cancel(CdlTransaction transaction)
{
- CYG_PRECONDITION_CLASSC(package);
- CdlLoadableBody::transaction_cancel_unload(transaction, package);
- package = 0;
+ CYG_PRECONDITION_CLASSC(package);
+ CdlLoadableBody::transaction_cancel_unload(transaction, package);
+ package = 0;
}
protected:
public CdlTransactionCommitCancelOp
{
friend class CdlTest;
-
+
public:
CdlConfiguration_CommitCancelHardwareName(std::string old_name_arg)
- : CdlTransactionCommitCancelOp()
+ : CdlTransactionCommitCancelOp()
{
- old_name = old_name_arg;
+ old_name = old_name_arg;
}
~CdlConfiguration_CommitCancelHardwareName()
{
- old_name = "";
+ old_name = "";
}
void commit(CdlTransaction transaction)
{
- // The new name is already installed, nothing more needs to happen.
- CYG_UNUSED_PARAM(CdlTransaction, transaction);
+ // The new name is already installed, nothing more needs to happen.
+ CYG_UNUSED_PARAM(CdlTransaction, transaction);
}
void cancel(CdlTransaction transaction)
{
- // Restore the old name
- CdlToplevel toplevel = transaction->get_toplevel();
- CYG_ASSERTC(0 != toplevel);
- CdlConfiguration configuration = dynamic_cast<CdlConfiguration>(toplevel);
- CYG_ASSERT_CLASSC(configuration);
+ // Restore the old name
+ CdlToplevel toplevel = transaction->get_toplevel();
+ CYG_ASSERTC(0 != toplevel);
+ CdlConfiguration configuration = dynamic_cast<CdlConfiguration>(toplevel);
+ CYG_ASSERT_CLASSC(configuration);
- configuration->set_hardware_name(old_name);
- CYG_UNUSED_PARAM(CdlTransaction, transaction);
+ configuration->set_hardware_name(old_name);
+ CYG_UNUSED_PARAM(CdlTransaction, transaction);
}
-
+
protected:
private:
public CdlTransactionCommitCancelOp
{
friend class CdlTest;
-
+
public:
CdlConfiguration_CommitCancelTemplateName(std::string old_name_arg)
- : CdlTransactionCommitCancelOp()
+ : CdlTransactionCommitCancelOp()
{
- old_name = old_name_arg;
+ old_name = old_name_arg;
}
~CdlConfiguration_CommitCancelTemplateName()
{
- old_name = "";
+ old_name = "";
}
void commit(CdlTransaction transaction)
{
- // The new name is already installed, nothing more needs to happen.
- CYG_UNUSED_PARAM(CdlTransaction, transaction);
+ // The new name is already installed, nothing more needs to happen.
+ CYG_UNUSED_PARAM(CdlTransaction, transaction);
}
void cancel(CdlTransaction transaction)
{
- // Restore the old name
- CdlToplevel toplevel = transaction->get_toplevel();
- CYG_ASSERTC(0 != toplevel);
- CdlConfiguration configuration = dynamic_cast<CdlConfiguration>(toplevel);
- CYG_ASSERT_CLASSC(configuration);
+ // Restore the old name
+ CdlToplevel toplevel = transaction->get_toplevel();
+ CYG_ASSERTC(0 != toplevel);
+ CdlConfiguration configuration = dynamic_cast<CdlConfiguration>(toplevel);
+ CYG_ASSERT_CLASSC(configuration);
- configuration->set_template_name(old_name);
- CYG_UNUSED_PARAM(CdlTransaction, transaction);
+ configuration->set_template_name(old_name);
+ CYG_UNUSED_PARAM(CdlTransaction, transaction);
}
-
+
protected:
private:
};
//}}}
-//{{{ CdlConfiguration::load_package()
+//{{{ CdlConfiguration::load_package()
// ----------------------------------------------------------------------------
// Loading a package into the current level. This involves the following
void
CdlConfigurationBody::load_package(CdlTransaction transaction, std::string name, std::string version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::load_package");
CYG_REPORT_FUNCARG1XV(this);
// Locate the database entry. Also check the version (filling it in if necessary).
// Get hold of the package directory and the initial script.
if (!database->is_known_package(name)) {
- throw CdlInputOutputException("Unknown package " + name);
+ throw CdlInputOutputException("Unknown package " + name);
}
const std::vector<std::string>& versions = database->get_package_versions(name);
if ("" == version) {
- version = *(versions.begin());
+ version = *(versions.begin());
} else {
- if (std::find(versions.begin(), versions.end(), version) == versions.end()) {
- throw CdlInputOutputException("Package " + name + " does not have an installed version `" + version + "'.");
- }
+ if (std::find(versions.begin(), versions.end(), version) == versions.end()) {
+ throw CdlInputOutputException("Package " + name + " does not have an installed version `" + version + "'.");
+ }
}
std::string directory = database->get_package_directory(name);
std::string script = database->get_package_script(name);
std::string tcl_cmd = "regsub -all -- {\\\\} [file join " + directory + " " + version + "] / result; return $result";
std::string tcl_result;
if (TCL_OK != interp->eval(tcl_cmd, tcl_result)) {
- throw CdlInputOutputException("Cannot load package `" + name + "', internal error constructing pathname.");
+ throw CdlInputOutputException("Cannot load package `" + name + "', internal error constructing pathname.");
}
directory = tcl_result;
-
+
tcl_cmd = "file isdirectory [file join \"" + database->get_component_repository() + "\" " + directory + "]";
if ((TCL_OK != interp->eval(tcl_cmd, tcl_result)) || ("1" != tcl_result)) {
- throw CdlInputOutputException("Cannot load package `" + name + "', there is no directory `" + directory + "'.");
+ throw CdlInputOutputException("Cannot load package `" + name + "', there is no directory `" + directory + "'.");
}
-
+
// Make sure that there is no name conflict. No resources have been allocated
// yet, so this is a good time.
CdlNode node = lookup(name);
if (0 != node) {
- if (0 != dynamic_cast<CdlPackage>(node)) {
- throw CdlInputOutputException("Package `" + name + "' is already loaded.");
- } else {
+ if (0 != dynamic_cast<CdlPackage>(node)) {
+ throw CdlInputOutputException("Package `" + name + "' is already loaded.");
+ } else {
- std::string msg = "Name clash for package `" + name + "',there is a `" +
- node->get_class_name() + " " + name + "' already loaded";
- CdlLoadable owner_pkg = node->get_owner();
- if (0 != owner_pkg) {
- msg += " in package " + owner_pkg->get_name();
- }
- throw CdlInputOutputException(msg);
- }
+ std::string msg = "Name clash for package `" + name + "',there is a `" +
+ node->get_class_name() + " " + name + "' already loaded";
+ CdlLoadable owner_pkg = node->get_owner();
+ if (0 != owner_pkg) {
+ msg += " in package " + owner_pkg->get_name();
+ }
+ throw CdlInputOutputException(msg);
+ }
}
// Now create the package object itself.
CdlPackage package = 0;
bool bound = false;
CdlConfiguration_CommitCancelLoad* load_op = 0;
-
+
try {
- package = new CdlPackageBody(name, this, directory);
-
- // The package should be added to the hierarchy immediately.
- // All nodes will get added to the hierarchy as they are
- // created, an operation that has to be undone during
- // failure.
- this->add_node(package, this, package);
-
- // Load the package data. The various nodes will all end up
- // in a hierarchy below the package, but without any checks
- // for name conflicts etc and ignoring any re-parenting.
- CdlInterpreter interp = package->get_interpreter();
- CYG_ASSERT_CLASSC(interp);
-
- interp->add_command("unknown", &CdlParse::unknown_command);
- CdlInterpreterBody::DiagSupport diag_support(interp, error_fn, warn_fn);
-
- // Next figure out the script name, and make sure that it exists.
- std::string actual_script = package->find_absolute_file(script, "cdl");
- if ("" == actual_script) {
- throw CdlInputOutputException("Package " + name + ", unable to find initial script " + script);
- }
- tcl_cmd = "file isfile \"" + actual_script + "\"";
- if ((TCL_OK != interp->eval(tcl_cmd, tcl_result)) || ("1" != tcl_result)) {
- throw CdlInputOutputException("Package " + name + ", " + actual_script + " is not a CDL script");
- }
-
- // The script is valid. Set up the interpreter appropriately.
- CdlParse::clear_error_count(interp);
- static CdlInterpreterCommandEntry commands[] =
- {
- CdlInterpreterCommandEntry("cdl_package", &CdlPackageBody::parse_package ),
- CdlInterpreterCommandEntry("cdl_component", &CdlComponentBody::parse_component ),
- CdlInterpreterCommandEntry("cdl_option", &CdlOptionBody::parse_option ),
- CdlInterpreterCommandEntry("cdl_interface", &CdlInterfaceBody::parse_interface ),
- CdlInterpreterCommandEntry("cdl_dialog", &CdlDialogBody::parse_dialog ),
- CdlInterpreterCommandEntry("cdl_wizard", &CdlWizardBody::parse_wizard ),
- CdlInterpreterCommandEntry("", 0 )
- };
- CdlInterpreterBody::CommandSupport interp_cmds(interp, commands);
- CdlInterpreterBody::ContainerSupport interp_container(interp, package);
- CdlInterpreterBody::ContextSupport interp_context(interp, actual_script);
-
- // The interpreter is now ready.
- (void) interp->eval_file(actual_script);
-
- // Clean out the commands etc. This interpreter may get used again
- // in future, and it should not be possible to define new options
- // etc. in that invocation.
- interp->remove_command("unknown");
-
- // All the data has been read in without generating an
- // exception. However there may have been errors reported via
- // the parse_error_fn, and any errors at all should result
- // in an exception.
- int error_count = CdlParse::get_error_count(interp);
- if (error_count > 0) {
- std::string tmp;
- Cdl::integer_to_string(error_count, tmp);
- throw CdlParseException("Package " + name + ", " + tmp + " error" +
- ((error_count > 1) ? "s" : "") +
- " occurred while reading in the CDL data.");
- }
-
- // All the data has been read in, implying that there are no
- // fatal problems with the data. Now try to bind all
- // references to and from this loadable.
- package->bind(transaction);
- bound = true;
-
- // Finally, create a suitable transaction commit/cancel object
- // and add it to the transaction.
- load_op = new CdlConfiguration_CommitCancelLoad(package);
- transaction->add_commit_cancel_op(load_op);
-
+ package = new CdlPackageBody(name, this, directory);
+
+ // The package should be added to the hierarchy immediately.
+ // All nodes will get added to the hierarchy as they are
+ // created, an operation that has to be undone during
+ // failure.
+ this->add_node(package, this, package);
+
+ // Load the package data. The various nodes will all end up
+ // in a hierarchy below the package, but without any checks
+ // for name conflicts etc and ignoring any re-parenting.
+ CdlInterpreter interp = package->get_interpreter();
+ CYG_ASSERT_CLASSC(interp);
+
+ interp->add_command("unknown", &CdlParse::unknown_command);
+ CdlInterpreterBody::DiagSupport diag_support(interp, error_fn, warn_fn);
+
+ // Next figure out the script name, and make sure that it exists.
+ std::string actual_script = package->find_absolute_file(script, "cdl");
+ if ("" == actual_script) {
+ throw CdlInputOutputException("Package " + name + ", unable to find initial script " + script);
+ }
+ tcl_cmd = "file isfile \"" + actual_script + "\"";
+ if ((TCL_OK != interp->eval(tcl_cmd, tcl_result)) || ("1" != tcl_result)) {
+ throw CdlInputOutputException("Package " + name + ", " + actual_script + " is not a CDL script");
+ }
+
+ // The script is valid. Set up the interpreter appropriately.
+ CdlParse::clear_error_count(interp);
+ static CdlInterpreterCommandEntry commands[] =
+ {
+ CdlInterpreterCommandEntry("cdl_package", &CdlPackageBody::parse_package ),
+ CdlInterpreterCommandEntry("cdl_component", &CdlComponentBody::parse_component ),
+ CdlInterpreterCommandEntry("cdl_option", &CdlOptionBody::parse_option ),
+ CdlInterpreterCommandEntry("cdl_interface", &CdlInterfaceBody::parse_interface ),
+ CdlInterpreterCommandEntry("cdl_dialog", &CdlDialogBody::parse_dialog ),
+ CdlInterpreterCommandEntry("cdl_wizard", &CdlWizardBody::parse_wizard ),
+ CdlInterpreterCommandEntry("", 0 )
+ };
+ CdlInterpreterBody::CommandSupport interp_cmds(interp, commands);
+ CdlInterpreterBody::ContainerSupport interp_container(interp, package);
+ CdlInterpreterBody::ContextSupport interp_context(interp, actual_script);
+
+ // The interpreter is now ready.
+ (void) interp->eval_file(actual_script);
+
+ // Clean out the commands etc. This interpreter may get used again
+ // in future, and it should not be possible to define new options
+ // etc. in that invocation.
+ interp->remove_command("unknown");
+
+ // All the data has been read in without generating an
+ // exception. However there may have been errors reported via
+ // the parse_error_fn, and any errors at all should result
+ // in an exception.
+ int error_count = CdlParse::get_error_count(interp);
+ if (error_count > 0) {
+ std::string tmp;
+ Cdl::integer_to_string(error_count, tmp);
+ throw CdlParseException("Package " + name + ", " + tmp + " error" +
+ ((error_count > 1) ? "s" : "") +
+ " occurred while reading in the CDL data.");
+ }
+
+ // All the data has been read in, implying that there are no
+ // fatal problems with the data. Now try to bind all
+ // references to and from this loadable.
+ package->bind(transaction);
+ bound = true;
+
+ // Finally, create a suitable transaction commit/cancel object
+ // and add it to the transaction.
+ load_op = new CdlConfiguration_CommitCancelLoad(package);
+ transaction->add_commit_cancel_op(load_op);
+
} catch (...) {
- // Something went wrong during the create or load. It is necessary
- // to delete the package. Undo all the operations above, in
- // reverse order. The add_commit_cancel_op() was the last step,
- // so need not be undone here.
- if (0 != load_op) {
- delete load_op;
- }
-
- if (0 != package) {
- // Note: no attempt is made to recover from errors here
- if (bound) {
- package->unbind(transaction);
- }
- this->remove_loadable_from_toplevel(package);
- delete package;
- }
- throw;
+ // Something went wrong during the create or load. It is necessary
+ // to delete the package. Undo all the operations above, in
+ // reverse order. The add_commit_cancel_op() was the last step,
+ // so need not be undone here.
+ if (0 != load_op) {
+ delete load_op;
+ }
+
+ if (0 != package) {
+ // Note: no attempt is made to recover from errors here
+ if (bound) {
+ package->unbind(transaction);
+ }
+ this->remove_loadable_from_toplevel(package);
+ delete package;
+ }
+ throw;
}
// FIXME: implement limbo support
-
+
// We also have a sensible value for the package as a whole.
// Use this value for both default and user - after all the
// user has selected the package.
}
//}}}
-//{{{ CdlConfiguration::unload_package()
+//{{{ CdlConfiguration::unload_package()
// ----------------------------------------------------------------------------
// Unloading a package is very simple. If requested, save all current
CYG_PRECONDITION_CLASSC(package);
if (limbo) {
- const std::vector<CdlNode>& pkg_contents = package->get_owned();
- std::vector<CdlNode>::const_iterator node_i;
-
- for (node_i = pkg_contents.begin(); node_i != pkg_contents.end(); node_i++) {
- CdlValuable valuable = dynamic_cast<CdlValuable>(*node_i);
- if (0 != valuable) {
- if (valuable->has_source(CdlValueSource_Inferred) ||
- valuable->has_source(CdlValueSource_Wizard) ||
- valuable->has_source(CdlValueSource_User)) {
-
- set_limbo_value(valuable);
- }
- }
- }
+ const std::vector<CdlNode>& pkg_contents = package->get_owned();
+ std::vector<CdlNode>::const_iterator node_i;
+
+ for (node_i = pkg_contents.begin(); node_i != pkg_contents.end(); node_i++) {
+ CdlValuable valuable = dynamic_cast<CdlValuable>(*node_i);
+ if (0 != valuable) {
+ if (valuable->has_source(CdlValueSource_Inferred) ||
+ valuable->has_source(CdlValueSource_Wizard) ||
+ valuable->has_source(CdlValueSource_User)) {
+
+ set_limbo_value(valuable);
+ }
+ }
+ }
}
bool unbound = false;
bool removed = false;
CdlConfiguration_CommitCancelUnload* unload_op = 0;
try {
-
- package->unbind(transaction);
- unbound = true;
- this->remove_loadable_from_toplevel(package);
- removed = true;
- unload_op = new CdlConfiguration_CommitCancelUnload(package);
- transaction->add_commit_cancel_op(unload_op);
-
+
+ package->unbind(transaction);
+ unbound = true;
+ this->remove_loadable_from_toplevel(package);
+ removed = true;
+ unload_op = new CdlConfiguration_CommitCancelUnload(package);
+ transaction->add_commit_cancel_op(unload_op);
+
} catch(...) {
- if (0 != unload_op) {
- delete unload_op;
- }
- if (removed) {
- this->add_loadable_to_toplevel(package);
- }
- if (unbound) {
- package->bind(transaction);
- }
- throw;
- }
-
+ if (0 != unload_op) {
+ delete unload_op;
+ }
+ if (removed) {
+ this->add_loadable_to_toplevel(package);
+ }
+ if (unbound) {
+ package->bind(transaction);
+ }
+ throw;
+ }
+
CYG_REPORT_RETURN();
}
//}}}
-//{{{ CdlConfiguration::change_package_version()
+//{{{ CdlConfiguration::change_package_version()
// ----------------------------------------------------------------------------
// Changing a package version is just a case of unloading the old version
void
CdlConfigurationBody::change_package_version(CdlTransaction transaction, CdlPackage package, std::string new_version,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::change_package_version");
CYG_REPORT_FUNCARG3XV(this, transaction, package);
std::string name = package->get_name();
const std::vector<std::string>& pkg_versions = database->get_package_versions(name);
if ("" == new_version) {
- new_version = *(pkg_versions.begin());
+ new_version = *(pkg_versions.begin());
} else if (std::find(pkg_versions.begin(), pkg_versions.end(), new_version) == pkg_versions.end()) {
- throw CdlInputOutputException("Version " + new_version + " of package " + name + " is not installed.");
+ throw CdlInputOutputException("Version " + new_version + " of package " + name + " is not installed.");
}
bool unloaded = false;
try {
- this->unload_package(transaction, package, limbo);
- unloaded = true;
- this->load_package(transaction, name, new_version, error_fn, warn_fn, limbo);
+ this->unload_package(transaction, package, limbo);
+ unloaded = true;
+ this->load_package(transaction, name, new_version, error_fn, warn_fn, limbo);
} catch(...) {
- if (unloaded) {
- // There should be a commit/cancel op for the unload package step.
- // This can be undone.
- CdlTransactionCommitCancelOp* unload_op = transaction->get_last_commit_cancel_op();
- CYG_ASSERTC(0 != unload_op);
- CYG_ASSERTC(0 != dynamic_cast<CdlConfiguration_CommitCancelUnload*>(unload_op));
- transaction->cancel_last_commit_cancel_op();
- CYG_UNUSED_PARAM(CdlTransactionCommitCancelOp*, unload_op);
- }
- throw;
+ if (unloaded) {
+ // There should be a commit/cancel op for the unload package step.
+ // This can be undone.
+ CdlTransactionCommitCancelOp* unload_op = transaction->get_last_commit_cancel_op();
+ CYG_ASSERTC(0 != unload_op);
+ CYG_ASSERTC(0 != dynamic_cast<CdlConfiguration_CommitCancelUnload*>(unload_op));
+ transaction->cancel_last_commit_cancel_op();
+ CYG_UNUSED_PARAM(CdlTransactionCommitCancelOp*, unload_op);
+ }
+ throw;
}
CYG_REPORT_RETURN();
}
//}}}
-//{{{ CdlConfiguration::set_hardware() etc.
+//{{{ CdlConfiguration::set_hardware() etc.
// ----------------------------------------------------------------------------
// Setting the hardware involves unloading the old hardware, if any, and
void
CdlConfigurationBody::set_hardware(CdlTransaction transaction, std::string target_name,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::set_hardware");
CYG_REPORT_FUNCARG2XV(this, transaction);
// Minimal consistency check before attempting anything complicated.
if (!database->is_known_target(target_name)) {
- throw CdlInputOutputException("Unknown target " + target_name);
+ throw CdlInputOutputException("Unknown target " + target_name);
}
CdlInterpreter interp = this->get_interpreter();
CdlInterpreterBody::DiagSupport diag_support(interp, error_fn, warn_fn);
CdlInterpreterBody::ContextSupport context_support(interp, "Hardware selection");
-
+
CdlConfiguration_CommitCancelHardwareName* rename_op = new CdlConfiguration_CommitCancelHardwareName(current_hardware);
try {
- transaction->add_commit_cancel_op(rename_op);
- const std::vector<CdlLoadable>& loadables = this->get_loadables();
- int i;
- for (i = (int) loadables.size() - 1; i >= 0; i--) {
- CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
- if ((0 != package) && package->belongs_to_hardware()) {
- this->unload_package(transaction, package, limbo);
- }
- }
- current_hardware = "";
-
- if ("" != target_name) {
-
- const std::vector<std::string>& packages = database->get_target_packages(target_name);
- std::vector<std::string>::const_iterator name_i;
- for (name_i = packages.begin(); name_i != packages.end(); name_i++) {
- // Target specifications may refer to packages that are not
- // installed. This is useful in e.g. an anoncvs environment.
- if (database->is_known_package(*name_i)) {
- // It is possible for a hardware package to have been
- // loaded separately, in which case there is no point in
- // loading it again.
- if (0 == this->lookup(*name_i)) {
- this->load_package(transaction, *name_i, "",
- error_fn, warn_fn, limbo);
- CdlPackage package = dynamic_cast<CdlPackage>(this->lookup(*name_i));
- CYG_LOOP_INVARIANT_CLASSC(package);
- package->loaded_for_hardware = true;
- }
- } else {
- CdlParse::report_warning(interp, "",
- std::string("The target specification lists a package `") + *name_i +
- "' which is not present in the component repository.");
- }
- }
- }
- current_hardware = target_name;
-
+ transaction->add_commit_cancel_op(rename_op);
+ const std::vector<CdlLoadable>& loadables = this->get_loadables();
+ int i;
+ for (i = (int) loadables.size() - 1; i >= 0; i--) {
+ CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
+ if ((0 != package) && package->belongs_to_hardware()) {
+ this->unload_package(transaction, package, limbo);
+ }
+ }
+ current_hardware = "";
+
+ if ("" != target_name) {
+
+ const std::vector<std::string>& packages = database->get_target_packages(target_name);
+ std::vector<std::string>::const_iterator name_i;
+ for (name_i = packages.begin(); name_i != packages.end(); name_i++) {
+ // Target specifications may refer to packages that are not
+ // installed. This is useful in e.g. an anoncvs environment.
+ if (database->is_known_package(*name_i)) {
+ // It is possible for a hardware package to have been
+ // loaded separately, in which case there is no point in
+ // loading it again.
+ if (0 == this->lookup(*name_i)) {
+ this->load_package(transaction, *name_i, "",
+ error_fn, warn_fn, limbo);
+ CdlPackage package = dynamic_cast<CdlPackage>(this->lookup(*name_i));
+ CYG_LOOP_INVARIANT_CLASSC(package);
+ package->loaded_for_hardware = true;
+ }
+ } else {
+ CdlParse::report_warning(interp, "",
+ std::string("The target specification lists a package `") + *name_i +
+ "' which is not present in the component repository.");
+ }
+ }
+ }
+ current_hardware = target_name;
+
} catch(...) {
- // Cancel all operations up to and including the rename_op
- CdlTransactionCommitCancelOp* cancel_op = 0;
- do {
- cancel_op = transaction->get_last_commit_cancel_op();
- CYG_LOOP_INVARIANTC(0 != cancel_op);
- transaction->cancel_last_commit_cancel_op();
- } while(cancel_op != rename_op);
- throw;
+ // Cancel all operations up to and including the rename_op
+ CdlTransactionCommitCancelOp* cancel_op = 0;
+ do {
+ cancel_op = transaction->get_last_commit_cancel_op();
+ CYG_LOOP_INVARIANTC(0 != cancel_op);
+ transaction->cancel_last_commit_cancel_op();
+ } while(cancel_op != rename_op);
+ throw;
}
// There may have been enables/disables and value data for that target
// FIXME: any problems get ignored quietly. There should at least
// be some warnings.
if ("" != target_name) {
- const std::vector<std::string>& enables = database->get_target_enables(target_name);
- const std::vector<std::string>& disables = database->get_target_disables(target_name);
- const std::vector<std::pair<std::string, std::string> >& set_values = database->get_target_set_values(target_name);
-
- if ((0 != enables.size()) || (0 != disables.size()) || (0 != set_values.size())) {
- std::vector<std::string>::const_iterator opt_i;
- CdlNode node;
- CdlValuable valuable;
- CdlValueFlavor flavor;
-
- for (opt_i = enables.begin(); opt_i != enables.end(); opt_i++) {
- valuable = 0;
- node = this->lookup(*opt_i);
- if (0 != node) {
- valuable = dynamic_cast<CdlValuable>(node);
- if (0 != valuable) {
- }
- }
- if (0 != valuable) {
- flavor = valuable->get_flavor();
- if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) {
- valuable->enable(transaction, CdlValueSource_User);
- } else {
- CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
- std::string("The option `") + *opt_i +
- "' is supposed to be enabled for this target.\n" +
- "However the option does not have a bool or booldata flavors.");
- }
- } else {
- CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
- std::string("The option `") + *opt_i +
- "' is supposed to be enabled for this target.\n" +
- "However this option is not in the current configuration.");
- }
- }
- for (opt_i = disables.begin(); opt_i != disables.end(); opt_i++) {
- valuable = 0;
- node = this->lookup(*opt_i);
- if (0 != node) {
- valuable = dynamic_cast<CdlValuable>(node);
- }
- if (0 != valuable) {
- flavor = valuable->get_flavor();
- if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) {
- valuable->disable(transaction, CdlValueSource_User);
- } else {
- CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
- std::string("The option `") + *opt_i +
- "' is supposed to be disabled for this target.\n" +
- "However the option does not have a bool or booldata flavors.");
- }
- } else {
- CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
- std::string("The option `") + *opt_i +
- "' is supposed to be disabled for this target.\n" +
- "However this option is not in the current configuration.");
- }
- }
- std::vector<std::pair<std::string,std::string> >::const_iterator value_i;
- for (value_i = set_values.begin(); value_i != set_values.end(); value_i++) {
- valuable = 0;
- node = this->lookup(value_i->first);
- if (0 != node) {
- valuable = dynamic_cast<CdlValuable>(node);
- }
- if (0 != valuable) {
- flavor = valuable->get_flavor();
- if ((CdlValueFlavor_BoolData == flavor) || (CdlValueFlavor_Data == flavor)) {
- valuable->set_value(transaction, value_i->second, CdlValueSource_User);
- } else {
- CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
- std::string("The option `") + *opt_i +
- "' is supposed to be given the value `" + value_i->second +
- "' for this target.\n" +
- "However the option does not have a data or booldata flavor.");
- }
- } else {
- CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
- std::string("The option `") + *opt_i +
- "' is supposed to be given the value `" + value_i->second +
- "' for this target.\n" +
- "However this option is not in the current configuration.");
- }
- }
- }
+ const std::vector<std::string>& enables = database->get_target_enables(target_name);
+ const std::vector<std::string>& disables = database->get_target_disables(target_name);
+ const std::vector<std::pair<std::string, std::string> >& set_values = database->get_target_set_values(target_name);
+
+ if ((0 != enables.size()) || (0 != disables.size()) || (0 != set_values.size())) {
+ std::vector<std::string>::const_iterator opt_i;
+ CdlNode node;
+ CdlValuable valuable;
+ CdlValueFlavor flavor;
+
+ for (opt_i = enables.begin(); opt_i != enables.end(); opt_i++) {
+ valuable = 0;
+ node = this->lookup(*opt_i);
+ if (0 != node) {
+ valuable = dynamic_cast<CdlValuable>(node);
+ if (0 != valuable) {
+ }
+ }
+ if (0 != valuable) {
+ flavor = valuable->get_flavor();
+ if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) {
+ valuable->enable(transaction, CdlValueSource_User);
+ } else {
+ CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
+ std::string("The option `") + *opt_i +
+ "' is supposed to be enabled for this target.\n" +
+ "However the option does not have a bool or booldata flavors.");
+ }
+ } else {
+ CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
+ std::string("The option `") + *opt_i +
+ "' is supposed to be enabled for this target.\n" +
+ "However this option is not in the current configuration.");
+ }
+ }
+ for (opt_i = disables.begin(); opt_i != disables.end(); opt_i++) {
+ valuable = 0;
+ node = this->lookup(*opt_i);
+ if (0 != node) {
+ valuable = dynamic_cast<CdlValuable>(node);
+ }
+ if (0 != valuable) {
+ flavor = valuable->get_flavor();
+ if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) {
+ valuable->disable(transaction, CdlValueSource_User);
+ } else {
+ CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
+ std::string("The option `") + *opt_i +
+ "' is supposed to be disabled for this target.\n" +
+ "However the option does not have a bool or booldata flavors.");
+ }
+ } else {
+ CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
+ std::string("The option `") + *opt_i +
+ "' is supposed to be disabled for this target.\n" +
+ "However this option is not in the current configuration.");
+ }
+ }
+ std::vector<std::pair<std::string,std::string> >::const_iterator value_i;
+ for (value_i = set_values.begin(); value_i != set_values.end(); value_i++) {
+ valuable = 0;
+ node = this->lookup(value_i->first);
+ if (0 != node) {
+ valuable = dynamic_cast<CdlValuable>(node);
+ }
+ if (0 != valuable) {
+ flavor = valuable->get_flavor();
+ if ((CdlValueFlavor_BoolData == flavor) || (CdlValueFlavor_Data == flavor)) {
+ valuable->set_value(transaction, value_i->second, CdlValueSource_User);
+ } else {
+ CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
+ std::string("The option `") + *opt_i +
+ "' is supposed to be given the value `" + value_i->second +
+ "' for this target.\n" +
+ "However the option does not have a data or booldata flavor.");
+ }
+ } else {
+ CdlParse::report_warning(interp, std::string("target `") + target_name + "'",
+ std::string("The option `") + *opt_i +
+ "' is supposed to be given the value `" + value_i->second +
+ "' for this target.\n" +
+ "However this option is not in the current configuration.");
+ }
+ }
+ }
}
CYG_REPORT_RETURN();
CdlConfiguration_CommitCancelHardwareName* rename_op = new CdlConfiguration_CommitCancelHardwareName(current_hardware);
try {
- transaction->add_commit_cancel_op(rename_op);
+ transaction->add_commit_cancel_op(rename_op);
} catch(...) {
- delete rename_op;
- throw;
+ delete rename_op;
+ throw;
}
current_hardware = "";
try {
- const std::vector<CdlLoadable>& loadables = this->get_loadables();
- for (int i = (int) loadables.size() - 1; i >= 0; i--) {
- CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
- if ((0 != package) && package->belongs_to_hardware()) {
- this->unload_package(transaction, package, limbo);
- }
- }
+ const std::vector<CdlLoadable>& loadables = this->get_loadables();
+ for (int i = (int) loadables.size() - 1; i >= 0; i--) {
+ CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
+ if ((0 != package) && package->belongs_to_hardware()) {
+ this->unload_package(transaction, package, limbo);
+ }
+ }
} catch(...) {
- CdlTransactionCommitCancelOp* cancel_op = 0;
- do {
- cancel_op = transaction->get_last_commit_cancel_op();
- CYG_LOOP_INVARIANTC(0 != cancel_op);
- transaction->cancel_last_commit_cancel_op();
- } while(cancel_op != rename_op);
- throw;
+ CdlTransactionCommitCancelOp* cancel_op = 0;
+ do {
+ cancel_op = transaction->get_last_commit_cancel_op();
+ CYG_LOOP_INVARIANTC(0 != cancel_op);
+ transaction->cancel_last_commit_cancel_op();
+ } while(cancel_op != rename_op);
+ throw;
}
CYG_REPORT_RETURN();
}
//}}}
-//{{{ CdlConfiguration::set_template() etc
+//{{{ CdlConfiguration::set_template() etc
// ----------------------------------------------------------------------------
void
CdlConfigurationBody::set_template_file(CdlTransaction transaction, std::string filename,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn, bool limbo)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::set_template_file");
CYG_REPORT_FUNCARG3XV(this, transaction, limbo);
// with savefiles.
const std::vector<CdlLoadable>& loadables = this->get_loadables();
unsigned int load_i = loadables.size();
-
+
try {
- transaction->add_commit_cancel_op(rename_op);
- const std::vector<CdlLoadable>& loadables = this->get_loadables();
- for (i = (int) loadables.size() - 1; i >= 0; i--) {
- CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
- if ((0 != package) && package->belongs_to_template()) {
- this->unload_package(transaction, package, limbo);
- }
- }
- current_template = "";
-
- this->add(transaction, filename, error_fn, warn_fn);
- this->current_template = filename;
- this->set_name(saved_name);
- this->description = saved_description;
- this->current_hardware = saved_hardware;
-
- for ( ; load_i < loadables.size(); load_i++) {
- CdlPackage pkg = dynamic_cast<CdlPackage>(loadables[load_i]);
- CYG_ASSERT_CLASSC(pkg);
- pkg->loaded_for_template = true;
- }
-
+ transaction->add_commit_cancel_op(rename_op);
+ const std::vector<CdlLoadable>& loadables = this->get_loadables();
+ for (i = (int) loadables.size() - 1; i >= 0; i--) {
+ CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
+ if ((0 != package) && package->belongs_to_template()) {
+ this->unload_package(transaction, package, limbo);
+ }
+ }
+ current_template = "";
+
+ this->add(transaction, filename, error_fn, warn_fn);
+ this->current_template = filename;
+ this->set_name(saved_name);
+ this->description = saved_description;
+ this->current_hardware = saved_hardware;
+
+ for ( ; load_i < loadables.size(); load_i++) {
+ CdlPackage pkg = dynamic_cast<CdlPackage>(loadables[load_i]);
+ CYG_ASSERT_CLASSC(pkg);
+ pkg->loaded_for_template = true;
+ }
+
} catch(...) {
-
- this->set_name(saved_name);
- this->description = saved_description;
- this->current_hardware = saved_hardware;
-
- // Cancel all operations up to and including the rename_op
- CdlTransactionCommitCancelOp* cancel_op = 0;
- do {
- cancel_op = transaction->get_last_commit_cancel_op();
- CYG_LOOP_INVARIANTC(0 != cancel_op);
- transaction->cancel_last_commit_cancel_op();
- } while(cancel_op != rename_op);
- throw;
- }
-
+
+ this->set_name(saved_name);
+ this->description = saved_description;
+ this->current_hardware = saved_hardware;
+
+ // Cancel all operations up to and including the rename_op
+ CdlTransactionCommitCancelOp* cancel_op = 0;
+ do {
+ cancel_op = transaction->get_last_commit_cancel_op();
+ CYG_LOOP_INVARIANTC(0 != cancel_op);
+ transaction->cancel_last_commit_cancel_op();
+ } while(cancel_op != rename_op);
+ throw;
+ }
+
CYG_REPORT_RETURN();
}
CdlConfiguration_CommitCancelTemplateName* rename_op = new CdlConfiguration_CommitCancelTemplateName(current_template);
try {
- transaction->add_commit_cancel_op(rename_op);
+ transaction->add_commit_cancel_op(rename_op);
} catch(...) {
- delete rename_op;
- throw;
+ delete rename_op;
+ throw;
}
current_template = "";
try {
- const std::vector<CdlLoadable>& loadables = this->get_loadables();
- for (int i = (int) loadables.size() - 1; i >= 0; i--) {
- CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
- if ((0 != package) && package->belongs_to_template()) {
- this->unload_package(transaction, package, limbo);
- }
- }
+ const std::vector<CdlLoadable>& loadables = this->get_loadables();
+ for (int i = (int) loadables.size() - 1; i >= 0; i--) {
+ CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
+ if ((0 != package) && package->belongs_to_template()) {
+ this->unload_package(transaction, package, limbo);
+ }
+ }
} catch(...) {
- CdlTransactionCommitCancelOp* cancel_op = 0;
- do {
- cancel_op = transaction->get_last_commit_cancel_op();
- CYG_LOOP_INVARIANTC(0 != cancel_op);
- transaction->cancel_last_commit_cancel_op();
- } while(cancel_op != rename_op);
- throw;
- }
-
+ CdlTransactionCommitCancelOp* cancel_op = 0;
+ do {
+ cancel_op = transaction->get_last_commit_cancel_op();
+ CYG_LOOP_INVARIANTC(0 != cancel_op);
+ transaction->cancel_last_commit_cancel_op();
+ } while(cancel_op != rename_op);
+ throw;
+ }
+
CYG_REPORT_RETURN();
}
//}}}
-//{{{ Persistence support
+//{{{ Persistence support
-//{{{ initialize_savefile_support()
+//{{{ initialize_savefile_support()
// ----------------------------------------------------------------------------
// Initialization. The purpose of this code is to determine all the
CYG_REPORT_FUNCNAME("CdlConfiguration::initialize_savefile_support");
CYG_REPORT_FUNCARG1XV(this);
CYG_PRECONDITION_THISC();
-
+
// Start with the generic stuff such as cdl_savefile_version and
// cdl_command.
this->CdlToplevelBody::initialize_savefile_support();
}
//}}}
-//{{{ CdlConfiguration::save() - internal
+//{{{ CdlConfiguration::save() - internal
// ----------------------------------------------------------------------------
// The exported interface is CdlConfiguration::save(). This takes a single
std::string text = "";
if (!minimal) {
- text =
+ text =
"# This section defines the toplevel configuration object. The only\n\
# values that can be changed are the name of the configuration and\n\
# the description field. It is not possible to modify the target,\n\
std::string config_data = this->get_description();
if (!minimal || ("" != text)) {
- text += " description " + CdlInterpreterBody::quote(config_data) + " ;\n";
+ text += " description " + CdlInterpreterBody::quote(config_data) + " ;\n";
}
// Repeat the warning.
if (!minimal) {
- text += "\n # These fields should not be modified.\n";
+ text += "\n # These fields should not be modified.\n";
}
config_data = this->get_hardware();
if ("" != config_data) {
- text += " hardware " + CdlInterpreterBody::quote(config_data) + " ;\n";
+ text += " hardware " + CdlInterpreterBody::quote(config_data) + " ;\n";
}
config_data = this->get_template();
if ("" != config_data) {
- text += " template " + CdlInterpreterBody::quote(config_data) + " ;\n";
+ text += " template " + CdlInterpreterBody::quote(config_data) + " ;\n";
}
std::vector<CdlLoadable>::const_iterator load_i;
const std::vector<CdlLoadable>& packages = get_loadables();
for (load_i = packages.begin(); load_i != packages.end(); load_i++) {
- CdlPackage pkg = dynamic_cast<CdlPackage>(*load_i);
- CYG_ASSERT_CLASSC(pkg);
- text += " package ";
- if (pkg->belongs_to_template()) {
- text += "-template ";
- }
- if (pkg->belongs_to_hardware()) {
- text += "-hardware ";
- }
- text += CdlInterpreterBody::quote(pkg->get_name()) + " " + CdlInterpreterBody::quote(pkg->get_value()) + " ;\n";
+ CdlPackage pkg = dynamic_cast<CdlPackage>(*load_i);
+ CYG_ASSERT_CLASSC(pkg);
+ text += " package ";
+ if (pkg->belongs_to_template()) {
+ text += "-template ";
+ }
+ if (pkg->belongs_to_hardware()) {
+ text += "-hardware ";
+ }
+ text += CdlInterpreterBody::quote(pkg->get_name()) + " " + CdlInterpreterBody::quote(pkg->get_value()) + " ;\n";
}
interp->write_data(chan, text);
-
+
// If the package was loaded from a file then there may be additional
// data associated with the configuration that is not currently
// recognised. This call preserves that data.
}
//}}}
-//{{{ CdlConfiguration::save() - exported interface
+//{{{ CdlConfiguration::save() - exported interface
// ----------------------------------------------------------------------------
// This is the exported interface for saving a configuration. The specified
// This happens during the first save or load operation, or when
// the application starts to register its own savefile extensions.
if (!CdlToplevelBody::savefile_support_initialized()) {
- this->initialize_savefile_support();
+ this->initialize_savefile_support();
}
// A Tcl interpreter is needed for the call to OpenFileChannel(),
// is not manipulated in any way. Instead just pass it to Tcl.
Tcl_Channel chan = Tcl_OpenFileChannel(interp->get_tcl_interpreter(), const_cast<char*>(filename.c_str()), "w", 0666);
if (0 == chan) {
- throw CdlInputOutputException("Unable to open file " + filename + "\n" + interp->get_result());
+ throw CdlInputOutputException("Unable to open file " + filename + "\n" + interp->get_result());
}
// The channel may end up being registered in various different
std::string tmp;
try {
- if (!minimal) {
- interp->write_data(chan, "# eCos saved configuration\n\n");
- }
-
- CdlToplevelBody::save_separator(interp, chan, "commands", minimal);
- this->CdlToplevelBody::save_command_details(interp, chan, 0, minimal);
- CdlToplevelBody::save_separator(interp, chan, "toplevel", minimal);
- this->save(interp, chan, 0, minimal);
- CdlToplevelBody::save_separator(interp, chan, "conflicts", minimal);
- this->CdlToplevelBody::save_conflicts(interp, chan, 0, minimal);
- CdlToplevelBody::save_separator(interp, chan, "contents", minimal);
- this->CdlContainerBody::save(interp, chan, 0, minimal);
- this->save_unsupported_commands(interp, chan, 0, minimal);
-
+ if (!minimal) {
+ interp->write_data(chan, "# eCos saved configuration\n\n");
+ }
+
+ CdlToplevelBody::save_separator(interp, chan, "commands", minimal);
+ this->CdlToplevelBody::save_command_details(interp, chan, 0, minimal);
+ CdlToplevelBody::save_separator(interp, chan, "toplevel", minimal);
+ this->save(interp, chan, 0, minimal);
+ CdlToplevelBody::save_separator(interp, chan, "conflicts", minimal);
+ this->CdlToplevelBody::save_conflicts(interp, chan, 0, minimal);
+ CdlToplevelBody::save_separator(interp, chan, "contents", minimal);
+ this->CdlContainerBody::save(interp, chan, 0, minimal);
+ this->save_unsupported_commands(interp, chan, 0, minimal);
+
} catch(...) {
- Tcl_UnregisterChannel(0, chan);
- // NOTE: deleting the file is necessary, it is a bad idea to
- // end up with incomplete save files. It would be even better
- // to write to a temporary file and only overwrite the old
- // savefile on success.
- //
- // Tcl does not provide direct access to the file delete
- // facility, so it is necessary to evaluate a script. This
- // introduces quoting and security problems, since the
- // filename might contain spaces, square brackets, braces...
- // To avoid these problems a variable is used.
- interp->set_variable("__cdlconfig_filename", filename);
- interp->eval("file delete $__cdlconfig_filename", tmp);
- interp->unset_variable("__cdlconfig_filename");
-
- throw;
+ Tcl_UnregisterChannel(0, chan);
+ // NOTE: deleting the file is necessary, it is a bad idea to
+ // end up with incomplete save files. It would be even better
+ // to write to a temporary file and only overwrite the old
+ // savefile on success.
+ //
+ // Tcl does not provide direct access to the file delete
+ // facility, so it is necessary to evaluate a script. This
+ // introduces quoting and security problems, since the
+ // filename might contain spaces, square brackets, braces...
+ // To avoid these problems a variable is used.
+ interp->set_variable("__cdlconfig_filename", filename);
+ interp->eval("file delete $__cdlconfig_filename", tmp);
+ interp->unset_variable("__cdlconfig_filename");
+
+ throw;
}
// This call will perform the appropriate close.
}
//}}}
-//{{{ CdlConfiguration::load() and add()
+//{{{ CdlConfiguration::load() and add()
// ----------------------------------------------------------------------------
// Most of the work is done in add(). load() simply creates a new configuration
// and then invokes add().
CdlConfiguration
CdlConfigurationBody::load(std::string filename, CdlPackagesDatabase db, CdlInterpreter interp,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
{
CYG_REPORT_FUNCNAMETYPE("CdlConfiguration::load", "result %p");
CYG_REPORT_FUNCARG4XV(db, interp, error_fn, warn_fn);
CYG_PRECONDITION_CLASSC(db);
CYG_PRECONDITION_CLASSC(interp);
-
+
CdlConfiguration result = CdlConfigurationBody::make("eCos", db, interp);
if (0 == result) {
- CYG_REPORT_RETVAL(result);
- return result;
+ CYG_REPORT_RETVAL(result);
+ return result;
}
-
+
try {
- result->add(filename, error_fn, warn_fn);
- result->save_file = filename;
+ result->add(filename, error_fn, warn_fn);
+ result->save_file = filename;
} catch(...) {
- delete result;
- throw;
+ delete result;
+ throw;
}
CYG_REPORT_RETVAL(result);
// ----------------------------------------------------------------------------
void
CdlConfigurationBody::add(CdlTransaction transaction, std::string filename,
- CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
+ CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
{
CYG_REPORT_FUNCNAME("CdlConfiguration::add");
CYG_REPORT_FUNCARG3XV(this, error_fn, warn_fn);
// Initialize the savefile support, so that it is known what
// commands can occur in a savefile.
if (!CdlToplevelBody::savefile_support_initialized()) {
- this->initialize_savefile_support();
+ this->initialize_savefile_support();
}
-
+
// The interpreter should not have any left-over junk.
CdlInterpreter interp = this->get_interpreter();
CYG_PRECONDITION_CLASSC(interp);
CdlInterpreterBody::ContextSupport context_support(interp, filename);
try {
- interp->set_transaction(transaction);
-
- std::vector<CdlInterpreterCommandEntry> commands;
- this->get_savefile_commands(commands);
- CdlInterpreterBody::CommandSupport interp_cmds(interp, commands);
-
- interp->eval_file(filename);
-
- // All the data has been read in without generating an
- // exception. However there may have been errors reported via
- // the error_fn handling, and any errors at all should result
- // in an exception.
- int error_count = CdlParse::get_error_count(interp);
- if (error_count > 0) {
- std::string tmp;
- Cdl::integer_to_string(error_count, tmp);
- throw CdlInputOutputException("Invalid savefile \"" + filename + "\".\n" +
- tmp + " error" + ((error_count > 1) ? "s" : "") +
- " occurred while reading in the savefile data.");
- }
-
+ interp->set_transaction(transaction);
+
+ std::vector<CdlInterpreterCommandEntry> commands;
+ this->get_savefile_commands(commands);
+ CdlInterpreterBody::CommandSupport interp_cmds(interp, commands);
+
+ interp->eval_file(filename);
+
+ // All the data has been read in without generating an
+ // exception. However there may have been errors reported via
+ // the error_fn handling, and any errors at all should result
+ // in an exception.
+ int error_count = CdlParse::get_error_count(interp);
+ if (error_count > 0) {
+ std::string tmp;
+ Cdl::integer_to_string(error_count, tmp);
+ throw CdlInputOutputException("Invalid savefile \"" + filename + "\".\n" +
+ tmp + " error" + ((error_count > 1) ? "s" : "") +
+ " occurred while reading in the savefile data.");
+ }
+
} catch(...) {
- interp->set_transaction(0);
- throw;
+ interp->set_transaction(0);
+ throw;
}
interp->set_transaction(0);
}
//}}}
-//{{{ savefile commands
+//{{{ savefile commands
// ----------------------------------------------------------------------------
// A cdl_configuration command does not actually do very much. It acts as
// This is not done, to allow multiple savefiles to be loaded into
// a single configuration in future.
int
-CdlConfigurationBody::savefile_configuration_command(CdlInterpreter interp, int argc, const char* argv[])
+CdlConfigurationBody::savefile_configuration_command(CdlInterpreter interp, int argc, const char *argv[])
{
CYG_REPORT_FUNCNAMETYPE("CdlConfiguration::savefile_configuration_command", "result %d");
CYG_PRECONDITION_CLASSC(interp);
std::vector<CdlInterpreterCommandEntry> subcommands;
std::vector<CdlInterpreterCommandEntry>* toplevel_commands = 0;
-
+
try {
- std::vector<std::pair<std::string,std::string> > options;
- int data_index = CdlParse::parse_options(interp, "cdl_configuration command", 0, argc, argv, 1, options);
-
- // A broken cdl_configuration command is pretty fatal, chances are
- // that the entire load is going to fail.
- if (data_index != (argc - 2)) {
- CdlParse::report_error(interp, "", "Invalid cdl_configuration command in savefile, expecting two arguments.");
- } else {
- config->set_name(argv[1]);
- config->get_savefile_subcommands("cdl_configuration", subcommands);
- toplevel_commands = interp->push_commands(subcommands);
-
- std::string tcl_result;
- result = interp->eval(argv[2], tcl_result);
-
- interp->pop_commands(toplevel_commands);
- toplevel_commands = 0;
- }
-
+ std::vector<std::pair<std::string,std::string> > options;
+ int data_index = CdlParse::parse_options(interp, "cdl_configuration command", 0, argc, argv, 1, options);
+
+ // A broken cdl_configuration command is pretty fatal, chances are
+ // that the entire load is going to fail.
+ if (data_index != (argc - 2)) {
+ CdlParse::report_error(interp, "", "Invalid cdl_configuration command in savefile, expecting two arguments.");
+ } else {
+ config->set_name(argv[1]);
+ config->get_savefile_subcommands("cdl_configuration", subcommands);
+ toplevel_commands = interp->push_commands(subcommands);
+
+ std::string tcl_result;
+ result = interp->eval(argv[2], tcl_result);
+
+ interp->pop_commands(toplevel_commands);
+ toplevel_commands = 0;
+ }
+
} catch(...) {
- if (0 != toplevel_commands) {
- interp->pop_commands(toplevel_commands);
- }
- throw;
+ if (0 != toplevel_commands) {
+ interp->pop_commands(toplevel_commands);
+ }
+ throw;
}
CYG_REPORT_RETVAL(result);
// ----------------------------------------------------------------------------
int
-CdlConfigurationBody::savefile_description_command(CdlInterpreter interp, int argc, const char* argv[])
+CdlConfigurationBody::savefile_description_command(CdlInterpreter interp, int argc, const char *argv[])
{
CYG_REPORT_FUNCNAME("CdlConfiguration::savefile_description_command");
CYG_PRECONDITION_CLASSC(interp);
std::vector<std::pair<std::string,std::string> > options;
int data_index = CdlParse::parse_options(interp, "cdl_configuration/description command", 0, argc, argv, 1, options);
-
+
if (data_index != (argc - 1)) {
- CdlParse::report_warning(interp, "",
- "Ignoring invalid configuration description command, expecting a single argument.");
+ CdlParse::report_warning(interp, "",
+ "Ignoring invalid configuration description command, expecting a single argument.");
} else {
- config->description = argv[1];
- }
+ config->description = argv[1];
+ }
return TCL_OK;
}
// ----------------------------------------------------------------------------
int
-CdlConfigurationBody::savefile_hardware_command(CdlInterpreter interp, int argc, const char* argv[])
+CdlConfigurationBody::savefile_hardware_command(CdlInterpreter interp, int argc, const char *argv[])
{
CYG_REPORT_FUNCNAME("CdlConfiguration::savefile_hardware_command");
CYG_PRECONDITION_CLASSC(interp);
std::vector<std::pair<std::string,std::string> > options;
int data_index = CdlParse::parse_options(interp, "cdl_configuration/hardware command", 0, argc, argv, 1, options);
-
+
if (data_index != (argc - 1)) {
- CdlParse::report_warning(interp, "", "Ignoring invalid configuration hardware command, expecting a single argument.");
+ CdlParse::report_warning(interp, "", "Ignoring invalid configuration hardware command, expecting a single argument.");
} else {
- config->current_hardware = argv[1];
+ config->current_hardware = argv[1];
}
return TCL_OK;
// ----------------------------------------------------------------------------
int
-CdlConfigurationBody::savefile_template_command(CdlInterpreter interp, int argc, const char* argv[])
+CdlConfigurationBody::savefile_template_command(CdlInterpreter interp, int argc, const char *argv[])
{
CYG_REPORT_FUNCNAME("CdlConfiguration::savefile_template_command");
CYG_PRECONDITION_CLASSC(interp);
std::vector<std::pair<std::string,std::string> > options;
int data_index = CdlParse::parse_options(interp, "cdl_configuration/template command", 0, argc, argv, 1, options);
-
+
if (data_index != (argc - 1)) {
- CdlParse::report_warning(interp, "", "Ignoring invalid configuration template command, expecting a single argument.");
+ CdlParse::report_warning(interp, "", "Ignoring invalid configuration template command, expecting a single argument.");
} else {
- config->current_template = argv[1];
+ config->current_template = argv[1];
}
-
+
return TCL_OK;
}
// ----------------------------------------------------------------------------
int
-CdlConfigurationBody::savefile_package_command(CdlInterpreter interp, int argc, const char* argv[])
+CdlConfigurationBody::savefile_package_command(CdlInterpreter interp, int argc, const char *argv[])
{
CYG_REPORT_FUNCNAME("CdlConfiguration::savefile_package_command");
CYG_PRECONDITION_CLASSC(interp);
-
+
CdlToplevel toplevel = interp->get_toplevel();
CYG_ASSERT_CLASSC(toplevel);
CdlConfiguration config = dynamic_cast<CdlConfiguration>(toplevel);
std::string pkgname;
std::string pkgversion;
CdlPackage pkg = 0;
-
+
std::vector<std::pair<std::string,std::string> > options;
- static char* optlist[] = {
- "template:f",
- "hardware:f",
- 0
+ static const char *optlist[] = {
+ "template:f",
+ "hardware:f",
+ 0
};
int data_index = CdlParse::parse_options(interp, "cdl_configuration/package command", optlist, argc, argv, 1, options);
if (data_index == (argc - 1)) {
- CdlParse::report_warning(interp, "", std::string("Missing version information for package `")
- + argv[argc - 1] + "'.");
- pkgname = argv[argc - 1];
- pkgversion = "";
+ CdlParse::report_warning(interp, "", std::string("Missing version information for package `")
+ + argv[argc - 1] + "'.");
+ pkgname = argv[argc - 1];
+ pkgversion = "";
} else if (data_index == (argc - 2)) {
- pkgname = argv[argc - 2];
- pkgversion = argv[argc - 1];
+ pkgname = argv[argc - 2];
+ pkgversion = argv[argc - 1];
} else {
- // If we cannot load all the packages then much of the
- // savefile is likely to be problematical.
- CdlParse::report_error(interp, "", "Invalid cdl_configuration/package command, expecting name and version");
- CYG_REPORT_RETURN();
- return TCL_OK;
+ // If we cannot load all the packages then much of the
+ // savefile is likely to be problematical.
+ CdlParse::report_error(interp, "", "Invalid cdl_configuration/package command, expecting name and version");
+ CYG_REPORT_RETURN();
+ return TCL_OK;
}
if (0 != config->lookup(pkgname)) {
- // If the package was already loaded, check the version string. If the versions
- // are identical then we do not need to worry any further. Otherwise a mismatch
- // warning is appropriate.
- CdlNode node = config->lookup(pkgname);
- CYG_ASSERT_CLASSC(node);
- pkg = dynamic_cast<CdlPackage>(node);
- if (0 == pkg) {
- // The name is in use, but it is not a package
- CdlParse::report_error(interp, "",
- std::string("Unable to load package `") + pkgname + "', the name is already in use.");
- } else if (pkgversion != pkg->get_value()) {
- CdlParse::report_warning(interp, "",
- std::string("Cannot load version `") + pkgversion + "' of package `" +
- pkgname + "', version `" + pkg->get_value() + "' is already loaded.");
- }
+ // If the package was already loaded, check the version string. If the versions
+ // are identical then we do not need to worry any further. Otherwise a mismatch
+ // warning is appropriate.
+ CdlNode node = config->lookup(pkgname);
+ CYG_ASSERT_CLASSC(node);
+ pkg = dynamic_cast<CdlPackage>(node);
+ if (0 == pkg) {
+ // The name is in use, but it is not a package
+ CdlParse::report_error(interp, "",
+ std::string("Unable to load package `") + pkgname + "', the name is already in use.");
+ } else if (pkgversion != pkg->get_value()) {
+ CdlParse::report_warning(interp, "",
+ std::string("Cannot load version `") + pkgversion + "' of package `" +
+ pkgname + "', version `" + pkg->get_value() + "' is already loaded.");
+ }
} else if (!db->is_known_package(pkgname)) {
- CdlParse::report_error(interp, "",
- std::string("Attempt to load an unknown package `") + pkgname + "'.");
+ CdlParse::report_error(interp, "",
+ std::string("Attempt to load an unknown package `") + pkgname + "'.");
} else {
- if ("" != pkgversion) {
- const std::vector<std::string>& versions = db->get_package_versions(pkgname);
- if (versions.end() == std::find(versions.begin(), versions.end(), pkgversion)) {
- CdlParse::report_warning(interp, "",
- std::string("The savefile specifies version `") + pkgversion +
- "' for package `" + pkgname + "'\nThis version is not available.\n" +
- "Using the most recent version instead.");
- pkgversion = "";
- }
- }
- CdlDiagnosticFnPtr error_fn = interp->get_error_fn_ptr();
- CdlDiagnosticFnPtr warn_fn = interp->get_warning_fn_ptr();
- CdlTransaction transaction = interp->get_transaction();
- config->load_package(transaction, pkgname, pkgversion, error_fn, warn_fn, false);
- CdlNode pkg_node = config->lookup(pkgname);
- CYG_ASSERTC(0 != pkg_node);
- pkg = dynamic_cast<CdlPackage>(pkg_node);
- CYG_ASSERT_CLASSC(pkg);
+ if ("" != pkgversion) {
+ const std::vector<std::string>& versions = db->get_package_versions(pkgname);
+ if (versions.end() == std::find(versions.begin(), versions.end(), pkgversion)) {
+ CdlParse::report_warning(interp, "",
+ std::string("The savefile specifies version `") + pkgversion +
+ "' for package `" + pkgname + "'\nThis version is not available.\n" +
+ "Using the most recent version instead.");
+ pkgversion = "";
+ }
+ }
+ CdlDiagnosticFnPtr error_fn = interp->get_error_fn_ptr();
+ CdlDiagnosticFnPtr warn_fn = interp->get_warning_fn_ptr();
+ CdlTransaction transaction = interp->get_transaction();
+ config->load_package(transaction, pkgname, pkgversion, error_fn, warn_fn, false);
+ CdlNode pkg_node = config->lookup(pkgname);
+ CYG_ASSERTC(0 != pkg_node);
+ pkg = dynamic_cast<CdlPackage>(pkg_node);
+ CYG_ASSERT_CLASSC(pkg);
}
if ((0 != pkg) && (0 != options.size())) {
- std::vector<std::pair<std::string,std::string> >::const_iterator opt_i;
- for (opt_i = options.begin(); opt_i != options.end(); opt_i++) {
- if (opt_i->first == "template") {
- pkg->loaded_for_template = true;
- } else if (opt_i->first == "hardware") {
- pkg->loaded_for_hardware = true;
- }
- }
- }
-
+ std::vector<std::pair<std::string,std::string> >::const_iterator opt_i;
+ for (opt_i = options.begin(); opt_i != options.end(); opt_i++) {
+ if (opt_i->first == "template") {
+ pkg->loaded_for_template = true;
+ } else if (opt_i->first == "hardware") {
+ pkg->loaded_for_hardware = true;
+ }
+ }
+ }
+
return TCL_OK;
}
//}}}
//}}}
-