src: Fixed FilePath::canonical() for UNIX

* fixed clang warnings
* fixed ApplicationSettings loaded from wrong location in tests
* added symlink within canonical path to tests
This commit is contained in:
Eberhard Graether
2017-08-10 02:04:03 +02:00
parent ece2cbfe14
commit d9c8de2951
13 changed files with 91 additions and 89 deletions
+1
View File
@@ -0,0 +1 @@
../target
+16 -17
View File
@@ -222,6 +222,22 @@ int main(int argc, char *argv[])
QScopedPointer<QtNetworkFactory> networkFactory; QScopedPointer<QtNetworkFactory> networkFactory;
QScopedPointer<QtViewFactory> viewFactory; QScopedPointer<QtViewFactory> viewFactory;
if (!commandLineParser.runWithoutGUI())
{
qtApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf");
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".ttf");
networkFactory.reset(new QtNetworkFactory());
viewFactory.reset(new QtViewFactory());
}
Application::createInstance(version, viewFactory.data(), networkFactory.data());
ScopedFunctor f([](){
Application::destroyInstance();
});
if (commandLineParser.runWithoutGUI()) if (commandLineParser.runWithoutGUI())
{ {
@@ -235,23 +251,6 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
} }
else
{
qtApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf");
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".ttf");
networkFactory.reset(new QtNetworkFactory());
viewFactory.reset(new QtViewFactory());
}
Application::createInstance(version, viewFactory.data(), networkFactory.data());
ScopedFunctor f([](){
Application::destroyInstance();
});
prefillPaths(); prefillPaths();
addLanguageModules(); addLanguageModules();
+4 -10
View File
@@ -271,17 +271,11 @@ void TaskBuildIndex::updateIndexingDialog(
if (!sourcePath.empty()) if (!sourcePath.empty())
{ {
std::stringstream ss; std::stringstream ss;
ss << "[" << m_indexingFileCount ss << "[" << m_indexingFileCount << "/" << sourceFileCount << "] Indexing file: " << sourcePath.str();
<< "/" << sourceFileCount
<< "] Indexing file: ";
ss << sourcePath.str();
MessageStatus(ss.str(), false, true).dispatch(); MessageStatus(ss.str(), false, true).dispatch();
} }
if (std::shared_ptr<DialogView> dialogView = Application::getInstance()->getDialogView()) Application::getInstance()->getDialogView()->updateIndexingDialog(
{ m_indexingFileCount, indexedSourceFileCount, sourceFileCount, sourcePath.str()
dialogView->updateIndexingDialog( );
m_indexingFileCount, indexedSourceFileCount, sourceFileCount, sourcePath.str()
);
}
} }
@@ -11,6 +11,10 @@ Command::Command(const std::string name, CommandLineParser* parser)
{ {
} }
Command::~Command()
{
}
const std::string Command::name() const std::string Command::name()
{ {
return m_name; return m_name;
@@ -32,5 +36,4 @@ void Command::printHelp()
} }
} }
} // namespace cmd } // namespace cmd
@@ -8,13 +8,15 @@
namespace po = boost::program_options; namespace po = boost::program_options;
namespace commandline { namespace commandline {
enum class ReturnStatus; enum class ReturnStatus;
class CommandLineParser; class CommandLineParser;
class Command
class Command { {
public: public:
Command(const std::string name, CommandLineParser* parser = nullptr); Command(const std::string name, CommandLineParser* parser = nullptr);
virtual ~Command();
const std::string name(); const std::string name();
@@ -83,6 +83,10 @@ CommandConfig::CommandConfig(CommandLineParser* parser)
{ {
} }
CommandConfig::~CommandConfig()
{
}
void CommandConfig::setup() void CommandConfig::setup()
{ {
po::options_description options("Config Options"); po::options_description options("Config Options");
@@ -112,7 +116,7 @@ void CommandConfig::setup()
m_options.add(options); m_options.add(options);
} }
void printVector(std::string title, std::vector<FilePath> vec) void printVector(const std::string& title, const std::vector<FilePath>& vec)
{ {
std::cout << "\n " << title << ":"; std::cout << "\n " << title << ":";
if (vec.empty()) if (vec.empty())
@@ -125,17 +129,8 @@ void printVector(std::string title, std::vector<FilePath> vec)
} }
} }
void CommandConfig::printSettings() void CommandConfig::printSettings(ApplicationSettings* settings)
{ {
ApplicationSettings* settings = ApplicationSettings::getInstance().get();
settings->load(UserPaths::getAppSettingsPath());
if (settings == nullptr)
{
LOG_ERROR("Could not load application settings");
return;
}
std::cout << "Sourcetrail Settings:\n" std::cout << "Sourcetrail Settings:\n"
<< "\n indexerthread count: " << settings->getIndexerThreadCount() << "\n indexerthread count: " << settings->getIndexerThreadCount()
<< "\n use-processes: " << settings->getMultiProcessIndexingEnabled() << "\n use-processes: " << settings->getMultiProcessIndexingEnabled()
@@ -144,9 +139,9 @@ void CommandConfig::printSettings()
<< "\n jvm-path: " << settings->getJavaPath() << "\n jvm-path: " << settings->getJavaPath()
<< "\n jvm-max-memory: " << settings->getJavaMaximumMemory() << "\n jvm-max-memory: " << settings->getJavaMaximumMemory()
<< "\n maven-path: " << settings->getMavenPath().str(); << "\n maven-path: " << settings->getMavenPath().str();
printVector("global-header-search-paths", std::move(settings->getHeaderSearchPaths())); printVector("global-header-search-paths", settings->getHeaderSearchPaths());
printVector("global-framework-search-paths", std::move(settings->getFrameworkSearchPaths())); printVector("global-framework-search-paths", settings->getFrameworkSearchPaths());
printVector("jre-system-library-paths", std::move(settings->getJreSystemLibraryPaths())); printVector("jre-system-library-paths", settings->getJreSystemLibraryPaths());
License license; License license;
license.loadFromEncodedString(settings->getLicenseString(), AppPath::getAppPath()); license.loadFromEncodedString(settings->getLicenseString(), AppPath::getAppPath());
std::cout << "\nValid license: " << license.isValid() << std::endl; std::cout << "\nValid license: " << license.isValid() << std::endl;
@@ -178,14 +173,18 @@ ReturnStatus CommandConfig::parse(std::vector<std::string>& args)
return ReturnStatus::CMD_QUIT; return ReturnStatus::CMD_QUIT;
} }
if (args[0] == "show" || vm.count("show")) ApplicationSettings* settings = ApplicationSettings::getInstance().get();
if (settings == nullptr)
{ {
printSettings(); LOG_ERROR("No application settings loaded");
return ReturnStatus::CMD_QUIT; return ReturnStatus::CMD_QUIT;
} }
ApplicationSettings* settings = ApplicationSettings::getInstance().get(); if (args[0] == "show" || vm.count("show"))
settings->load(UserPaths::getAppSettingsPath()); {
printSettings(settings);
return ReturnStatus::CMD_QUIT;
}
parseAndSetValue(&ApplicationSettings::setMultiProcessIndexingEnabled, "use-processes", settings, vm); parseAndSetValue(&ApplicationSettings::setMultiProcessIndexingEnabled, "use-processes", settings, vm);
parseAndSetValue(&ApplicationSettings::setLoggingEnabled, "logging-enabled", settings, vm); parseAndSetValue(&ApplicationSettings::setLoggingEnabled, "logging-enabled", settings, vm);
@@ -5,21 +5,25 @@
#include <iostream> #include <iostream>
#include "utility/commandline/commands/CommandlineCommand.h" #include "utility/commandline/commands/CommandlineCommand.h"
class ApplicationSettings;
class CommandLineParser; class CommandLineParser;
namespace commandline namespace commandline
{ {
enum class ReturnStatus; enum class ReturnStatus;
class CommandConfig : public Command { class CommandConfig
: public Command
{
public: public:
CommandConfig(CommandLineParser* parser); CommandConfig(CommandLineParser* parser);
virtual ~CommandConfig();
virtual void setup(); virtual void setup();
virtual ReturnStatus parse(std::vector<std::string>& args); virtual ReturnStatus parse(std::vector<std::string>& args);
private:
void printSettings();
private:
void printSettings(ApplicationSettings* settings);
}; };
} // namespace cmd } // namespace cmd
@@ -11,6 +11,10 @@ CommandIndex::CommandIndex(CommandLineParser* parser)
{ {
} }
CommandIndex::~CommandIndex()
{
}
void CommandIndex::setup() void CommandIndex::setup()
{ {
po::options_description options("Config Options"); po::options_description options("Config Options");
@@ -2,6 +2,7 @@
#define COMMANDLINE_COMMAND_INDEX_H #define COMMANDLINE_COMMAND_INDEX_H
#include <memory> #include <memory>
#include "boost/program_options.hpp" #include "boost/program_options.hpp"
#include "utility/commandline/commands/CommandlineCommand.h" #include "utility/commandline/commands/CommandlineCommand.h"
@@ -12,9 +13,12 @@ namespace commandline {
enum class ReturnStatus; enum class ReturnStatus;
class CommandIndex : public Command { class CommandIndex
: public Command
{
public: public:
CommandIndex(CommandLineParser* parser); CommandIndex(CommandLineParser* parser);
virtual ~CommandIndex();
virtual void setup(); virtual void setup();
virtual ReturnStatus parse(std::vector<std::string>& args); virtual ReturnStatus parse(std::vector<std::string>& args);
+18 -34
View File
@@ -120,61 +120,45 @@ FilePath FilePath::absolute() const
FilePath FilePath::canonical() const FilePath FilePath::canonical() const
{ {
if (m_canonicalized) if (m_canonicalized || !exists())
{ {
return FilePath(*this); return FilePath(*this);
} }
if (!exists())
{
return FilePath(*this);
}
boost::filesystem::path abs_p = boost::filesystem::absolute(m_path);
boost::filesystem::path canonicalPath; boost::filesystem::path canonicalPath;
#if defined(_WIN32)
boost::filesystem::path abs_p = boost::filesystem::absolute(m_path);
for (boost::filesystem::path::iterator it = abs_p.begin(); it != abs_p.end(); ++it) for (boost::filesystem::path::iterator it = abs_p.begin(); it != abs_p.end(); ++it)
{ {
if (*it == "..") if (*it == "..")
{ {
// /a/b/.. is not necessarily /a if b is a symbolic link canonicalPath = canonicalPath.parent_path();
if (boost::filesystem::is_symlink(canonicalPath))
{
canonicalPath /= *it;
}
// /a/b/../.. is not /a/b/.. under most circumstances
// We can end up with ..s in our result because of symbolic links
else if (canonicalPath.filename() == "..")
{
canonicalPath /= *it;
}
// Otherwise it should be safe to resolve the parent
else
{
canonicalPath = canonicalPath.parent_path();
}
} }
else if (*it == ".") else if (*it == ".")
{ {
// Ignore continue;
} }
else else
{ {
// Just cat other path entries
canonicalPath /= *it; canonicalPath /= *it;
}
if (boost::filesystem::is_symlink(canonicalPath)) if (boost::filesystem::is_symlink(canonicalPath))
{
boost::filesystem::path symlink = boost::filesystem::read_symlink(canonicalPath);
if (!symlink.empty())
{ {
// on Windows the read_symlink function discards the drive letter (this is a boost bug). Therefore boost::filesystem::path symlink = boost::filesystem::read_symlink(canonicalPath);
// we need to make the path absolute again. We also have to discard the trailing \0 characters so if (!symlink.empty())
// that we can continue appending to the path. {
canonicalPath = utility::substrBeforeFirst(boost::filesystem::absolute(symlink).string(), '\0'); // on Windows the read_symlink function discards the drive letter (this is a boost bug). Therefore
// we need to make the path absolute again. We also have to discard the trailing \0 characters so
// that we can continue appending to the path.
canonicalPath = utility::substrBeforeFirst(boost::filesystem::absolute(symlink).string(), '\0');
}
} }
} }
} }
#else
canonicalPath = boost::filesystem::canonical(m_path);
#endif
FilePath ret(canonicalPath); FilePath ret(canonicalPath);
ret.m_canonicalized = true; ret.m_canonicalized = true;
+10
View File
@@ -170,6 +170,16 @@ public:
TS_ASSERT_EQUALS(path.absolute(), path.canonical()); TS_ASSERT_EQUALS(path.absolute(), path.canonical());
} }
void test_file_path_canonical_removes_symlinks()
{
#ifndef _WIN32
FilePath pathA("data/FilePathTestSuite/parent/target/d.cpp");
FilePath pathB("data/FilePathTestSuite/target/d.cpp");
TS_ASSERT_EQUALS(pathB.absolute(), pathA.canonical());
#endif
}
void test_file_path_compares_paths_with_posix_and_windows_format() void test_file_path_compares_paths_with_posix_and_windows_format()
{ {
#ifdef _WIN32 #ifdef _WIN32
+1 -3
View File
@@ -1,6 +1,6 @@
#include "TestSuiteFixture.h" #include "TestSuiteFixture.h"
#include <sstream> #include <iostream>
#include "utility/logging/FileLogger.h" #include "utility/logging/FileLogger.h"
#include "utility/logging/LogManager.h" #include "utility/logging/LogManager.h"
@@ -15,8 +15,6 @@ TestSuiteFixture::~TestSuiteFixture()
{ {
} }
#include <iostream>
bool TestSuiteFixture::setUpWorld() bool TestSuiteFixture::setUpWorld()
{ {
LogManager* logManager = LogManager::getInstance().get(); LogManager* logManager = LogManager::getInstance().get();