Merge branch 'master' of gitlab.2:f1x1t/myxlib

This commit is contained in:
2019-10-19 06:47:55 +03:00
28 changed files with 302 additions and 66 deletions

View 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
View File

@ -0,0 +1 @@
#include "config.hpp"

7
src/myx/base/config.hpp Normal file
View 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_

View 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_ */

View 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)

View 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

View 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_

View 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
View 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
View 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
View 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
View 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
View 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
View 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_

View 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

View 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_