FileFinder.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
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             // Getting here is impossible
00093             NEVER_REACHED;
00094             break;
00095     }
00096 
00097     if (msFaking && msFakeWhat == relativeTo)
00098     {
00099         // Fake the resulting path
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         // If it doesn't exist, it isn't a file
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         // If it doesn't exist, it isn't a directory
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 }
Generated on Thu Dec 22 13:00:05 2011 for Chaste by  doxygen 1.6.3