Обновлён алгоритм работы с каталогами

This commit is contained in:
2020-06-03 12:20:59 +03:00
parent 395ffb080a
commit b86cf01973
9 changed files with 240 additions and 231 deletions

View File

@ -3,16 +3,10 @@ set(TRGT filesystem)
# cmake-format: off
# Список файлов исходных текстов
set(TRGT_cpp
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.cpp
${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.cpp)
set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp)
# Список заголовочных файлов
set(TRGT_hpp
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp)
set(TRGT_hpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on

View File

@ -1,41 +0,0 @@
#ifndef MYX_BASE_CURRENT_EXECUTABLE_CPP_
#define MYX_BASE_CURRENT_EXECUTABLE_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/filesystem/current_executable.hpp>
#else
#pragma once
#endif
#include <myx/base/config.hpp>
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
#if !defined ( __linux__ )
error "Class CurrentExecutable is supported only in Linux"
#endif
MYXLIB_INLINE CurrentExecutable::CurrentExecutable() :
m_procFilePath( QStringLiteral( "/proc/self/exe" ) )
{
m_canonicalFilePath = m_procFilePath.canonicalFilePath();
}
MYXLIB_INLINE const QFileInfo& CurrentExecutable::canonicalFilePath() const
{
return( m_canonicalFilePath );
}
} // namespace filesystem
} // namespace myx
#endif // MYX_BASE_CURRENT_EXECUTABLE_CPP_

View File

@ -1,51 +0,0 @@
/**
* @file current_executable.hpp
* @brief Параметры исполняемого файла
*/
#ifndef MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_
#define MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_
#pragma once
#include <myx/base/config.hpp>
#include <QDir>
#include <QFileInfo>
#include <QString>
namespace myx {
namespace filesystem {
class CurrentExecutable
{
/// @brief Путь к символической ссылке, указывающей на текущий исполняемый файл
QFileInfo m_procFilePath;
/// @brief Канонический путь к текущему исполняемому файлу
QFileInfo m_canonicalFilePath;
friend class Paths;
public:
/**
* @brief Конструктор, собирающий информацию о текущем исполняемом файле.
*/
CurrentExecutable();
/**
* @brief Канонический путь к текущему исполняемому файлу
*/
const QFileInfo& canonicalFilePath() const;
}; // class CurrentExecutable
} // namespace filesystem
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "current_executable.cpp"
#endif
#endif // MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_

View File

@ -8,7 +8,6 @@
#endif
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <paths.h>
@ -22,11 +21,22 @@ namespace filesystem {
MYXLIB_INLINE Paths::Paths() = default;
MYXLIB_INLINE void Paths::setupSystemDirectories( const QString& defaultEtcDirectory,
MYXLIB_INLINE void Paths::setupSystemDirectories( const QString& defaultPrefixDirectory,
const QString& defaultEtcDirectory,
const QString& defaultConstDataDirectory,
const QString& defaultVarDataDirectory,
const QString& defaultLogDirectory )
{
QFileInfo prefixDirInfo { defaultPrefixDirectory };
if ( prefixDirInfo.isDir() && prefixDirInfo.isReadable() )
{
m_prefixDirectory = defaultPrefixDirectory;
}
else
{
m_prefixDirectory = ".";
}
QFileInfo etcDirInfo { defaultEtcDirectory };
if ( etcDirInfo.isDir() && etcDirInfo.isReadable() )
{
@ -77,7 +87,8 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
if ( binUnityRegexp.indexIn( binaryDir ) >= 0 )
{
binaryDir.remove( binUnityRegexp );
setupSystemDirectories( binaryDir + "/etc",
setupSystemDirectories( binaryDir,
binaryDir + "/etc",
binaryDir + "/files/data",
binaryDir + "/files/lib",
binaryDir + "/files/log" );
@ -88,6 +99,7 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
QRegExp binRegexp( "/s*bin$" );
if ( binRegexp.indexIn( binaryDir ) == -1 )
{
m_prefixDirectory = m_executableDirectory;
m_systemConstDataDirectory = m_executableDirectory;
m_systemVarDataDirectory = m_executableDirectory;
m_systemConfigDirectory = m_executableDirectory;
@ -100,7 +112,8 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
if ( optRegexp.indexIn( binaryDir ) >= 0 )
{
binaryDir.remove( binRegexp );
setupSystemDirectories( binaryDir + "/etc",
setupSystemDirectories( binaryDir,
binaryDir + "/etc",
binaryDir + "/files/data",
binaryDir + "/files/lib",
binaryDir + "/files/log" );
@ -110,7 +123,8 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
if ( binaryDir.startsWith( QStringLiteral( "/usr/local" ) ) )
{
setupSystemDirectories( "/usr/local/etc/" + m_projectName,
setupSystemDirectories( "/usr/local",
"/usr/local/etc/" + m_projectName,
"/usr/local/share/" + m_projectName,
"/var/lib/" + m_projectName,
"/var/log/" + m_projectName );
@ -120,7 +134,8 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
{
setupSystemDirectories( "/etc/" + m_projectName,
setupSystemDirectories( "/usr",
"/etc/" + m_projectName,
"/usr/share/" + m_projectName,
"/var/lib/" + m_projectName,
"/var/log/" + m_projectName );
@ -131,6 +146,7 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
if ( binaryDir.startsWith( m_homeDirectory + "/.local/bin" ) ||
binaryDir.startsWith( m_homeDirectory + "/bin" ) )
{
m_prefixDirectory = m_homeDirectory;
m_systemConfigDirectory = m_userConfigDirectory;
m_systemConstDataDirectory = m_userConstDataDirectory;
m_systemVarDataDirectory = m_userVarDataDirectory;
@ -140,7 +156,8 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
}
binaryDir.remove( binRegexp );
setupSystemDirectories( binaryDir + "/etc",
setupSystemDirectories( binaryDir,
binaryDir + "/etc",
binaryDir + "/files/data",
binaryDir + "/files/lib",
binaryDir + "/files/log" );
@ -151,10 +168,11 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
MYXLIB_INLINE bool Paths::init( const QString& projectDir, const QString& configFileExtension )
{
CurrentExecutable exe;
m_executableName = exe.m_canonicalFilePath.fileName();
m_executableFilePath = exe.m_canonicalFilePath.absoluteFilePath();
m_executableDirectory = exe.m_canonicalFilePath.absolutePath();
QFileInfo procSelfExe( QStringLiteral( "/proc/self/exe" ) );
QFileInfo currentExecutable = procSelfExe.canonicalFilePath();
m_executableName = currentExecutable.fileName();
m_executableFilePath = currentExecutable.absoluteFilePath();
m_executableDirectory = currentExecutable.absolutePath();
m_projectName = projectDir.isEmpty() ? m_executableName
: projectDir;
@ -334,6 +352,12 @@ MYXLIB_INLINE const QString& Paths::executableDirectory() const
return( m_executableDirectory );
}
MYXLIB_INLINE const QString& Paths::prefixDirectory() const
{
return( m_prefixDirectory );
}
} // namespace filesystem
} // namespace myx

View File

@ -9,7 +9,6 @@
#pragma once
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <QDir>
#include <QFileInfo>
@ -53,6 +52,9 @@ class Paths
QString m_executableFilePath;
QString m_executableDirectory;
/// @brief Общий префикс для файлов проекта
QString m_prefixDirectory;
/// @brief Путь к каталогу с временными файлами
QString m_tempDirectory;
/// @brief Путь к домашнему каталогу текущего пользователя
@ -85,7 +87,8 @@ class Paths
/// @brief Расширение для файла настройки
QString m_configFileExtension;
void setupSystemDirectories( const QString& defaultEtcDirectory,
void setupSystemDirectories( const QString& defaultPrefixDirectory,
const QString& defaultEtcDirectory,
const QString& defaultConstDataDirectory,
const QString& defaultVarDataDirectory,
const QString& defaultLogDirectory );

View File

@ -1,44 +0,0 @@
#ifndef MYX_BASE_PATHS_MT_CPP_
#define MYX_BASE_PATHS_MT_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/filesystem/paths_mt.hpp>
#else
#pragma once
#endif
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
MYXLIB_INLINE PathsMT::PathsMT() = default;
MYXLIB_INLINE PathsMT& PathsMT::instance()
{
volatile PathsMT* localInstance = sInstance.load( std::memory_order_acquire );
if ( localInstance == nullptr )
{
std::lock_guard< std::mutex > myLock( sMutex );
localInstance = sInstance.load( std::memory_order_relaxed );
if ( localInstance == nullptr ) // -V1036
{
localInstance = new PathsMT();
sInstance.store( const_cast< PathsMT* >( localInstance ), std::memory_order_release ); // NOLINT
}
}
return( const_cast< PathsMT& >( *localInstance ) ); // NOLINT
}
} // namespace filesystem
} // namespace myx
#endif // MYX_BASE_PATHS_MT_CPP_

View File

@ -1,59 +0,0 @@
/**
* @file paths.hpp
* @brief Стандартные пути к каталогам и файлам
*/
#ifndef MYX_FILESYSTEM_PATHS_MT_HPP_
#define MYX_FILESYSTEM_PATHS_MT_HPP_
#pragma once
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <myx/filesystem/paths.hpp>
#include <QDir>
#include <QFileInfo>
#include <QString>
#include <atomic>
#include <future>
#include <mutex>
#include <thread>
namespace myx {
namespace filesystem {
/// @brief Потокобезопасная версия класса myx::filesystem::Paths
class PathsMT : public Paths
{
PathsMT();
~PathsMT() = default;
static std::atomic< PathsMT* > sInstance;
static std::mutex sMutex;
public:
PathsMT( const PathsMT& ) = delete;
PathsMT& operator=( const PathsMT& ) = delete;
PathsMT( PathsMT&& ) = delete;
PathsMT& operator=( PathsMT&& ) = delete;
/**
* @brief getInstance
* @return Уникальный экземпляр класса PathsMT
*/
static PathsMT& instance();
}; // class PathsMT
} // namespace filesystem
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "paths_mt.cpp"
#endif
#endif // MYX_FILESYSTEM_PATHS_MT_HPP_