Merge branch 'master' of gitlab.2:f1x1t/myxlib
This commit is contained in:
47
src/myx/base/CMakeLists.txt
Normal file
47
src/myx/base/CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
||||
# Название основной цели и имя библиотеки в текущем каталоге
|
||||
set(current_target base)
|
||||
|
||||
set(current_target_sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.cpp
|
||||
)
|
||||
|
||||
# Список заголовочных файлов (используется для установки)
|
||||
set(current_target_headers
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
|
||||
)
|
||||
|
||||
add_common_library(TARGET ${current_target} OUTPUT_NAME myx-${current_target}
|
||||
SOURCES ${current_target_sources} ${current_target_headers})
|
||||
common_target_properties(${current_target})
|
||||
add_clang_tidy_check(${current_target} ${current_target_sources})
|
||||
add_clang_analyze_check(${current_target} ${current_target_sources})
|
||||
add_clazy_check(${current_target} ${current_target_sources})
|
||||
add_pvs_check(${current_target})
|
||||
add_uncrustify_format(${current_target} ${current_target_sources} ${current_target_headers})
|
||||
|
||||
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||
|
||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||
add_custom_target(${current_target}-install-headers
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
|
||||
)
|
||||
|
||||
set_target_properties(${current_target}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME myx-base
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# Правила для установки
|
||||
install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
install(FILES ${CMAKE_BINARY_DIR}/include/cmlib_config.hpp
|
||||
${CMAKE_BINARY_DIR}/include/config_flags.hpp
|
||||
${current_target_headers}
|
||||
COMPONENT headers
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${current_target})
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${current_target}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
1
src/myx/base/config.cpp
Normal file
1
src/myx/base/config.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "config.hpp"
|
7
src/myx/base/config.hpp
Normal file
7
src/myx/base/config.hpp
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef MYX_BASE_CONFIG_HPP_
|
||||
#define MYX_BASE_CONFIG_HPP_
|
||||
|
||||
#include "cmlib_config.hpp"
|
||||
#include "config_flags.hpp"
|
||||
|
||||
#endif // MYX_BASE_CONFIG_HPP_
|
7
src/myx/base/config_flags.hpp.in
Normal file
7
src/myx/base/config_flags.hpp.in
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_
|
||||
#define @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_
|
||||
|
||||
// #cmakedefine
|
||||
|
||||
#endif /* @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_ */
|
||||
|
54
src/myx/filesystem/CMakeLists.txt
Normal file
54
src/myx/filesystem/CMakeLists.txt
Normal file
@ -0,0 +1,54 @@
|
||||
# Название основной цели и имя библиотеки в текущем каталоге
|
||||
set(current_target filesystem)
|
||||
|
||||
# Список файлов исходных текстов
|
||||
set(current_target_sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/whereami.cpp
|
||||
)
|
||||
|
||||
# Список заголовочных файлов (используется для установки)
|
||||
set(current_target_headers
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/whereami.hpp
|
||||
)
|
||||
|
||||
add_common_library(TARGET ${current_target}
|
||||
OUTPUT_NAME myx-${current_target}
|
||||
SOURCES ${current_target_sources})
|
||||
common_target_properties(${current_target})
|
||||
|
||||
add_clang_tidy_check(${current_target} ${current_target_sources})
|
||||
add_clang_analyze_check(${current_target} ${current_target_sources})
|
||||
add_clazy_check(${current_target} ${current_target_sources})
|
||||
add_pvs_check(${current_target})
|
||||
add_uncrustify_format(${current_target} ${current_target_sources} ${current_target_headers})
|
||||
|
||||
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||
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 PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||
target_include_directories(${current_target} PRIVATE ${CMAKE_BINARY_DIR}/include)
|
||||
|
||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||
add_custom_target(${current_target}-install-headers
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
|
||||
)
|
||||
|
||||
set_target_properties(${current_target}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME myx-filesystem
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# Правила для установки
|
||||
install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
install(FILES ${current_target_headers}
|
||||
COMPONENT headers
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${current_target})
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${current_target}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
247
src/myx/filesystem/paths.cpp
Normal file
247
src/myx/filesystem/paths.cpp
Normal file
@ -0,0 +1,247 @@
|
||||
#include "paths.hpp"
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include "whereami++.h"
|
||||
|
||||
#include <paths.h>
|
||||
#include <QString>
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
QString Paths::executableFileName() const
|
||||
{
|
||||
return( m_executableFileName );
|
||||
}
|
||||
|
||||
|
||||
void Paths::setExecutableFileName( const QString& executableFileName )
|
||||
{
|
||||
m_executableFileName = executableFileName;
|
||||
}
|
||||
|
||||
|
||||
QString Paths::configFileName() const
|
||||
{
|
||||
return( m_configFileName );
|
||||
}
|
||||
|
||||
|
||||
void Paths::setConfigFileName( const QString& configFileName )
|
||||
{
|
||||
m_configFileName = configFileName;
|
||||
}
|
||||
|
||||
|
||||
QFileInfo Paths::executableFilePath() const
|
||||
{
|
||||
return( m_executableFilePath );
|
||||
}
|
||||
|
||||
|
||||
void Paths::setExecutableFilePath( const QFileInfo& executableFilePath )
|
||||
{
|
||||
m_executableFilePath = executableFilePath;
|
||||
}
|
||||
|
||||
|
||||
QFileInfo Paths::configFilePath() const
|
||||
{
|
||||
return( m_configFilePath );
|
||||
}
|
||||
|
||||
|
||||
void Paths::setConfigFilePath( const QFileInfo& configFilePath )
|
||||
{
|
||||
m_configFilePath = configFilePath;
|
||||
}
|
||||
|
||||
|
||||
Paths::Paths()
|
||||
{
|
||||
m_prefixDirectory = "/opt/" + QCoreApplication::organizationName().toLower() +
|
||||
"/" + QCoreApplication::applicationName().toLower();
|
||||
m_binaryDirectory = m_prefixDirectory.absolutePath() + "/bin";
|
||||
m_configDirectory = m_prefixDirectory.absolutePath() + "/etc";
|
||||
m_cacheDirectory = m_prefixDirectory.absolutePath() + "/var";
|
||||
m_tempDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "TMPDIR" ) ) );
|
||||
m_dataDirectory = m_prefixDirectory.absolutePath() + "/share";
|
||||
m_homeDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "HOME" ) ) );
|
||||
m_executableFileName = QCoreApplication::applicationName().toLower();
|
||||
m_configFileName = m_executableFileName + ".conf";
|
||||
m_executableFilePath = m_binaryDirectory.absolutePath() + "/" + m_executableFileName;
|
||||
m_configFilePath = m_binaryDirectory.absolutePath() + "/" + m_configFileName;
|
||||
|
||||
|
||||
if ( m_tempDirectory.absolutePath().isEmpty() || ( m_tempDirectory.path() == "." ) )
|
||||
{
|
||||
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()
|
||||
{
|
||||
whereami::whereami_path_t executablePath = whereami::getExecutablePath();
|
||||
|
||||
m_executableFileName = QString::fromStdString( executablePath.basename() );
|
||||
m_binaryDirectory = QString::fromStdString( executablePath.dirname() );
|
||||
m_executableFilePath = QFile( m_binaryDirectory.absolutePath() + "/" + m_executableFileName );
|
||||
|
||||
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_dataDirectory = m_prefixDirectory.absolutePath() + "/share";
|
||||
m_configFilePath = QFile( m_configDirectory.absolutePath() + "/" +
|
||||
QCoreApplication::applicationName() + ".conf" );
|
||||
}
|
||||
|
||||
if ( m_prefixDirectory.absolutePath().startsWith( "/opt" ) ||
|
||||
m_prefixDirectory.absolutePath().startsWith( "/usr" ) )
|
||||
{
|
||||
QString dataDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "XDG_DATA_HOME" ) ) );
|
||||
if ( dataDirectory.isEmpty() )
|
||||
{
|
||||
dataDirectory = m_homeDirectory.absolutePath() + ".local/share";
|
||||
}
|
||||
m_dataDirectory = dataDirectory + "/" +
|
||||
QCoreApplication::organizationName().toLower() + "/" +
|
||||
QCoreApplication::applicationName().toLower();
|
||||
|
||||
QString configDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "XDG_CONFIG_HOME" ) ) );
|
||||
if ( configDirectory.isEmpty() )
|
||||
{
|
||||
configDirectory = m_homeDirectory.absolutePath() + ".config";
|
||||
}
|
||||
m_configDirectory = configDirectory + "/" +
|
||||
QCoreApplication::organizationName().toLower() + "/" +
|
||||
QCoreApplication::applicationName().toLower();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
return( true );
|
||||
} // Paths::updatePaths
|
||||
|
||||
|
||||
bool Paths::makeDefaultDirectories()
|
||||
{
|
||||
bool status = true;
|
||||
|
||||
if ( !m_dataDirectory.mkpath( m_dataDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_configDirectory.mkpath( m_configDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_cacheDirectory.mkpath( m_cacheDirectory.absolutePath() ) ) { status = false; }
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
QString Paths::findConfigFile( const QString& defaultConfigFile )
|
||||
{
|
||||
if ( QFileInfo( defaultConfigFile ).isReadable() )
|
||||
{
|
||||
m_configFilePath = defaultConfigFile;
|
||||
return( defaultConfigFile );
|
||||
}
|
||||
|
||||
auto fileName = QString::fromLocal8Bit( qgetenv( QCoreApplication::applicationName()
|
||||
.toUpper().toUtf8() + "_CONFIG" ) );
|
||||
if ( QFileInfo( fileName ).isReadable() )
|
||||
{
|
||||
m_configFilePath = fileName;
|
||||
return( fileName );
|
||||
}
|
||||
|
||||
if ( QFileInfo( m_configFilePath ).isReadable() )
|
||||
{
|
||||
return( m_configFilePath.absoluteFilePath() );
|
||||
}
|
||||
|
||||
return( QString() );
|
||||
} // Paths::findConfigFile
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
59
src/myx/filesystem/paths.hpp
Normal file
59
src/myx/filesystem/paths.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef MYX_FILESYSTEM_PATHS_HPP_
|
||||
#define MYX_FILESYSTEM_PATHS_HPP_
|
||||
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
class Paths
|
||||
{
|
||||
QDir m_prefixDirectory;
|
||||
QDir m_binaryDirectory;
|
||||
QDir m_configDirectory;
|
||||
QDir m_cacheDirectory;
|
||||
QDir m_tempDirectory;
|
||||
QDir m_dataDirectory;
|
||||
QDir m_homeDirectory;
|
||||
QString m_executableFileName;
|
||||
QString m_configFileName;
|
||||
QFileInfo m_executableFilePath;
|
||||
QFileInfo m_configFilePath;
|
||||
|
||||
public:
|
||||
Paths();
|
||||
QDir prefixDirectory() const;
|
||||
void setPrefixDirectory( const QString& prefixDirectory );
|
||||
QDir binaryDirectory() const;
|
||||
void setBinaryDirectory( const QString& binaryDirectory );
|
||||
QDir configDirectory() const;
|
||||
void setConfigDirectory( const QString& configDirectory );
|
||||
QDir cacheDirectory() const;
|
||||
void setCacheDirectory( const QString& cacheDirectory );
|
||||
QDir tempDirectory() const;
|
||||
void setTempDirectory( const QString& tempDirectory );
|
||||
QDir dataDirectory() const;
|
||||
void setDataDirectory( const QString& dataDirectory );
|
||||
QString executableFileName() const;
|
||||
void setExecutableFileName( const QString& executableFileName );
|
||||
QString configFileName() const;
|
||||
void setConfigFileName( const QString& configFileName );
|
||||
QFileInfo executableFilePath() const;
|
||||
void setExecutableFilePath( const QFileInfo& executableFilePath );
|
||||
QFileInfo configFilePath() const;
|
||||
void setConfigFilePath( const QFileInfo& configFilePath );
|
||||
|
||||
bool updatePaths();
|
||||
bool makeDefaultDirectories();
|
||||
|
||||
QString findConfigFile( const QString& defaultConfigFile = "" );
|
||||
}; // class Paths
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_FILESYSTEM_PATHS_HPP_
|
45
src/myx/log/CMakeLists.txt
Normal file
45
src/myx/log/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
||||
# Название основной цели и имя библиотеки в текущем каталоге
|
||||
set(current_target log)
|
||||
|
||||
# Список файлов исходных текстов
|
||||
set(current_target_sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spdlog.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spdlog_qt.cpp
|
||||
)
|
||||
|
||||
# Список заголовочных файлов (используется для установки)
|
||||
set(current_target_headers
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spdlog.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spdlog_qt.hpp
|
||||
)
|
||||
|
||||
add_common_library(TARGET ${current_target} OUTPUT_NAME myx-${current_target}
|
||||
SOURCES ${current_target_sources})
|
||||
common_target_properties(${current_target})
|
||||
add_clang_tidy_check(${current_target} ${current_target_sources})
|
||||
add_clang_analyze_check(${current_target} ${current_target_sources})
|
||||
add_clazy_check(${current_target} ${current_target_sources})
|
||||
add_pvs_check(${current_target})
|
||||
add_uncrustify_format(${current_target} ${current_target_sources} ${current_target_headers})
|
||||
|
||||
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||
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 PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||
add_custom_target(${current_target}-install-headers
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
|
||||
)
|
||||
|
||||
# Правила для установки
|
||||
install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
install(FILES ${current_target_headers}
|
||||
COMPONENT headers
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${current_target})
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${current_target}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
259
src/myx/log/spdlog.cpp
Normal file
259
src/myx/log/spdlog.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
#include "spdlog.hpp"
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace log {
|
||||
|
||||
Logger default_logger( "default" );
|
||||
|
||||
|
||||
Logger::Logger( std::string name ) :
|
||||
m_logger( nullptr ),
|
||||
m_name( std::move( name ) ),
|
||||
m_outputPattern( "[%H:%M:%S %z] [%n] [%^---%L---%$] %v" ),
|
||||
m_baseFileName( "default" ),
|
||||
m_maxRotatingFileSize( rotatingFileSize ),
|
||||
m_maxRotatingFilesCount( 3 ),
|
||||
m_outputLevel( spdlog::level::trace ),
|
||||
m_flushLevel( spdlog::level::warn ),
|
||||
m_nullSink( nullptr ),
|
||||
m_stdoutSink( nullptr ),
|
||||
m_stderrSink( nullptr ),
|
||||
m_syslogSink( nullptr ),
|
||||
m_basicFileSink( nullptr ),
|
||||
m_rotatingFileSink( nullptr ),
|
||||
m_dailyFileSink( nullptr )
|
||||
{
|
||||
m_logger = std::make_shared< spdlog::logger >( m_name, nullptr );
|
||||
m_logger->sinks().clear();
|
||||
m_logger->flush_on( m_flushLevel );
|
||||
m_logger->set_level( m_outputLevel );
|
||||
m_logger->set_pattern( m_outputPattern );
|
||||
}
|
||||
|
||||
|
||||
spdlog::level::level_enum Logger::outputLevel() const
|
||||
{
|
||||
return( m_outputLevel );
|
||||
}
|
||||
|
||||
|
||||
void Logger::setOutputLevel( const spdlog::level::level_enum outputLevel )
|
||||
{
|
||||
m_outputLevel = outputLevel;
|
||||
}
|
||||
|
||||
|
||||
spdlog::level::level_enum Logger::flushLevel() const
|
||||
{
|
||||
return( m_flushLevel );
|
||||
}
|
||||
|
||||
|
||||
void Logger::setFlushLevel( const spdlog::level::level_enum flushLevel )
|
||||
{
|
||||
m_flushLevel = flushLevel;
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::outputPattern() const
|
||||
{
|
||||
return( m_outputPattern );
|
||||
}
|
||||
|
||||
|
||||
void Logger::setOutputPattern( const std::string& outputPattern )
|
||||
{
|
||||
m_outputPattern = outputPattern;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr< spdlog::logger > Logger::logger()
|
||||
{
|
||||
return( m_logger );
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::name() const
|
||||
{
|
||||
return( m_name );
|
||||
}
|
||||
|
||||
|
||||
void Logger::setName( const std::string& name )
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
|
||||
std::string Logger::baseFileName() const
|
||||
{
|
||||
return( m_baseFileName );
|
||||
}
|
||||
|
||||
|
||||
void Logger::setBaseFileName( const std::string& baseFileName )
|
||||
{
|
||||
m_baseFileName = baseFileName;
|
||||
}
|
||||
|
||||
|
||||
void Logger::enableNullSink()
|
||||
{
|
||||
if ( m_nullSink == nullptr )
|
||||
{
|
||||
m_nullSink = std::make_shared< spdlog::sinks::null_sink_st >();
|
||||
m_logger->sinks().push_back( m_nullSink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::disableNullSink()
|
||||
{
|
||||
if ( m_nullSink != nullptr )
|
||||
{
|
||||
auto sinks = m_logger->sinks();
|
||||
sinks.erase( std::remove( sinks.begin(), sinks.end(), m_nullSink ), sinks.end() );
|
||||
m_nullSink.reset();
|
||||
m_nullSink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::enableStdoutSink()
|
||||
{
|
||||
if ( m_stdoutSink == nullptr )
|
||||
{
|
||||
m_stdoutSink = std::make_shared< spdlog::sinks::ansicolor_stdout_sink_st >();
|
||||
m_logger->sinks().push_back( m_stdoutSink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::disableStdoutSink()
|
||||
{
|
||||
if ( m_stdoutSink != nullptr )
|
||||
{
|
||||
auto sinks = m_logger->sinks();
|
||||
sinks.erase( std::remove( sinks.begin(), sinks.end(), m_stdoutSink ), sinks.end() );
|
||||
m_stdoutSink.reset();
|
||||
m_stdoutSink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::enableStderrSink()
|
||||
{
|
||||
if ( m_stderrSink == nullptr )
|
||||
{
|
||||
m_stderrSink = std::make_shared< spdlog::sinks::ansicolor_stderr_sink_st >();
|
||||
m_logger->sinks().push_back( m_stderrSink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::disableStderrSink()
|
||||
{
|
||||
if ( m_stderrSink != nullptr )
|
||||
{
|
||||
auto sinks = m_logger->sinks();
|
||||
sinks.erase( std::remove( sinks.begin(), sinks.end(), m_stderrSink ), sinks.end() );
|
||||
m_stderrSink.reset();
|
||||
m_stderrSink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::enableSyslogSink()
|
||||
{
|
||||
if ( m_syslogSink == nullptr )
|
||||
{
|
||||
m_syslogSink = std::make_shared< spdlog::sinks::syslog_sink_st >();
|
||||
m_logger->sinks().push_back( m_syslogSink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::disableSyslogSink()
|
||||
{
|
||||
if ( m_syslogSink != nullptr )
|
||||
{
|
||||
auto sinks = m_logger->sinks();
|
||||
sinks.erase( std::remove( sinks.begin(), sinks.end(), m_syslogSink ), sinks.end() );
|
||||
m_syslogSink.reset();
|
||||
m_syslogSink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::enableBasicFileSink()
|
||||
{
|
||||
if ( m_basicFileSink == nullptr )
|
||||
{
|
||||
m_basicFileSink = std::make_shared< spdlog::sinks::basic_file_sink_st >( m_baseFileName );
|
||||
m_logger->sinks().push_back( m_basicFileSink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::disableBasicFileSink()
|
||||
{
|
||||
if ( m_basicFileSink != nullptr )
|
||||
{
|
||||
auto sinks = m_logger->sinks();
|
||||
sinks.erase( std::remove( sinks.begin(), sinks.end(), m_basicFileSink ), sinks.end() );
|
||||
m_basicFileSink.reset();
|
||||
m_basicFileSink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::enableRotatingFileSink()
|
||||
{
|
||||
if ( m_rotatingFileSink == nullptr )
|
||||
{
|
||||
m_rotatingFileSink = std::make_shared< spdlog::sinks::rotating_file_sink_st >( m_baseFileName, m_maxRotatingFileSize, m_maxRotatingFilesCount );
|
||||
m_logger->sinks().push_back( m_rotatingFileSink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::disableRotatingFileSink()
|
||||
{
|
||||
if ( m_rotatingFileSink != nullptr )
|
||||
{
|
||||
auto sinks = m_logger->sinks();
|
||||
sinks.erase( std::remove( sinks.begin(), sinks.end(), m_rotatingFileSink ), sinks.end() );
|
||||
m_rotatingFileSink.reset();
|
||||
m_rotatingFileSink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::enableDailyFileSink()
|
||||
{
|
||||
if ( m_dailyFileSink == nullptr )
|
||||
{
|
||||
const int rotationHour = 23;
|
||||
const int rotationMinute = 59;
|
||||
m_dailyFileSink = std::make_shared< spdlog::sinks::daily_file_sink_st >( m_baseFileName, rotationHour, rotationMinute );
|
||||
m_logger->sinks().push_back( m_dailyFileSink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Logger::disableDailyFileSink()
|
||||
{
|
||||
if ( m_dailyFileSink != nullptr )
|
||||
{
|
||||
auto sinks = m_logger->sinks();
|
||||
sinks.erase( std::remove( sinks.begin(), sinks.end(), m_dailyFileSink ), sinks.end() );
|
||||
m_dailyFileSink.reset();
|
||||
m_dailyFileSink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
|
||||
} // namespace myx
|
122
src/myx/log/spdlog.hpp
Normal file
122
src/myx/log/spdlog.hpp
Normal file
@ -0,0 +1,122 @@
|
||||
#ifndef MYX_LOG_SPDLOG_HPP_
|
||||
#define MYX_LOG_SPDLOG_HPP_
|
||||
|
||||
#include <spdlog/sinks/sink.h>
|
||||
#include <spdlog/sinks/null_sink.h>
|
||||
#include <spdlog/sinks/syslog_sink.h>
|
||||
#include <spdlog/sinks/basic_file_sink.h>
|
||||
#include <spdlog/sinks/rotating_file_sink.h>
|
||||
#include <spdlog/sinks/daily_file_sink.h>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace log {
|
||||
|
||||
const size_t rotatingFileSize = 256 * 1024;
|
||||
|
||||
class Logger
|
||||
{
|
||||
std::shared_ptr< spdlog::logger > m_logger;
|
||||
std::string m_name;
|
||||
std::string m_outputPattern;
|
||||
std::string m_baseFileName;
|
||||
std::size_t m_maxRotatingFileSize;
|
||||
std::size_t m_maxRotatingFilesCount;
|
||||
spdlog::level::level_enum m_outputLevel;
|
||||
spdlog::level::level_enum m_flushLevel;
|
||||
std::shared_ptr< spdlog::sinks::null_sink_st > m_nullSink;
|
||||
std::shared_ptr< spdlog::sinks::ansicolor_stdout_sink_st > m_stdoutSink;
|
||||
std::shared_ptr< spdlog::sinks::ansicolor_stderr_sink_st > m_stderrSink;
|
||||
std::shared_ptr< spdlog::sinks::syslog_sink_st > m_syslogSink;
|
||||
std::shared_ptr< spdlog::sinks::basic_file_sink_st > m_basicFileSink;
|
||||
std::shared_ptr< spdlog::sinks::rotating_file_sink_st > m_rotatingFileSink;
|
||||
std::shared_ptr< spdlog::sinks::daily_file_sink_st > m_dailyFileSink;
|
||||
|
||||
public:
|
||||
Logger( std::string name );
|
||||
|
||||
void init();
|
||||
std::shared_ptr< spdlog::logger > logger();
|
||||
std::string name() const;
|
||||
void setName( const std::string& name );
|
||||
std::string baseFileName() const;
|
||||
void setBaseFileName( const std::string& baseFileName );
|
||||
|
||||
void enableNullSink();
|
||||
void disableNullSink();
|
||||
void enableStdoutSink();
|
||||
void disableStdoutSink();
|
||||
void enableStderrSink();
|
||||
void disableStderrSink();
|
||||
void enableSyslogSink();
|
||||
void disableSyslogSink();
|
||||
void enableBasicFileSink();
|
||||
void disableBasicFileSink();
|
||||
void enableRotatingFileSink();
|
||||
void disableRotatingFileSink();
|
||||
void enableDailyFileSink();
|
||||
void disableDailyFileSink();
|
||||
spdlog::level::level_enum outputLevel() const;
|
||||
void setOutputLevel( const spdlog::level::level_enum outputLevel );
|
||||
spdlog::level::level_enum flushLevel() const;
|
||||
void setFlushLevel( const spdlog::level::level_enum flushLevel );
|
||||
std::string outputPattern() const;
|
||||
void setOutputPattern( const std::string& outputPattern );
|
||||
}; // class Logger
|
||||
|
||||
extern Logger default_logger;
|
||||
|
||||
|
||||
template < class F, class ... Args >
|
||||
void trace( F&& format, Args&& ... args ) noexcept
|
||||
{
|
||||
default_logger.logger()->trace( std::forward< F >( format ),
|
||||
std::forward< Args >( args )... );
|
||||
}
|
||||
|
||||
|
||||
template < class F, class ... Args >
|
||||
void debug( F&& format, Args&& ... args ) noexcept
|
||||
{
|
||||
default_logger.logger()->debug( std::forward< F >( format ),
|
||||
std::forward< Args >( args )... );
|
||||
}
|
||||
|
||||
|
||||
template < class F, class ... Args >
|
||||
void info( F&& format, Args&& ... args ) noexcept
|
||||
{
|
||||
default_logger.logger()->info( std::forward< F >( format ),
|
||||
std::forward< Args >( args )... );
|
||||
}
|
||||
|
||||
|
||||
template < class F, class ... Args >
|
||||
void warn( F&& format, Args&& ... args ) noexcept
|
||||
{
|
||||
default_logger.logger()->warn( std::forward< F >( format ),
|
||||
std::forward< Args >( args )... );
|
||||
}
|
||||
|
||||
|
||||
template < class F, class ... Args >
|
||||
void error( F&& format, Args&& ... args ) noexcept
|
||||
{
|
||||
default_logger.logger()->error( std::forward< F >( format ),
|
||||
std::forward< Args >( args )... );
|
||||
}
|
||||
|
||||
|
||||
template < class F, class ... Args >
|
||||
void log( spdlog::level::level_enum lv, F&& format, Args&& ... args ) noexcept
|
||||
{
|
||||
default_logger.logger()->log( lv, std::forward< F >( format ),
|
||||
std::forward< Args >( args )... );
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
|
||||
} // namespace myx
|
||||
|
||||
|
||||
#endif // ifndef MYX_LOG_SPDLOG_HPP_
|
44
src/myx/log/spdlog_qt.cpp
Normal file
44
src/myx/log/spdlog_qt.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "spdlog.hpp"
|
||||
#include "spdlog_qt.hpp"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace log {
|
||||
|
||||
void spdlog_qt_message_handler( QtMsgType type, const QMessageLogContext& context, const QString& qMsg )
|
||||
{
|
||||
Q_UNUSED( context )
|
||||
|
||||
if ( !default_logger.logger() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto message = qMsg.toUtf8();
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case QtDebugMsg:
|
||||
default_logger.logger()->debug( message.constData() );
|
||||
break;
|
||||
case QtInfoMsg:
|
||||
default_logger.logger()->info( message.constData() );
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
default_logger.logger()->warn( message.constData() );
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
default_logger.logger()->critical( message.constData() );
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
default_logger.logger()->critical( "FATAL: %s", message.constData() );
|
||||
QCoreApplication::exit( 1 );
|
||||
break;
|
||||
}
|
||||
} // messageHandler
|
||||
|
||||
} // namespace log
|
||||
|
||||
} // namespace myx
|
18
src/myx/log/spdlog_qt.hpp
Normal file
18
src/myx/log/spdlog_qt.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef MYX_LOG_SPDLOG_QT_HPP_
|
||||
#define MYX_LOG_SPDLOG_QT_HPP_
|
||||
|
||||
#include <QMessageLogContext>
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace log {
|
||||
|
||||
void spdlog_qt_message_handler( QtMsgType type, const QMessageLogContext& context, const QString& qMsg );
|
||||
|
||||
} // namespace log
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_LOG_SPDLOG_QT_HPP_
|
43
src/myx/qt/CMakeLists.txt
Normal file
43
src/myx/qt/CMakeLists.txt
Normal file
@ -0,0 +1,43 @@
|
||||
# Название основной цели и имя библиотеки в текущем каталоге
|
||||
set(current_target qt)
|
||||
|
||||
# Список файлов исходных текстов
|
||||
set(current_target_sources ${CMAKE_CURRENT_SOURCE_DIR}/translators.cpp)
|
||||
|
||||
# Список заголовочных файлов (используется для установки)
|
||||
set(current_target_headers ${CMAKE_CURRENT_SOURCE_DIR}/backports.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp)
|
||||
|
||||
add_common_library(TARGET ${current_target}
|
||||
OUTPUT_NAME myx-${current_target}
|
||||
SOURCES ${current_target_sources})
|
||||
common_target_properties(${current_target})
|
||||
add_clang_tidy_check(${current_target} ${current_target_sources})
|
||||
add_clang_analyze_check(${current_target} ${current_target_sources})
|
||||
add_clazy_check(${current_target} ${current_target_sources})
|
||||
add_pvs_check(${current_target})
|
||||
add_uncrustify_format(${current_target} ${current_target_sources} ${current_target_headers})
|
||||
|
||||
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||
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 PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
# Цель, используемая только для установки заголовочных файлов без компиляции
|
||||
# проекта
|
||||
add_custom_target(${current_target}-install-headers
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=headers
|
||||
-P
|
||||
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
|
||||
# Правила для установки
|
||||
install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
install(FILES ${current_target_headers}
|
||||
COMPONENT headers
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${current_target})
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${current_target}.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
31
src/myx/qt/backports.hpp
Normal file
31
src/myx/qt/backports.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef MYX_QT_BACKPORTS_HPP_
|
||||
#define MYX_QT_BACKPORTS_HPP_
|
||||
|
||||
#if ( defined ( TARGET_LSB_ID_AstraLinuxSE ) && defined ( TARGET_LSB_CODENAME_smolensk ) )
|
||||
|
||||
#define override
|
||||
|
||||
#if QT_VERSION <= 0x050700
|
||||
#include <QtGlobal>
|
||||
template< typename ... Args >
|
||||
struct QOverload
|
||||
{
|
||||
template< typename C, typename R >
|
||||
static constexpr auto of( R ( C::* pmf )( Args... ) )->decltype( pmf )
|
||||
{
|
||||
return( pmf );
|
||||
}
|
||||
};
|
||||
|
||||
// this adds const to non-const objects (like std::as_const)
|
||||
template < typename T >
|
||||
Q_DECL_CONSTEXPR typename std::add_const< T >::type& qAsConst( T& t ) noexcept { return( t ); }
|
||||
// prevent rvalue arguments:
|
||||
template < typename T >
|
||||
void qAsConst( const T&& ) = delete;
|
||||
|
||||
|
||||
#endif // if QT_VERSION <= 0x050700
|
||||
#endif // if ( defined ( TARGET_LSB_ID_AstraLinuxSE ) && defined ( TARGET_LSB_CODENAME_smolensk ) )
|
||||
|
||||
#endif // MYX_QT_BACKPORTS_HPP_
|
57
src/myx/qt/translators.cpp
Normal file
57
src/myx/qt/translators.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include <myx/base/config.hpp>
|
||||
#include "translators.hpp"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QLocale>
|
||||
#include <QLibraryInfo>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace qt {
|
||||
|
||||
void append_translators( QTranslatorsList& translators, const QString& appName )
|
||||
{
|
||||
auto* translator = new QTranslator( qApp );
|
||||
|
||||
if ( translator->load( QLocale(), appName, QStringLiteral( "_" ),
|
||||
QStringLiteral( ":/qm" ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
translator = new QTranslator( qApp );
|
||||
if ( translator->load( QLocale::system(),
|
||||
QStringLiteral( "qt" ), QStringLiteral( "_" ),
|
||||
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
translator = new QTranslator( qApp );
|
||||
if ( translator->load( QStringLiteral( "qtbase_" ) + QLocale::system().name(),
|
||||
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
for ( auto i : qAsConst( translators ) )
|
||||
{
|
||||
qApp->installTranslator( i );
|
||||
}
|
||||
} // install_translators
|
||||
|
||||
} // namespace qt
|
||||
|
||||
} // namespace myx
|
20
src/myx/qt/translators.hpp
Normal file
20
src/myx/qt/translators.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef MYX_LOG_QT_TRANSLATORS_HPP_
|
||||
#define MYX_LOG_QT_TRANSLATORS_HPP_
|
||||
|
||||
#include <myx/qt/backports.hpp>
|
||||
|
||||
#include <QTranslator>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace qt {
|
||||
|
||||
typedef QList< QTranslator* > QTranslatorsList;
|
||||
|
||||
void append_translators( QTranslatorsList& translators, const QString& appName );
|
||||
|
||||
} // namespace qt
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_LOG_QT_TRANSLATORS_HPP_
|
Reference in New Issue
Block a user