diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/disk_interface.cc | 51 | ||||
-rw-r--r-- | src/disk_interface.h | 49 | ||||
-rw-r--r-- | src/ninja.h | 27 | ||||
-rw-r--r-- | src/ninja_jumble.cc | 33 |
4 files changed, 101 insertions, 59 deletions
diff --git a/src/disk_interface.cc b/src/disk_interface.cc new file mode 100644 index 0000000..70564d7 --- /dev/null +++ b/src/disk_interface.cc @@ -0,0 +1,51 @@ +// 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 "disk_interface.h" + +namespace { + +std::string DirName(const std::string& path) { +#ifdef WIN32 + const char kPathSeparator = '\\'; +#else + const char kPathSeparator = '/'; +#endif + + std::string::size_type slash_pos = path.rfind(kPathSeparator); + if (slash_pos == std::string::npos) + return std::string(); // Nothing to do. + while (slash_pos > 0 && path[slash_pos - 1] == kPathSeparator) + --slash_pos; + return path.substr(0, slash_pos); +} + +} // namespace + +bool DiskInterface::MakeDirs(const std::string& path) { + std::string dir = DirName(path); + if (dir.empty()) + return true; // Reached root; assume it's there. + int mtime = Stat(dir); + if (mtime < 0) + return false; // Error. + if (mtime > 0) + return true; // Exists already; we're done. + + // Directory doesn't exist. Try creating its parent first. + bool success = MakeDirs(dir); + if (!success) + return false; + return MakeDir(dir); +} diff --git a/src/disk_interface.h b/src/disk_interface.h new file mode 100644 index 0000000..b8d9786 --- /dev/null +++ b/src/disk_interface.h @@ -0,0 +1,49 @@ +// 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. + +#ifndef NINJA_DISK_INTERFACE_H_ +#define NINJA_DISK_INTERFACE_H_ + +#include <string> + +/// Interface for accessing the disk. +/// +/// Abstract so it can be mocked out for tests. The real implementation +/// is RealDiskInterface. +struct DiskInterface { + virtual ~DiskInterface() {} + + /// stat() a file, returning the mtime, or 0 if missing and -1 on + /// other errors. + virtual int Stat(const std::string& path) = 0; + + /// Create a directory, returning false on failure. + virtual bool MakeDir(const std::string& path) = 0; + + /// Read a file to a string. Fill in |err| on error. + virtual std::string ReadFile(const std::string& path, std::string* err) = 0; + + /// Remove the file named @a path. It behaves like 'rm -f path' so no errors + /// are reported if it does not exists. + /// @returns 0 if the file has been removed, + /// 1 if the file does not exist, and + /// -1 if an error occurs. + virtual int RemoveFile(const std::string& path) = 0; + + /// Create all the parent directories for path; like mkdir -p + /// `basename path`. + bool MakeDirs(const std::string& path); +}; + +#endif // NINJA_DISK_INTERFACE_H_ diff --git a/src/ninja.h b/src/ninja.h index 8102bb7..1e797b6 100644 --- a/src/ninja.h +++ b/src/ninja.h @@ -23,6 +23,7 @@ #include <string> #include <vector> +#include "disk_interface.h" #include "eval_env.h" #include "stat_cache.h" @@ -33,32 +34,6 @@ struct FileStat; struct Node; struct Rule; -/// Interface for accessing the disk. -/// -/// Abstract so it can be mocked out for tests. The real implementation -/// is RealDiskInterface. -struct DiskInterface { - virtual ~DiskInterface() {} - - /// stat() a file, returning the mtime, or 0 if missing and -1 on - /// other errors. - virtual int Stat(const string& path) = 0; - /// Create a directory, returning false on failure. - virtual bool MakeDir(const string& path) = 0; - /// Read a file to a string. Fill in |err| on error. - virtual string ReadFile(const string& path, string* err) = 0; - /// Remove the file named @a path. It behaves like 'rm -f path' so no errors - /// are reported if it does not exists. - /// @returns 0 if the file has been removed, - /// 1 if the file does not exist, and - /// -1 if an error occurs. - virtual int RemoveFile(const string& path) = 0; - - /// Create all the parent directories for path; like mkdir -p - /// `basename path`. - bool MakeDirs(const string& path); -}; - /// Implementation of DiskInterface that actually hits the disk. struct RealDiskInterface : public DiskInterface { virtual ~RealDiskInterface() {} diff --git a/src/ninja_jumble.cc b/src/ninja_jumble.cc index c4399d1..f3b726a 100644 --- a/src/ninja_jumble.cc +++ b/src/ninja_jumble.cc @@ -41,39 +41,6 @@ int RealDiskInterface::Stat(const string& path) { return true; } -string DirName(const string& path) { - -#ifdef WIN32 - const char kPathSeparator = '\\'; -#else - const char kPathSeparator = '/'; -#endif - - string::size_type slash_pos = path.rfind(kPathSeparator); - if (slash_pos == string::npos) - return ""; // Nothing to do. - while (slash_pos > 0 && path[slash_pos - 1] == kPathSeparator) - --slash_pos; - return path.substr(0, slash_pos); -} - -bool DiskInterface::MakeDirs(const string& path) { - string dir = DirName(path); - if (dir.empty()) - return true; // Reached root; assume it's there. - int mtime = Stat(dir); - if (mtime < 0) - return false; // Error. - if (mtime > 0) - return true; // Exists already; we're done. - - // Directory doesn't exist. Try creating its parent first. - bool success = MakeDirs(dir); - if (!success) - return false; - return MakeDir(dir); -} - string RealDiskInterface::ReadFile(const string& path, string* err) { string contents; int ret = ::ReadFile(path, &contents, err); |