aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-02 09:36:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-02 09:36:34 +0200
commit428ce65eebccc1992695f075e58b62598f771279 (patch)
tree054635c5c1d9d787f0f7db254d0ca3ec3825551e
parent324ec39cafb1f12e7114e21391113f314ff70faf (diff)
Optimize out path::normalize() calls
-rw-r--r--build2/algorithm.cxx3
-rw-r--r--build2/parser.cxx31
-rw-r--r--build2/search.cxx10
3 files changed, 34 insertions, 10 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index 595603c..fea3d25 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -43,7 +43,8 @@ namespace build2
if (tt == nullptr)
fail << "unknown target type " << n.type << " in name " << n;
- n.dir.normalize ();
+ if (!n.dir.empty ())
+ n.dir.normalize ();
// @@ OUT: for now we assume the prerequisite's out is undetermined.
// Would need to pass a pair of names.
diff --git a/build2/parser.cxx b/build2/parser.cxx
index ce31042..bb724aa 100644
--- a/build2/parser.cxx
+++ b/build2/parser.cxx
@@ -27,6 +27,8 @@ namespace build2
typedef token_type type;
+ static const dir_path root_dir ("/");
+
class parser::enter_scope
{
public:
@@ -40,14 +42,28 @@ namespace build2
// since "/" is a relative path on Windows (and we use "/" even on
// Windows for that gloabl scope).
//
- if (d != dir_path ("/"))
+ if (d != root_dir)
{
- // Relative scopes are opened relative to out, not src.
+ // Try hard not to call normalize(). Most of the time we will go just
+ // one level deeper.
//
+ bool n (true);
+
if (d.relative ())
- d = p.scope_->out_path () / d;
+ {
+ // Relative scopes are opened relative to out, not src.
+ //
+ if (d.simple () && d.string () != "." && d.string () != "..")
+ {
+ d = dir_path (p.scope_->out_path ()) /= d.string ();
+ n = false;
+ }
+ else
+ d = p.scope_->out_path () / d;
+ }
- d.normalize ();
+ if (n)
+ d.normalize ();
}
p.switch_scope (d);
@@ -600,7 +616,8 @@ namespace build2
if (ti == nullptr)
fail (ploc) << "unknown target type " << pn.type;
- pn.dir.normalize ();
+ if (!pn.dir.empty ())
+ pn.dir.normalize ();
// Find or insert.
//
@@ -800,14 +817,14 @@ namespace build2
//
path p (move (n.dir));
if (n.value.empty ())
- p /= path ("buildfile");
+ p /= "buildfile";
else
{
bool d (path::traits::is_separator (n.value.back ()));
p /= path (move (n.value));
if (d)
- p /= path ("buildfile");
+ p /= "buildfile";
}
l6 ([&]{trace (l) << "relative path " << p;});
diff --git a/build2/search.cxx b/build2/search.cxx
index 6d0a5e9..68191f5 100644
--- a/build2/search.cxx
+++ b/build2/search.cxx
@@ -107,8 +107,14 @@ namespace build2
// Check if there is a file.
//
const dir_path& s (pk.scope->src_path ());
- path f (s / *tk.dir / path (*tk.name));
- f.normalize ();
+
+ path f (s);
+ if (!tk.dir->empty ())
+ {
+ f /= *tk.dir;
+ f.normalize ();
+ }
+ f /= *tk.name;
if (!ext->empty ())
{