aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-02-20 09:29:56 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-02-20 09:29:56 +0200
commitc23346c4cda9e0c2318c302dc6014d3fef53a6d3 (patch)
tree2a24d82d2445a8adbdf6e88ef22a5ce4d1957a19
parent8bd89cfca333e58f6990d7d168649dfc79878f31 (diff)
Rework extension handling logic
We no longer support hxx{vector.}. Rather, the target type can decide, e.g., based on a config variable, whether to append an extension. Also, in the future we may support a syntax to specify that this is a complete name, e.g., hxx{'vector'}.
-rw-r--r--build/cxx/rule.cxx4
-rw-r--r--build/parser.cxx12
-rw-r--r--build/path27
-rw-r--r--build/path.ixx16
-rw-r--r--build/path.txx56
-rw-r--r--build/prerequisite.cxx2
-rw-r--r--build/target.cxx2
7 files changed, 55 insertions, 64 deletions
diff --git a/build/cxx/rule.cxx b/build/cxx/rule.cxx
index 8d2c0b2..26ad213 100644
--- a/build/cxx/rule.cxx
+++ b/build/cxx/rule.cxx
@@ -208,6 +208,10 @@ namespace build
// extension. Here we can assume the name part is a valid
// filesystem name.
//
+ // Note that if the file has no extension, we record an empty
+ // extension rather than NULL (which would signify that the
+ // extension needs to be added).
+ //
path d (file.directory ());
string n (file.leaf ().base ().string ());
const char* es (file.extension ());
diff --git a/build/parser.cxx b/build/parser.cxx
index 1cb0684..d1f3d8a 100644
--- a/build/parser.cxx
+++ b/build/parser.cxx
@@ -242,12 +242,12 @@ namespace build
// Extract extension.
//
- string::size_type j (n.rfind ('.'));
+ string::size_type j (path::traits::find_extension (n));
if (j != string::npos)
{
- e = &extension_pool.find (n.c_str () + j + 1);
- n.resize (j);
+ e = &extension_pool.find (n.c_str () + j);
+ n.resize (j - 1);
}
}
@@ -318,12 +318,12 @@ namespace build
// Extract extension.
//
- string::size_type j (n.rfind ('.'));
+ string::size_type j (path::traits::find_extension (n));
if (j != string::npos)
{
- e = &extension_pool.find (n.c_str () + j + 1);
- n.resize (j);
+ e = &extension_pool.find (n.c_str () + j);
+ n.resize (j - 1);
}
}
diff --git a/build/path b/build/path
index 8eb560b..9b3668d 100644
--- a/build/path
+++ b/build/path
@@ -74,6 +74,33 @@ namespace build
return string_type::npos;
}
+ static size_type
+ find_extension (string_type const& s)
+ {
+ size_type i (s.size ());
+
+ for (; i > 0; --i)
+ {
+ C c (s[i - 1]);
+
+ if (c == '.')
+ break;
+
+ if (is_separator (c))
+ {
+ i = 0;
+ break;
+ }
+ }
+
+ // Weed out paths like ".txt" (and "/.txt") and "txt.".
+ //
+ if (i > 1 && !is_separator (s[i - 2]) && i != s.size ())
+ return i - 1;
+ else
+ return string_type::npos;
+ }
+
static int
compare (string_type const& l, string_type const& r)
{
diff --git a/build/path.ixx b/build/path.ixx
index f742060..60d3bc3 100644
--- a/build/path.ixx
+++ b/build/path.ixx
@@ -57,6 +57,22 @@ namespace build
return *this;
}
+ template <typename C>
+ inline basic_path<C> basic_path<C>::
+ base () const
+ {
+ size_type p (traits::find_extension (path_));
+ return p != string_type::npos ? basic_path (path_.c_str (), p) : *this;
+ }
+
+ template <typename C>
+ inline const C* basic_path<C>::
+ extension () const
+ {
+ size_type p (traits::find_extension (path_));
+ return p != string_type::npos ? path_.c_str () + p + 1 : nullptr;
+ }
+
#ifndef _WIN32
template <typename C>
inline typename basic_path<C>::string_type basic_path<C>::
diff --git a/build/path.txx b/build/path.txx
index f576870..881dc17 100644
--- a/build/path.txx
+++ b/build/path.txx
@@ -34,62 +34,6 @@ namespace build
: basic_path ();
}
- template <typename C>
- basic_path<C> basic_path<C>::
- base () const
- {
- size_type i (path_.size ());
-
- for (; i > 0; --i)
- {
- if (path_[i - 1] == '.')
- break;
-
- if (traits::is_separator (path_[i - 1]))
- {
- i = 0;
- break;
- }
- }
-
- // Weed out paths like ".txt" and "/.txt"
- //
- if (i > 1 && !traits::is_separator (path_[i - 2]))
- {
- return basic_path (path_.c_str (), i - 1);
- }
- else
- return *this;
- }
-
- template <typename C>
- const C* basic_path<C>::
- extension () const
- {
- size_type i (path_.size ());
-
- for (; i > 0; --i)
- {
- if (path_[i - 1] == '.')
- break;
-
- if (traits::is_separator (path_[i - 1]))
- {
- i = 0;
- break;
- }
- }
-
- // Weed out paths like ".txt" and "/.txt"
- //
- if (i > 1 && !traits::is_separator (path_[i - 2]))
- {
- return path_.c_str () + i;
- }
- else
- return nullptr;
- }
-
#ifdef _WIN32
template <typename C>
typename basic_path<C>::string_type basic_path<C>::
diff --git a/build/prerequisite.cxx b/build/prerequisite.cxx
index 8d86392..71bde5f 100644
--- a/build/prerequisite.cxx
+++ b/build/prerequisite.cxx
@@ -46,7 +46,7 @@ namespace build
os << p.name;
- if (p.ext != nullptr)
+ if (p.ext != nullptr && !p.ext->empty ())
os << '.' << *p.ext;
os << '}';
diff --git a/build/target.cxx b/build/target.cxx
index 31a7f59..7a40c61 100644
--- a/build/target.cxx
+++ b/build/target.cxx
@@ -38,7 +38,7 @@ namespace build
os << t.name;
- if (t.ext != nullptr)
+ if (t.ext != nullptr && !t.ext->empty ())
os << '.' << *t.ext;
os << '}';