diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-01-05 15:00:39 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-01-05 15:00:39 +0200 |
commit | 7e3f16c393a614e0a951abe3f7237c8169d689a9 (patch) | |
tree | 0943dbfad1e0fbf72e0ccd4f85eb2172d6fa91f6 /build | |
parent | c0c85b67516653c181fbce7c61c2df3e31e4edd8 (diff) |
Determine work, home, and {src,out}_{root,base} directories
Diffstat (limited to 'build')
-rw-r--r-- | build/bd.cxx | 62 | ||||
-rw-r--r-- | build/buildfile | 5 | ||||
-rw-r--r-- | build/context | 22 | ||||
-rw-r--r-- | build/context.cxx | 19 | ||||
-rw-r--r-- | build/path | 16 | ||||
-rw-r--r-- | build/path.txx | 40 |
6 files changed, 160 insertions, 4 deletions
diff --git a/build/bd.cxx b/build/bd.cxx index 66130b2..394665a 100644 --- a/build/bd.cxx +++ b/build/bd.cxx @@ -2,7 +2,13 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -#include <time.h> // tzset() +#include <time.h> // tzset() +#include <string.h> // strerror() + +#include <stdlib.h> // getenv() +#include <unistd.h> // getuid() +#include <sys/types.h> // uid_t +#include <pwd.h> // struct passwd, getpwuid() #include <vector> #include <cassert> @@ -18,6 +24,7 @@ #include <build/algorithm> #include <build/process> #include <build/diagnostics> +#include <build/context> #include <build/lexer> #include <build/parser> @@ -147,6 +154,59 @@ main (int argc, char* argv[]) target_types.insert (cxx::ixx::static_type); target_types.insert (cxx::txx::static_type); + // Figure out directories: work, home, and {src,out}_{root,base}. + // + work = path::current (); + + if (const char* h = getenv ("HOME")) + home = path (h); + else + { + struct passwd* pw (getpwuid (getuid ())); + + if (pw == nullptr) + { + const char* msg (strerror (errno)); + cerr << "error: unable to determine home directory: " << msg << endl; + return 1; + } + + home = path (pw->pw_dir); + } + + //@@ Must be normalized. + // + out_base = work; + src_base = out_base; + + // The project's root directory is the one that contains the build/ + // sub-directory which contains the pre.build file. + // + for (path d (src_base); !d.root () && d != home; d = d.directory ()) + { + path f (d / path ("build/pre.build")); + if (path_mtime (f) != timestamp_nonexistent) + { + src_root = d; + break; + } + } + + if (src_root.empty ()) + { + src_root = src_base; + out_root = out_base; + } + else + out_root = out_base.directory (src_base.leaf (src_root)); + + cerr << "work dir: " << work << endl; + cerr << "home dir: " << home << endl; + cerr << "out_base: " << out_base << endl; + cerr << "src_base: " << src_base << endl; + cerr << "out_root: " << out_root << endl; + cerr << "src_root: " << src_root << endl; + // Parse buildfile. // path bf ("buildfile"); diff --git a/build/buildfile b/build/buildfile index 4e9aaa2..8bd80b7 100644 --- a/build/buildfile +++ b/build/buildfile @@ -1,5 +1,5 @@ -exe{bd}: obj{bd algorithm scope parser lexer target prerequisite rule \ - native cxx/target cxx/rule process timestamp path} +exe{bd1}: obj{bd algorithm scope parser lexer target prerequisite rule \ + native context cxx/target cxx/rule process timestamp path} obj{bd}: cxx{bd} obj{algorithm}: cxx{algorithm} @@ -10,6 +10,7 @@ obj{target}: cxx{target} obj{prerequisite}: cxx{prerequisite} obj{rule}: cxx{rule} obj{native}: cxx{native} +obj{context}: cxx{context} obj{cxx/target}: cxx{cxx/target} obj{cxx/rule}: cxx{cxx/rule} obj{process}: cxx{process} diff --git a/build/context b/build/context new file mode 100644 index 0000000..4c86b14 --- /dev/null +++ b/build/context @@ -0,0 +1,22 @@ +// file : build/context -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD_CONTEXT +#define BUILD_CONTEXT + +#include <build/path> + +namespace build +{ + extern path work; + extern path home; + + extern path src_root; + extern path out_root; + + extern path src_base; + extern path out_base; +} + +#endif // BUILD_CONTEXT diff --git a/build/context.cxx b/build/context.cxx new file mode 100644 index 0000000..ce80324 --- /dev/null +++ b/build/context.cxx @@ -0,0 +1,19 @@ +// file : build/context.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include <build/context> + +using namespace std; + +namespace build +{ + path work; + path home; + + path src_root; + path out_root; + + path src_base; + path out_base; +} @@ -224,12 +224,26 @@ namespace build basic_path leaf () const; + // Return the path without the specified directory part. Throws + // invalid_path if the directory is not a prefix of *this. Expects + // both paths to be normalized. + // + basic_path + leaf (basic_path const&) const; + // Return the directory part of the path or empty path if // there is no directory. // basic_path directory () const; + // Return the directory part of the path without the specified + // leaf part. Throws invalid_path if the leaf is not a suffix of + // *this. Expects both paths to be normalized. + // + basic_path + directory (basic_path const&) const; + // Return the path without the extension, if any. // basic_path @@ -297,7 +311,7 @@ namespace build } public: - string_type + const string_type& string () const { return path_; diff --git a/build/path.txx b/build/path.txx index 1502071..6a01547 100644 --- a/build/path.txx +++ b/build/path.txx @@ -104,6 +104,46 @@ namespace build } template <typename C> + basic_path<C> basic_path<C>:: + leaf (basic_path<C> const& d) const + { + size_type n (d.path_.size ()); + + if (n == 0) + return *this; + + size_type m (path_.size ()); + + if (m < n || path_.compare (0, n, d.path_) != 0) + throw invalid_basic_path<C> (path_); + + if (n != m) + n++; // Skip the directory separator. + + return basic_path (path_.c_str () + n, m - n); + } + + template <typename C> + basic_path<C> basic_path<C>:: + directory (basic_path<C> const& l) const + { + size_type n (l.path_.size ()); + + if (n == 0) + return *this; + + size_type m (path_.size ()); + + if (m < n || path_.compare (m - n, n, l.path_) != 0) + throw invalid_basic_path<C> (path_); + + if (n != m) + n++; // Skip the directory separator. + + return basic_path (path_.c_str (), m - n); + } + + template <typename C> basic_path<C>& basic_path<C>:: normalize () { |