Compare commits

..

No commits in common. "2901c5c04e6bd60c32aea15596508526dd09683b" and "a27f18d7b6c64d84f6bad8995dd4d2bc9022b777" have entirely different histories.

45 changed files with 444 additions and 810 deletions

View File

@ -1,25 +1,5 @@
--- ---
Checks: '-*, Checks: '-*,bugprone-*,cppcoreguidelines-*,google-*,clang-analyzer-*,misc-*,modernize-*,readability-*,performance-*,portability-*,readability-identifier-naming,-cppcoreguidelines-owning-memory'
bugprone-*,
clang-analyzer-*,
cppcoreguidelines-*,
google-*,
llvm-*,
misc-*,
modernize-*,
readability-*,
performance-*,
portability-*,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-readability-magic-numbers,
-readability-else-after-return,
-modernize-use-trailing-return-type,
-modernize-avoid-c-arrays,
-performance-no-automatic-move,
'
CheckOptions: CheckOptions:
- key: readability-identifier-naming.AbstractClassCase - key: readability-identifier-naming.AbstractClassCase
value: CamelCase value: CamelCase
@ -34,9 +14,9 @@ CheckOptions:
- key: readability-identifier-naming.ClassSuffix - key: readability-identifier-naming.ClassSuffix
value: '' value: ''
- key: readability-identifier-naming.ClassConstantCase - key: readability-identifier-naming.ClassConstantCase
value: CamelCase value: UPPER_CASE
- key: readability-identifier-naming.ClassConstantPrefix - key: readability-identifier-naming.ClassConstantPrefix
value: 'k_' value: ''
- key: readability-identifier-naming.ClassConstantSuffix - key: readability-identifier-naming.ClassConstantSuffix
value: '' value: ''
- key: readability-identifier-naming.ClassMemberCase - key: readability-identifier-naming.ClassMemberCase
@ -52,9 +32,9 @@ CheckOptions:
- key: readability-identifier-naming.ClassMethodSuffix - key: readability-identifier-naming.ClassMethodSuffix
value: '' value: ''
- key: readability-identifier-naming.ConstantCase - key: readability-identifier-naming.ConstantCase
value: CamelCase value: UPPER_CASE
- key: readability-identifier-naming.ConstantPrefix - key: readability-identifier-naming.ConstantPrefix
value: 'k_' value: PRE
- key: readability-identifier-naming.ConstantSuffix - key: readability-identifier-naming.ConstantSuffix
value: POST value: POST
- key: readability-identifier-naming.ConstantMemberCase - key: readability-identifier-naming.ConstantMemberCase
@ -100,9 +80,9 @@ CheckOptions:
- key: readability-identifier-naming.EnumSuffix - key: readability-identifier-naming.EnumSuffix
value: '' value: ''
- key: readability-identifier-naming.EnumConstantCase - key: readability-identifier-naming.EnumConstantCase
value: CamelCase value: UPPER_CASE
- key: readability-identifier-naming.EnumConstantPrefix - key: readability-identifier-naming.EnumConstantPrefix
value: 'k_' value: ''
- key: readability-identifier-naming.EnumConstantSuffix - key: readability-identifier-naming.EnumConstantSuffix
value: '' value: ''
- key: readability-identifier-naming.FunctionCase - key: readability-identifier-naming.FunctionCase
@ -112,9 +92,9 @@ CheckOptions:
- key: readability-identifier-naming.FunctionSuffix - key: readability-identifier-naming.FunctionSuffix
value: '' value: ''
- key: readability-identifier-naming.GlobalConstantCase - key: readability-identifier-naming.GlobalConstantCase
value: CamelCase value: UPPER_CASE
- key: readability-identifier-naming.GlobalConstantPrefix - key: readability-identifier-naming.GlobalConstantPrefix
value: 'k_' value: ''
- key: readability-identifier-naming.GlobalConstantSuffix - key: readability-identifier-naming.GlobalConstantSuffix
value: '' value: ''
- key: readability-identifier-naming.GlobalConstantPointerCase - key: readability-identifier-naming.GlobalConstantPointerCase
@ -150,7 +130,7 @@ CheckOptions:
- key: readability-identifier-naming.LocalConstantCase - key: readability-identifier-naming.LocalConstantCase
value: camelBack value: camelBack
- key: readability-identifier-naming.LocalConstantPrefix - key: readability-identifier-naming.LocalConstantPrefix
value: 'k_' value: ''
- key: readability-identifier-naming.LocalConstantSuffix - key: readability-identifier-naming.LocalConstantSuffix
value: '' value: ''
- key: readability-identifier-naming.LocalConstantPointerCase - key: readability-identifier-naming.LocalConstantPointerCase
@ -246,7 +226,7 @@ CheckOptions:
- key: readability-identifier-naming.StaticConstantCase - key: readability-identifier-naming.StaticConstantCase
value: camelBack value: camelBack
- key: readability-identifier-naming.StaticConstantPrefix - key: readability-identifier-naming.StaticConstantPrefix
value: 'k_' value: ''
- key: readability-identifier-naming.StaticConstantSuffix - key: readability-identifier-naming.StaticConstantSuffix
value: '' value: ''
- key: readability-identifier-naming.StaticVariableCase - key: readability-identifier-naming.StaticVariableCase

3
.gitignore vendored
View File

@ -2,6 +2,3 @@ CMakeLists.txt.user*
_build _build
_output _output
*.autosave *.autosave
files/lib/*
files/log/*

View File

@ -10,9 +10,6 @@ orel212-nightly:
bionic-nightly: bionic-nightly:
extends: .scheduled-bionic extends: .scheduled-bionic
focal-nightly:
extends: .scheduled-focal
elbrus-nightly: elbrus-nightly:
extends: .scheduled-elbrus extends: .scheduled-elbrus

View File

@ -1,6 +1,5 @@
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
GET_SOURCES_ATTEMPTS: 10
.scheduled-test: .scheduled-test:
only: only:
@ -67,11 +66,6 @@ variables:
image: bionic-dev image: bionic-dev
tags: ['docker'] tags: ['docker']
.scheduled-focal:
extends: .scheduled-test
image: focal-dev
tags: ['docker']
.scheduled-elbrus: .scheduled-elbrus:
extends: .scheduled-test extends: .scheduled-test
tags: ['elbrus'] tags: ['elbrus']

View File

@ -20,10 +20,6 @@ option(BUILD_EXAMPLES "Build examples" OFF)
# Поиск библиотек с помощью pkgconfig # Поиск библиотек с помощью pkgconfig
find_package(PkgConfig) find_package(PkgConfig)
# Потоки
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
# Qt5 # Qt5
find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED) find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED)

@ -1 +1 @@
Subproject commit c9c13df5527f59c4f9eff6229152205aa296605b Subproject commit 9719383c86dd3789f9fb34eff36967262188257f

@ -1 +1 @@
Subproject commit bab7df69d9fdf1f22db7b2173c9f1f40de2c476b Subproject commit b5e3fb02619418d2e574232033e3df37be99212e

@ -1 +1 @@
Subproject commit eb34f3ffb32205b382c4ee56de890b5de9371fa7 Subproject commit 878e1d8a27f1512d5c39fb8fdad467ba5f6d8285

View File

@ -27,13 +27,13 @@ add_dependencies(${current_target} filesystem)
# Qt5 # Qt5
# qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU) # qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU)
target_include_directories(${current_target} PRIVATE ${CMAKE_SOURCE_DIR}/src) target_include_directories(${current_target} PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${current_target} SYSTEM PUBLIC ${FMT_INCLUDE_DIRS})
target_include_directories(${current_target} SYSTEM PUBLIC ${SPDLOG_INCLUDE_DIRS})
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS}) target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
target_link_libraries(${current_target} myx-filesystem) target_link_libraries(${current_target} myx-filesystem)
target_link_libraries(${current_target} Qt5::Core) target_link_libraries(${current_target} Qt5::Core)
target_link_libraries(${current_target} Threads::Threads)
# Имя выходного файла для цели # Имя выходного файла для цели
set_target_properties(${current_target} set_target_properties(${current_target}
@ -46,7 +46,5 @@ add_sanitizers(${current_target})
# cotire(${current_target}) # cotire(${current_target})
add_dependencies(${current_target} create_auxilary_symlinks)
# Правила для установки # Правила для установки
install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -1,36 +1,22 @@
#include "cmlib_private_config.hpp"
#include <myx/base/config.hpp> #include <myx/base/config.hpp>
#include <myx/filesystem/paths.hpp> #include <myx/filesystem/paths.hpp>
#include <myx/filesystem/paths_mt.hpp>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug>
namespace MF = myx::filesystem; namespace MF = myx::filesystem;
// Переменные для защиты экземпляра класса MF::PathsMT
std::atomic< MF::PathsMT* > MF::PathsMT::mInstance;
std::mutex MF::PathsMT::mMutex;
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
(void)argc; (void)argc;
(void)argv; (void)argv;
QCoreApplication::setApplicationName( QStringLiteral( CMLIB_PROJECT_NAME ) ); QCoreApplication::setApplicationName( PROJECT_NAME );
MF::PathsMT& pathsMT = MF::PathsMT::instance(); MF::Paths paths;
MF::Paths& paths = MF::Paths::instance();
pathsMT.init( QStringLiteral( CMLIB_PROJECT_NAME ), QStringLiteral( "conf" ) ); paths.updatePaths();
pathsMT.findConfigFile( QStringLiteral( "test" ) ); paths.makeDefaultDirectories();
qDebug() << pathsMT.systemLogDirectory(); paths.findConfigFile( "test" );
qDebug() << pathsMT.systemConfigDirectory();
paths.init( QStringLiteral( CMLIB_PROJECT_NAME ), QStringLiteral( "conf" ) );
paths.findConfigFile( QStringLiteral( "test" ) );
qDebug() << paths.systemConstDataDirectory();
qDebug() << paths.configFileName();
return( 0 ); return( 0 );
} }

View File

@ -25,8 +25,10 @@ add_dependencies(${current_target} base)
add_dependencies(${current_target} qt) add_dependencies(${current_target} qt)
# Qt5 # Qt5
qt5_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU) qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU)
target_include_directories(${current_target} PRIVATE ${CMAKE_SOURCE_DIR}/src) target_include_directories(${current_target} PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${current_target} SYSTEM PUBLIC ${FMT_INCLUDE_DIRS})
target_include_directories(${current_target} SYSTEM PUBLIC ${SPDLOG_INCLUDE_DIRS})
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS}) target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
@ -44,7 +46,5 @@ add_sanitizers(${current_target})
# cotire(${current_target}) # cotire(${current_target})
add_dependencies(${current_target} create_auxilary_symlinks)
# Правила для установки # Правила для установки
install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -12,7 +12,7 @@ int main( int argc, char** argv )
MQ::QTranslatorsList tl; MQ::QTranslatorsList tl;
qDebug() << QObject::tr( "Yes" ); qDebug() << QObject::tr( "Yes" );
MQ::append_translators( tl, QStringLiteral( "example-qt-translators" ) ); MQ::append_translators( tl, "example-qt-translators" );
qDebug() << QObject::tr( "Yes" ); qDebug() << QObject::tr( "Yes" );
return( 0 ); return( 0 );

View File

View File

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View File

@ -8,8 +8,6 @@ set(current_target_sources
# Список заголовочных файлов (используется для установки) # Список заголовочных файлов (используется для установки)
set(current_target_headers set(current_target_headers
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp ${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
${CMAKE_CURRENT_SOURCE_DIR}/limits.hpp
${CMAKE_CURRENT_SOURCE_DIR}/enum_bitmask_operations.hpp
) )
add_common_library(TARGET ${current_target} OUTPUT_NAME myx-${current_target} add_common_library(TARGET ${current_target} OUTPUT_NAME myx-${current_target}
@ -42,7 +40,8 @@ install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIB
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif() endif()
install(FILES ${CMAKE_BINARY_DIR}/include/config_flags.hpp install(FILES ${CMAKE_BINARY_DIR}/include/cmlib_config.hpp
${CMAKE_BINARY_DIR}/include/config_flags.hpp
${current_target_headers} ${current_target_headers}
COMPONENT headers COMPONENT headers
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${current_target}) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${current_target})

View File

@ -1,6 +1,7 @@
#ifndef MYX_BASE_CONFIG_HPP_ #ifndef MYX_BASE_CONFIG_HPP_
#define MYX_BASE_CONFIG_HPP_ #define MYX_BASE_CONFIG_HPP_
#include "cmlib_config.hpp"
#include "config_flags.hpp" #include "config_flags.hpp"
#endif // MYX_BASE_CONFIG_HPP_ #endif // MYX_BASE_CONFIG_HPP_

View File

@ -1,58 +0,0 @@
#ifndef MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_
#define MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_
#pragma once
#include <type_traits>
namespace myx {
namespace base {
template< typename Enum >
struct EnableBitMaskOperators
{
static const bool enable = false;
};
template< typename Enum >
typename std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type
operator |( Enum lhs, Enum rhs )
{
using underlying = typename std::underlying_type< Enum >::type;
return( static_cast< Enum >(
static_cast< underlying >( lhs ) |
static_cast< underlying >( rhs )
) );
}
} // namespace base
} // namespace myx
/**
* @brief Макрос, предоставляющий возможность выполнять битовые операции в enum class
*
* Источник: http://blog.bitwigglers.org/using-enum-classes-as-type-safe-bitmasks/
* Пример использования:
*
* namespace ns {
* enum class Permissions
* {
* Readable = 0x4,
* Writeable = 0x2,
* Executable = 0x1
* };
* }
* ENABLE_BITMASK_OPERATORS(ns::Permissions)
*/
#define ENABLE_BITMASK_OPERATORS( x ) \
template<> \
struct myx::base::EnableBitMaskOperators< x > \
{ \
static const bool enable = true; \
};
#endif // ifndef MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_

View File

@ -1,31 +0,0 @@
#ifndef MYX_BASE_LIMITS_HPP_
#define MYX_BASE_LIMITS_HPP_
#pragma once
#include <limits>
namespace myx {
namespace base {
/**
* @brief Константа, представляющая значение, не являющееся числом, для типа float
*/
constexpr float k_FloatNAN { std::numeric_limits< float >::quiet_NaN() };
/**
* @brief Константа, представляющая значение, не являющееся числом, для типа double
*/
constexpr double k_DoubleNAN { std::numeric_limits< double >::quiet_NaN() };
/**
* @brief Константа, представляющая значение, не являющееся числом, для типа long double
*/
constexpr double k_LongDoubleNAN { std::numeric_limits< long double >::quiet_NaN() };
} // namespace base
} // namespace myx
#endif // MYX_BASE_LIMITS_HPP_

View File

@ -5,14 +5,12 @@ set(current_target filesystem)
set(current_target_sources set(current_target_sources
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.cpp ${CMAKE_CURRENT_SOURCE_DIR}/current_executable.cpp
${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.cpp
) )
# Список заголовочных файлов (используется для установки) # Список заголовочных файлов (используется для установки)
set(current_target_headers set(current_target_headers
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.hpp ${CMAKE_CURRENT_SOURCE_DIR}/current_executable.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp
) )
add_common_library(TARGET ${current_target} add_common_library(TARGET ${current_target}

View File

@ -1,31 +1,43 @@
#include "current_executable.hpp"
#include <myx/base/config.hpp> #include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <paths.h> #include <paths.h>
#include <QCoreApplication>
#include <QString> #include <QString>
#include <QCoreApplication>
namespace myx { namespace myx {
namespace filesystem { namespace filesystem {
#if !defined ( __linux__ )
error "Class CurrentExecutable is supported only in Linux"
#endif
CurrentExecutable::CurrentExecutable() : CurrentExecutable::CurrentExecutable() :
m_procFilePath( QStringLiteral( "/proc/self/exe" ) ) m_procFilePath( "/proc/self/exe" )
{ {
m_canonicalFilePath = m_procFilePath.canonicalFilePath(); auto canonicalFilePath = m_procFilePath.canonicalFilePath();
auto canonicalPath = m_procFilePath.canonicalPath();
m_fileName = canonicalFilePath.remove( canonicalPath ).remove( '/' );
m_canonicalFilePath = canonicalFilePath;
m_canonicalPath = canonicalPath;
} }
const QFileInfo& CurrentExecutable::canonicalFilePath() const QFileInfo CurrentExecutable::canonicalFilePath() const
{ {
return( m_canonicalFilePath ); return( m_canonicalFilePath );
} }
QDir CurrentExecutable::canonicalPath() const
{
return( m_canonicalPath );
}
QString CurrentExecutable::fileName() const
{
return( m_fileName );
}
} // namespace filesystem } // namespace filesystem
} // namespace myx } // namespace myx

View File

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

View File

@ -1,164 +1,210 @@
#include "paths.hpp"
#include <myx/base/config.hpp> #include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp> #include <myx/filesystem/current_executable.hpp>
#include <myx/filesystem/paths.hpp>
#include <paths.h> #include <paths.h>
#include <QCoreApplication>
#include <QString> #include <QString>
#include <QCoreApplication>
namespace myx { namespace myx {
namespace filesystem { namespace filesystem {
Paths::Paths() = default; QString Paths::executableFileName() const
Paths::HierarchyType Paths::getHierarchyType()
{ {
QRegExp binRegexp( "/s*bin$" ); return( m_currentExecutable.fileName() );
auto binaryDir = m_currentExecutable.m_canonicalFilePath.canonicalPath(); }
if ( binRegexp.indexIn( binaryDir ) == -1 )
{
return ( HierarchyType::kFlat );
}
QRegExp optRegexp( "^/opt(/|/.+/)" + m_projectName + "/" );
if ( optRegexp.indexIn( binaryDir ) >= 0 )
{
binaryDir.remove( binRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kOpt );
}
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
{
QFileInfo etcDirInfo { "/etc/" + m_projectName };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { "/usr/share/" + m_projectName };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { "/var/log/" + m_projectName };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kStandard );
}
if ( binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/.local/bin" ) ||
binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/bin" ) )
{
QFileInfo etcDirInfo { m_userConfigDirectory.canonicalPath() };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { m_userConstDataDirectory.canonicalPath() };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { m_userVarDataDirectory.canonicalPath() };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { m_userLogDirectory.canonicalPath() };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return( HierarchyType::kHome );
}
binaryDir.remove( binRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kUser );
} // Paths::getHierarchyType
bool Paths::init( const QString& projectDir, const QString& configFileExtension ) QString Paths::configFileName() const
{ {
m_projectName = projectDir.isEmpty() ? m_currentExecutable.m_canonicalFilePath.fileName() return( m_configFileName );
: projectDir; }
m_configFileExtension = configFileExtension.isEmpty() ? QStringLiteral( "conf" )
: configFileExtension;
m_configFileName = m_projectName + "." + m_configFileExtension;
m_homeDirectory = QString::fromLocal8Bit( qgetenv( "HOME" ) );
m_tempDirectory = QString::fromLocal8Bit( qgetenv( "TMPDIR" ) ); void Paths::setConfigFileName( const QString& configFileName )
if ( !m_tempDirectory.exists() || ( m_tempDirectory.path() == QStringLiteral( "." ) ) ) {
m_configFileName = configFileName;
}
QFileInfo Paths::executableFilePath() const
{
return( m_currentExecutable.canonicalFilePath() );
}
QFileInfo Paths::configFilePath() const
{
return( m_configFilePath );
}
void Paths::setConfigFilePath( const QFileInfo& configFilePath )
{
m_configFilePath = configFilePath;
}
QDir Paths::logDirectory() const
{
return( m_logDirectory );
}
void Paths::setLogDirectory( const QString& logDirectory )
{
m_logDirectory = logDirectory;
}
Paths::Paths( const QString& configFileExtension ) :
m_configFileExtension( configFileExtension )
{
m_prefixDirectory = "/opt/" + QCoreApplication::organizationName().toLower() +
"/" + QCoreApplication::applicationName().toLower();
auto pd = m_prefixDirectory.absolutePath();
m_binaryDirectory = pd + "/bin";
m_configDirectory = pd + "/etc";
m_cacheDirectory = pd + "/var";
m_logDirectory = pd + "/var/log";
m_tempDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "TMPDIR" ) ) );
m_dataDirectory = pd + "/share";
m_homeDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "HOME" ) ) );
m_configFileName = QCoreApplication::applicationName().toLower() +
"." + m_configFileExtension;
m_configFilePath = m_binaryDirectory.absolutePath() +
"/" + m_configFileName;
if ( m_tempDirectory.absolutePath().isEmpty() || ( m_tempDirectory.path() == "." ) )
{ {
m_tempDirectory = QStringLiteral( _PATH_TMP ); m_tempDirectory = _PATH_TMP;
}
}
QDir Paths::prefixDirectory() const
{
return( m_prefixDirectory );
}
void Paths::setPrefixDirectory( const QString& prefixDirectory )
{
m_prefixDirectory = prefixDirectory;
}
QDir Paths::binaryDirectory() const
{
return( m_binaryDirectory );
}
void Paths::setBinaryDirectory( const QString& binaryDirectory )
{
m_binaryDirectory = binaryDirectory;
}
QDir Paths::configDirectory() const
{
return( m_configDirectory );
}
void Paths::setConfigDirectory( const QString& configDirectory )
{
m_configDirectory = configDirectory;
}
QDir Paths::cacheDirectory() const
{
return( m_cacheDirectory );
}
void Paths::setCacheDirectory( const QString& cacheDirectory )
{
m_cacheDirectory = cacheDirectory;
}
QDir Paths::tempDirectory() const
{
return( m_tempDirectory );
}
void Paths::setTempDirectory( const QString& tempDirectory )
{
m_tempDirectory = tempDirectory;
}
QDir Paths::dataDirectory() const
{
return( m_dataDirectory );
}
void Paths::setDataDirectory( const QString& dataDirectory )
{
m_dataDirectory = dataDirectory;
}
bool Paths::updatePaths()
{
m_binaryDirectory = m_currentExecutable.canonicalPath();
if ( m_binaryDirectory.absolutePath().endsWith( "/bin" ) )
{
m_prefixDirectory = m_binaryDirectory.absolutePath().remove( QRegExp( "/bin$" ) );
m_configDirectory = m_prefixDirectory.absolutePath() + "/etc";
m_cacheDirectory = m_prefixDirectory.absolutePath() + "/var";
m_logDirectory = m_prefixDirectory.absolutePath() + "/var/log";
m_dataDirectory = m_prefixDirectory.absolutePath() + "/share";
m_configFilePath = QFile( m_configDirectory.absolutePath() +
"/" + QCoreApplication::applicationName() +
"." + m_configFileExtension );
} }
auto configHome = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) ); if ( m_prefixDirectory.absolutePath().startsWith( "/opt" ) ||
if ( configHome.isEmpty() ) m_prefixDirectory.absolutePath().startsWith( "/usr" ) )
{ {
configHome = m_homeDirectory.canonicalPath() + "/.config"; QString dataDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "XDG_DATA_HOME" ) ) );
} if ( dataDirectory.isEmpty() )
m_userConfigDirectory = configHome + "/" + m_projectName;
auto dataHome = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) );
if ( dataHome.isEmpty() )
{ {
dataHome = m_homeDirectory.canonicalPath() + "/.local/share"; dataDirectory = m_homeDirectory.absolutePath() + ".local/share";
} }
dataHome += "/" + m_projectName; m_dataDirectory = dataDirectory + "/" +
m_userConstDataDirectory = dataHome + "/data"; QCoreApplication::organizationName().toLower() + "/" +
m_userVarDataDirectory = dataHome + "/lib"; QCoreApplication::applicationName().toLower();
m_userLogDirectory = dataHome + "/log";
m_hierarchyType = getHierarchyType(); QString configDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "XDG_CONFIG_HOME" ) ) );
if ( configDirectory.isEmpty() )
if ( m_hierarchyType == HierarchyType::kFlat )
{ {
m_systemConstDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath(); configDirectory = m_homeDirectory.absolutePath() + ".config";
m_systemVarDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemConfigDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemLogDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
} }
m_configDirectory = configDirectory + "/" +
QCoreApplication::organizationName().toLower() + "/" +
QCoreApplication::applicationName().toLower();
m_configFilePath = m_systemConfigDirectory.canonicalPath() + "/" + m_configFileName; QString cacheDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "XDG_CACHE_HOME" ) ) );
if ( cacheDirectory.isEmpty() )
{
cacheDirectory = m_homeDirectory.absolutePath() + ".cache";
}
m_cacheDirectory = cacheDirectory + "/" +
QCoreApplication::organizationName().toLower() + "/" +
QCoreApplication::applicationName().toLower();
m_logDirectory = m_cacheDirectory.absolutePath() + "/log";
}
return( true ); return( true );
} // Paths::updatePaths } // Paths::updatePaths
@ -168,17 +214,17 @@ bool Paths::makeDefaultDirectories()
{ {
bool status = true; bool status = true;
if ( !m_userConfigDirectory.mkpath( m_userConfigDirectory.absolutePath() ) ) { status = false; } if ( !m_dataDirectory.mkpath( m_dataDirectory.absolutePath() ) ) { status = false; }
if ( !m_userVarDataDirectory.mkpath( m_userVarDataDirectory.absolutePath() ) ) { status = false; } if ( !m_configDirectory.mkpath( m_configDirectory.absolutePath() ) ) { status = false; }
if ( !m_userConstDataDirectory.mkpath( m_userConstDataDirectory.absolutePath() ) ) { status = false; } if ( !m_cacheDirectory.mkpath( m_cacheDirectory.absolutePath() ) ) { status = false; }
if ( !m_userLogDirectory.mkpath( m_userLogDirectory.absolutePath() ) ) { status = false; } if ( !m_logDirectory.mkpath( m_logDirectory.absolutePath() ) ) { status = false; }
return( status ); return( status );
} }
QString Paths::findConfigFile( const QString& defaultConfigFile ) QString Paths::findConfigFile( const QString& defaultConfigFile )
{ {
if ( !defaultConfigFile.isEmpty() && QFileInfo( defaultConfigFile ).isReadable() ) if ( QFileInfo( defaultConfigFile ).isReadable() )
{ {
m_configFilePath = defaultConfigFile; m_configFilePath = defaultConfigFile;
return( defaultConfigFile ); return( defaultConfigFile );
@ -200,108 +246,6 @@ QString Paths::findConfigFile( const QString& defaultConfigFile )
return( QString() ); return( QString() );
} // Paths::findConfigFile } // Paths::findConfigFile
QDir Paths::binaryDirectory() const
{
return( m_currentExecutable.m_canonicalFilePath.dir() );
}
const QDir& Paths::userConfigDirectory() const
{
return( m_userConfigDirectory );
}
const QDir& Paths::systemConfigDirectory() const
{
return( m_systemConfigDirectory );
}
const QFileInfo& Paths::configFilePath() const
{
return( m_configFilePath );
}
const QString& Paths::configFileName() const
{
return( m_configFileName );
}
const QString& Paths::configFileExtension() const
{
return( m_configFileExtension );
}
const QDir& Paths::userVarDataDirectory() const
{
return( m_userVarDataDirectory );
}
const QDir& Paths::systemVarDataDirectory() const
{
return( m_systemVarDataDirectory );
}
const QDir& Paths::userConstDataDirectory() const
{
return( m_userConstDataDirectory );
}
const QDir& Paths::systemConstDataDirectory() const
{
return( m_systemConstDataDirectory );
}
const QDir& Paths::userLogDirectory() const
{
return( m_userLogDirectory );
}
const QDir& Paths::systemLogDirectory() const
{
return( m_systemLogDirectory );
}
const QDir& Paths::tempDirectory() const
{
return( m_tempDirectory );
}
const QDir& Paths::homeDirectory() const
{
return( m_homeDirectory );
}
const QString& Paths::projectName() const
{
return( m_projectName );
}
QString Paths::executableFileName() const
{
return( m_currentExecutable.m_canonicalFilePath.fileName() );
}
const QFileInfo& Paths::executableFilePath() const
{
return( m_currentExecutable.m_canonicalFilePath );
}
} // namespace filesystem } // namespace filesystem
} // namespace myx } // namespace myx

View File

@ -6,8 +6,6 @@
#ifndef MYX_FILESYSTEM_PATHS_HPP_ #ifndef MYX_FILESYSTEM_PATHS_HPP_
#define MYX_FILESYSTEM_PATHS_HPP_ #define MYX_FILESYSTEM_PATHS_HPP_
#pragma once
#include <myx/filesystem/current_executable.hpp> #include <myx/filesystem/current_executable.hpp>
#include <QString> #include <QString>
@ -18,85 +16,125 @@ namespace myx {
namespace filesystem { namespace filesystem {
/// @brief Класс, предоставляющий методы для получения стандартных путей к каталогам и файлам
class Paths class Paths
{ {
enum class HierarchyType : intptr_t /// Путь к базовому каталогу
{ QDir m_prefixDirectory;
kSplit = 0x00, /// Путь к каталогу с исполняемым файлом
kFlat = 0x01, QDir m_binaryDirectory;
kOpt = 0x02, /// Путь к каталогу с изменяемыми файлами
kStandard = 0x04, QDir m_cacheDirectory;
kUser = 0x08, /// Путь к каталогу с временными файлами
kHome = 0x10,
};
/// @brief Тип расположения файлов по каталогам
HierarchyType m_hierarchyType { HierarchyType::kFlat };
/// @brief Параметры текущего исполняемого файла
CurrentExecutable m_currentExecutable;
/// @brief Имя проекта, которое используется при формировании имён файлов и каталогов
QString m_projectName;
/// @brief Путь к каталогу с временными файлами
QDir m_tempDirectory; QDir m_tempDirectory;
/// @brief Путь к домашнему каталогу текущего пользователя /// Путь к каталогу с неизменяемыми файлами
QDir m_dataDirectory;
/// Путь к каталогу с журналами работы
QDir m_logDirectory;
/// Путь к домашнему каталогу текущего пользователя
QDir m_homeDirectory; QDir m_homeDirectory;
/// Путь к каталогу с файлами настройки
/// @brief Путь к пользовательскому каталогу с изменяемыми файлами QDir m_configDirectory;
QDir m_userVarDataDirectory; /// Полный путь к файлу настройки
/// @brief Путь к системному каталогу с изменяемыми файлами
QDir m_systemVarDataDirectory;
/// @brief Путь к пользовательскому каталогу с неизменяемыми файлами
QDir m_userConstDataDirectory;
/// @brief Путь к системному каталогу с неизменяемыми файлами
QDir m_systemConstDataDirectory;
/// @brief Путь к пользовательскому каталогу с журналами работы
QDir m_userLogDirectory;
/// @brief Путь к системному каталогу с журналами работы
QDir m_systemLogDirectory;
/// @brief Путь к пользовательскому каталогу с файлами настройки
QDir m_userConfigDirectory;
/// @brief Путь к системному каталогу с файлами настройки
QDir m_systemConfigDirectory;
/// @brief Полный путь к файлу настройки
QFileInfo m_configFilePath; QFileInfo m_configFilePath;
/// @brief Имя файла настройки /// Имя файла настройки
QString m_configFileName; QString m_configFileName;
/// @brief Расширение для файла настройки /// Расширение для файла настройки
QString m_configFileExtension; QString m_configFileExtension;
HierarchyType getHierarchyType(); /// Параметры текущего исполняемого файла
CurrentExecutable m_currentExecutable;
protected:
Paths();
~Paths() = default;
Paths( const Paths& ) = delete;
Paths& operator=( const Paths& ) = delete;
public: public:
/** /**
* @brief getInstance * @brief Конструктор
* @return Уникальный экземпляр класса Paths * @param configFileExtension Расширение для файла настройки
*/ */
static Paths& instance() Paths( const QString& configFileExtension = "conf" );
{ /**
static Paths p; * @brief Получение пути к базовому каталогу
return( p ); */
} QDir prefixDirectory() const;
/**
* @brief Установка пути к базовому каталогу
*/
void setPrefixDirectory( const QString& prefixDirectory );
/**
* @brief Получение пути к каталогу с исполняемым файлом
*/
QDir binaryDirectory() const;
/**
* @brief Установка пути к каталогу с исполняемым файлом
*/
void setBinaryDirectory( const QString& binaryDirectory );
/**
* @brief Получение пути к каталогу с файлами настройки
*/
QDir configDirectory() const;
/**
* @brief Установка пути к каталогу с файлами настройки
*/
void setConfigDirectory( const QString& configDirectory );
/**
* @brief Получение пути к каталогу с изменяемыми файлами
*/
QDir cacheDirectory() const;
/**
* @brief Установка пути к каталогу с изменяемыми файлами
*/
void setCacheDirectory( const QString& cacheDirectory );
/**
* @brief Получение пути к каталогу с временными файлами
*/
QDir tempDirectory() const;
/**
* @brief Установка пути к каталогу с временными файлами
*/
void setTempDirectory( const QString& tempDirectory );
/**
* @brief Получение пути к каталогу с неизменяемыми файлами
*/
QDir dataDirectory() const;
/**
* @brief Установка пути к каталогу с неизменяемыми файлами
*/
void setDataDirectory( const QString& dataDirectory );
/**
* @brief Получение пути к каталогу с журналами работы
*/
QDir logDirectory() const;
/**
* @brief Установка пути к каталогу с журналами работы
*/
void setLogDirectory( const QString& logDirectory );
/**
* @brief Имя исполняемого файла
*/
QString executableFileName() const;
/**
* @brief Полный путь к исполняемому файлу
*/
QFileInfo executableFilePath() const;
/**
* @brief Имя файла настройки
*/
QString configFileName() const;
/**
* @brief Установка имени файла настройки
*/
void setConfigFileName( const QString& configFileName );
/**
* @brief Полный путь к файлу настройки
*/
QFileInfo configFilePath() const;
/**
* @brief Установка полного пути к файлу настройки
*/
void setConfigFilePath( const QFileInfo& configFilePath );
/** /**
* @brief Обновление путей с учётом расположения исполняемого файла * @brief Обновление путей с учётом расположения исполняемого файла
*/ */
bool init( const QString& projectDir, const QString& configFileExtension = QStringLiteral("conf") ); bool updatePaths();
/** /**
* @brief Создание стандартных каталогов * @brief Создание стандартных каталогов
*/ */
@ -106,101 +144,11 @@ public:
* @brief Поиск существующего файла настойки. * @brief Поиск существующего файла настойки.
* Поиск выполняется до тех пор пока не будет найден файл в следующем порядке: * Поиск выполняется до тех пор пока не будет найден файл в следующем порядке:
* 1. Имя файла, указанное в качестве параметра функции * 1. Имя файла, указанное в качестве параметра функции
* 2. Имя файла, заданное переменной окружения вида PROJECT_NAME_CONFIG * 2. Имя файла, заданное переменной окружения вида PORJECT_NAME_CONFIG
* 3. Имя файла, полученное из внутренней переменной класса * 3. Имя файла, полученное из внутренней переменной класса
* Если файл настройки не будет найден, то будет возвращена пустая строка * Если файл настройки не будет найден, то будет возвращена пустая строка
*/ */
QString findConfigFile( const QString& defaultConfigFile = QLatin1String("") ); QString findConfigFile( const QString& defaultConfigFile = "" );
/**
* @brief Получение пути к базовому каталогу
*/
const QDir& prefixDirectory() const;
/**
* @brief Получение пути к каталогу с исполняемым файлом
*/
QDir binaryDirectory() const;
/**
* @brief Получение пути к пользовательскому каталогу с файлами настройки
*/
const QDir& userConfigDirectory() const;
/**
* @brief Получение пути к системному каталогу с файлами настройки
*/
const QDir& systemConfigDirectory() const;
/**
* @brief Полный путь к файлу настройки
*/
const QFileInfo& configFilePath() const;
/**
* @brief Имя файла настройки
*/
const QString& configFileName() const;
/**
* @brief Расширение у файла настройки
*/
const QString& configFileExtension() const;
/**
* @brief Получение пути к пользовательскому каталогу с изменяемыми файлами
*/
const QDir& userVarDataDirectory() const;
/**
* @brief Получение пути к системному каталогу с изменяемыми файлами
*/
const QDir& systemVarDataDirectory() const;
/**
* @brief Получение пути к пользовательскому каталогу с неизменяемыми файлами
*/
const QDir& userConstDataDirectory() const;
/**
* @brief Получение пути к системному каталогу с неизменяемыми файлами
*/
const QDir& systemConstDataDirectory() const;
/**
* @brief Получение пути к пользовательскому каталогу с журналами работы
*/
const QDir& userLogDirectory() const;
/**
* @brief Получение пути к системному каталогу с журналами работы
*/
const QDir& systemLogDirectory() const;
/**
* @brief Получение пути к каталогу с временными файлами
*/
const QDir& tempDirectory() const;
/**
* @brief Получение пути к домашнему каталогу текущего пользователя
*/
const QDir& homeDirectory() const;
/**
* @brief Имя подкаталога для проекта
*/
const QString& projectName() const;
/**
* @brief Имя исполняемого файла
*/
QString executableFileName() const;
/**
* @brief Полный путь к исполняемому файлу
*/
const QFileInfo& executableFilePath() const;
}; // class Paths }; // class Paths
} // namespace filesystem } // namespace filesystem

View File

@ -1,34 +0,0 @@
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <myx/filesystem/paths_mt.hpp>
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
PathsMT::PathsMT() = default;
PathsMT& PathsMT::instance()
{
volatile PathsMT* localInstance = mInstance.load( std::memory_order_acquire );
if ( localInstance == nullptr )
{
std::lock_guard< std::mutex > myLock( mMutex );
localInstance = mInstance.load( std::memory_order_relaxed );
if ( localInstance == nullptr ) // -V1036
{
localInstance = new PathsMT();
mInstance.store( const_cast< PathsMT* >( localInstance ), std::memory_order_release ); // NOLINT
}
}
return( const_cast< PathsMT& >( *localInstance ) ); // NOLINT
}
} // namespace filesystem
} // namespace myx

View File

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

View File

@ -1,5 +1,5 @@
#include <myx/math/almost_equal_ulps.hpp>
#include <myx/math/float_cmp_types.hpp> #include <myx/math/float_cmp_types.hpp>
#include <myx/math/almost_equal_ulps.hpp>
#include <cmath> #include <cmath>
@ -14,7 +14,6 @@ bool almost_equal_ulps( const float a, const float b,
float_cmp_t uB( b ); float_cmp_t uB( b );
// Если знаки разные, то числа не равны. // Если знаки разные, то числа не равны.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() ) if ( uA.negative() != uB.negative() )
{ {
// Кроме случая, когда +0==-0 // Кроме случая, когда +0==-0
@ -22,7 +21,7 @@ bool almost_equal_ulps( const float a, const float b,
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wfloat-equal"
#endif #endif
if ( a == b ) // -V550 if ( a == b )
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
@ -33,7 +32,6 @@ bool almost_equal_ulps( const float a, const float b,
} }
// Разница в младших битах. // Разница в младших битах.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i ); auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff ) if ( ulpsDiff <= maxUlpsDiff )
{ {
@ -50,7 +48,6 @@ bool almost_equal_ulps( const double a, const double b,
double_cmp_t uB( b ); double_cmp_t uB( b );
// Если знаки разные, то числа не равны. // Если знаки разные, то числа не равны.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() ) if ( uA.negative() != uB.negative() )
{ {
// Кроме случая, когда +0==-0 // Кроме случая, когда +0==-0
@ -58,7 +55,7 @@ bool almost_equal_ulps( const double a, const double b,
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wfloat-equal"
#endif #endif
if ( a == b ) // -V550 if ( a == b )
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
@ -69,7 +66,6 @@ bool almost_equal_ulps( const double a, const double b,
} }
// Разница в младших битах. // Разница в младших битах.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i ); auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff ) if ( ulpsDiff <= maxUlpsDiff )
{ {

View File

@ -1,5 +1,5 @@
#include <myx/math/almost_equal_ulps_and_abs.hpp>
#include <myx/math/float_cmp_types.hpp> #include <myx/math/float_cmp_types.hpp>
#include <myx/math/almost_equal_ulps_and_abs.hpp>
#include <cmath> #include <cmath>
@ -22,14 +22,12 @@ bool almost_equal_ulps_and_abs( const float a, const float b,
float_cmp_t uB( b ); float_cmp_t uB( b );
// Different signs means they do not match. // Different signs means they do not match.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() ) if ( uA.negative() != uB.negative() )
{ {
return( false ); return( false );
} }
// Find the difference in ULPs. // Find the difference in ULPs.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
int ulpsDiff = std::abs( uA.i - uB.i ); int ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff ) if ( ulpsDiff <= maxUlpsDiff )
{ {
@ -55,14 +53,12 @@ bool almost_equal_ulps_and_abs( const double a, const double b,
double_cmp_t uB( b ); double_cmp_t uB( b );
// Different signs means they do not match. // Different signs means they do not match.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() ) if ( uA.negative() != uB.negative() )
{ {
return( false ); return( false );
} }
// Find the difference in ULPs. // Find the difference in ULPs.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i ); auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff ) if ( ulpsDiff <= maxUlpsDiff )
{ {

View File

@ -15,7 +15,7 @@ namespace math {
* \return Квадрат значения * \return Квадрат значения
*/ */
template < typename T > template < typename T >
auto pow2( T const& value ) -> decltype( boost::math::pow< 2 >( value ) ) auto pow2( T const& value )->decltype( boost::math::pow< 2 >( value ) )
{ {
return( boost::math::pow< 2 >( value ) ); return( boost::math::pow< 2 >( value ) );
} }

View File

@ -11,7 +11,7 @@ template< typename ... Args >
struct QOverload struct QOverload
{ {
template< typename C, typename R > template< typename C, typename R >
static constexpr auto of( R ( C::* pmf )( Args... ) ) -> decltype( pmf ) static constexpr auto of( R ( C::* pmf )( Args... ) )->decltype( pmf )
{ {
return( pmf ); return( pmf );
} }

View File

@ -1,10 +1,9 @@
#include <myx/base/config.hpp>
#include "translators.hpp" #include "translators.hpp"
#include <myx/base/config.hpp>
#include <QCoreApplication> #include <QCoreApplication>
#include <QLibraryInfo>
#include <QLocale> #include <QLocale>
#include <QLibraryInfo>
namespace myx { namespace myx {
@ -12,10 +11,10 @@ namespace qt {
void append_translators( QTranslatorsList& translators, const QString& appName ) void append_translators( QTranslatorsList& translators, const QString& appName )
{ {
auto* translator = new QTranslator( qApp ); auto translator = new QTranslator( qApp );
if ( translator->load( QLocale(), if ( translator->load( QLocale(), appName, QStringLiteral( "_" ),
appName, QStringLiteral( "_" ), QStringLiteral( ":/qm" ) ) ) QStringLiteral( ":/qm" ) ) )
{ {
translators.append( translator ); translators.append( translator );
} }
@ -47,11 +46,11 @@ void append_translators( QTranslatorsList& translators, const QString& appName )
translator->deleteLater(); translator->deleteLater();
} }
for ( auto* i : qAsConst( translators ) ) for ( auto i : qAsConst( translators ) )
{ {
qApp->installTranslator( i ); qApp->installTranslator( i );
} }
} // append_translators } // install_translators
} // namespace qt } // namespace qt

View File

@ -1,9 +1,7 @@
#include <client.hpp> #include <client.hpp>
#include <client_p.hpp> #include <client_p.hpp>
namespace myx { using namespace qxredis;
namespace redis {
ClientPrivate::ClientPrivate( Client* client ) : ClientPrivate::ClientPrivate( Client* client ) :
lexer ( &socket ), lexer ( &socket ),
@ -50,7 +48,7 @@ Request* Client::sendCommand( const QByteArray& command )
{ {
d->socket.write( command + "\r\n" ); d->socket.write( command + "\r\n" );
auto* request = new Request( this ); auto request = new Request( this );
d->queue.enqueue( request ); d->queue.enqueue( request );
return( request ); return( request );
} }
@ -66,7 +64,3 @@ bool Client::waitForDisconnected( int msecs )
{ {
return( d->socket.waitForDisconnected( msecs ) ); return( d->socket.waitForDisconnected( msecs ) );
} }
} // namespace redis
} // namespace myx

View File

@ -1,5 +1,5 @@
#ifndef MYX_REDIS_CLIENT_HPP_ #ifndef QXREDIS_CLIENT_HPP_
#define MYX_REDIS_CLIENT_HPP_ #define QXREDIS_CLIENT_HPP_
#include <QObject> #include <QObject>
#include <QScopedPointer> #include <QScopedPointer>
@ -7,16 +7,15 @@
#include <config.hpp> #include <config.hpp>
#include <request.hpp> #include <request.hpp>
namespace myx { namespace qxredis
{
namespace redis { class QXREDIS_EXPORT ClientPrivate;
class MYX_REDIS_EXPORT ClientPrivate;
/** /**
* @brief Provides access to a Redis server * @brief Provides access to a Redis server
*/ */
class MYX_REDIS_EXPORT Client : public QObject class QXREDIS_EXPORT Client : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -104,10 +103,8 @@ public:
private: private:
const QScopedPointer< ClientPrivate > d; const QScopedPointer< ClientPrivate > d;
}; // class MYX_REDIS_EXPORT }; // class QXREDIS_EXPORT
} // namespace redis } // namespace QXRedis
} // namespace myx #endif // QXREDIS_CLIENT_HPP_
#endif // MYX_REDIS_CLIENT_HPP_

View File

@ -1,5 +1,5 @@
#ifndef MYX_REDIS_CLIENT_P_HPP_ #ifndef QREDIS_CLIENT_P_H
#define MYX_REDIS_CLIENT_P_HPP_ #define QREDIS_CLIENT_P_H
#include <QObject> #include <QObject>
#include <QQueue> #include <QQueue>
@ -11,9 +11,8 @@
#include <lexer.hpp> #include <lexer.hpp>
#include <parser.hpp> #include <parser.hpp>
namespace myx { namespace qxredis
{
namespace redis {
class ClientPrivate : public QObject class ClientPrivate : public QObject
{ {
@ -29,10 +28,9 @@ public:
Parser parser; Parser parser;
private: private:
Q_SLOT void sendReply(const myx::redis::Reply & ); Q_SLOT void sendReply(const qxredis::Reply & );
}; // class ClientPrivate }; // class ClientPrivate
} } // namespace QRedis
}
#endif // MYX_REDIS_CLIENT_P_HPP_ #endif // QREDIS_CLIENT_H

View File

@ -1,14 +1,15 @@
#ifndef MYX_REDIS_CONFIG_HPP_ #ifndef QXREDIS_CONFIG_HPP_
#define MYX_REDIS_CONFIG_HPP_ #define QXREDIS_CONFIG_HPP_
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
// #if defined( qredis_EXPORTS ) // #if defined( qredis_EXPORTS )
#define MYX_REDIS_EXPORT Q_DECL_EXPORT #define QXREDIS_EXPORT Q_DECL_EXPORT
// #else // #else
// #define MYX_REDIS_EXPORT Q_DECL_IMPORT // #define QXREDIS_EXPORT Q_DECL_IMPORT
// #endif // #endif
#include "cmlib_config.hpp"
#include "config_flags.hpp" #include "config_flags.hpp"
#endif // MYX_REDIS_CONFIG_HPP_ #endif // QXREDIS_CONFIG_HPP_

View File

@ -4,3 +4,4 @@
// #cmakedefine // #cmakedefine
#endif /* @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_ */ #endif /* @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_ */

View File

@ -1,8 +1,6 @@
#include "lexer.hpp" #include "lexer.hpp"
namespace myx { using namespace qxredis;
namespace redis {
Lexer::Lexer( QIODevice* device, QObject* parent ) : Lexer::Lexer( QIODevice* device, QObject* parent ) :
QObject ( parent ), QObject ( parent ),
@ -102,7 +100,7 @@ bool Lexer::readUnsafeString()
bool Lexer::readSafeString() bool Lexer::readSafeString()
{ {
if ( m_buffer.size() - m_length < 2 ) if ( m_buffer.size() < m_length + 2 )
{ {
return( false ); return( false );
} }
@ -115,7 +113,3 @@ bool Lexer::readSafeString()
m_state = DoingNothing; m_state = DoingNothing;
return( true ); return( true );
} }
} // namespace redis
} // namespace myx

View File

@ -1,12 +1,11 @@
#ifndef MYX_REDIS_LEXER_HPP_ #ifndef QXREDIS_LEXER_HPP_
#define MYX_REDIS_LEXER_HPP_ #define QXREDIS_LEXER_HPP_
#include <QIODevice> #include <QIODevice>
#include <QObject> #include <QObject>
namespace myx { namespace qxredis
{
namespace redis {
class Lexer : public QObject class Lexer : public QObject
{ {
@ -47,8 +46,6 @@ private:
int m_length; int m_length;
}; // class Lexer }; // class Lexer
} // namespace redis } // namespace QRedis
} // namespace myx #endif // QREDIS_LEXER_H
#endif // MYX_REDIS_LEXER_HPP_

View File

@ -1,8 +1,6 @@
#include "parser.hpp" #include "parser.hpp"
namespace myx { using namespace qxredis;
namespace redis {
Parser::Parser( Lexer* lexer, QObject* parent ) : Parser::Parser( Lexer* lexer, QObject* parent ) :
QObject( parent ) QObject( parent )
@ -76,7 +74,3 @@ void Parser::descend()
tos().reply.value().toList().append( QVariant::fromValue( r ) ); tos().reply.value().toList().append( QVariant::fromValue( r ) );
} }
} }
} // namespace redis
} // namespace myx

View File

@ -1,5 +1,5 @@
#ifndef MYX_REDIS_PARSER_HPP_ #ifndef QREDIS_PARSER_H
#define MYX_REDIS_PARSER_HPP_ #define QREDIS_PARSER_H
#include <QList> #include <QList>
#include <QObject> #include <QObject>
@ -9,9 +9,8 @@
#include <reply.hpp> #include <reply.hpp>
#include <lexer.hpp> #include <lexer.hpp>
namespace myx { namespace qxredis
{
namespace redis {
class Parser : public QObject class Parser : public QObject
{ {
@ -21,7 +20,7 @@ public:
Parser( Lexer*, QObject* = nullptr ); Parser( Lexer*, QObject* = nullptr );
virtual ~Parser() = default; virtual ~Parser() = default;
Q_SIGNAL void reply( const myx::redis::Reply& ); Q_SIGNAL void reply( const qxredis::Reply& );
private: private:
Q_SLOT void readCharacter( const char ); Q_SLOT void readCharacter( const char );
@ -50,8 +49,6 @@ public:
Task& tos() { return( stack.last() ); } Task& tos() { return( stack.last() ); }
}; // class Parser }; // class Parser
} // namespace redis } // namespace QRedis
} // namespace myx #endif // QREDIS_PARSER_H
#endif // MYX_REDIS_PARSER_HPP_

View File

@ -1,18 +1,17 @@
#ifndef MYX_REDIS_REPLY_HPP_ #ifndef QXREDIS_REPLY_HPP_
#define MYX_REDIS_REPLY_HPP_ #define QXREDIS_REPLY_HPP_
#include <QVariant> #include <QVariant>
#include <config.hpp> #include <config.hpp>
namespace myx { namespace qxredis
{
namespace redis {
/** /**
* @brief Represents a Redis reply * @brief Represents a Redis reply
*/ */
class MYX_REDIS_EXPORT Reply class QXREDIS_EXPORT Reply
{ {
public: public:
@ -99,12 +98,10 @@ private:
Type _type; Type _type;
QVariant _value; QVariant _value;
}; // class MYX_REDIS_EXPORT Reply }; // class QXREDIS_EXPORT Reply
} // namespace redis } // namespace qxredis
} // namespace myx Q_DECLARE_METATYPE( qxredis::Reply )
Q_DECLARE_METATYPE( myx::redis::Reply ) #endif // QXREDIS_REPLY_HPP_
#endif // MYX_REDIS_REPLY_HPP_

View File

@ -3,9 +3,7 @@
#include <request.hpp> #include <request.hpp>
#include <request_p.hpp> #include <request_p.hpp>
namespace myx { using namespace qxredis;
namespace redis {
void RequestPrivate::quitEventLoop() void RequestPrivate::quitEventLoop()
{ {
@ -36,7 +34,3 @@ bool Request::waitForReply( int msecs )
*/ */
return( ( d->loop.exec( QEventLoop::ExcludeUserInputEvents ) != 0 ) ); return( ( d->loop.exec( QEventLoop::ExcludeUserInputEvents ) != 0 ) );
} }
} // namespace redis
} // namespace myx

View File

@ -1,5 +1,5 @@
#ifndef MYX_REDIS_REQUEST_HPP_ #ifndef QREDIS_REQUEST_H
#define MYX_REDIS_REQUEST_HPP_ #define QREDIS_REQUEST_H
#include <QObject> #include <QObject>
#include <QScopedPointer> #include <QScopedPointer>
@ -7,16 +7,15 @@
#include <config.hpp> #include <config.hpp>
#include <reply.hpp> #include <reply.hpp>
namespace myx { namespace qxredis
{
namespace redis { class QXREDIS_EXPORT RequestPrivate;
class MYX_REDIS_EXPORT RequestPrivate;
/** /**
* @brief Represents a Redis command and its response * @brief Represents a Redis command and its response
*/ */
class MYX_REDIS_EXPORT Request : public QObject class QXREDIS_EXPORT Request : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -44,15 +43,13 @@ public:
* @brief Emitted when a reply is received * @brief Emitted when a reply is received
* @param reply the reply received * @param reply the reply received
*/ */
Q_SIGNAL void reply( const myx::redis::Reply& reply ); Q_SIGNAL void reply( const qxredis::Reply& reply );
private: private:
const QScopedPointer< RequestPrivate > d; const QScopedPointer< RequestPrivate > d;
}; // class MYX_REDIS_EXPORT }; // class QXREDIS_EXPORT
} // namespace redis } // namespace QRedis
} // namespace myx #endif // QREDIS_REQUEST_H
#endif // MYX_REDIS_REQUEST_HPP_

View File

@ -1,12 +1,11 @@
#ifndef MYX_REDIS_REQUEST_P_HPP_ #ifndef QREDIS_REQUEST_P_H
#define MYX_REDIS_REQUEST_P_HPP_ #define QREDIS_REQUEST_P_H
#include <QEventLoop> #include <QEventLoop>
#include <QObject> #include <QObject>
namespace myx { namespace qxredis
{
namespace redis {
class RequestPrivate : public QObject class RequestPrivate : public QObject
{ {
@ -19,7 +18,6 @@ public:
Q_SLOT void quitEventLoop(); Q_SLOT void quitEventLoop();
}; };
} } // namespace QRedis
} #endif // QREDIS_REQUEST_P_H
#endif // MYX_REDIS_REQUEST_P_HPP_