FileFinder.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "FileFinder.hpp"
00030 #include "ChasteBuildRoot.hpp"
00031 #include "OutputFileHandler.hpp"
00032 #include "Exception.hpp"
00033 #include "GetCurrentWorkingDirectory.hpp"
00034 #include <fstream>
00035 #include <cassert>
00036 #include <sys/stat.h>
00037
00038 bool FileFinder::msFaking = false;
00039
00040 RelativeTo::Value FileFinder::msFakeWhat = RelativeTo::Absolute;
00041
00042 std::string FileFinder::msFakePath = "";
00043
00044
00045 FileFinder::FileFinder()
00046 : mAbsPath("UNSET!")
00047 {
00048 }
00049
00050 FileFinder::FileFinder(const std::string& rRelativePath, RelativeTo::Value relativeTo)
00051 {
00052 SetPath(rRelativePath, relativeTo);
00053 }
00054
00055 FileFinder::FileFinder(const std::string& rLeafName, const FileFinder& rParentOrSibling)
00056 {
00057 SetPath(rLeafName, rParentOrSibling);
00058 }
00059
00060 void FileFinder::SetPath(const std::string& rRelativePath, RelativeTo::Value relativeTo)
00061 {
00062 switch (relativeTo)
00063 {
00064 case RelativeTo::ChasteSourceRoot:
00065 mAbsPath = ChasteBuildRootDir() + rRelativePath;
00066 break;
00067
00068 case RelativeTo::ChasteTestOutput:
00069 mAbsPath = OutputFileHandler::GetChasteTestOutputDirectory() + rRelativePath;
00070 break;
00071
00072 case RelativeTo::CWD:
00073 mAbsPath = GetCurrentWorkingDirectory() + "/" + rRelativePath;
00074 break;
00075
00076 case RelativeTo::Absolute:
00077 mAbsPath = rRelativePath;
00078 break;
00079
00080 case RelativeTo::AbsoluteOrCwd:
00081 if (FileFinder::IsAbsolutePath(rRelativePath))
00082 {
00083 mAbsPath = rRelativePath;
00084 }
00085 else
00086 {
00087 mAbsPath = GetCurrentWorkingDirectory() + "/" + rRelativePath;
00088 }
00089 break;
00090
00091 default:
00092
00093 NEVER_REACHED;
00094 break;
00095 }
00096
00097 if (msFaking && msFakeWhat == relativeTo)
00098 {
00099
00100 mAbsPath = msFakePath + "/" + rRelativePath;
00101 }
00102
00103 if (IsDir())
00104 {
00105 if (*(mAbsPath.end()-1) != '/')
00106 {
00107 mAbsPath = mAbsPath + "/";
00108 }
00109 }
00110 }
00111
00112 void FileFinder::SetPath(const std::string& rLeafName, const FileFinder& rParentOrSibling)
00113 {
00114 if (!rParentOrSibling.Exists())
00115 {
00116 EXCEPTION("Reference path '" << rParentOrSibling.GetAbsolutePath() << "' does not exist.");
00117 }
00118 if (rParentOrSibling.IsDir())
00119 {
00120 SetPath(rParentOrSibling.GetAbsolutePath() + rLeafName, RelativeTo::Absolute);
00121 }
00122 else
00123 {
00124 SetPath(rParentOrSibling.GetParent().GetAbsolutePath() + rLeafName, RelativeTo::Absolute);
00125 }
00126 }
00127
00128 bool FileFinder::Exists() const
00129 {
00130 struct stat our_stats;
00131 int retcode = stat(GetAbsolutePath().c_str(), &our_stats);
00132 return (retcode == 0);
00133 }
00134
00135 bool FileFinder::IsFile() const
00136 {
00137 bool result;
00138 struct stat our_stats;
00139 int retcode = stat(GetAbsolutePath().c_str(), &our_stats);
00140 if (retcode == 0)
00141 {
00142 result = S_ISREG(our_stats.st_mode);
00143 }
00144 else
00145 {
00146
00147 result = false;
00148 }
00149 return result;
00150 }
00151
00152 bool FileFinder::IsDir() const
00153 {
00154 bool result;
00155 struct stat our_stats;
00156 int retcode = stat(GetAbsolutePath().c_str(), &our_stats);
00157 if (retcode == 0)
00158 {
00159 result = S_ISDIR(our_stats.st_mode);
00160 }
00161 else
00162 {
00163
00164 result = false;
00165 }
00166 return result;
00167 }
00168
00169 std::string FileFinder::GetAbsolutePath() const
00170 {
00171 return mAbsPath;
00172 }
00173
00174 bool FileFinder::IsNewerThan(const FileFinder& rOtherEntity) const
00175 {
00176 assert(Exists());
00177 assert(rOtherEntity.Exists());
00178 struct stat our_stats, other_stats;
00179 stat(GetAbsolutePath().c_str(), &our_stats);
00180 stat(rOtherEntity.GetAbsolutePath().c_str(), &other_stats);
00181 return our_stats.st_mtime > other_stats.st_mtime;
00182 }
00183
00184 std::string FileFinder::GetLeafName() const
00185 {
00186 std::string full_name = GetAbsolutePath();
00187 size_t slash = full_name.rfind('/');
00188 EXCEPT_IF_NOT(slash != std::string::npos);
00189 return full_name.substr(slash+1);
00190 }
00191
00192 FileFinder FileFinder::GetParent() const
00193 {
00194 std::string full_name = GetAbsolutePath();
00195 size_t limit = full_name.length() > 1 ? full_name.length() - 2 : std::string::npos;
00196 size_t slash = full_name.rfind('/', limit);
00197 EXCEPT_IF_NOT(slash != std::string::npos);
00198 return FileFinder(full_name.substr(0, slash), RelativeTo::Absolute);
00199 }
00200
00201 bool FileFinder::IsAbsolutePath(const std::string& rPath)
00202 {
00203 return rPath[0]=='/';
00204 }
00205
00206 void FileFinder::FakePath(RelativeTo::Value fakeWhat, const std::string& rFakePath)
00207 {
00208 msFakeWhat = fakeWhat;
00209 msFakePath = rFakePath;
00210 msFaking = true;
00211 }
00212
00213 void FileFinder::StopFaking()
00214 {
00215 msFaking = false;
00216 }