]> git.tdb.fi Git - builder.git/commitdiff
Move variable expansion from Config to SourcePackage
authorMikko Rasa <tdb@tdb.fi>
Wed, 19 Jan 2011 14:14:33 +0000 (14:14 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 19 Jan 2011 14:14:33 +0000 (14:14 +0000)
Allow variables to be used in component sources

source/component.cpp
source/component.h
source/config.cpp
source/sourcepackage.cpp
source/sourcepackage.h

index c440e4c90df9c07c30db084f75d5fc8678963d73..04c9d17204dd8729cc2b56993bd9697041f480d5 100644 (file)
@@ -40,6 +40,15 @@ Component::Component(SourcePackage &p, Type t, const string &n):
        deflt(true)
 { }
 
+void Component::configure(const StringMap &opts, unsigned flag)
+{
+       for(StringList::iterator i=sources.begin(); i!=sources.end(); ++i)
+               *i = (pkg.get_source()/pkg.expand_string(*i)).str();
+
+       for(PackageList::const_iterator i=requires.begin(); i!=requires.end(); ++i)
+               (*i)->configure(opts, flag&2);
+}
+
 void Component::create_build_info()
 {
        const PackageList &pkg_reqs = pkg.get_requires();
@@ -99,9 +108,9 @@ void Component::create_build_info()
        }
        else if(module_host)
        {
-               const PathList &host_src = module_host->get_sources();
-               for(PathList::const_iterator i=host_src.begin(); i!=host_src.end(); ++i)
-                       build_info.incpath.push_back(i->str());
+               const StringList &host_src = module_host->get_sources();
+               for(StringList::const_iterator i=host_src.begin(); i!=host_src.end(); ++i)
+                       build_info.incpath.push_back(*i);
        }
 
        build_info.unique();
@@ -245,16 +254,17 @@ void Component::create_targets() const
 PathList Component::collect_source_files() const
 {
        PathList files;
-       for(PathList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
+       for(StringList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
        {
-               if(FS::is_dir(*i))
+               FS::Path path(*i);
+               if(FS::is_dir(path))
                {
-                       list<string> sfiles = list_files(*i);
+                       list<string> sfiles = list_files(path);
                        for(list<string>::iterator j=sfiles.begin(); j!=sfiles.end(); ++j)
-                               files.push_back(*i / *j);
+                               files.push_back(path / *j);
                }
                else
-                       files.push_back(*i);
+                       files.push_back(path);
        }
 
        return files;
@@ -287,7 +297,7 @@ void Component::Loader::finish()
 
 void Component::Loader::source(const string &s)
 {
-       comp.sources.push_back(comp.pkg.get_source()/s);
+       comp.sources.push_back(s);
 }
 
 void Component::Loader::require(const string &n)
index 3a358ce04f36b0770cea5251997d62d6d0ae2b8f..d83cc6eeb182ea525708dd7e4fc933bc5c34e888 100644 (file)
@@ -60,7 +60,7 @@ protected:
        SourcePackage &pkg;
        Type type;
        std::string name;
-       PathList sources;
+       StringList sources;
        bool install;
        const Component *module_host;
        bool modular;
@@ -73,13 +73,15 @@ public:
        const SourcePackage &get_package() const { return pkg; }
        Type get_type() const { return type; }
        const std::string &get_name() const { return name; }
-       const PathList &get_sources() const { return sources; }
+       const StringList &get_sources() const { return sources; }
        const BuildInfo &get_build_info() const { return build_info; }
        bool get_install() const { return install; }
        bool is_modular() const { return modular; }
        const PackageList &get_requires() const { return requires; }
        bool is_default() const { return deflt; }
 
+       void configure(const StringMap &, unsigned);
+
        /** Prepares the build information for building.  Pulls build info from the
        parent and dependency packages, and adds any component-specific flags. */
        void create_build_info();
index 4ec969ac581d849bcd3cf6cb50bec4ef3654832d..dd5cda148dea67a838e73d0d720fb47cdea6c966 100644 (file)
@@ -5,7 +5,6 @@ Copyright © 2006-2009  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
-#include <cstdlib>
 #include <msp/core/except.h>
 #include <msp/fs/stat.h>
 #include <msp/fs/utils.h>
@@ -97,49 +96,8 @@ bool Config::update(const StringMap &opts)
 
 void Config::finish()
 {
-       for(unsigned n=0; n<20; ++n)
-       {
-               bool changed = false;
-               for(OptionMap::iterator i=options.begin(); i!=options.end(); ++i)
-               {
-                       Option &opt = i->second;
-                       string::size_type dollar = 0;
-                       while((dollar = opt.value.find('$', dollar))!=string::npos)
-                       {
-                               string::size_type end;
-                               string var;
-                               if(opt.value[dollar+1]=='{')
-                               {
-                                       end = opt.value.find('}', dollar+2);
-                                       if(end==string::npos)
-                                               throw Exception("Unterminated variable reference");
-                                       var = opt.value.substr(dollar+2, end-dollar-2);
-                                       ++end;
-                               }
-                               else
-                               {
-                                       for(end=dollar+1; (isalnum(opt.value[end]) && opt.value[end]!='_'); ++end) ;
-                                       var = opt.value.substr(dollar+1, end-dollar-1);
-                               }
-
-                               string value;
-                               if(is_option(var))
-                                       value = get_option(var).value;
-                               else if(var=="arch")
-                                       value = package.get_builder().get_current_arch().get_name();
-                               else if(const char *ptr = getenv(var.c_str()))
-                                       value = ptr;
-
-                               opt.value.replace(dollar, end-dollar, value);
-
-                               dollar += value.size();
-                               changed = true;
-                       }
-               }
-
-               if(!changed)
-                       break;
-       }
+       for(OptionMap::iterator i=options.begin(); i!=options.end(); ++i)
+               i->second.value = package.expand_string(i->second.value);
 }
 
 void Config::save() const
index e946d018a51953a44149a6888179500a2923fd32..a466089ae75aad13b049d5e5e3660a930f597ec3 100644 (file)
@@ -5,6 +5,7 @@ Copyright © 2007-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#include <cstdlib>
 #include <msp/io/print.h>
 #include <msp/strings/lexicalcast.h>
 #include <msp/strings/utils.h>
@@ -78,6 +79,50 @@ LibMode SourcePackage::get_library_mode() const
                throw Exception("Unknown library mode");
 }
 
+string SourcePackage::expand_string(const string &str) const
+{
+       string result = str;
+       string::size_type dollar = 0;
+       unsigned n = 0;
+       while((dollar = result.find('$'))!=string::npos)
+       {
+               if(n>1000)
+                       throw Exception("Too much variable expansions");
+
+               string::size_type end;
+               string var;
+               if(dollar+1<result.size() && result[dollar+1]=='{')
+               {
+                       end = result.find('}', dollar+2);
+                       if(end==string::npos)
+                               throw Exception("Unterminated variable reference");
+                       var = result.substr(dollar+2, end-dollar-2);
+                       ++end;
+               }
+               else
+               {
+                       for(end=dollar+1; (isalnum(result[end]) || result[end]=='_'); ++end) ;
+                       var = result.substr(dollar+1, end-dollar-1);
+               }
+
+               string value;
+               if(config.is_option(var))
+                       value = config.get_option(var).value;
+               else if(var=="arch")
+                       value = builder.get_current_arch().get_name();
+               else if(var=="system")
+                       value = builder.get_current_arch().get_system();
+               else if(const char *ptr = getenv(var.c_str()))
+                       value = ptr;
+
+               result.replace(dollar, end-dollar, value);
+
+               ++n;
+       }
+
+       return result;
+}
+
 void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
 {
        init_config();
@@ -117,11 +162,7 @@ void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
        deps_cache.load();
 
        for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
-       {
-               const PackageList &reqs = i->get_requires();
-               for(PackageList::const_iterator j=reqs.begin(); j!=reqs.end(); ++j)
-                       (*j)->configure(opts, flag&2);
-       }
+               i->configure(opts, flag);
 }
 
 void SourcePackage::init_config()
@@ -274,5 +315,5 @@ void SourcePackage::Loader::tar_file(const string &f)
        SourcePackage &spkg = static_cast<SourcePackage &>(pkg);
        for(ComponentList::iterator i=spkg.components.begin(); i!=spkg.components.end(); ++i)
                if(i->get_type()==Component::TARBALL && i->get_name()=="@src")
-                       const_cast<PathList &>(i->get_sources()).push_back(spkg.source/f);
+                       const_cast<StringList &>(i->get_sources()).push_back((spkg.source/f).str());
 }
index e170399aa4ab14db6abd94a3b7bc1f17f884db66..5218592ff9d0a0743957b17bf24e70fbe8cf2315 100644 (file)
@@ -81,6 +81,7 @@ public:
 
        LibMode get_library_mode() const;
        DependencyCache &get_deps_cache() const { return deps_cache; }
+       std::string expand_string(const std::string &) const;
 private:
        virtual void do_configure(const StringMap &, unsigned);