From f8f63a4a6a88b96b3d7c71c50881c8658d8b4fe4 Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Wed, 10 Aug 2011 09:47:32 -0300 Subject: Factor out DiskInterface class into its own source/header files. This is a TODO in src/ninja_jumble.cc Signed-off-by: Thiago Farina --- configure.py | 2 +- src/disk_interface.cc | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/disk_interface.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ninja.h | 27 +-------------------------- src/ninja_jumble.cc | 33 --------------------------------- 5 files changed, 102 insertions(+), 60 deletions(-) create mode 100644 src/disk_interface.cc create mode 100644 src/disk_interface.h diff --git a/configure.py b/configure.py index 24d7374..7c79e2b 100755 --- a/configure.py +++ b/configure.py @@ -132,7 +132,7 @@ if platform not in ('mingw'): n.comment('Core source files all build into ninja library.') for name in ['build', 'build_log', 'clean', 'eval_env', 'graph', 'graphviz', 'parsers', 'util', 'stat_cache', - 'ninja_jumble']: + 'ninja_jumble', 'disk_interface']: objs += cxx(name) if platform == 'mingw': objs += cxx('subprocess-win32') 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 + +/// 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 #include +#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); -- cgit v0.12