diff --git a/bin/test/data/FilePathTestSuite/test/c.h b/bin/test/data/FilePathTestSuite/test/c.h new file mode 100644 index 00000000..e69de29b diff --git a/src/app/qt/element/QtCodeArea.cpp b/src/app/qt/element/QtCodeArea.cpp index 1495f060..b3f2e967 100644 --- a/src/app/qt/element/QtCodeArea.cpp +++ b/src/app/qt/element/QtCodeArea.cpp @@ -247,7 +247,7 @@ void QtCodeArea::mouseDoubleClickEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { - MessageShowFile(m_fileWidget->getFilePath().absoluteStr(), m_startLineNumber, m_startLineNumber + blockCount() - 1).dispatch(); + MessageShowFile(m_fileWidget->getFilePath().str(), m_startLineNumber, m_startLineNumber + blockCount() - 1).dispatch(); } } diff --git a/src/app/qt/element/QtCodeFile.cpp b/src/app/qt/element/QtCodeFile.cpp index c4bd80fc..0a8331c1 100644 --- a/src/app/qt/element/QtCodeFile.cpp +++ b/src/app/qt/element/QtCodeFile.cpp @@ -270,7 +270,7 @@ void QtCodeFile::clickedMaximizeButton() } else { - MessageShowFile(m_filePath.absoluteStr(), 0, 0).dispatch(); + MessageShowFile(m_filePath.str(), 0, 0).dispatch(); } m_minimizeButton->setEnabled(true); diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index ecc14ad2..55d2c3e0 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -213,8 +213,6 @@ add_files( settings/ApplicationSettings.h settings/ColorScheme.cpp settings/ColorScheme.h - settings/CommonSettings.cpp - settings/CommonSettings.h settings/ProjectSettings.cpp settings/ProjectSettings.h settings/Settings.cpp diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 59b1e831..d0d4a2fa 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -63,7 +63,7 @@ void Project::clearProjectSettings() bool Project::setSourceDirectoryPath(const std::string& sourceDirectoryPath) { m_projectSettingsFilepath = sourceDirectoryPath + "/ProjectSettings.xml"; - bool success = ProjectSettings::getInstance()->setSourcePaths(std::vector(1, sourceDirectoryPath)); + bool success = ProjectSettings::getInstance()->setSourcePaths(std::vector(1, sourceDirectoryPath)); if (success) { @@ -131,8 +131,8 @@ void Project::createFileManager() { std::shared_ptr projSettings = ProjectSettings::getInstance(); - std::vector sourcePaths(projSettings->getSourcePaths()); - std::vector includePaths(sourcePaths); + std::vector sourcePaths(projSettings->getSourcePaths()); + std::vector includePaths(sourcePaths); std::vector sourceExtensions = projSettings->getSourceExtensions(); std::vector includeExtensions = projSettings->getHeaderExtensions(); diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index ac06c94b..c59c2896 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -178,8 +178,7 @@ void Storage::onError(const ParseLocation& location, const std::string& message) } bool duplicate = false; - std::string filePath = location.filePath; - TokenLocationFile* file = m_errorLocationCollection.findTokenLocationFileByPath(filePath); + TokenLocationFile* file = m_errorLocationCollection.findTokenLocationFileByPath(location.filePath); if (file) { @@ -202,7 +201,7 @@ void Storage::onError(const ParseLocation& location, const std::string& message) Id errorId = m_errorMessages.size(); m_errorLocationCollection.addTokenLocation( - errorId, filePath, + errorId, location.filePath, location.startLineNumber, location.startColumnNumber, location.endLineNumber, location.endColumnNumber ); @@ -1480,7 +1479,7 @@ void Storage::removeNodeIfUnreferenced(Node* node) void Storage::log(std::string type, std::string str, const ParseLocation& location) const { LOG_INFO_STREAM( - << type << ": " << str << " <" << location.filePath << " " + << type << ": " << str << " <" << location.filePath.str() << " " << location.startLineNumber << ":" << location.startColumnNumber << " " << location.endLineNumber << ":" << location.endColumnNumber << ">" ); diff --git a/src/lib/data/parser/ParseLocation.cpp b/src/lib/data/parser/ParseLocation.cpp index 453a6652..5905a5d1 100644 --- a/src/lib/data/parser/ParseLocation.cpp +++ b/src/lib/data/parser/ParseLocation.cpp @@ -20,6 +20,10 @@ ParseLocation::ParseLocation( , endLineNumber(lineNumber) , endColumnNumber(columnNumber) { + if (this->filePath.exists()) + { + this->filePath = this->filePath.canonical(); + } } ParseLocation::ParseLocation( @@ -33,9 +37,13 @@ ParseLocation::ParseLocation( , endLineNumber(endLineNumber) , endColumnNumber(endColumnNumber) { + if (this->filePath.exists()) + { + this->filePath = this->filePath.canonical(); + } } bool ParseLocation::isValid() const { - return filePath.size() > 0; + return !filePath.empty(); } diff --git a/src/lib/data/parser/ParseLocation.h b/src/lib/data/parser/ParseLocation.h index a97e6234..14ab6633 100644 --- a/src/lib/data/parser/ParseLocation.h +++ b/src/lib/data/parser/ParseLocation.h @@ -3,6 +3,7 @@ #include +#include "utility/file/FilePath.h" #include "utility/types.h" struct ParseLocation @@ -21,7 +22,7 @@ struct ParseLocation bool isValid() const; - std::string filePath; + FilePath filePath; uint startLineNumber; uint startColumnNumber; uint endLineNumber; diff --git a/src/lib/data/parser/Parser.h b/src/lib/data/parser/Parser.h index ff34659e..5de9de89 100644 --- a/src/lib/data/parser/Parser.h +++ b/src/lib/data/parser/Parser.h @@ -5,7 +5,8 @@ #include #include -class FilePath; +#include "utility/file/FilePath.h" + class ParserClient; class TextAccess; @@ -16,9 +17,9 @@ public: { Arguments(); - std::vector headerSearchPaths; - std::vector systemHeaderSearchPaths; - std::vector frameworkSearchPaths; + std::vector headerSearchPaths; + std::vector systemHeaderSearchPaths; + std::vector frameworkSearchPaths; std::vector compilerFlags; bool logErrors; }; diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index daf56d74..1a7cb5b2 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -354,7 +354,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration) getParseLocationForNamedDecl(*it), specializedRecordNameHierarchy, specializedRecordType, specializationParentNameHierarchy ); - std::string specializationFilePath = getParseLocationForNamedDecl(specializationDecl).filePath; + std::string specializationFilePath = getParseLocationForNamedDecl(specializationDecl).filePath.str(); const clang::TemplateArgumentList &argList = specializationDecl->getTemplateArgs(); for (size_t i = 0; i < argList.size(); i++) @@ -484,7 +484,7 @@ bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declarat { const clang::QualType argumentType = argument.getAsType(); m_client->onTemplateArgumentTypeParsed( - ParseLocation(specializedFunctionLocation.filePath, 0, 0), // TODO: Find a valid ParseLocation here! + ParseLocation(specializedFunctionLocation.filePath.str(), 0, 0), // TODO: Find a valid ParseLocation here! utility::qualTypeToDataType(argumentType)->getTypeNameHierarchy(), specializedFunction.nameHierarchy); } diff --git a/src/lib/data/parser/cxx/CxxParser.cpp b/src/lib/data/parser/cxx/CxxParser.cpp index e01ce68d..134c93b2 100644 --- a/src/lib/data/parser/cxx/CxxParser.cpp +++ b/src/lib/data/parser/cxx/CxxParser.cpp @@ -68,7 +68,7 @@ void CxxParser::parseFiles(const std::vector& filePaths, const Argumen std::vector sourcePaths; for (const FilePath& path : m_fileRegister->getUnparsedSourceFilePaths()) { - sourcePaths.push_back(path.absoluteStr()); + sourcePaths.push_back(path.absolute().str()); } runTool(sourcePaths); @@ -114,19 +114,19 @@ std::vector CxxParser::getCommandlineArguments(const Arguments& arg args.insert(args.begin(), arguments.compilerFlags.begin(), arguments.compilerFlags.end()); - for (const std::string& path : arguments.headerSearchPaths) + for (const FilePath& path : arguments.headerSearchPaths) { - args.push_back("-I" + path); + args.push_back("-I" + path.str()); } - for (const std::string& path : arguments.systemHeaderSearchPaths) + for (const FilePath& path : arguments.systemHeaderSearchPaths) { - args.push_back("-isystem" + path); + args.push_back("-isystem" + path.str()); } - for (const std::string& path : arguments.frameworkSearchPaths) + for (const FilePath& path : arguments.frameworkSearchPaths) { - args.push_back("-iframework" + path); + args.push_back("-iframework" + path.str()); } return args; diff --git a/src/lib/data/parser/cxx/TaskParseCxx.cpp b/src/lib/data/parser/cxx/TaskParseCxx.cpp index 2aad74ea..87eaf356 100644 --- a/src/lib/data/parser/cxx/TaskParseCxx.cpp +++ b/src/lib/data/parser/cxx/TaskParseCxx.cpp @@ -28,7 +28,7 @@ void TaskParseCxx::enter() for (const FilePath& path : m_parser.getFileRegister()->getUnparsedSourceFilePaths()) { - m_sourcePaths.push(path.absoluteStr()); + m_sourcePaths.push(path.absolute().str()); } } diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp index d3f848e5..bf83e48f 100644 --- a/src/lib/settings/ApplicationSettings.cpp +++ b/src/lib/settings/ApplicationSettings.cpp @@ -21,6 +21,22 @@ std::string ApplicationSettings::getStartupProjectFilePath() const return getValue("StartupProject", ""); } +std::vector ApplicationSettings::getHeaderSearchPaths() const +{ + return getPathValues("source/HeaderSearchPaths/HeaderSearchPath"); +} + +std::vector ApplicationSettings::getFrameworkSearchPaths() const +{ + return getPathValues("source/FrameworkSearchPaths/FrameworkSearchPath"); +} + +std::vector ApplicationSettings::getCompilerFlags() const +{ + std::vector defaultValues; + return getValues("source/CompilerFlags/CompilerFlag", defaultValues); +} + std::string ApplicationSettings::getFontName() const { return getValue("application/font_name", "Source Code Pro"); diff --git a/src/lib/settings/ApplicationSettings.h b/src/lib/settings/ApplicationSettings.h index 4f029490..29827381 100644 --- a/src/lib/settings/ApplicationSettings.h +++ b/src/lib/settings/ApplicationSettings.h @@ -3,10 +3,10 @@ #include -#include "settings/CommonSettings.h" +#include "settings/Settings.h" class ApplicationSettings - : public CommonSettings + : public Settings { public: static std::shared_ptr getInstance(); @@ -14,6 +14,11 @@ public: std::string getStartupProjectFilePath() const; + // source + std::vector getHeaderSearchPaths() const; + std::vector getFrameworkSearchPaths() const; + std::vector getCompilerFlags() const; + // application std::string getFontName() const; void setFontName(const std::string& fontName); diff --git a/src/lib/settings/CommonSettings.cpp b/src/lib/settings/CommonSettings.cpp deleted file mode 100644 index 141484fd..00000000 --- a/src/lib/settings/CommonSettings.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "settings/CommonSettings.h" - -CommonSettings::~CommonSettings() -{ -} - -std::vector CommonSettings::getHeaderSearchPaths() const -{ - std::vector defaultValues; - return getValues("source/HeaderSearchPaths/HeaderSearchPath", defaultValues); -} - -std::vector CommonSettings::getFrameworkSearchPaths() const -{ - std::vector defaultValues; - return getValues("source/FrameworkSearchPaths/FrameworkSearchPath", defaultValues); -} - -std::vector CommonSettings::getCompilerFlags() const -{ - std::vector defaultValues; - return getValues("source/CompilerFlags/CompilerFlag", defaultValues); -} - -CommonSettings::CommonSettings() -{ -} diff --git a/src/lib/settings/CommonSettings.h b/src/lib/settings/CommonSettings.h deleted file mode 100644 index e57c8c3d..00000000 --- a/src/lib/settings/CommonSettings.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef COMMON_SETTINGS_H -#define COMMON_SETTINGS_H - -#include "settings/Settings.h" - -class CommonSettings - : public Settings -{ -public: - virtual ~CommonSettings(); - - // source - std::vector getHeaderSearchPaths() const; - std::vector getFrameworkSearchPaths() const; - std::vector getCompilerFlags() const; - -protected: - CommonSettings(); -}; - -#endif // COMMON_SETTINGS_H diff --git a/src/lib/settings/ProjectSettings.cpp b/src/lib/settings/ProjectSettings.cpp index cd498263..221f4585 100644 --- a/src/lib/settings/ProjectSettings.cpp +++ b/src/lib/settings/ProjectSettings.cpp @@ -20,15 +20,49 @@ ProjectSettings::~ProjectSettings() { } -std::vector ProjectSettings::getSourcePaths() const +void ProjectSettings::save(const FilePath& filePath) { - std::vector defaultValues; - return getValues("source/SourcePaths/SourcePath", defaultValues); + moveRelativePathValues("source/SourcePaths/SourcePath", filePath); + moveRelativePathValues("source/HeaderSearchPaths/HeaderSearchPath", filePath); + moveRelativePathValues("source/FrameworkSearchPaths/FrameworkSearchPath", filePath); + + Settings::save(filePath); } -bool ProjectSettings::setSourcePaths(const std::vector& sourcePaths) +std::vector ProjectSettings::getSourcePaths() const { - return setValues("source/SourcePaths/SourcePath", sourcePaths); + return getRelativePathValues("source/SourcePaths/SourcePath"); +} + +bool ProjectSettings::setSourcePaths(const std::vector& sourcePaths) +{ + return setPathValues("source/SourcePaths/SourcePath", sourcePaths); +} + +std::vector ProjectSettings::getHeaderSearchPaths() const +{ + return getRelativePathValues("source/HeaderSearchPaths/HeaderSearchPath"); +} + +bool ProjectSettings::setHeaderSearchPaths(const std::vector& headerSearchPaths) +{ + return setPathValues("source/HeaderSearchPaths/HeaderSearchPath", headerSearchPaths); +} + +std::vector ProjectSettings::getFrameworkSearchPaths() const +{ + return getRelativePathValues("source/FrameworkSearchPaths/FrameworkSearchPath"); +} + +bool ProjectSettings::setFrameworkSearchPaths(const std::vector& frameworkSearchPaths) +{ + return setPathValues("source/FrameworkSearchPaths/FrameworkSearchPath", frameworkSearchPaths); +} + +std::vector ProjectSettings::getCompilerFlags() const +{ + std::vector defaultValues; + return getValues("source/CompilerFlags/CompilerFlag", defaultValues); } std::vector ProjectSettings::getHeaderExtensions() const diff --git a/src/lib/settings/ProjectSettings.h b/src/lib/settings/ProjectSettings.h index f392bb5a..4d8b0bff 100644 --- a/src/lib/settings/ProjectSettings.h +++ b/src/lib/settings/ProjectSettings.h @@ -4,18 +4,28 @@ #include #include -#include "settings/CommonSettings.h" +#include "settings/Settings.h" class ProjectSettings - : public CommonSettings + : public Settings { public: static std::shared_ptr getInstance(); ~ProjectSettings(); + virtual void save(const FilePath& filePath); + // source - std::vector getSourcePaths() const; - bool setSourcePaths(const std::vector& sourcePaths); + std::vector getSourcePaths() const; + bool setSourcePaths(const std::vector& sourcePaths); + + std::vector getHeaderSearchPaths() const; + bool setHeaderSearchPaths(const std::vector& headerSearchPaths); + + std::vector getFrameworkSearchPaths() const; + bool setFrameworkSearchPaths(const std::vector& frameworkSearchPaths); + + std::vector getCompilerFlags() const; // extensions std::vector getHeaderExtensions() const; diff --git a/src/lib/settings/Settings.cpp b/src/lib/settings/Settings.cpp index a83406e6..833b99ec 100644 --- a/src/lib/settings/Settings.cpp +++ b/src/lib/settings/Settings.cpp @@ -9,11 +9,11 @@ Settings::~Settings() { } -bool Settings::load(const std::string& filePath) +bool Settings::load(const FilePath& filePath) { - if (FileSystem::exists(filePath)) + if (filePath.exists()) { - m_config = ConfigManager::createAndLoad(TextAccess::createFromFile(filePath)); + m_config = ConfigManager::createAndLoad(TextAccess::createFromFile(filePath.str())); m_filePath = filePath; return true; } @@ -27,9 +27,9 @@ bool Settings::load(const std::string& filePath) void Settings::save() { - if (m_config.get() && m_filePath.size()) + if (m_config.get() && m_filePath.exists()) { - m_config->save(m_filePath); + m_config->save(m_filePath.str()); } else { @@ -37,11 +37,13 @@ void Settings::save() } } -void Settings::save(const std::string& filePath) +void Settings::save(const FilePath& filePath) { + setFilePath(filePath); + if (m_config) { - m_config->save(filePath); + m_config->save(filePath.str()); } else { @@ -52,10 +54,85 @@ void Settings::save(const std::string& filePath) void Settings::clear() { m_config = ConfigManager::createEmpty(); - m_filePath.clear(); + m_filePath = FilePath(); } Settings::Settings() { clear(); } + +const FilePath& Settings::getFilePath() const +{ + return m_filePath; +} + +void Settings::setFilePath(const FilePath& filePath) +{ + m_filePath = filePath; +} + +std::vector Settings::getPathValues(const std::string& key) const +{ + std::vector values; + values = getValues(key, values); + + std::vector paths; + for (const std::string& path : values) + { + paths.push_back(FilePath(path)); + } + return paths; +} + +std::vector Settings::getRelativePathValues(const std::string& key) const +{ + std::vector values; + values = getValues(key, values); + + std::vector paths; + for (const std::string& path : values) + { + FilePath filePath(path); + if (!filePath.isAbsolute()) + { + filePath = m_filePath.parentDirectory().concat(filePath); + } + + paths.push_back(filePath.canonical()); + } + return paths; +} + +bool Settings::setPathValues(const std::string& key, const std::vector& paths) +{ + std::vector values; + for (const FilePath& path : paths) + { + values.push_back(path.str()); + } + + return setValues(key, values); +} + +bool Settings::moveRelativePathValues(const std::string& key, const FilePath& filePath) +{ + std::vector values; + values = getValues(key, values); + + FilePath oldPath = m_filePath.absolute(); + FilePath newPath = filePath.absolute(); + + for (size_t i = 0; i < values.size(); i++) + { + FilePath path(values[i]); + if (!path.isAbsolute()) + { + path = oldPath.parentDirectory().concat(path); + path = path.canonical().relativeTo(newPath); + values[i] = path.str(); + } + } + + return setValues(key, values); +} diff --git a/src/lib/settings/Settings.h b/src/lib/settings/Settings.h index 25844ae7..e0d42974 100644 --- a/src/lib/settings/Settings.h +++ b/src/lib/settings/Settings.h @@ -6,34 +6,44 @@ #include #include "utility/ConfigManager.h" +#include "utility/file/FilePath.h" class Settings { public: virtual ~Settings(); - bool load(const std::string& filePath); + bool load(const FilePath& filePath); void save(); - void save(const std::string& filePath); + virtual void save(const FilePath& filePath); void clear(); protected: Settings(); + const FilePath& getFilePath() const; + void setFilePath(const FilePath& filePath); + template T getValue(const std::string& key, T defaultValue) const; template std::vector getValues(const std::string& key, std::vector defaultValues) const; + std::vector getPathValues(const std::string& key) const; + std::vector getRelativePathValues(const std::string& key) const; + template bool setValue(const std::string& key, T value); template bool setValues(const std::string& key, std::vector values); + bool setPathValues(const std::string& key, const std::vector& paths); + bool moveRelativePathValues(const std::string& key, const FilePath& filePath); + private: - std::string m_filePath; + FilePath m_filePath; std::shared_ptr m_config; }; diff --git a/src/lib/utility/file/FileManager.cpp b/src/lib/utility/file/FileManager.cpp index 0f4e8c87..163c36ae 100644 --- a/src/lib/utility/file/FileManager.cpp +++ b/src/lib/utility/file/FileManager.cpp @@ -6,8 +6,8 @@ #include "utility/file/FileSystem.h" FileManager::FileManager( - std::vector sourcePaths, - std::vector includePaths, + std::vector sourcePaths, + std::vector includePaths, std::vector sourceExtensions, std::vector includeExtensions ) @@ -22,12 +22,12 @@ FileManager::~FileManager() { } -const std::vector& FileManager::getSourcePaths() const +const std::vector& FileManager::getSourcePaths() const { return m_sourcePaths; } -const std::vector& FileManager::getIncludePaths() const +const std::vector& FileManager::getIncludePaths() const { return m_includePaths; } @@ -51,14 +51,14 @@ void FileManager::fetchFilePaths() m_removedFiles.insert(it->first); } - std::vector, std::vector>> pathsExtensionsPairs; + std::vector, std::vector>> pathsExtensionsPairs; pathsExtensionsPairs.push_back(std::make_pair(m_includePaths, m_includeExtensions)); pathsExtensionsPairs.push_back(std::make_pair(m_sourcePaths, m_sourceExtensions)); for (size_t i = 0; i < pathsExtensionsPairs.size(); i++) { std::vector fileInfos = - FileSystem::getFileInfosFromDirectoryPaths(pathsExtensionsPairs[i].first, pathsExtensionsPairs[i].second); + FileSystem::getFileInfosFromPaths(pathsExtensionsPairs[i].first, pathsExtensionsPairs[i].second); for (FileInfo fileInfo: fileInfos) { diff --git a/src/lib/utility/file/FileManager.h b/src/lib/utility/file/FileManager.h index 8aac62b5..5788404b 100644 --- a/src/lib/utility/file/FileManager.h +++ b/src/lib/utility/file/FileManager.h @@ -11,15 +11,15 @@ class FileManager { public: FileManager( - std::vector sourcePaths, - std::vector includePaths, + std::vector sourcePaths, + std::vector includePaths, std::vector sourceExtensions, std::vector includeExtensions ); ~FileManager(); - const std::vector& getSourcePaths() const; - const std::vector& getIncludePaths() const; + const std::vector& getSourcePaths() const; + const std::vector& getIncludePaths() const; void reset(); void fetchFilePaths(); @@ -33,8 +33,8 @@ public: virtual bool hasIncludeExtension(const FilePath& filePath) const; private: - std::vector m_sourcePaths; - std::vector m_includePaths; + std::vector m_sourcePaths; + std::vector m_includePaths; std::vector m_sourceExtensions; std::vector m_includeExtensions; diff --git a/src/lib/utility/file/FilePath.cpp b/src/lib/utility/file/FilePath.cpp index 324fcf72..23230a3b 100644 --- a/src/lib/utility/file/FilePath.cpp +++ b/src/lib/utility/file/FilePath.cpp @@ -1,5 +1,10 @@ #include "utility/file/FilePath.h" +FilePath::FilePath() + : m_exists(false) +{ +} + FilePath::FilePath(const char* filePath) : m_path(filePath) , m_exists(false) @@ -21,21 +26,100 @@ FilePath::FilePath(const boost::filesystem::path& filePath) init(); } +boost::filesystem::path FilePath::path() const +{ + return m_path; +} + +bool FilePath::empty() const +{ + return m_path.empty(); +} + bool FilePath::exists() const { return m_exists; } +bool FilePath::isDirectory() const +{ + return boost::filesystem::is_directory(m_path); +} + +bool FilePath::isAbsolute() const +{ + return m_path.is_absolute(); +} + +FilePath FilePath::parentDirectory() const +{ + return m_path.parent_path(); +} + +FilePath FilePath::absolute() const +{ + return boost::filesystem::absolute(m_path); +} + +FilePath FilePath::canonical() const +{ + if (m_exists) + { + return boost::filesystem::canonical(m_path); + } + + return FilePath(m_path); +} + +FilePath FilePath::relativeTo(const FilePath& other) const +{ + boost::filesystem::path a = m_path; + boost::filesystem::path b = other.m_path; + + if (a.root_path() != b.root_path()) + { + return str(); + } + + boost::filesystem::path::const_iterator itA = a.begin(); + boost::filesystem::path::const_iterator itB = b.begin(); + + while (*itA == *itB && itA != a.end() && itB != b.end()) + { + itA++; + itB++; + } + + boost::filesystem::path r; + + if (itB != b.end()) + { + itB++; + + for (; itB != b.end(); itB++) + { + r /= ".."; + } + } + + for (; itA != a.end(); itA++) + { + r /= *itA; + } + + return r; +} + +FilePath FilePath::concat(const FilePath& other) const +{ + return boost::filesystem::path(m_path) / other.m_path; +} + std::string FilePath::str() const { return m_path.generic_string(); } -std::string FilePath::absoluteStr() const -{ - return boost::filesystem::absolute(m_path).generic_string(); -} - std::string FilePath::fileName() const { return m_path.filename().generic_string(); @@ -89,6 +173,5 @@ void FilePath::init() if (boost::filesystem::exists(m_path)) { m_exists = true; - m_path = boost::filesystem::canonical(m_path); } } diff --git a/src/lib/utility/file/FilePath.h b/src/lib/utility/file/FilePath.h index deea1388..5c0e8c06 100644 --- a/src/lib/utility/file/FilePath.h +++ b/src/lib/utility/file/FilePath.h @@ -8,14 +8,26 @@ class FilePath { public: + FilePath(); FilePath(const char* filePath); FilePath(const std::string& filePath); FilePath(const boost::filesystem::path& filePath); + boost::filesystem::path path() const; + + bool empty() const; bool exists() const; + bool isDirectory() const; + bool isAbsolute() const; + + FilePath parentDirectory() const; + + FilePath absolute() const; + FilePath canonical() const; + FilePath relativeTo(const FilePath& other) const; + FilePath concat(const FilePath& other) const; std::string str() const; - std::string absoluteStr() const; std::string fileName() const; std::string extension() const; diff --git a/src/lib/utility/file/FileSystem.cpp b/src/lib/utility/file/FileSystem.cpp index 3d190e8c..78221b09 100644 --- a/src/lib/utility/file/FileSystem.cpp +++ b/src/lib/utility/file/FileSystem.cpp @@ -5,8 +5,7 @@ std::vector FileSystem::getFileNamesFromDirectory( const std::string& path, const std::vector& extensions -) -{ +){ std::vector files; if (boost::filesystem::is_directory(path)) @@ -53,16 +52,15 @@ std::vector FileSystem::getFileNamesFromDirectoryUpdatedAfter( return files; } -std::vector FileSystem::getFileInfosFromDirectoryPaths( - const std::vector& directoryPaths, const std::vector& fileExtensions) -{ +std::vector FileSystem::getFileInfosFromPaths( + const std::vector& paths, const std::vector& fileExtensions +){ std::vector files; - for (const std::string& directoryPath: directoryPaths) + for (const FilePath& path: paths) { - boost::filesystem::path path(directoryPath); - if (boost::filesystem::is_directory(path)) + if (path.isDirectory()) { - boost::filesystem::recursive_directory_iterator it(path); + boost::filesystem::recursive_directory_iterator it(path.path()); boost::filesystem::recursive_directory_iterator endit; while (it != endit) { @@ -75,9 +73,9 @@ std::vector FileSystem::getFileInfosFromDirectoryPaths( ++it; } } - else if (boost::filesystem::exists(path) && hasExtension(path.string(), fileExtensions)) + else if (path.exists() && path.hasExtension(fileExtensions)) { - std::time_t t = boost::filesystem::last_write_time(path); + std::time_t t = boost::filesystem::last_write_time(path.path()); boost::posix_time::ptime lastWriteTime = boost::posix_time::from_time_t(t); files.push_back(FileInfo(path, lastWriteTime)); } diff --git a/src/lib/utility/file/FileSystem.h b/src/lib/utility/file/FileSystem.h index ca8ea268..3db76234 100644 --- a/src/lib/utility/file/FileSystem.h +++ b/src/lib/utility/file/FileSystem.h @@ -14,8 +14,8 @@ public: static std::vector getFileNamesFromDirectoryUpdatedAfter( const std::string& path, const std::vector& extensions, const std::string& timeString); - static std::vector getFileInfosFromDirectoryPaths( - const std::vector& directoryPaths, const std::vector& fileExtensions); + static std::vector getFileInfosFromPaths( + const std::vector& paths, const std::vector& fileExtensions); static std::string getTimeStringNow(); diff --git a/src/test/FileManagerTestSuite.h b/src/test/FileManagerTestSuite.h index e763f3d4..5c838123 100644 --- a/src/test/FileManagerTestSuite.h +++ b/src/test/FileManagerTestSuite.h @@ -7,9 +7,9 @@ class FileManagerTestSuite : public CxxTest::TestSuite public: void test_file_manager_is_created_empty() { - std::vector sourcePaths; + std::vector sourcePaths; sourcePaths.push_back("./data/FileManagerTestSuite/src/"); - std::vector includePaths; + std::vector includePaths; includePaths.push_back("./data/FileManagerTestSuite/include/"); std::vector sourceExtensions; sourceExtensions.push_back(".cpp"); @@ -27,9 +27,9 @@ public: void test_file_manager_has_added_file_paths_after_first_fetch() { - std::vector sourcePaths; + std::vector sourcePaths; sourcePaths.push_back("./data/FileManagerTestSuite/src/"); - std::vector includePaths; + std::vector includePaths; includePaths.push_back("./data/FileManagerTestSuite/include/"); std::vector sourceExtensions; sourceExtensions.push_back(".cpp"); @@ -46,9 +46,9 @@ public: void test_file_manager_has_no_added_file_paths_after_second_fetch() { - std::vector sourcePaths; + std::vector sourcePaths; sourcePaths.push_back("./data/FileManagerTestSuite/src/"); - std::vector includePaths; + std::vector includePaths; includePaths.push_back("./data/FileManagerTestSuite/include/"); std::vector sourceExtensions; sourceExtensions.push_back(".cpp"); @@ -66,9 +66,9 @@ public: void test_file_manager_has_updated_file_paths_after_second_fetch() { - std::vector sourcePaths; + std::vector sourcePaths; sourcePaths.push_back("./data/FileManagerTestSuite/src/"); - std::vector includePaths; + std::vector includePaths; includePaths.push_back("./data/FileManagerTestSuite/include/"); std::vector sourceExtensions; sourceExtensions.push_back(".cpp"); diff --git a/src/test/FilePathTestSuite.h b/src/test/FilePathTestSuite.h index fc91f49c..85b27dbc 100644 --- a/src/test/FilePathTestSuite.h +++ b/src/test/FilePathTestSuite.h @@ -5,6 +5,13 @@ class FilePathTestSuite : public CxxTest::TestSuite { public: + void test_file_path_gets_created_empty() + { + FilePath path; + + TS_ASSERT_EQUALS(path.str(), ""); + } + void test_file_path_gets_created_with_char_array() { FilePath path("data/FilePathTestSuite/main.cpp"); @@ -28,6 +35,15 @@ public: TS_ASSERT_EQUALS(path, path2); } + void test_file_path_empty() + { + FilePath path1("data/FilePathTestSuite/a.cpp"); + FilePath path2; + + TS_ASSERT(!path1.empty()); + TS_ASSERT(path2.empty()); + } + void test_file_path_exists() { FilePath path("data/FilePathTestSuite/a.cpp"); @@ -42,6 +58,39 @@ public: TS_ASSERT(!path.exists()); } + void test_file_path_is_directory() + { + FilePath path("data/FilePathTestSuite/a.cpp"); + + TS_ASSERT(!path.isDirectory()); + TS_ASSERT(path.parentDirectory().isDirectory()); + } + + void test_file_path_is_absolute() + { + FilePath path("data/FilePathTestSuite/a.cpp"); + + TS_ASSERT(!path.isAbsolute()); + TS_ASSERT(path.absolute().isAbsolute()); + } + + void test_file_path_parent_directory() + { + FilePath path("data/FilePathTestSuite/a.cpp"); + + TS_ASSERT(path.parentDirectory().str() == "data/FilePathTestSuite"); + TS_ASSERT(path.parentDirectory().parentDirectory().str() == "data"); + } + + void test_file_path_relative_to_other_path() + { + FilePath pathA("data/FilePathTestSuite/a.cpp"); + FilePath pathB("data/FilePathTestSuite/test/c.h"); + + TS_ASSERT_EQUALS(pathA.relativeTo(pathB).str(), "../a.cpp"); + TS_ASSERT_EQUALS(pathB.relativeTo(pathA).str(), "test/c.h"); + } + void test_file_path_file_name() { FilePath path("data/FilePathTestSuite/abc.h"); @@ -86,11 +135,18 @@ public: void test_file_path_equals_relative_and_absolute_paths() { FilePath pathA("data/FilePathTestSuite/a.cpp"); - FilePath pathA2(pathA.absoluteStr()); + FilePath pathA2(pathA.absolute()); TS_ASSERT_EQUALS(pathA, pathA2); } + void test_file_path_equals_absolute_and_canonical_paths() + { + FilePath path("data/../data/FilePathTestSuite/./a.cpp"); + + TS_ASSERT_EQUALS(path.absolute(), path.canonical()); + } + void test_file_path_compares_paths_with_posix_and_windows_format() { #ifdef _WIN32 diff --git a/src/test/FileSystemTestSuite.h b/src/test/FileSystemTestSuite.h index 2b9411dc..d71bb023 100644 --- a/src/test/FileSystemTestSuite.h +++ b/src/test/FileSystemTestSuite.h @@ -78,11 +78,10 @@ public: extensions.push_back(".hpp"); extensions.push_back(".cpp"); - std::vector directoryPaths; + std::vector directoryPaths; directoryPaths.push_back("./data/FileSystemTestSuite"); - std::vector files = - FileSystem::getFileInfosFromDirectoryPaths(directoryPaths, extensions); + std::vector files = FileSystem::getFileInfosFromPaths(directoryPaths, extensions); TS_ASSERT_EQUALS(files.size(), 5); } diff --git a/src/test/SettingsTestSuite.h b/src/test/SettingsTestSuite.h index 031bc9ce..9266d01d 100644 --- a/src/test/SettingsTestSuite.h +++ b/src/test/SettingsTestSuite.h @@ -114,20 +114,20 @@ public: void test_load_source_path_from_file() { ProjectSettings::getInstance()->load("data/SettingsTestSuite/settings.xml"); - std::vector paths = ProjectSettings::getInstance()->getSourcePaths(); + std::vector paths = ProjectSettings::getInstance()->getSourcePaths(); TS_ASSERT_EQUALS(paths.size(), 1); - TS_ASSERT_EQUALS(paths[0], "data"); + TS_ASSERT_EQUALS(paths[0].str(), "data/SettingsTestSuite/data"); } void test_load_header_search_paths_from_file() { ProjectSettings::getInstance()->load("data/SettingsTestSuite/settings.xml"); - std::vector paths = ProjectSettings::getInstance()->getHeaderSearchPaths(); + std::vector paths = ProjectSettings::getInstance()->getHeaderSearchPaths(); TS_ASSERT_EQUALS(paths.size(), 2); - TS_ASSERT_EQUALS(paths[0], "data/"); - TS_ASSERT_EQUALS(paths[1], "src/"); + TS_ASSERT_EQUALS(paths[0].str(), "data/SettingsTestSuite/data/"); + TS_ASSERT_EQUALS(paths[1].str(), "data/SettingsTestSuite/src/"); } private: diff --git a/src/test/helper/TestFileManager.cpp b/src/test/helper/TestFileManager.cpp index 4286c120..f843436f 100644 --- a/src/test/helper/TestFileManager.cpp +++ b/src/test/helper/TestFileManager.cpp @@ -2,8 +2,8 @@ TestFileManager::TestFileManager() : FileManager( - std::vector(), - std::vector(), + std::vector(), + std::vector(), std::vector(), std::vector() )