URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [libcdl/] [cdl.hxx] - Rev 786
Compare with Previous | Blame | View Log
#ifndef __CDL_HXX
# define __CDL_HXX
//{{{ Banner
//============================================================================
//
// cdl.hxx
//
// This header file declares the classes related to software
// configuration.
//
//============================================================================
// ####ECOSHOSTGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of the eCos host tools.
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
//
// 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 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., 51 Franklin Street,
// Fifth Floor, Boston, MA 02110-1301, USA.
// -------------------------------------------
// ####ECOSHOSTGPLCOPYRIGHTEND####
//============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): bartv
// Contact(s): bartv
// Date: 1998/02/09
// Version: 0.02
// Requires: cdlcore.hxx
// Usage: #include <cdl.hxx>
//
//####DESCRIPTIONEND####
//============================================================================
//}}}
//{{{ nested #include's
// ----------------------------------------------------------------------------
// Software CDL depends on the core but adds no new system requirements.
#ifndef __CDLCORE_HXX
# include <cdlcore.hxx>
#endif
//}}}
//{{{ Forward declarations of the body classes
// ----------------------------------------------------------------------------
// This section provides forward declarations of the main classes used
// for software configuration.
class CdlConfigurationBody;
class CdlPackageBody;
class CdlComponentBody;
class CdlOptionBody;
class CdlPackagesDatabaseBody;
typedef CdlConfigurationBody* CdlConfiguration;
typedef CdlPackageBody* CdlPackage;
typedef CdlComponentBody* CdlComponent;
typedef CdlOptionBody* CdlOption;
typedef CdlPackagesDatabaseBody* CdlPackagesDatabase;
typedef const CdlConfigurationBody* CdlConstConfiguration;
typedef const CdlPackageBody* CdlConstPackage;
typedef const CdlComponentBody* CdlConstComponent;
typedef const CdlOptionBody* CdlConstOption;
typedef const CdlPackagesDatabaseBody* CdlConstPackagesDatabase;
//}}}
//{{{ CdlPackagesDatabase class
// ----------------------------------------------------------------------------
// An eCos component repository can get to be quite complicated. There will
// be a number of core packages supplied by Red Hat. There may also be some
// number of third party and unsupported packages. Each package may come in
// several different versions. Keeping track of everything that has been
// installed should involve a separate administration tool, and there should
// be some sort of database of all this information.
//
// At the time of writing there is no such administration tool and there is
// no database with details of the various packages. Instead there is a
// static file "packages" at the top level of the component repository,
// containing some of the desired information.
//
// For now a temporary CdlPackagesDatabase class is provided.
// Essentially this provides C++ access to the packages file. In the
// long term this class will be replaced completely by a full and more
// rational implementation.
//
// The packages database class also, temporarily, provides information about
// targets and templates. This will change in future. A target will be specified
// by a save file, the output from Hardy. A template will also be specified by
// a save file, a partial software configuration.
class CdlPackagesDatabaseBody {
friend class CdlTest;
friend class CdlDbParser;
public:
static CdlPackagesDatabase make(std::string = "", CdlDiagnosticFnPtr /* error */ = 0,
CdlDiagnosticFnPtr /* warn */ = 0);
bool update(void);
~CdlPackagesDatabaseBody();
std::string get_component_repository() const;
const std::vector<std::string>& get_packages(void) const;
bool is_known_package(std::string) const;
const std::string& get_package_description(std::string) const;
const std::vector<std::string>& get_package_aliases(std::string) const;
const std::vector<std::string>& get_package_versions(std::string) const;
const std::string& get_package_directory(std::string) const;
const std::string& get_package_repository(std::string, std::string /* version */ = "") const;
const std::string& get_package_script(std::string) const;
bool is_hardware_package(std::string) const;
const std::vector<std::string>& get_targets(void) const;
bool is_known_target(std::string) const;
const std::string& get_target_description(std::string) const;
const std::vector<std::string>& get_target_aliases(std::string) const;
const std::vector<std::string>& get_target_packages(std::string) const;
const std::vector<std::string>& get_target_enables(std::string) const;
const std::vector<std::string>& get_target_disables(std::string) const;
const std::vector<std::pair<std::string,std::string> >& get_target_set_values(std::string) const;
const std::vector<std::string>& get_templates(void) const;
bool is_known_template(std::string) const;
std::string get_template_filename(std::string, std::string = "") const;
const std::vector<std::string>& get_template_versions(std::string) const;
const std::string get_template_description(std::string, std::string = "");
const std::vector<std::string>& get_template_packages(std::string, std::string = "");
static void extract_template_details(std::string /* filename */, std::string& /* description */,
std::vector<std::string>& /* packages */);
// What are the valid compiler flag variables (ARCHFLAGS, ERRFLAGS, ...)?
// For now the library provides a static vector of these things, but
// this area is likely to change in future
static const std::vector<std::string>& get_valid_cflags();
// Control verbosity when reading in a database
static void set_verbose(bool);
bool check_this(cyg_assert_class_zeal = cyg_quick) const;
CYGDBG_DECLARE_MEMLEAK_COUNTER();
private:
// The only valid constructor gets invoked from the make() member function.
// The argument should be a pathname for the component repository. The
// constructor is responsible for reading in the whole packages file.
CdlPackagesDatabaseBody(std::string, CdlDiagnosticFnPtr, CdlDiagnosticFnPtr);
std::string component_repository;
std::vector<std::string> package_names;
struct package_data {
public:
std::string description;
std::vector<std::string> aliases;
std::vector<std::string> versions;
std::map<std::string, std::string> repositories; /* one entry per version */
std::string directory;
std::string script;
bool hardware;
};
std::map<std::string,struct package_data> packages;
std::vector<std::string> target_names;
struct target_data {
public:
std::string description;
std::vector<std::string> aliases;
std::vector<std::string> packages;
std::vector<std::string> enable;
std::vector<std::string> disable;
std::vector<std::pair<std::string, std::string> > set_values;
};
std::map<std::string, struct target_data> targets;
std::vector<std::string> template_names;
struct template_version_data {
public:
std::string description;
std::vector<std::string> packages;
};
struct template_data {
public:
std::vector<std::string> versions;
std::map<std::string, std::string> files;
std::map<std::string, struct template_version_data> version_details;
};
std::map<std::string, struct template_data> templates;
enum {
CdlPackagesDatabaseBody_Invalid = 0,
CdlPackagesDatabaseBody_Magic = 0x50896acb
} cdlpackagesdatabasebody_cookie;
// This allows test cases to overwrite the name of the file
// containing the database information.
static const char* database_name;
// Control whether or not minor problems with the database should be
// reported.
static bool verbose_mode;
// The default constructor, copy constructor and assignment operator are illegal.
CdlPackagesDatabaseBody();
CdlPackagesDatabaseBody(const CdlPackagesDatabaseBody&);
CdlPackagesDatabaseBody& operator=(const CdlPackagesDatabaseBody&);
};
//}}}
//{{{ CdlConfiguration class
// ----------------------------------------------------------------------------
// The CdlConfiguration class is the toplevel used for mainpulating
// software configurations. It consists of a number of loaded packages,
// each of which consists of some hierarchy of components and options,
// plus dialogs, wizards, and interfaces from the core.
//
// Typically an application will deal with only one configuration at a
// time. There will be exceptions. The most obvious example would be
// some sort of diff utility, but there may well be times when a user
// wants to edit multiple configurations. One example would be a board
// containing two separate processors, e.g. a conventional one coupled
// with a separate DSP, and eCos is supposed to run on both: the two
// chips will need to interact, and hence there may well be
// configurability dependencies between them.
//
// A configuration object does not exist in isolation. It must be tied
// to an eCos component repository via a database objects. It must
// also be supplied with a suitable Tcl interpreter.
class CdlConfigurationBody : public virtual CdlToplevelBody
{
friend class CdlTest;
public:
// ----------------------------------------------------------------------------
// Create a new configuration.
// Currently this requires a name, a database and a master interpreter.
// The name is not used very much, but does appear in savefiles.
// The packages database and the interpreter must be created before
// any configuration object.
static CdlConfiguration make(std::string /* name */, CdlPackagesDatabase, CdlInterpreter);
CdlPackagesDatabase get_database() const;
// Loading and unloading packages. This can happen in a number
// of different ways:
//
// 1) explicitly adding or removing a single package
// 2) changing the version of a package, which means unloading
// the old version and reloading the new one. Generally
// user settings should be preserved where possible.
// 3) loading in a full or minimal savefile. The library
// does not actually distinguish between the two when
// loading, only when saving.
// 4) adding a full or minimal savefile.
// 5) setting a template for the first time. This is much the
// same as adding a minimal savefile. However the library
// keeps track of the "current" template and only one
// can be loaded at a time. The library does not keep
// track of which savefile(s) have been added.
// 6) changing a template. This means unloading the packages
// that were loaded for the old template, then loading in
// the new one.
// 7) unsetting the template. This just involves an unload.
// 8) setting the hardware. Currently the database defines
// each supported target, listing the packages that should
// be loaded and possibly some option details. This is
// subject to change in future.
// 9) changing the hardware. This is much the same as changing
// the template.
// 10) unsetting the hardware.
//
// The unload operations are comparatively safe, although
// they can result in new conflicts and the user may well want
// to cancel the operation after discovering how many new
// problems there would be. The load operations are a bit more
// dangerous since they depend on external data and hence can
// fail for a variety of reasons: missing files, corrupt files,
// clashes with existing data, ... Changing e.g. a template
// is especially dangerous because of the number of things
// that can go wrong. All of these operations need to happen
// in a transaction which the user can cancel. There are two
// versions of all the relevant routines, one which operates
// in an existing transaction and one which creates a new
// one.
//
// Any operation that involves loading CDL data takes two
// CdlDiagnosticFnPtr arguments, one for errors and one for
// warnings. These should report the message to the user by
// some suitable means. The error fnptr may throw a
// CdlParseException to abort the current load immediately,
// otherwise the load operation will be aborted at the end
// if any errors were detected. New conflicts are not
// handled by these diagnostic functions, instead they
// are handled by the normal transaction methods.
// A version argument of "" implies the most recent version.
void load_package(std::string /* name */, std::string /* version */,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void load_package(CdlTransaction, std::string /* name */, std::string /* version */,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void unload_package(std::string /* name */, bool /* limbo */ = true);
void unload_package(CdlPackage, bool /* limbo */ = true);
void unload_package(CdlTransaction, std::string /* name */, bool /* limbo */ = true);
void unload_package(CdlTransaction, CdlPackage, bool /* limbo */ = true);
void change_package_version(std::string /*name*/, std::string /*version*/,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void change_package_version(CdlPackage, std::string /*version*/, CdlDiagnosticFnPtr /* error */,
CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void change_package_version(CdlTransaction, std::string /*name*/, std::string /*version*/,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void change_package_version(CdlTransaction, CdlPackage, std::string /*version*/, CdlDiagnosticFnPtr /* error */,
CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
// Loading a savefile is different in that it creates a new
// toplevel. Since transactions can only be created if the
// toplevel already exists, it is not possible to have a
// per-transaction load() operation. It is possible to have
// a per-transaction add() operation.
static CdlConfiguration load(std::string /* filename */, CdlPackagesDatabase, CdlInterpreter,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */);
void add(std::string /* filename */,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */);
void add(CdlTransaction, std::string /* filename */,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */);
// As with packages, a version of "" implies the most recent.
void set_template(std::string, std::string /* version */,
CdlDiagnosticFnPtr, CdlDiagnosticFnPtr /* warn */,bool /* limbo */ = true);
void set_template_file(std::string,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void set_template(CdlTransaction, std::string, std::string /* version */,
CdlDiagnosticFnPtr, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void set_template_file(CdlTransaction, std::string,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void unload_template(bool /* limbo */ = true);
void unload_template(CdlTransaction, bool /* limbo */ = true);
std::string get_template() const;
void set_template_name(std::string); // Intended for library use only
void set_hardware(std::string,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void set_hardware(CdlTransaction, std::string,
CdlDiagnosticFnPtr /* error */, CdlDiagnosticFnPtr /* warn */, bool /* limbo */ = true);
void unload_hardware(bool /* limbo */ = true);
void unload_hardware(CdlTransaction, bool /* limbo */ = true);
std::string get_hardware() const;
void set_hardware_name(std::string); // Intended for library use only
// ----------------------------------------------------------------------------
// Save a configuration to a file
void save(std::string, bool /* minimal */ = false);
void initialize_savefile_support();
std::string get_save_file() const;
// ----------------------------------------------------------------------------
// Get rid of a configuration.
~CdlConfigurationBody();
virtual std::string get_class_name() const;
bool check_this(cyg_assert_class_zeal = cyg_quick) const;
CYGDBG_DECLARE_MEMLEAK_COUNTER();
private:
// The only legal constructor, invoked from make() and load()
CdlConfigurationBody(std::string, CdlPackagesDatabase, CdlInterpreter);
// The internal implementation of the persistence support
virtual void save(CdlInterpreter, Tcl_Channel, int, bool);
static int savefile_configuration_command(CdlInterpreter, int, const char*[]);
static int savefile_description_command(CdlInterpreter, int, const char*[]);
static int savefile_hardware_command(CdlInterpreter, int, const char*[]);
static int savefile_template_command(CdlInterpreter, int, const char*[]);
static int savefile_package_command(CdlInterpreter, int, const char*[]);
std::string current_hardware;
std::string current_template;
std::string description;
CdlPackagesDatabase database;
std::string save_file;
enum {
CdlConfigurationBody_Invalid = 0,
CdlConfigurationBody_Magic = 0x5c409a3d
} cdlconfigurationbody_cookie;
// The constructor can only be invoked via the make() and load()
// members. Other constructors and the assignment operator are
// illegal.
CdlConfigurationBody();
CdlConfigurationBody(const CdlConfigurationBody&);
CdlConfigurationBody& operator=(const CdlConfigurationBody&);
};
//}}}
//{{{ CdlPackage class
// ----------------------------------------------------------------------------
// Packages inherit from most of the base classes.
class CdlPackageBody : public virtual CdlNodeBody,
public virtual CdlContainerBody,
public virtual CdlUserVisibleBody,
public virtual CdlValuableBody,
public virtual CdlParentableBody,
public virtual CdlBuildableBody,
public virtual CdlDefinableBody,
public virtual CdlLoadableBody,
public virtual CdlBuildLoadableBody,
public virtual CdlDefineLoadableBody
{
friend class CdlTest;
// Packages should not be created by application code, but
// the CdlConfiguration class must be able to do so inside
// load_package();
friend class CdlConfigurationBody;
public:
~CdlPackageBody();
static int parse_package(CdlInterpreter, int, const char*[]);
static int parse_hardware(CdlInterpreter, int, const char*[]);
static int parse_install_proc(CdlInterpreter, int, const char*[]);
static int parse_license_proc(CdlInterpreter, int, const char*[]);
// Override the CdlDefineLoadable member. Hardware packages always
// send their configuration options to hardware.h
virtual std::string get_config_header() const;
bool is_hardware_package() const;
bool has_install_proc() const;
const cdl_tcl_code& get_install_proc() const;
bool has_license_proc() const;
const cdl_tcl_code& get_license_proc() const;
// Propagation support. Because of multiple virtual inheritance
// it is necessary to invoke the container and valuable
// update members.
virtual void update(CdlTransaction, CdlUpdate);
// Persistence support.
virtual void save(CdlInterpreter, Tcl_Channel, int, bool);
static void initialize_savefile_support(CdlToplevel);
static int savefile_package_command(CdlInterpreter, int, const char*[]);
// Was this package loaded because of a template or hardware setting?
bool belongs_to_template() const;
bool belongs_to_hardware() const;
virtual std::string get_class_name() const;
bool check_this(cyg_assert_class_zeal = cyg_quick) const;
CYGDBG_DECLARE_MEMLEAK_COUNTER();
private:
// The only valid constructor requires a number of fields
CdlPackageBody(std::string /* name */, CdlConfiguration, std::string /* repository */, std::string /* directory */);
// Other constructors are illegal
CdlPackageBody();
CdlPackageBody(const CdlPackageBody&);
CdlPackageBody& operator=(const CdlPackageBody&);
bool loaded_for_template;
bool loaded_for_hardware;
enum {
CdlPackageBody_Invalid = 0,
CdlPackageBody_Magic = 0x1d7c0d43
} cdlpackagebody_cookie;
};
//}}}
//{{{ CdlComponent class
// ----------------------------------------------------------------------------
// Similarly components just inherit from the appropriate base classes.
class CdlComponentBody : public virtual CdlNodeBody,
public virtual CdlContainerBody,
public virtual CdlUserVisibleBody,
public virtual CdlValuableBody,
public virtual CdlParentableBody,
public virtual CdlBuildableBody,
public virtual CdlDefinableBody
{
friend class CdlTest;
public:
~CdlComponentBody();
static int parse_component(CdlInterpreter, int, const char*[]);
static int parse_script(CdlInterpreter, int, const char*[]);
// Propagation support. Because of multiple virtual inheritance
// it is necessary to invoke the container and valuable
// update members.
virtual void update(CdlTransaction, CdlUpdate);
// Persistence support.
virtual void save(CdlInterpreter, Tcl_Channel, int, bool);
static void initialize_savefile_support(CdlToplevel);
static int savefile_component_command(CdlInterpreter, int, const char*[]);
virtual std::string get_class_name() const;
bool check_this(cyg_assert_class_zeal = cyg_quick) const;
CYGDBG_DECLARE_MEMLEAK_COUNTER();
private:
// The only valid constructor requires a name.
CdlComponentBody(std::string);
enum {
CdlComponentBody_Invalid = 0,
CdlComponentBody_Magic = 0x6359d9a7
} cdlcomponentbody_cookie;
// Other constructors are illegal
CdlComponentBody();
CdlComponentBody(const CdlComponentBody&);
CdlComponentBody& operator=(const CdlComponentBody&);
};
//}}}
//{{{ CdlOption class
// ----------------------------------------------------------------------------
// Again options just inherit their functionality from the base classes.
class CdlOptionBody : public virtual CdlNodeBody,
public virtual CdlUserVisibleBody,
public virtual CdlValuableBody,
public virtual CdlParentableBody,
public virtual CdlBuildableBody,
public virtual CdlDefinableBody
{
friend class CdlTest;
public:
~CdlOptionBody();
static int parse_option(CdlInterpreter, int, const char*[]);
// Persistence support.
virtual void save(CdlInterpreter, Tcl_Channel, int, bool);
static void initialize_savefile_support(CdlToplevel);
static int savefile_option_command(CdlInterpreter, int, const char*[]);
virtual std::string get_class_name() const;
bool check_this(cyg_assert_class_zeal = cyg_quick) const;
CYGDBG_DECLARE_MEMLEAK_COUNTER();
private:
CdlOptionBody(std::string);
enum {
CdlOptionBody_Invalid = 0,
CdlOptionBody_Magic = 0x1c1162d1
} cdloptionbody_cookie;
CdlOptionBody();
CdlOptionBody(const CdlOptionBody&);
CdlOptionBody& operator=(const CdlOptionBody&);
};
//}}}
#endif /* !__CDL_HXX */
// EOF cdl.hxx