From 89a75eff08cd7355f07235938aff4769f97068e5 Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Sat, 19 Mar 2011 18:53:43 -0300 Subject: 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 --- build.ninja | 1 + src/graph.cc | 54 +----------------------------------------------------- src/graph.h | 3 --- src/graph_test.cc | 33 --------------------------------- src/util.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/util.h | 11 +++++++++++ src/util_test.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 117 insertions(+), 89 deletions(-) create mode 100644 src/util_test.cc diff --git a/build.ninja b/build.ninja index c993ecf..84c10d4 100644 --- a/build.ninja +++ b/build.ninja @@ -63,6 +63,7 @@ build $builddir/ninja_test.o: cxx src/ninja_test.cc build $builddir/parsers_test.o: cxx src/parsers_test.cc build $builddir/subprocess_test.o: cxx src/subprocess_test.cc build $builddir/test.o: cxx src/test.cc +build $builddir/util_test.o: cxx src/util_test.cc build ninja_test: link $builddir/build_test.o $builddir/build_log_test.o \ $builddir/graph_test.o $builddir/ninja_test.o $builddir/parsers_test.o \ $builddir/subprocess_test.o $builddir/test.o $builddir/ninja.a 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 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::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 #include +#include + 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 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::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 + // 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); +} -- cgit v0.12