diff options
author | Thiago Farina <tfransosi@gmail.com> | 2011-03-19 21:53:43 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2011-04-15 19:20:51 (GMT) |
commit | 89a75eff08cd7355f07235938aff4769f97068e5 (patch) | |
tree | fff51cd97b561d91ef6a670d21116cd0b03543e9 /src | |
parent | 343c526e6a0c35816c4876bfc923cef15ef7a989 (diff) | |
download | Ninja-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.cc | 54 | ||||
-rw-r--r-- | src/graph.h | 3 | ||||
-rw-r--r-- | src/graph_test.cc | 33 | ||||
-rw-r--r-- | src/util.cc | 54 | ||||
-rw-r--r-- | src/util.h | 11 | ||||
-rw-r--r-- | src/util_test.cc | 50 |
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; +} @@ -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); +} |