aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ninja_test.cc18
-rw-r--r--strutil.cc24
-rw-r--r--strutil.h2
-rw-r--r--strutil_test.cc53
-rw-r--r--testutil.h36
5 files changed, 98 insertions, 35 deletions
diff --git a/ninja_test.cc b/ninja_test.cc
index f1fb522..5fc410e 100644
--- a/ninja_test.cc
+++ b/ninja_test.cc
@@ -18,25 +18,10 @@
#include "log.h"
#include "ninja.h"
+#include "testutil.h"
namespace {
-#define ASSERT_EQ(a, b) \
- do { \
- if ((a) != (b)) { \
- fprintf(stderr, \
- "Assertion failure at %s:%d: %s (which is \"%s\") vs %s\n", \
- __FILE__, __LINE__, #a, c_str(a), #b); \
- } \
- } while(0)
-
-const char* c_str(const string& s) { return s.c_str(); }
-const char* c_str(size_t v) {
- static char buf[64];
- sprintf(buf, "%zd", v);
- return buf;
-}
-
string GetDepfile(string cmd, string* new_cmd) {
new_cmd->clear();
string r;
@@ -90,4 +75,5 @@ int main() {
g_log_no_exit = true;
TestGetDepfile();
TestGetGomaccPosForAndroidCompileCommand();
+ assert(!g_failed);
}
diff --git a/strutil.cc b/strutil.cc
index 7afe743..ea5d633 100644
--- a/strutil.cc
+++ b/strutil.cc
@@ -266,7 +266,12 @@ StringPiece StripExt(StringPiece s) {
return s.substr(0, found);
}
-void NormalizePath(string* o, size_t start_index) {
+void NormalizePath(string* o) {
+ if (o->empty())
+ return;
+ size_t start_index = 0;
+ if ((*o)[0] == '/')
+ start_index++;
size_t j = start_index;
size_t prev_start = start_index;
for (size_t i = start_index; i <= o->size(); i++) {
@@ -280,13 +285,18 @@ void NormalizePath(string* o, size_t start_index) {
StringPiece prev_dir = StringPiece(o->data() + prev_start, j - prev_start);
if (prev_dir == ".") {
j--;
- } else if (prev_dir == "..") {
- j -= 4;
- j = o->rfind('/', j);
- if (j == string::npos) {
+ } else if (prev_dir == ".." && j != 2 /* .. */) {
+ if (j == 3) {
+ // /..
j = start_index;
} else {
- j++;
+ j -= 4;
+ j = o->rfind('/', j);
+ if (j == string::npos) {
+ j = start_index;
+ } else {
+ j++;
+ }
}
} else if (!prev_dir.empty()) {
if (c) {
@@ -316,7 +326,7 @@ void AbsPath(StringPiece s, string* o) {
*o += '/';
}
AppendString(s, o);
- NormalizePath(o, 1);
+ NormalizePath(o);
}
template<typename Cond>
diff --git a/strutil.h b/strutil.h
index 2dd229c..8c47f1c 100644
--- a/strutil.h
+++ b/strutil.h
@@ -118,7 +118,7 @@ StringPiece Dirname(StringPiece s);
StringPiece Basename(StringPiece s);
StringPiece GetExt(StringPiece s);
StringPiece StripExt(StringPiece s);
-void NormalizePath(string* o, size_t start_index = 0);
+void NormalizePath(string* o);
void AbsPath(StringPiece s, string* o);
size_t FindOutsideParen(StringPiece s, char c);
diff --git a/strutil_test.cc b/strutil_test.cc
index b9c5580..048a974 100644
--- a/strutil_test.cc
+++ b/strutil_test.cc
@@ -22,18 +22,21 @@
#include <vector>
#include "string_piece.h"
+#include "testutil.h"
using namespace std;
+namespace {
+
void TestWordScanner() {
vector<StringPiece> ss;
for (StringPiece tok : WordScanner("foo bar baz")) {
ss.push_back(tok);
}
assert(ss.size() == 3LU);
- assert(ss[0] == "foo");
- assert(ss[1] == "bar");
- assert(ss[2] == "baz");
+ ASSERT_EQ(ss[0], "foo");
+ ASSERT_EQ(ss[1], "bar");
+ ASSERT_EQ(ss[2], "baz");
}
void TestHasPrefix() {
@@ -57,14 +60,14 @@ string SubstPattern(StringPiece str, StringPiece pat, StringPiece subst) {
}
void TestSubstPattern() {
- assert(SubstPattern("x.c", "%.c", "%.o") == "x.o");
- assert(SubstPattern("c.x", "c.%", "o.%") == "o.x");
- assert(SubstPattern("x.c.c", "%.c", "%.o") == "x.c.o");
- assert(SubstPattern("x.x y.c", "%.c", "%.o") == "x.x y.o");
- assert(SubstPattern("x.%.c", "%.%.c", "OK") == "OK");
- assert(SubstPattern("x.c", "x.c", "OK") == "OK");
- assert(SubstPattern("x.c.c", "x.c", "XX") == "x.c.c");
- assert(SubstPattern("x.x.c", "x.c", "XX") == "x.x.c");
+ ASSERT_EQ(SubstPattern("x.c", "%.c", "%.o"), "x.o");
+ ASSERT_EQ(SubstPattern("c.x", "c.%", "o.%"), "o.x");
+ ASSERT_EQ(SubstPattern("x.c.c", "%.c", "%.o"), "x.c.o");
+ ASSERT_EQ(SubstPattern("x.x y.c", "%.c", "%.o"), "x.x y.o");
+ ASSERT_EQ(SubstPattern("x.%.c", "%.%.c", "OK"), "OK");
+ ASSERT_EQ(SubstPattern("x.c", "x.c", "OK"), "OK");
+ ASSERT_EQ(SubstPattern("x.c.c", "x.c", "XX"), "x.c.c");
+ ASSERT_EQ(SubstPattern("x.x.c", "x.c", "XX"), "x.x.c");
}
void TestNoLineBreak() {
@@ -84,6 +87,32 @@ void TestHasWord() {
assert(!HasWord("foo bar baz", "fo"));
}
+static string NormalizePath(string s) {
+ ::NormalizePath(&s);
+ return s;
+}
+
+void TestNormalizePath() {
+ ASSERT_EQ(NormalizePath(""), "");
+ ASSERT_EQ(NormalizePath("."), "");
+ ASSERT_EQ(NormalizePath("/"), "/");
+ ASSERT_EQ(NormalizePath("/tmp"), "/tmp");
+ ASSERT_EQ(NormalizePath("////tmp////"), "/tmp");
+ ASSERT_EQ(NormalizePath("a////b"), "a/b");
+ ASSERT_EQ(NormalizePath("a//.//b"), "a/b");
+ ASSERT_EQ(NormalizePath("a////b//../c/////"), "a/c");
+ ASSERT_EQ(NormalizePath("../foo"), "../foo");
+ ASSERT_EQ(NormalizePath("./foo"), "foo");
+ ASSERT_EQ(NormalizePath("x/y/..//../foo"), "foo");
+ ASSERT_EQ(NormalizePath("x/../../foo"), "../foo");
+ ASSERT_EQ(NormalizePath("/../foo"), "/foo");
+ ASSERT_EQ(NormalizePath("/../../foo"), "/foo");
+ ASSERT_EQ(NormalizePath("/a/../../foo"), "/foo");
+ ASSERT_EQ(NormalizePath("/a/b/.."), "/a");
+}
+
+} // namespace
+
int main() {
TestWordScanner();
TestHasPrefix();
@@ -91,4 +120,6 @@ int main() {
TestSubstPattern();
TestNoLineBreak();
TestHasWord();
+ TestNormalizePath();
+ assert(!g_failed);
}
diff --git a/testutil.h b/testutil.h
new file mode 100644
index 0000000..7036409
--- /dev/null
+++ b/testutil.h
@@ -0,0 +1,36 @@
+// Copyright 2015 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 <assert.h>
+
+#include "string_piece.h"
+
+bool g_failed;
+
+#define ASSERT_EQ(a, b) \
+ do { \
+ if ((a) != (b)) { \
+ fprintf(stderr, \
+ "Assertion failure at %s:%d: %s (which is \"%.*s\") vs %s\n", \
+ __FILE__, __LINE__, #a, SPF(GetStringPiece(a)), #b); \
+ g_failed = true; \
+ } \
+ } while(0)
+
+StringPiece GetStringPiece(StringPiece s) { return s; }
+StringPiece GetStringPiece(size_t v) {
+ static char buf[64];
+ sprintf(buf, "%zd", v);
+ return buf;
+}