changeset 870:67a8feb8144a

Turn ECOS_REPOSITORY into a path rather than a single directory
author bartv
date Wed, 26 Mar 2003 17:57:58 +0000
parents 4f2928474597
children 4f1b647b74e0
files host/libcdl/ChangeLog host/libcdl/base.cxx host/libcdl/build.cxx host/libcdl/cdl.hxx host/libcdl/cdlcore.hxx host/libcdl/config.cxx host/libcdl/database.cxx host/libcdl/package.cxx host/tools/configtool/ChangeLog host/tools/configtool/common/common/build.cxx host/tools/configtool/standalone/common/ChangeLog host/tools/configtool/standalone/common/ecosconfig.cxx
diffstat 12 files changed, 203 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/host/libcdl/ChangeLog
+++ b/host/libcdl/ChangeLog
@@ -1,3 +1,14 @@
+2003-03-26  Bart Veer  <bartv@ecoscentric.com>
+
+	* cdl.hxx, config.cxx.cxx, package.cxx:
+	Update derived classes now that the repository is per-loadable
+	rather than per-toplevel. Also turn ECOS_REPOSITORY into a
+	path rather than a single directory, updating all affected
+	database and config code.
+
+	* base.cxx, build.cxx, cdlcore.hxx: make the repository a
+	characteristic of each loadable rather than of the toplevel
+
 2003-02-12  Bart Veer  <bartv@ecoscentric.com>
 
 	* Makefile.in, configure, testsuite/Makefile.in:
--- a/host/libcdl/base.cxx
+++ b/host/libcdl/base.cxx
@@ -10,7 +10,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
-// Copyright (C) 2002 Bart Veer
+// Copyright (C) 2002, 2003 Bart Veer
 // Copyright (C) 1999, 2000 Red Hat, Inc.
 //
 // This file is part of the eCos host tools.
@@ -999,7 +999,7 @@ CdlContainerBody::check_this(cyg_assert_
 // updates of the owned vector happen inside the CdlToplevel
 // add_node() and remove_node() family.
 
-CdlLoadableBody::CdlLoadableBody(CdlToplevel toplevel, std::string dir)
+CdlLoadableBody::CdlLoadableBody(CdlToplevel toplevel, std::string repo, std::string dir)
     : CdlContainerBody()
 {
     CYG_REPORT_FUNCNAME("CdlLoadable:: constructor");
@@ -1007,6 +1007,7 @@ CdlLoadableBody::CdlLoadableBody(CdlTopl
     CYG_PRECONDITION_CLASSC(toplevel);
 
     // Initialize enough of the object to support check_this()
+    repository  = repo;
     directory   = dir;
     interp      = 0;
     remove_node_loadables_position = -1;
@@ -1092,6 +1093,7 @@ CdlLoadableBody::~CdlLoadableBody()
     CYG_ASSERTC(0 == owned.size());
     delete interp;
     interp      = 0;
+    repository  = "";
     directory   = "";
 
     CYGDBG_MEMLEAK_DESTRUCTOR();
@@ -1146,6 +1148,17 @@ CdlLoadableBody::get_interpreter() const
 }
 
 std::string
+CdlLoadableBody::get_repository() const
+{
+    CYG_REPORT_FUNCNAME("CdlLoadable::get_repository");
+    CYG_REPORT_FUNCARG1XV(this);
+    CYG_PRECONDITION_THISC();
+
+    CYG_REPORT_RETURN();
+    return repository;
+}
+
+std::string
 CdlLoadableBody::get_directory() const
 {
     CYG_REPORT_FUNCNAME("CdlLoadable::get_directory");
@@ -1488,7 +1501,7 @@ CdlLoadableBody::find_absolute_file(std:
     CYG_PRECONDITIONC("" != filename);
 
     // These variable names should be kept in step with CdlBuildable::update_all_build_info()
-    interp->set_variable("::cdl_topdir",  get_toplevel()->get_directory());
+    interp->set_variable("::cdl_topdir",  repository);
     interp->set_variable("::cdl_pkgdir",  directory);
     interp->set_variable("::cdl_prefdir", dirname);
     interp->set_variable("::cdl_target",  filename);
@@ -1536,7 +1549,7 @@ CdlLoadableBody::find_relative_file(std:
     CYG_PRECONDITIONC("" != filename);
 
     // These variable names should be kept in step with CdlBuildable::update_all_build_info()
-    interp->set_variable("::cdl_topdir",  get_toplevel()->get_directory());
+    interp->set_variable("::cdl_topdir",  repository);
     interp->set_variable("::cdl_pkgdir",  directory);
     interp->set_variable("::cdl_prefdir", dirname);
     interp->set_variable("::cdl_target",  filename);
@@ -1578,7 +1591,7 @@ CdlLoadableBody::has_subdirectory(std::s
 
     bool        result = false;
     
-    interp->set_variable("::cdl_topdir",  get_toplevel()->get_directory());
+    interp->set_variable("::cdl_topdir",  repository);
     interp->set_variable("::cdl_pkgdir",  directory);
     interp->set_variable("::cdl_target",  name);
 
@@ -1652,7 +1665,7 @@ CdlLoadableBody::check_this(cyg_assert_c
 // an interpreter, so this should not happen until the world
 // is ready to deal with such errors.
 
-CdlToplevelBody::CdlToplevelBody(CdlInterpreter interp_arg, std::string directory_arg)
+CdlToplevelBody::CdlToplevelBody(CdlInterpreter interp_arg)
     : CdlContainerBody()
 {
     CYG_REPORT_FUNCNAME("CdlToplevel:: constructor");
@@ -1661,7 +1674,6 @@ CdlToplevelBody::CdlToplevelBody(CdlInte
 
     // The STL containers will take care of themselves.
     interp      = interp_arg;
-    directory   = directory_arg;
     transaction = 0;
 
     // A toplevel is always active, override the default setting for a node
@@ -2118,17 +2130,6 @@ CdlToplevelBody::set_description(std::st
 }
 
 std::string
-CdlToplevelBody::get_directory() const
-{
-    CYG_REPORT_FUNCNAME("CdlToplevel::get_directory");
-    CYG_REPORT_FUNCARG1XV(this);
-    CYG_PRECONDITION_THISC();
-
-    CYG_REPORT_RETURN();
-    return directory;
-}
-
-std::string
 CdlToplevelBody::get_class_name() const
 {
     CYG_REPORT_FUNCNAME("CdlToplevel::get_class_name");
--- a/host/libcdl/build.cxx
+++ b/host/libcdl/build.cxx
@@ -544,14 +544,16 @@ CdlBuildableBody::update_all_build_info(
     CdlLoadable loadable        = get_owner();
     CYG_ASSERT_CLASSC(loadable);
     std::string directory       = loadable->get_directory();
+    std::string repository      = loadable->get_repository();
     CYG_ASSERTC("" != directory);
+    CYG_ASSERTC("" != repository);
     CdlInterpreter interp       = loadable->get_interpreter();
     CYG_ASSERT_CLASSC(interp);
 
     // The interpreter needs some information about the locations
     // of various things. This code has to be kept in step with
     // CdlLoadable::find_relative_file()
-    interp->set_variable("::cdl_topdir", get_toplevel()->get_directory());
+    interp->set_variable("::cdl_topdir", repository);
     interp->set_variable("::cdl_pkgdir", directory);
 
     // For many packages the sources will reside in a src subdirectory.
@@ -964,7 +966,7 @@ update_header_file_info(CdlConstBuildLoa
 
     // It is necessary to search for the appropriate files.
     CdlInterpreter interp = loadable->get_interpreter();
-    std::string    path   = loadable->get_toplevel()->get_directory() + "/" + loadable->get_directory();
+    std::string    path   = loadable->get_repository() + "/" + loadable->get_directory();
     if (has_include_subdir) {
         std::vector<std::string> files;
         std::vector<std::string>::const_iterator file_i;
@@ -1051,8 +1053,9 @@ CdlBuildLoadableBody::update_build_info(
     CdlBuildInfo_Loadable tmp_info;
     build_info.entries.push_back(tmp_info);
     CdlBuildInfo_Loadable& this_info = *(build_info.entries.rbegin());
-    this_info.name      = get_name();
-    this_info.directory = get_directory();
+    this_info.name          = get_name();
+    this_info.repository    = get_repository();
+    this_info.directory     = get_directory();
 
     // Take care of the header files
     update_header_file_info(this, this_info);
@@ -1090,8 +1093,8 @@ CdlBuildLoadableBody::update_all_build_i
     CdlBuildInfo_Loadable tmp_info;
     build_info.entries.push_back(tmp_info);
     CdlBuildInfo_Loadable& this_info = *(build_info.entries.rbegin());
-    this_info.name      = get_name();
-    this_info.directory = get_directory();
+    this_info.name       = get_name();
+    this_info.directory  = get_directory();
 
     std::string loadable_library = default_library_name;
     if (has_property(CdlPropertyId_Library)) {
--- a/host/libcdl/cdl.hxx
+++ b/host/libcdl/cdl.hxx
@@ -13,7 +13,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
-// Copyright (C) 2002 Bart Veer
+// Copyright (C) 2002, 2003 Bart Veer
 // Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
 //
 // This file is part of the eCos host tools.
@@ -130,6 +130,7 @@ class CdlPackagesDatabaseBody {
     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;
 
@@ -175,6 +176,7 @@ class CdlPackagesDatabaseBody {
         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;
@@ -202,6 +204,7 @@ class CdlPackagesDatabaseBody {
     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;
@@ -482,7 +485,7 @@ class CdlPackageBody : public virtual Cd
   private:
 
     // The only valid constructor requires a number of fields
-    CdlPackageBody(std::string /* name */, CdlConfiguration, std::string /* directory */);
+    CdlPackageBody(std::string /* name */, CdlConfiguration, std::string /* repository */, std::string /* directory */);
 
     // Other constructors are illegal
     CdlPackageBody();
--- a/host/libcdl/cdlcore.hxx
+++ b/host/libcdl/cdlcore.hxx
@@ -15,7 +15,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
-// Copyright (C) 2002 Bart Veer
+// Copyright (C) 2002, 2003 Bart Veer
 // Copyright (C) 1999, 2000, 2001 Red Hat, Inc.
 //
 // This file is part of the eCos host tools.
@@ -3634,6 +3634,7 @@ class CdlLoadableBody : virtual public C
     const std::vector<CdlNode>&         get_owned() const;
     bool                                owns(CdlConstNode) const;
     CdlInterpreter                      get_interpreter() const;
+    std::string                         get_repository() const;
     std::string                         get_directory() const;
 
     // Some properties such as doc and compile reference filenames.
@@ -3661,7 +3662,7 @@ class CdlLoadableBody : virtual public C
 
   protected:
 
-    CdlLoadableBody(CdlToplevel, std::string /* directory */);
+    CdlLoadableBody(CdlToplevel, std::string /* repository */, std::string /* directory */);
 
     // Needed by derived classes, but not actually used.
     CdlLoadableBody();
@@ -3670,6 +3671,7 @@ class CdlLoadableBody : virtual public C
     
     std::vector<CdlNode> owned;
     CdlInterpreter       interp;
+    std::string          repository;
     std::string          directory;
 
     // Used by add/remove_node_from_toplevel()
@@ -3792,11 +3794,6 @@ class CdlToplevelBody : virtual public C
     // Each toplevel must have an associated master Tcl interpreter.
     CdlInterpreter      get_interpreter() const;
 
-    // Each toplevel should also have an associated directory for 
-    // the component repository. It is not required that all loadables
-    // are relative to this, but that is the default behaviour.
-    std::string         get_directory() const;
-
     // Each toplevel may have a single active main transaction.
     // For now there is no support for concurrent transactions
     // operating on a single toplevel (although nested transactions
@@ -3843,7 +3840,7 @@ class CdlToplevelBody : virtual public C
     CYGDBG_DECLARE_MEMLEAK_COUNTER();
 
   protected:
-    CdlToplevelBody(CdlInterpreter, std::string);
+    CdlToplevelBody(CdlInterpreter);
 
   private:
 
@@ -3853,7 +3850,6 @@ class CdlToplevelBody : virtual public C
     CdlInterpreter                      interp;
     CdlContainer                        orphans;
     std::string                         description;
-    std::string                         directory;
     std::list<CdlConflict>              conflicts;
     std::list<CdlConflict>              structural_conflicts;
 
@@ -5333,6 +5329,7 @@ class CdlBuildInfo_Loadable {
 
   public:
     std::string         name;           /* CYGPKG_INFRA         */
+    std::string         repository;     /* arbitrary path       */
     std::string         directory;      /* infra/current        */
     std::vector<CdlBuildInfo_Header>            headers;
     std::vector<CdlBuildInfo_Compile>           compiles;
--- a/host/libcdl/config.cxx
+++ b/host/libcdl/config.cxx
@@ -10,7 +10,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
-// Copyright (C) 2002 Bart Veer
+// Copyright (C) 2002, 2003 Bart Veer
 // Copyright (C) 1999, 2000 Red Hat, Inc.
 //
 // This file is part of the eCos host tools.
@@ -74,7 +74,7 @@ CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConfigu
 
 CdlConfigurationBody::CdlConfigurationBody(std::string name, CdlPackagesDatabase db, CdlInterpreter interp)
     : CdlNodeBody(name),
-      CdlToplevelBody(interp, db->get_component_repository())
+      CdlToplevelBody(interp)
 {
     CYG_REPORT_FUNCNAME("CdlConfiguration:: constructor");
     CYG_REPORT_FUNCARG1XV(this);
@@ -747,6 +747,7 @@ CdlConfigurationBody::load_package(CdlTr
             throw CdlInputOutputException("Package " + name + " does not have an installed version `" + version + "'.");
         }
     }
+    std::string repository      = database->get_package_repository(name, version);
     std::string directory       = database->get_package_directory(name);
     std::string script          = database->get_package_script(name);
     CYG_ASSERTC(("" != directory) && ("" != script));
@@ -763,7 +764,7 @@ CdlConfigurationBody::load_package(CdlTr
     }
     directory = tcl_result;
     
-    tcl_cmd   = "file isdirectory [file join \"" + database->get_component_repository() + "\" " + directory + "]";
+    tcl_cmd   = "file isdirectory [file join \"" + 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 + "'.");
     }
@@ -792,7 +793,7 @@ CdlConfigurationBody::load_package(CdlTr
     CdlConfiguration_CommitCancelLoad* load_op  = 0;
     
     try {
-        package = new CdlPackageBody(name, this, directory);
+        package = new CdlPackageBody(name, this, repository, directory);
 
         // The package should be added to the hierarchy immediately.
         // All nodes will get added to the hierarchy as they are
@@ -1256,12 +1257,11 @@ CdlConfigurationBody::set_template_file(
     // Each new package needs to be registered as a template one.
     // NOTE: this may break if we start doing more interesting things
     // 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();
+        unsigned int load_i;
         for (i = (int) loadables.size() - 1; i >= 0; i--) {
             CdlPackage package = dynamic_cast<CdlPackage>(loadables[i]);
             if ((0 != package) && package->belongs_to_template()) {
@@ -1269,7 +1269,8 @@ CdlConfigurationBody::set_template_file(
             }
         }
         current_template = "";
-
+        load_i = loadables.size();
+        
         this->add(transaction, filename, error_fn, warn_fn);
         this->current_template = filename;
         this->set_name(saved_name);
--- a/host/libcdl/database.cxx
+++ b/host/libcdl/database.cxx
@@ -12,7 +12,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
-// Copyright (C) 2002 Bart Veer
+// Copyright (C) 2002, 2003 Bart Veer
 // Copyright (C) 1999, 2000, 2001 Red Hat, Inc.
 //
 // This file is part of the eCos host tools.
@@ -152,13 +152,6 @@ CdlDbParser::new_package(CdlInterpreter 
         return TCL_OK;
     }
     std::string pkg_name        = argv[1];
-
-    // Better make sure that this is not a duplicate definition.
-    if (std::find(db->package_names.begin(), db->package_names.end(), pkg_name) != db->package_names.end()) {
-        CdlParse::report_warning(interp, diag_package + pkg_name, "Duplicate package entry, ignoring second occurence.");
-        CYG_REPORT_RETVAL(TCL_OK);
-        return TCL_OK;
-    }
     
     // The package data is constructed locally. It only gets added to
     // the database in the absence of errors.
@@ -227,8 +220,6 @@ CdlDbParser::new_package(CdlInterpreter 
                 std::vector<std::string> subdirs;
                 unsigned int i;
                 interp->locate_subdirs(pkgdir, subdirs);
-                std::sort(subdirs.begin(), subdirs.end(), Cdl::version_cmp());
-                
                 for (i = 0; i < subdirs.size(); i++) {
                     if (("CVS" == subdirs[i]) || ("cvs" == subdirs[i])) {
                         continue;
@@ -243,6 +234,7 @@ CdlDbParser::new_package(CdlInterpreter 
                         }
                     }
                     package.versions.push_back(subdirs[i]);
+                    package.repositories[subdirs[i]] = repo;
                 }
                 if (0 == package.versions.size()) {
                     CdlParse::report_warning(interp, diag_package + pkg_name,
@@ -254,9 +246,23 @@ CdlDbParser::new_package(CdlInterpreter 
     }
 
     // If the package is still ok, now is the time to add it to the database.
+    // It may be a new package, or there may already be an entry from a previous
+    // repository.
     if (package_ok && (old_error_count == CdlParse::get_error_count(interp))) {
-        db->package_names.push_back(pkg_name);
-        db->packages[pkg_name] = package;
+        if ( std::find(db->package_names.begin(), db->package_names.end(), pkg_name) == db->package_names.end()) {
+            db->package_names.push_back(pkg_name);
+            db->packages[pkg_name] = package;
+        } else {
+            // Only add versions which are not already present.
+            std::vector<std::string>::const_iterator version_i;
+            for (version_i = package.versions.begin(); version_i != package.versions.end(); version_i++) {
+                if (std::find(db->packages[pkg_name].versions.begin(), db->packages[pkg_name].versions.end(),
+                              *version_i) == db->packages[pkg_name].versions.end()) {
+                    db->packages[pkg_name].versions.push_back(*version_i);
+                    db->packages[pkg_name].repositories[*version_i] = package.repositories[*version_i];
+                }
+            }
+        }
     }
 
     CYG_REPORT_RETVAL(result);
@@ -441,10 +447,9 @@ CdlDbParser::new_target(CdlInterpreter i
     
     std::string target_name     = argv[1];
 
-    // Better make sure that this is not a duplicate definition.
+    // This may be a duplicate definition if the target was defined in an
+    // earlier repository
     if (std::find(db->target_names.begin(), db->target_names.end(), target_name) != db->target_names.end()) {
-        CdlParse::report_warning(interp, diag_target + target_name,
-                                 "Duplicate target entry, ignoring second occurence.");
         CYG_REPORT_RETVAL(TCL_OK);
         return TCL_OK;
     }
@@ -778,43 +783,80 @@ CdlPackagesDatabaseBody::CdlPackagesData
         CdlInterpreterBody::CommandSupport cmds(interp, commands);
         CdlInterpreterBody::DiagSupport diag(interp, error_fn, warn_fn);
         CdlInterpreterBody::AssocSupport assoc(interp, dbparser_database_key, static_cast<ClientData>(this));
-        CdlInterpreterBody::VariableSupport var(interp, dbparser_component_repository, repo);
         interp->add_command("unknown", &CdlParse::unknown_command);
         CdlParse::clear_error_count(interp);
 
-        // Ignore errors at this stage, instead check error count at the end.
-        (void) interp->eval_file(component_repository + "/" + database_name);
-    
-        // Now start looking for templates. These should reside in the
-        // templates subdirectory of the component repository. Each template
-        // should be in its own directory, and inside each directory should
-        // be versioned template files with a .ect extension.
-        std::string templates_dir = repo + "/" + "templates";
-        std::vector<std::string> subdirs;
-        interp->locate_subdirs(templates_dir, subdirs);
+        unsigned int index, search;
+        for ( index = 0; index < repo.size(); ) {
 
-        unsigned int i;
-        for (i = 0; i < subdirs.size(); i++) {
-            // Do not add the template to the known ones until we are sure there is
-            // at least one valid template.
-            std::vector<std::string> files;
-            interp->locate_files(templates_dir + "/" + subdirs[i], files);
-            unsigned int j;
-            for (j = 0; j < files.size(); j++) {
-                if ((4 < files[j].size()) && (".ect" == files[j].substr(files[j].size() - 4))) {
+            // Get the next entry in the search path. In a normal world
+            // the separator is :, but in a VC++ Windows world it is ;
+            for ( search = index; search < repo.size(); search++) {
+#ifdef _MSC_VER
+                if ( ';' == repo[search]) {
+                    break;
+                }
+#else
+                if ( ':' == repo[search]) {
                     break;
                 }
+#endif                
             }
-            if (j != files.size()) {
-                this->template_names.push_back(subdirs[i]);
-                for ( ; j < files.size(); j++) {
+            std::string this_repo   = repo.substr(index, search - index);
+            index = search + 1;
+            
+            // Ignore errors at this stage, instead check error count at the end.
+            interp->set_variable(std::string(dbparser_component_repository), this_repo);
+            (void) interp->eval_file(this_repo + "/" + database_name);
+    
+            // Now start looking for templates. These should reside in the
+            // templates subdirectory of the component repository. Each template
+            // should be in its own directory, and inside each directory should
+            // be versioned template files with a .ect extension.
+            std::string templates_dir = this_repo + "/" + "templates";
+            std::vector<std::string> subdirs;
+            interp->locate_subdirs(templates_dir, subdirs);
+
+            unsigned int i;
+            for (i = 0; i < subdirs.size(); i++) {
+                // Do not add the template to the known ones until we are sure there is
+                // at least one valid template.
+                std::vector<std::string> files;
+                interp->locate_files(templates_dir + "/" + subdirs[i], files);
+                unsigned int j;
+                for (j = 0; j < files.size(); j++) {
                     if ((4 < files[j].size()) && (".ect" == files[j].substr(files[j].size() - 4))) {
-                        this->templates[subdirs[i]].versions.push_back(files[j].substr(0, files[j].size() - 4));
+                        break;
+                    }
+                }
+                if (j != files.size()) {
+                    std::string tmplt = subdirs[i];
+                    if  (std::find(this->template_names.begin(), this->template_names.end(), tmplt) == this->template_names.end()) {
+                        this->template_names.push_back(tmplt);
+                    }
+                    for ( ; j < files.size(); j++) {
+                        if ((4 < files[j].size()) && (".ect" == files[j].substr(files[j].size() - 4))) {
+                            std::string version = files[j].substr(0, files[j].size() - 4);
+                            if (std::find(templates[tmplt].versions.begin(), templates[tmplt].versions.end(), version) == templates[tmplt].versions.end()) {
+                                templates[tmplt].versions.push_back(version);
+                                templates[tmplt].files[version] = templates_dir + "/" + tmplt + "/" + files[j] ;
+                            }
+                        }
                     }
                 }
             }
         }
 
+        // The package and template version should be sorted
+        std::vector<std::string>::const_iterator pkg_i;
+        for (pkg_i = package_names.begin(); pkg_i != package_names.end(); pkg_i++) {
+            std::sort(packages[*pkg_i].versions.begin(), packages[*pkg_i].versions.end(), Cdl::version_cmp());
+        }
+        std::vector<std::string>::const_iterator tmpl_i;
+        for (tmpl_i = template_names.begin(); tmpl_i != template_names.end(); tmpl_i++) {
+            std::sort(templates[*tmpl_i].versions.begin(), templates[*tmpl_i].versions.end(), Cdl::version_cmp());
+        }
+        
         // Consistency checks. All target-specific packages should
         // have the hardware attribute. Also, all the packages should
         // exist. Problems only result in warnings and only when
@@ -828,7 +870,7 @@ CdlPackagesDatabaseBody::CdlPackagesData
                     if (std::find(package_names.begin(), package_names.end(), *name_j) == package_names.end()) {
                         CdlParse::report_warning(interp, diag_target + *name_i,
                                                  std::string("This target refers to an unknown package `") + *name_j + "'.");
-                    }
+                        }   
                     if (!packages[*name_j].hardware) {
                         CdlParse::report_warning(interp, diag_target + *name_i,
                                                  std::string("This target refers to a package `") + *name_j +
@@ -837,6 +879,7 @@ CdlPackagesDatabaseBody::CdlPackagesData
                 }
             }
         }
+        
         // Now, were there any errors while reading in the database?
         // If so it is necessary to throw an exception here, to make sure
         // that things get cleaned up properly.
@@ -1096,6 +1139,42 @@ CdlPackagesDatabaseBody::get_package_dir
 }
 
 const std::string&
+CdlPackagesDatabaseBody::get_package_repository(std::string pkg_name, std::string vsn) const
+{
+    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_repository");
+    CYG_REPORT_FUNCARG1XV(this);
+    CYG_PRECONDITION_THISC();
+
+    static std::string dummy = "";
+    
+    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
+    if (pkgs_i == packages.end()) {
+        CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::get_package_repository()");
+        CYG_REPORT_RETURN();
+        return dummy;
+    }
+
+    std::map<std::string,std::string>::const_iterator repo_i;
+    if (("" == vsn) && (0 == pkgs_i->second.versions.size())) {
+        CYG_REPORT_RETURN();
+        return dummy;
+    }
+
+    if ("" == vsn) {
+        vsn = *(pkgs_i->second.versions.begin());
+    }
+    repo_i = pkgs_i->second.repositories.find(vsn);
+    if (repo_i == pkgs_i->second.repositories.end()) {
+        CYG_FAIL("Invalid package version passed to CdlPackagesDatabase::get_package_repository()");
+        CYG_REPORT_RETURN();
+        return dummy;
+    }
+        
+    CYG_REPORT_RETURN();
+    return repo_i->second;
+}
+
+const std::string&
 CdlPackagesDatabaseBody::get_package_script(std::string pkg_name) const
 {
     CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_script");
@@ -1318,7 +1397,7 @@ CdlPackagesDatabaseBody::get_template_ve
 }
 
 std::string
-CdlPackagesDatabaseBody::get_template_filename(std::string template_name, std::string version_name) const
+CdlPackagesDatabaseBody::get_template_filename(std::string template_name, std::string version) const
 {
     CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_template_filename");
     CYG_REPORT_FUNCARG1XV(this);
@@ -1334,12 +1413,12 @@ CdlPackagesDatabaseBody::get_template_fi
         CYG_REPORT_RETURN();
         return "";
     }
-    if ("" == version_name) {
+    if ("" == version) {
         CYG_ASSERTC(0 != template_i->second.versions.size());
-        version_name = template_i->second.versions[0];
+        version = template_i->second.versions[0];
     } else {
         std::vector<std::string>::const_iterator vsn_i = std::find(template_i->second.versions.begin(),
-                                                                   template_i->second.versions.end(), version_name);
+                                                                   template_i->second.versions.end(), version);
         if (vsn_i == template_i->second.versions.end()) {
             CYG_FAIL("Invalid template version passed to CdlPackagesDatabase::get_template_filename");
             CYG_REPORT_RETURN();
@@ -1347,7 +1426,8 @@ CdlPackagesDatabaseBody::get_template_fi
         }
     }
 
-    std::string result = component_repository + "/templates/" + template_name + "/" + version_name + ".ect";
+    std::map<std::string,std::string>::const_iterator file_i = template_i->second.files.find(version);
+    std::string result = file_i->second;
     CYG_REPORT_RETURN();
     return result;
 }
--- a/host/libcdl/package.cxx
+++ b/host/libcdl/package.cxx
@@ -10,7 +10,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
-// Copyright (C) 2002 Bart Veer
+// Copyright (C) 2002, 2003 Bart Veer
 // Copyright (C) 1999, 2000 Red Hat, Inc.
 //
 // This file is part of the eCos host tools.
@@ -72,7 +72,7 @@ CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlPackage
 // ----------------------------------------------------------------------------
 // Constructor. The real work is actually done in the base classes
 // and the parser.
-CdlPackageBody::CdlPackageBody(std::string name_arg, CdlConfiguration toplevel, std::string dir)
+CdlPackageBody::CdlPackageBody(std::string name_arg, CdlConfiguration toplevel, std::string repo, std::string dir)
     : CdlNodeBody(name_arg),
       CdlContainerBody(),
       CdlUserVisibleBody(),
@@ -80,7 +80,7 @@ CdlPackageBody::CdlPackageBody(std::stri
       CdlParentableBody(),
       CdlBuildableBody(),
       CdlDefinableBody(),
-      CdlLoadableBody(toplevel, dir),
+      CdlLoadableBody(toplevel, repo, dir),
       CdlBuildLoadableBody(),
       CdlDefineLoadableBody()
 {
--- a/host/tools/configtool/ChangeLog
+++ b/host/tools/configtool/ChangeLog
@@ -1,3 +1,8 @@
+2003-03-26  Bart Veer  <bartv@ecoscentric.com>
+
+	* common/common/build.cxx: There is no longer a single repository,
+	instead each package can come from different repositories.
+
 2003-03-26  John Dallaway  <jld@ecoscentric.com>
 
 	* standalone/wxwin/makefile.gnu: Tidy up.
--- a/host/tools/configtool/common/common/build.cxx
+++ b/host/tools/configtool/common/common/build.cxx
@@ -1,6 +1,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
+// Copyright (C) 2003 Bart Veer
 // Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
 //
 // This program is part of the eCos host tools.
@@ -353,7 +354,6 @@ bool generate_makefile (const CdlConfigu
 	fprintf (stream, makefile_header.c_str ());
 
 	// generate the global variables
-	fprintf (stream, "export REPOSITORY := %s\n", cygpath (config->get_database ()->get_component_repository ()).c_str ());
 	fprintf (stream, "export PREFIX := %s\n", cygpath (install_tree).c_str ());
 	fprintf (stream, "export COMMAND_PREFIX := %s\n", command_prefix.c_str ());
 	fprintf (stream, "export CC := $(COMMAND_PREFIX)gcc\n");
@@ -366,6 +366,7 @@ bool generate_makefile (const CdlConfigu
 	fprintf (stream, "export AR := $(COMMAND_PREFIX)ar\n\n");
 
 	// generate the package variables
+	fprintf (stream, "export REPOSITORY := %s\n", cygpath (info.repository).c_str());
 	fprintf (stream, "PACKAGE := %s\n", info.directory.c_str ());
 	fprintf (stream, "OBJECT_PREFIX := %s\n", object_prefix.c_str ());
 	fprintf (stream, "CFLAGS := %s\n", get_flags (config, &info, "CFLAGS").c_str ());
@@ -516,7 +517,6 @@ bool generate_toplevel_makefile (const C
 	fprintf (stream, makefile_header.c_str ());
 
 	// generate the variables
-	fprintf (stream, "export REPOSITORY := %s\n", cygpath (config->get_database ()->get_component_repository ()).c_str ());
 #if defined(_WIN32) || defined(__CYGWIN__)
     fprintf (stream, "export HOST := CYGWIN\n");
 #else
--- a/host/tools/configtool/standalone/common/ChangeLog
+++ b/host/tools/configtool/standalone/common/ChangeLog
@@ -1,3 +1,11 @@
+2003-03-26  Bart Veer  <bartv@ecoscentric.com>
+
+	* ecosconfig.cxx: remove TRANSLATE_PATH() support, no longer
+	needed and causes confusion because you end up with repositories
+	containing a : character that now gets interpreted as a path
+	separator. Also fix a couple of bugs related to template
+	versioning.
+
 2003-02-12  Bart Veer  <bartv@ecoscentric.com>
 
 	* Makefile.in, configure:
--- a/host/tools/configtool/standalone/common/ecosconfig.cxx
+++ b/host/tools/configtool/standalone/common/ecosconfig.cxx
@@ -55,30 +55,6 @@
 #define DEFAULT_SAVE_FILE "ecos.ecc"
 static char* tool = "ecosconfig";
 
-// When running under cygwin there may be confusion between cygwin and
-// Windows paths. Some paths will be passed on to the Tcl library,
-// which sometimes will accept a cygwin path and sometimes not. This
-// does not affect the VC++ build which only accepts Windows paths,
-// and obviously it does not affect any Unix platfom.
-#ifdef __CYGWIN__
-static std::string
-translate_path(std::string& path)
-{
-    std::string result;
-    char buffer [MAXPATHLEN + 1];
-    if ("" == path) {
-        result = path;
-    } else {
-        cygwin_conv_to_win32_path (path.c_str (), buffer);
-        result = std::string(buffer);
-    }
-    return result;
-}
-# define TRANSLATE_PATH(a) translate_path(a)
-#else
-# define TRANSLATE_PATH(a) (a)
-#endif
-
 int main (int argc, char * argv []) {
 
     // process command qualifiers
@@ -280,10 +256,6 @@ int main (int argc, char * argv []) {
         }
     }
 
-    repository          = TRANSLATE_PATH(repository);
-    savefile            = TRANSLATE_PATH(savefile);
-    install_prefix      = TRANSLATE_PATH(install_prefix);
-
     // Initialize the cdl_exec code (not quite sure why this needs a
     // separate object rather than just a bunch of statics). 
     cdl_exec exec (trim_path (repository), savefile, trim_path (install_prefix), no_resolve);
@@ -302,7 +274,7 @@ int main (int argc, char * argv []) {
 
     if ("new" == command) {
         // Usage: ecosconfig new <target> [template [version]]
-        if ((command_index == argc) || ((command_index + 3) <= argc)) {
+        if ((command_index == argc) || ((command_index + 3) < argc)) {
             usage_message();
         } else {
             // The default values for template and template_version
@@ -392,7 +364,7 @@ int main (int argc, char * argv []) {
         if (command_index + 1 == argc) {
             status = exec.cmd_template (argv [command_index]);
         } else if (command_index + 2 == argc) {
-            status = exec.cmd_template (argv [command_index], argv [command_index]);
+            status = exec.cmd_template (argv [command_index], argv [command_index + 1]);
         } else {
             usage_message ();
         }
@@ -401,7 +373,6 @@ int main (int argc, char * argv []) {
         // Usage: ecosconfige export <filename>
         if (command_index + 1 == argc) {
             std::string filename = std::string(argv[command_index]);
-            filename = TRANSLATE_PATH(filename);
             status = exec.cmd_export(filename);
         } else {
             usage_message ();
@@ -411,7 +382,6 @@ int main (int argc, char * argv []) {
         // Usage: ecosconfig import <filename>
         if (command_index + 1 == argc) {
             std::string filename = std::string(argv[command_index]);
-            filename = TRANSLATE_PATH(filename);
             status = exec.cmd_import(filename);
         } else {
             usage_message ();