From 5f253113890126337cd1a19f28caaadb2534d34c Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Wed, 29 Jul 2015 22:20:26 +0200 Subject: [PATCH] logic: paths in ProjectSettings relative to file not working directory This change checks all paths in the ProjectSettings file for relativity and makes them relative to the location of the ProjectSettings file if necessary. The paths are also correctly saved relative to the file. --- bin/test/data/FilePathTestSuite/test/c.h | 0 src/app/qt/element/QtCodeArea.cpp | 2 +- src/app/qt/element/QtCodeFile.cpp | 2 +- src/lib/CMakeLists.txt | 2 - src/lib/Project.cpp | 6 +- src/lib/data/Storage.cpp | 7 +- src/lib/data/parser/ParseLocation.cpp | 10 ++- src/lib/data/parser/ParseLocation.h | 3 +- src/lib/data/parser/Parser.h | 9 ++- src/lib/data/parser/cxx/ASTVisitor.cpp | 4 +- src/lib/data/parser/cxx/CxxParser.cpp | 14 ++-- src/lib/data/parser/cxx/TaskParseCxx.cpp | 2 +- src/lib/settings/ApplicationSettings.cpp | 16 ++++ src/lib/settings/ApplicationSettings.h | 9 ++- src/lib/settings/CommonSettings.cpp | 27 ------- src/lib/settings/CommonSettings.h | 21 ------ src/lib/settings/ProjectSettings.cpp | 44 +++++++++-- src/lib/settings/ProjectSettings.h | 18 ++++- src/lib/settings/Settings.cpp | 93 +++++++++++++++++++++-- src/lib/settings/Settings.h | 16 +++- src/lib/utility/file/FileManager.cpp | 12 +-- src/lib/utility/file/FileManager.h | 12 +-- src/lib/utility/file/FilePath.cpp | 95 ++++++++++++++++++++++-- src/lib/utility/file/FilePath.h | 14 +++- src/lib/utility/file/FileSystem.cpp | 20 +++-- src/lib/utility/file/FileSystem.h | 4 +- src/test/FileManagerTestSuite.h | 16 ++-- src/test/FilePathTestSuite.h | 58 ++++++++++++++- src/test/FileSystemTestSuite.h | 5 +- src/test/SettingsTestSuite.h | 10 +-- src/test/helper/TestFileManager.cpp | 4 +- 31 files changed, 407 insertions(+), 148 deletions(-) create mode 100644 bin/test/data/FilePathTestSuite/test/c.h delete mode 100644 src/lib/settings/CommonSettings.cpp delete mode 100644 src/lib/settings/CommonSettings.h 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() )