diff options
-rw-r--r-- | ninja_test.cc | 18 | ||||
-rw-r--r-- | strutil.cc | 24 | ||||
-rw-r--r-- | strutil.h | 2 | ||||
-rw-r--r-- | strutil_test.cc | 53 | ||||
-rw-r--r-- | testutil.h | 36 |
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); } @@ -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> @@ -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; +} |