summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Farina <tfransosi@gmail.com>2011-03-19 21:53:43 (GMT)
committerEvan Martin <martine@danga.com>2011-04-15 19:20:51 (GMT)
commit89a75eff08cd7355f07235938aff4769f97068e5 (patch)
treefff51cd97b561d91ef6a670d21116cd0b03543e9 /src
parent343c526e6a0c35816c4876bfc923cef15ef7a989 (diff)
downloadNinja-89a75eff08cd7355f07235938aff4769f97068e5.zip
Ninja-89a75eff08cd7355f07235938aff4769f97068e5.tar.gz
Ninja-89a75eff08cd7355f07235938aff4769f97068e5.tar.bz2
Move CanonicalizePath into util.h so it can be shared by the other modules.
Also add util_test.cc and move the CanonicalizePathTest into there. Signed-off-by: Thiago Farina <tfarina@chromium.org>
Diffstat (limited to 'src')
-rw-r--r--src/graph.cc54
-rw-r--r--src/graph.h3
-rw-r--r--src/graph_test.cc33
-rw-r--r--src/util.cc54
-rw-r--r--src/util.h11
-rw-r--r--src/util_test.cc50
6 files changed, 116 insertions, 89 deletions
diff --git a/src/graph.cc b/src/graph.cc
index 35ae088..a4317ba 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -19,59 +19,7 @@
#include "build_log.h"
#include "ninja.h"
#include "parsers.h"
-
-// Canonicalize a path like "foo/../bar.h" into just "bar.h".
-bool CanonicalizePath(string* path, string* err) {
- // Try to fast-path out the common case.
- if (path->find("/.") == string::npos &&
- path->find("./") == string::npos) {
- return true;
- }
-
- string inpath = *path;
- vector<const char*> parts;
- for (string::size_type start = 0; start < inpath.size(); ++start) {
- string::size_type end = inpath.find('/', start);
- if (end == string::npos)
- end = inpath.size();
- else
- inpath[end] = 0;
- parts.push_back(inpath.data() + start);
- start = end;
- }
-
- vector<const char*>::iterator i = parts.begin();
- while (i != parts.end()) {
- const char* part = *i;
- if (part[0] == '.') {
- if (part[1] == 0) {
- // "."; strip.
- parts.erase(i);
- continue;
- } else if (part[1] == '.' && part[2] == 0) {
- // ".."; go up one.
- if (i == parts.begin()) {
- *err = "can't canonicalize path '" + *path + "' that reaches "
- "above its directory";
- return false;
- }
- --i;
- parts.erase(i, i + 2);
- continue;
- }
- }
- ++i;
- }
- path->clear();
-
- for (i = parts.begin(); i != parts.end(); ++i) {
- if (!path->empty())
- path->push_back('/');
- path->append(*i);
- }
-
- return true;
-}
+#include "util.h"
bool FileStat::Stat(DiskInterface* disk_interface) {
mtime_ = disk_interface->Stat(path_);
diff --git a/src/graph.h b/src/graph.h
index ecf9e54..f3cfa97 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -119,7 +119,4 @@ struct Edge {
bool is_phony() const;
};
-// Exposed for testing.
-bool CanonicalizePath(string* path, string* err);
-
#endif // NINJA_GRAPH_H_
diff --git a/src/graph_test.cc b/src/graph_test.cc
index b67cf99..ba41440 100644
--- a/src/graph_test.cc
+++ b/src/graph_test.cc
@@ -16,39 +16,6 @@
#include "test.h"
-TEST(CanonicalizePath, PathSamples) {
- string path = "foo.h";
- string err;
- EXPECT_TRUE(CanonicalizePath(&path, &err));
- EXPECT_EQ("", err);
- EXPECT_EQ("foo.h", path);
-
- path = "./foo.h"; err = "";
- EXPECT_TRUE(CanonicalizePath(&path, &err));
- EXPECT_EQ("", err);
- EXPECT_EQ("foo.h", path);
-
- path = "./foo/./bar.h"; err = "";
- EXPECT_TRUE(CanonicalizePath(&path, &err));
- EXPECT_EQ("", err);
- EXPECT_EQ("foo/bar.h", path);
-
- path = "./x/foo/../bar.h"; err = "";
- EXPECT_TRUE(CanonicalizePath(&path, &err));
- EXPECT_EQ("", err);
- EXPECT_EQ("x/bar.h", path);
-
- path = "./x/foo/../../bar.h"; err = "";
- EXPECT_TRUE(CanonicalizePath(&path, &err));
- EXPECT_EQ("", err);
- EXPECT_EQ("bar.h", path);
-
- path = "./x/../foo/../../bar.h"; err = "";
- EXPECT_FALSE(CanonicalizePath(&path, &err));
- EXPECT_EQ("can't canonicalize path './x/../foo/../../bar.h' that reaches "
- "above its directory", err);
-}
-
struct GraphTest : public StateTestWithBuiltinRules {
VirtualFileSystem fs_;
};
diff --git a/src/util.cc b/src/util.cc
index 1968702..d0236bc 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -18,6 +18,8 @@
#include <stdio.h>
#include <stdlib.h>
+#include <vector>
+
void Fatal(const char* msg, ...) {
va_list ap;
fprintf(stderr, "FATAL: ");
@@ -27,3 +29,55 @@ void Fatal(const char* msg, ...) {
fprintf(stderr, "\n");
exit(1);
}
+
+bool CanonicalizePath(std::string* path, std::string* err) {
+ // Try to fast-path out the common case.
+ if (path->find("/.") == std::string::npos &&
+ path->find("./") == std::string::npos) {
+ return true;
+ }
+
+ std::string inpath = *path;
+ std::vector<const char*> parts;
+ for (std::string::size_type start = 0; start < inpath.size(); ++start) {
+ std::string::size_type end = inpath.find('/', start);
+ if (end == std::string::npos)
+ end = inpath.size();
+ else
+ inpath[end] = 0;
+ parts.push_back(inpath.data() + start);
+ start = end;
+ }
+
+ std::vector<const char*>::iterator i = parts.begin();
+ while (i != parts.end()) {
+ const char* part = *i;
+ if (part[0] == '.') {
+ if (part[1] == 0) {
+ // "."; strip.
+ parts.erase(i);
+ continue;
+ } else if (part[1] == '.' && part[2] == 0) {
+ // ".."; go up one.
+ if (i == parts.begin()) {
+ *err = "can't canonicalize path '" + *path + "' that reaches "
+ "above its directory";
+ return false;
+ }
+ --i;
+ parts.erase(i, i + 2);
+ continue;
+ }
+ }
+ ++i;
+ }
+ path->clear();
+
+ for (i = parts.begin(); i != parts.end(); ++i) {
+ if (!path->empty())
+ path->push_back('/');
+ path->append(*i);
+ }
+
+ return true;
+}
diff --git a/src/util.h b/src/util.h
index 188528c..8c5a6a8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -12,6 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#ifndef NINJA_UTIL_H_
+#define NINJA_UTIL_H_
+#pragma once
+
+#include <string>
+
// Dump a backtrace to stderr.
// |skip_frames| is how many frames to skip;
// DumpBacktrace implicitly skips itself already.
@@ -19,3 +25,8 @@ void DumpBacktrace(int skip_frames);
// Log a fatal message, dump a backtrace, and exit.
void Fatal(const char* msg, ...);
+
+// Canonicalize a path like "foo/../bar.h" into just "bar.h".
+bool CanonicalizePath(std::string* path, std::string* err);
+
+#endif // NINJA_UTIL_H_
diff --git a/src/util_test.cc b/src/util_test.cc
new file mode 100644
index 0000000..145c80e
--- /dev/null
+++ b/src/util_test.cc
@@ -0,0 +1,50 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util.h"
+
+#include "test.h"
+
+TEST(CanonicalizePath, PathSamples) {
+ std::string path = "foo.h";
+ std::string err;
+ EXPECT_TRUE(CanonicalizePath(&path, &err));
+ EXPECT_EQ("", err);
+ EXPECT_EQ("foo.h", path);
+
+ path = "./foo.h"; err = "";
+ EXPECT_TRUE(CanonicalizePath(&path, &err));
+ EXPECT_EQ("", err);
+ EXPECT_EQ("foo.h", path);
+
+ path = "./foo/./bar.h"; err = "";
+ EXPECT_TRUE(CanonicalizePath(&path, &err));
+ EXPECT_EQ("", err);
+ EXPECT_EQ("foo/bar.h", path);
+
+ path = "./x/foo/../bar.h"; err = "";
+ EXPECT_TRUE(CanonicalizePath(&path, &err));
+ EXPECT_EQ("", err);
+ EXPECT_EQ("x/bar.h", path);
+
+ path = "./x/foo/../../bar.h"; err = "";
+ EXPECT_TRUE(CanonicalizePath(&path, &err));
+ EXPECT_EQ("", err);
+ EXPECT_EQ("bar.h", path);
+
+ path = "./x/../foo/../../bar.h"; err = "";
+ EXPECT_FALSE(CanonicalizePath(&path, &err));
+ EXPECT_EQ("can't canonicalize path './x/../foo/../../bar.h' that reaches "
+ "above its directory", err);
+}