Merge branch 'master' of gitlab.2:f1x1t/myxlib
This commit is contained in:
commit
0a544a773d
198
.gitignore
vendored
198
.gitignore
vendored
@ -1,8 +1,200 @@
|
|||||||
CMakeLists.txt.user*
|
# Каталог для результатов сборки проекта
|
||||||
_build
|
_build
|
||||||
|
|
||||||
|
# Каталог для тестирования установки
|
||||||
_output
|
_output
|
||||||
.cmake/
|
|
||||||
*.autosave
|
# Файлы настроек, редактируемые во время отладки,
|
||||||
|
# за исключением шаблонных файлов
|
||||||
|
files/etc/*.conf
|
||||||
|
!files/etc/*.example.conf
|
||||||
|
|
||||||
|
# Каталоги, в которые разрешена запись данных во время работы программы
|
||||||
files/lib/*
|
files/lib/*
|
||||||
files/log/*
|
files/log/*
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### Общие настройки для C, C++, Fortran, Qt, CMake, Ninja, LaTeX и редакторов
|
||||||
|
###
|
||||||
|
|
||||||
|
###
|
||||||
|
### Временные файлы текстовых редакторов
|
||||||
|
###
|
||||||
|
*.bak
|
||||||
|
*.gho
|
||||||
|
*.tmp
|
||||||
|
*.dotdropbak
|
||||||
|
|
||||||
|
###
|
||||||
|
### LyX
|
||||||
|
###
|
||||||
|
*.lyx~
|
||||||
|
*.lyx#
|
||||||
|
|
||||||
|
###
|
||||||
|
### Vim
|
||||||
|
###
|
||||||
|
# Swap
|
||||||
|
[._]*.s[a-v][a-z]
|
||||||
|
!*.svg # comment out if you don't need vector files
|
||||||
|
[._]*.sw[a-p]
|
||||||
|
[._]s[a-rt-v][a-z]
|
||||||
|
[._]ss[a-gi-z]
|
||||||
|
[._]sw[a-p]
|
||||||
|
|
||||||
|
# Temporary
|
||||||
|
.netrwhist
|
||||||
|
*~
|
||||||
|
# Auto-generated tag files
|
||||||
|
tags
|
||||||
|
# Persistent undo
|
||||||
|
[._]*.un~
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### C++
|
||||||
|
###
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### CMake
|
||||||
|
###
|
||||||
|
CMakeLists.txt.user*
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Testing
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
_deps
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### Ninja
|
||||||
|
###
|
||||||
|
.ninja_deps
|
||||||
|
.ninja_log
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### GCC coverage testing tool files
|
||||||
|
###
|
||||||
|
*.gcno
|
||||||
|
*.gcda
|
||||||
|
*.gcov
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### Qt
|
||||||
|
###
|
||||||
|
object_script.*.Release
|
||||||
|
object_script.*.Debug
|
||||||
|
*_plugin_import.cpp
|
||||||
|
/.qmake.cache
|
||||||
|
/.qmake.stash
|
||||||
|
*.pro.user
|
||||||
|
*.pro.user.*
|
||||||
|
*.qbs.user
|
||||||
|
*.qbs.user.*
|
||||||
|
*.moc
|
||||||
|
moc_*.cpp
|
||||||
|
moc_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
*.qmlc
|
||||||
|
*.jsc
|
||||||
|
Makefile*
|
||||||
|
*build-*
|
||||||
|
*.qm
|
||||||
|
*.prl
|
||||||
|
|
||||||
|
# Qt unit tests
|
||||||
|
target_wrapper.*
|
||||||
|
|
||||||
|
# QtCreator
|
||||||
|
*.autosave
|
||||||
|
|
||||||
|
# QtCreator Qml
|
||||||
|
*.qmlproject.user
|
||||||
|
*.qmlproject.user.*
|
||||||
|
|
||||||
|
# QtCreator local machine specific files for imported projects
|
||||||
|
*creator.user*
|
||||||
|
|
||||||
|
*_qmlcache.qrc
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### Latex
|
||||||
|
###
|
||||||
|
*.acn
|
||||||
|
*.acr
|
||||||
|
*.alg
|
||||||
|
*.aux
|
||||||
|
*.bbl
|
||||||
|
*.blg
|
||||||
|
*.dvi
|
||||||
|
*.fdb_latexmk
|
||||||
|
*.glg
|
||||||
|
*.glo
|
||||||
|
*.gls
|
||||||
|
*.idx
|
||||||
|
*.ilg
|
||||||
|
*.ind
|
||||||
|
*.ist
|
||||||
|
*.lof
|
||||||
|
*.log
|
||||||
|
*.lot
|
||||||
|
*.maf
|
||||||
|
*.mtc
|
||||||
|
*.mtc0
|
||||||
|
*.nav
|
||||||
|
*.nlo
|
||||||
|
*.out
|
||||||
|
*.pdfsync
|
||||||
|
*.ps
|
||||||
|
*.snm
|
||||||
|
*.synctex.gz
|
||||||
|
*.toc
|
||||||
|
*.vrb
|
||||||
|
*.xdy
|
||||||
|
*.tdo
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
include:
|
include:
|
||||||
- local: .gitlab-ci/scheduled.yml
|
- project: 'f1x1t/gitlab-ci'
|
||||||
|
ref: master
|
||||||
|
file: 'scheduled.yml'
|
||||||
|
|
||||||
smolensk15-nightly:
|
smolensk15-nightly:
|
||||||
extends: .scheduled-smolensk15
|
extends: .scheduled-smolensk15
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
variables:
|
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
|
||||||
GET_SOURCES_ATTEMPTS: 10
|
|
||||||
|
|
||||||
.scheduled-test:
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- schedules
|
|
||||||
cache:
|
|
||||||
paths: ['*.status']
|
|
||||||
before_script:
|
|
||||||
- >
|
|
||||||
if [ -f "${CI_JOB_NAME}.status" ]; then
|
|
||||||
if [ "$(cat ${CI_JOB_NAME}.status)" == "${CI_COMMIT_SHA}" ]; then
|
|
||||||
echo "=== Commit ${CI_COMMIT_SHORT_SHA} already tested with job ${CI_JOB_NAME} ==="
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
- >
|
|
||||||
if [ -n "${APT_UPDATE_CMD}" ]; then
|
|
||||||
${APT_UPDATE_CMD}
|
|
||||||
fi
|
|
||||||
- >
|
|
||||||
if [ -n "${APT_INSTALL_CMD}" ]; then
|
|
||||||
${APT_INSTALL_CMD}
|
|
||||||
fi
|
|
||||||
script:
|
|
||||||
- >
|
|
||||||
if [ -f "${CI_JOB_NAME}.status" ]; then
|
|
||||||
if [ "$(cat ${CI_JOB_NAME}.status)" == "${CI_COMMIT_SHA}" ]; then
|
|
||||||
echo "=== Commit ${CI_COMMIT_SHORT_SHA} already tested with job ${CI_JOB_NAME} ==="
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
- rm -f ${CI_JOB_NAME}.status
|
|
||||||
- mkdir build
|
|
||||||
- cd build
|
|
||||||
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=_output -DCPACK_PACKAGING_INSTALL_PREFIX=/opt/rtis -DMYXLIB_BUILD_EXAMPLES_HO=ON -DMYXLIB_BUILD_LIBRARIES=ON -DMYXLIB_BUILD_EXAMPLES=ON ..
|
|
||||||
- ninja
|
|
||||||
- >
|
|
||||||
if [ -z "${CI_SHARED_ENVIRONMENT+x}" ]; then
|
|
||||||
ninja install
|
|
||||||
ninja package
|
|
||||||
ninja package_source
|
|
||||||
ninja deb
|
|
||||||
fi
|
|
||||||
- echo "${CI_COMMIT_SHA}" > "../${CI_JOB_NAME}.status"
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- build/*.xz
|
|
||||||
- build/*.deb
|
|
||||||
when: on_success
|
|
||||||
expire_in: 10 days
|
|
||||||
|
|
||||||
|
|
||||||
.scheduled-smolensk15:
|
|
||||||
extends: .scheduled-test
|
|
||||||
image: smolensk15-dev
|
|
||||||
tags: ['docker']
|
|
||||||
|
|
||||||
.scheduled-orel212:
|
|
||||||
extends: .scheduled-test
|
|
||||||
image: orel212-dev
|
|
||||||
tags: ['docker']
|
|
||||||
|
|
||||||
.scheduled-bionic:
|
|
||||||
extends: .scheduled-test
|
|
||||||
image: bionic-dev
|
|
||||||
tags: ['docker']
|
|
||||||
|
|
||||||
.scheduled-focal:
|
|
||||||
extends: .scheduled-test
|
|
||||||
image: focal-dev
|
|
||||||
tags: ['docker']
|
|
||||||
|
|
||||||
.scheduled-elbrus:
|
|
||||||
extends: .scheduled-test
|
|
||||||
tags: ['elbrus']
|
|
||||||
|
|
@ -23,11 +23,7 @@ endif()
|
|||||||
|
|
||||||
include(CMLibCommon)
|
include(CMLibCommon)
|
||||||
|
|
||||||
option(MYXLIB_BUILD_LIBRARIES "Build libraries" OFF)
|
option(MYXLIB_BUILD_EXAMPLES "Build examples" OFF)
|
||||||
if(MYXLIB_BUILD_LIBRARIES)
|
|
||||||
option(MYXLIB_BUILD_EXAMPLES "Build examples" OFF)
|
|
||||||
endif()
|
|
||||||
option(MYXLIB_BUILD_EXAMPLES_HO "Build examples using header only version" OFF)
|
|
||||||
|
|
||||||
# Поиск библиотек с помощью pkgconfig
|
# Поиск библиотек с помощью pkgconfig
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
@ -40,14 +36,20 @@ find_package(Threads REQUIRED)
|
|||||||
find_package(Qt5 COMPONENTS Core Network REQUIRED)
|
find_package(Qt5 COMPONENTS Core Network REQUIRED)
|
||||||
|
|
||||||
# Библиотеки
|
# Библиотеки
|
||||||
add_subdirectory(src/myx/base)
|
add_subdirectory(src/myx/backports/compiler)
|
||||||
|
add_subdirectory(src/myx/backports/cpp)
|
||||||
|
add_subdirectory(src/myx/backports/qt)
|
||||||
|
add_subdirectory(src/myx/core)
|
||||||
add_subdirectory(src/myx/filesystem)
|
add_subdirectory(src/myx/filesystem)
|
||||||
add_subdirectory(src/myx/qt)
|
add_subdirectory(src/myx/qt)
|
||||||
|
|
||||||
# Примеры
|
# Примеры
|
||||||
if(MYXLIB_BUILD_EXAMPLES OR MYXLIB_BUILD_EXAMPLES_HO)
|
if(MYXLIB_BUILD_EXAMPLES)
|
||||||
|
add_subdirectory(examples/core)
|
||||||
add_subdirectory(examples/filesystem)
|
add_subdirectory(examples/filesystem)
|
||||||
add_subdirectory(examples/qt)
|
add_subdirectory(examples/qt)
|
||||||
|
add_custom_target(examples example-core-endian example-filesystem-paths example-qt-tranlators
|
||||||
|
example-qt-posix-signal-watcher)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Документация
|
# Документация
|
||||||
|
@ -9,4 +9,4 @@ set(CPACK_COMPONENTS_ALL examples)
|
|||||||
set(CPACK_PACKAGE_CONTACT "Andrei Astafev <dev@246060.ru>")
|
set(CPACK_PACKAGE_CONTACT "Andrei Astafev <dev@246060.ru>")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Mixed functions")
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Mixed functions")
|
||||||
|
|
||||||
set(CMLIB_GENERATED_HEADERS_PATH ${CMAKE_BINARY_DIR}/include/myx/base)
|
set(CMLIB_GENERATED_HEADERS_PATH ${CMAKE_BINARY_DIR}/include/myx/core)
|
||||||
|
51
examples/core/01_endian/CMakeLists.txt
Normal file
51
examples/core/01_endian/CMakeLists.txt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Название основной цели в текущем каталоге
|
||||||
|
set(TRGT example-core-endian)
|
||||||
|
|
||||||
|
# Список файлов исходных текстов
|
||||||
|
set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/endian.cpp)
|
||||||
|
|
||||||
|
if(MYXLIB_BUILD_EXAMPLES)
|
||||||
|
# Путь поиска библиотек внутри проекта
|
||||||
|
link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||||
|
|
||||||
|
# Цель для создания исполняемого файла
|
||||||
|
add_executable(${TRGT} ${TRGT_cpp} ${TRGT_qrc})
|
||||||
|
common_target_properties(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clazy
|
||||||
|
add_clazy_check(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для автоматического форматирования кода
|
||||||
|
add_format_sources(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Qt5
|
||||||
|
target_include_directories(${TRGT} PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
add_dependencies(${TRGT} core)
|
||||||
|
|
||||||
|
target_link_libraries(${TRGT} Qt5::Core)
|
||||||
|
target_link_libraries(${TRGT} Threads::Threads)
|
||||||
|
|
||||||
|
# Имя выходного файла для цели
|
||||||
|
set_target_properties(${TRGT} PROPERTIES OUTPUT_NAME endian-minimal)
|
||||||
|
|
||||||
|
add_sanitizers(${TRGT})
|
||||||
|
|
||||||
|
cotire(${TRGT})
|
||||||
|
|
||||||
|
add_dependencies(${TRGT} create_auxilary_symlinks)
|
||||||
|
|
||||||
|
# Правила для установки
|
||||||
|
# install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
endif()
|
24
examples/core/01_endian/endian.cpp
Normal file
24
examples/core/01_endian/endian.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <myx/core/config.hpp>
|
||||||
|
#include <myx/core/endian_types.hpp>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
//NOLINTNEXTLINE
|
||||||
|
#define CMLIB_PROJECT_NAME "myxlib"
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
beint64 bi = 1;
|
||||||
|
int64_t bii = reinterpret_cast< int64_t* >( &bi )[0]; //NOLINT
|
||||||
|
qDebug() << hex << bi << bii;
|
||||||
|
|
||||||
|
leint64 li = 1;
|
||||||
|
int64_t lii = reinterpret_cast< int64_t* >( &li )[0]; //NOLINT
|
||||||
|
qDebug() << hex << li << lii;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
} // main
|
1
examples/core/CMakeLists.txt
Normal file
1
examples/core/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
add_subdirectory(01_endian)
|
@ -1,37 +0,0 @@
|
|||||||
#include <myx/base/config.hpp>
|
|
||||||
|
|
||||||
#include <myx/filesystem/paths.hpp>
|
|
||||||
#include <myx/filesystem/paths_mt.hpp>
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#define CMLIB_PROJECT_NAME "myxlib"
|
|
||||||
|
|
||||||
namespace MF = myx::filesystem;
|
|
||||||
|
|
||||||
// Переменные для защиты экземпляра класса MF::PathsMT
|
|
||||||
std::atomic< MF::PathsMT* > MF::PathsMT::mInstance;
|
|
||||||
std::mutex MF::PathsMT::mMutex;
|
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
|
||||||
{
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
QCoreApplication::setApplicationName( QStringLiteral( CMLIB_PROJECT_NAME ) );
|
|
||||||
MF::PathsMT& pathsMT = MF::PathsMT::instance();
|
|
||||||
MF::Paths& paths = MF::Paths::instance();
|
|
||||||
|
|
||||||
pathsMT.init( QStringLiteral( CMLIB_PROJECT_NAME ), QStringLiteral( "conf" ) );
|
|
||||||
pathsMT.findConfigFile( QStringLiteral( "test" ) );
|
|
||||||
qDebug() << pathsMT.systemLogDirectory().path();
|
|
||||||
qDebug() << pathsMT.systemConfigDirectory().path();
|
|
||||||
|
|
||||||
paths.init( QStringLiteral( CMLIB_PROJECT_NAME ), QStringLiteral( "conf" ) );
|
|
||||||
paths.findConfigFile( QStringLiteral( "test" ) );
|
|
||||||
qDebug() << paths.systemConstDataDirectory().path();
|
|
||||||
qDebug() << paths.configFileName();
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
# Название основной цели в текущем каталоге
|
# Название основной цели в текущем каталоге
|
||||||
set(TRGT example-filesystem-minimal)
|
set(TRGT example-filesystem-paths)
|
||||||
|
|
||||||
# Список файлов исходных текстов
|
# Список файлов исходных текстов
|
||||||
set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/minimal.cpp)
|
set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp)
|
||||||
|
|
||||||
if(MYXLIB_BUILD_EXAMPLES)
|
if(MYXLIB_BUILD_EXAMPLES)
|
||||||
# Путь поиска библиотек внутри проекта
|
# Путь поиска библиотек внутри проекта
|
||||||
@ -32,9 +32,9 @@ if(MYXLIB_BUILD_EXAMPLES)
|
|||||||
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||||
|
|
||||||
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
add_dependencies(${TRGT} base filesystem)
|
add_dependencies(${TRGT} core filesystem)
|
||||||
|
|
||||||
target_link_libraries(${TRGT} base_static filesystem_static)
|
target_link_libraries(${TRGT} filesystem_static)
|
||||||
target_link_libraries(${TRGT} Qt5::Core)
|
target_link_libraries(${TRGT} Qt5::Core)
|
||||||
target_link_libraries(${TRGT} Threads::Threads)
|
target_link_libraries(${TRGT} Threads::Threads)
|
||||||
|
|
||||||
@ -48,30 +48,5 @@ if(MYXLIB_BUILD_EXAMPLES)
|
|||||||
add_dependencies(${TRGT} create_auxilary_symlinks)
|
add_dependencies(${TRGT} create_auxilary_symlinks)
|
||||||
|
|
||||||
# Правила для установки
|
# Правила для установки
|
||||||
install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
# install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
endif()
|
|
||||||
|
|
||||||
if(MYXLIB_BUILD_EXAMPLES_HO)
|
|
||||||
# Цель для создания исполняемого файла
|
|
||||||
add_executable(${TRGT}-ho ${TRGT_cpp} ${TRGT_qrc})
|
|
||||||
common_target_properties(${TRGT}-ho)
|
|
||||||
|
|
||||||
target_include_directories(${TRGT}-ho PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
||||||
target_include_directories(${TRGT}-ho SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
add_dependencies(${TRGT}-ho base-header-only filesystem-header-only)
|
|
||||||
|
|
||||||
target_link_libraries(${TRGT}-ho Qt5::Core)
|
|
||||||
target_link_libraries(${TRGT}-ho Threads::Threads)
|
|
||||||
|
|
||||||
# Имя выходного файла для цели
|
|
||||||
set_target_properties(${TRGT}-ho PROPERTIES OUTPUT_NAME filesystem-minimal-ho)
|
|
||||||
|
|
||||||
add_sanitizers(${TRGT}-ho)
|
|
||||||
cotire(${TRGT}-ho)
|
|
||||||
|
|
||||||
add_dependencies(${TRGT}-ho create_auxilary_symlinks)
|
|
||||||
|
|
||||||
# Правила для установки
|
|
||||||
install(TARGETS ${TRGT}-ho COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
endif()
|
endif()
|
43
examples/filesystem/01_paths/paths.cpp
Normal file
43
examples/filesystem/01_paths/paths.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <myx/core/config.hpp>
|
||||||
|
|
||||||
|
#include <myx/filesystem/paths.hpp>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
//NOLINTNEXTLINE
|
||||||
|
#define CMLIB_PROJECT_NAME "myxlib"
|
||||||
|
|
||||||
|
namespace MF = myx::filesystem;
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
QCoreApplication::setApplicationName( QStringLiteral( CMLIB_PROJECT_NAME ) );
|
||||||
|
MF::Paths& paths = MF::Paths::instance();
|
||||||
|
|
||||||
|
paths.init( QStringLiteral( CMLIB_PROJECT_NAME ), QStringLiteral( "conf" ) );
|
||||||
|
|
||||||
|
qDebug() << "prefixDirectory : " << paths.prefixDirectory();
|
||||||
|
|
||||||
|
qDebug() << "executableName : " << paths.executableName();
|
||||||
|
qDebug() << "executableFilePath : " << paths.executableFilePath();
|
||||||
|
qDebug() << "executableDirectory : " << paths.executableDirectory();
|
||||||
|
|
||||||
|
qDebug() << "configFileName : " << paths.configFileName();
|
||||||
|
qDebug() << "configFilePath : " << paths.configFilePath();
|
||||||
|
|
||||||
|
qDebug() << "systemConfigDirectory : " << paths.systemConfigDirectory();
|
||||||
|
qDebug() << "systemConstDataDirectory : " << paths.systemConstDataDirectory();
|
||||||
|
qDebug() << "systemVarDataDirectory : " << paths.systemVarDataDirectory();
|
||||||
|
qDebug() << "systemLogDirectory : " << paths.systemLogDirectory();
|
||||||
|
|
||||||
|
qDebug() << "userConfigDirectory : " << paths.userConfigDirectory();
|
||||||
|
qDebug() << "userConstDataDirectory : " << paths.userConstDataDirectory();
|
||||||
|
qDebug() << "userVarDataDirectory : " << paths.userVarDataDirectory();
|
||||||
|
qDebug() << "userLogDirectory : " << paths.userLogDirectory();
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
} // main
|
@ -1 +1 @@
|
|||||||
add_subdirectory(01_minimal)
|
add_subdirectory(01_paths)
|
||||||
|
@ -11,7 +11,6 @@ qt5_translation(
|
|||||||
LANGUAGES ru_RU)
|
LANGUAGES ru_RU)
|
||||||
|
|
||||||
if(MYXLIB_BUILD_EXAMPLES)
|
if(MYXLIB_BUILD_EXAMPLES)
|
||||||
|
|
||||||
# Путь поиска библиотек внутри проекта
|
# Путь поиска библиотек внутри проекта
|
||||||
link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||||
|
|
||||||
@ -39,9 +38,9 @@ if(MYXLIB_BUILD_EXAMPLES)
|
|||||||
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||||
|
|
||||||
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
add_dependencies(${TRGT} base qt)
|
add_dependencies(${TRGT} core qt)
|
||||||
|
|
||||||
target_link_libraries(${TRGT} base_static qt_static)
|
target_link_libraries(${TRGT} qt_static)
|
||||||
|
|
||||||
target_link_libraries(${TRGT} Qt5::Core)
|
target_link_libraries(${TRGT} Qt5::Core)
|
||||||
target_link_libraries(${TRGT} Threads::Threads)
|
target_link_libraries(${TRGT} Threads::Threads)
|
||||||
@ -56,30 +55,5 @@ if(MYXLIB_BUILD_EXAMPLES)
|
|||||||
add_dependencies(${TRGT} create_auxilary_symlinks)
|
add_dependencies(${TRGT} create_auxilary_symlinks)
|
||||||
|
|
||||||
# Правила для установки
|
# Правила для установки
|
||||||
install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
# install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
endif()
|
|
||||||
|
|
||||||
if(MYXLIB_BUILD_EXAMPLES_HO)
|
|
||||||
# Цель для создания исполняемого файла
|
|
||||||
add_executable(${TRGT}-ho ${TRGT_cpp} ${TRGT_qrc})
|
|
||||||
common_target_properties(${TRGT}-ho)
|
|
||||||
|
|
||||||
target_include_directories(${TRGT}-ho PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
||||||
target_include_directories(${TRGT}-ho SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
add_dependencies(${TRGT}-ho base-header-only qt-header-only)
|
|
||||||
|
|
||||||
target_link_libraries(${TRGT}-ho Qt5::Core)
|
|
||||||
target_link_libraries(${TRGT}-ho Threads::Threads)
|
|
||||||
|
|
||||||
# Имя выходного файла для цели
|
|
||||||
set_target_properties(${TRGT}-ho PROPERTIES OUTPUT_NAME qt-translators-ho)
|
|
||||||
|
|
||||||
add_sanitizers(${TRGT}-ho)
|
|
||||||
cotire(${TRGT}-ho)
|
|
||||||
|
|
||||||
add_dependencies(${TRGT}-ho create_auxilary_symlinks)
|
|
||||||
|
|
||||||
# Правила для установки
|
|
||||||
install(TARGETS ${TRGT}-ho COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
endif()
|
endif()
|
||||||
|
53
examples/qt/02_posix-signal-watcher/CMakeLists.txt
Normal file
53
examples/qt/02_posix-signal-watcher/CMakeLists.txt
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# Название основной цели в текущем каталоге
|
||||||
|
set(TRGT example-qt-posix-signal-watcher)
|
||||||
|
|
||||||
|
# Список файлов исходных текстов
|
||||||
|
set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/posix_signal_watcher.cpp)
|
||||||
|
|
||||||
|
if(MYXLIB_BUILD_EXAMPLES)
|
||||||
|
# Путь поиска библиотек внутри проекта
|
||||||
|
link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||||
|
|
||||||
|
# Цель для создания исполняемого файла
|
||||||
|
add_executable(${TRGT} ${TRGT_cpp})
|
||||||
|
common_target_properties(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clazy
|
||||||
|
add_clazy_check(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для автоматического форматирования кода
|
||||||
|
add_format_sources(${TRGT} ${TRGT_cpp})
|
||||||
|
|
||||||
|
# Qt5
|
||||||
|
target_include_directories(${TRGT} PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
add_dependencies(${TRGT} core qt)
|
||||||
|
|
||||||
|
target_link_libraries(${TRGT} qt_static)
|
||||||
|
|
||||||
|
target_link_libraries(${TRGT} Qt5::Core)
|
||||||
|
target_link_libraries(${TRGT} Threads::Threads)
|
||||||
|
|
||||||
|
# Имя выходного файла для цели
|
||||||
|
set_target_properties(${TRGT} PROPERTIES OUTPUT_NAME qt-posix-signal-watcher)
|
||||||
|
|
||||||
|
add_sanitizers(${TRGT})
|
||||||
|
|
||||||
|
cotire(${TRGT})
|
||||||
|
|
||||||
|
add_dependencies(${TRGT} create_auxilary_symlinks)
|
||||||
|
|
||||||
|
# Правила для установки
|
||||||
|
# install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
endif()
|
21
examples/qt/02_posix-signal-watcher/posix_signal_watcher.cpp
Normal file
21
examples/qt/02_posix-signal-watcher/posix_signal_watcher.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <myx/qt/posix_signal_watcher.hpp>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace MQ = myx::qt;
|
||||||
|
|
||||||
|
int main( int argc, char* argv[] )
|
||||||
|
{
|
||||||
|
QCoreApplication app( argc, argv );
|
||||||
|
qDebug() << "Hello from process" << QCoreApplication::applicationPid();
|
||||||
|
|
||||||
|
MQ::PosixSignalWatcher sigwatch;
|
||||||
|
sigwatch.watchForSignal( SIGINT );
|
||||||
|
sigwatch.watchForSignal( SIGTERM );
|
||||||
|
QObject::connect( &sigwatch, &MQ::PosixSignalWatcher::posixSignal, &app, &QCoreApplication::quit );
|
||||||
|
|
||||||
|
int exitcode = QCoreApplication::exec();
|
||||||
|
qDebug() << "Goodbye";
|
||||||
|
return( exitcode );
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
add_subdirectory(01_translators)
|
add_subdirectory(01_translators)
|
||||||
|
add_subdirectory(02_posix-signal-watcher)
|
||||||
|
@ -1,17 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE TS>
|
<!DOCTYPE TS>
|
||||||
<TS version="2.1" language="ru_RU">
|
<TS version="2.1" language="ru_RU">
|
||||||
<context>
|
|
||||||
<name>QObject</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../examples/qt/01_translators/translators.cpp" line="16"/>
|
|
||||||
<source>Yes</source>
|
|
||||||
<translation>Да</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../examples/qt/01_translators/translators.cpp" line="18"/>
|
|
||||||
<source>Cancel</source>
|
|
||||||
<translation>Отмена</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
</TS>
|
</TS>
|
||||||
|
42
src/myx/backports/compiler/CMakeLists.txt
Normal file
42
src/myx/backports/compiler/CMakeLists.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Название основной цели и имя библиотеки в текущем каталоге
|
||||||
|
set(TRGT backports-compiler)
|
||||||
|
|
||||||
|
# cmake-format: off
|
||||||
|
# Список файлов исходных текстов
|
||||||
|
set(TRGT_cpp)
|
||||||
|
|
||||||
|
# Список заголовочных файлов
|
||||||
|
set(TRGT_hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/gcc.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(TRGT_headers ${TRGT_hpp})
|
||||||
|
# cmake-format: on
|
||||||
|
|
||||||
|
add_library(${TRGT} INTERFACE)
|
||||||
|
target_sources(${TRGT} INTERFACE ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clazy
|
||||||
|
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для автоматического форматирования кода
|
||||||
|
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
target_include_directories(${TRGT} INTERFACE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||||
|
install(FILES ${TRGT_headers} COMPONENT base-dev
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/backports/compiler)
|
||||||
|
|
||||||
|
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||||
|
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
||||||
|
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
29
src/myx/backports/compiler/gcc.hpp
Normal file
29
src/myx/backports/compiler/gcc.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef MYX_BACKPORTS_COMPILER_GCC_HPP_
|
||||||
|
#define MYX_BACKPORTS_COMPILER_GCC_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
#define GCC_VERSION ( __GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ )
|
||||||
|
#if GCC_VERSION <= 40702
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wkeyword-macro"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( __cplusplus < 201103L )
|
||||||
|
#define constexpr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define override
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // if GCC_VERSION <= 40702
|
||||||
|
#endif // ifdef __GNUC__
|
||||||
|
|
||||||
|
#endif // ifndef MYX_BACKPORTS_COMPILER_GCC_HPP_
|
43
src/myx/backports/cpp/CMakeLists.txt
Normal file
43
src/myx/backports/cpp/CMakeLists.txt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Название основной цели и имя библиотеки в текущем каталоге
|
||||||
|
set(TRGT backports-cpp)
|
||||||
|
|
||||||
|
# cmake-format: off
|
||||||
|
# Список файлов исходных текстов
|
||||||
|
set(TRGT_cpp)
|
||||||
|
|
||||||
|
# Список заголовочных файлов
|
||||||
|
set(TRGT_hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/helpers.hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/span.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(TRGT_headers ${TRGT_hpp})
|
||||||
|
# cmake-format: on
|
||||||
|
|
||||||
|
add_library(${TRGT} INTERFACE)
|
||||||
|
target_sources(${TRGT} INTERFACE ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clazy
|
||||||
|
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для автоматического форматирования кода
|
||||||
|
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
target_include_directories(${TRGT} INTERFACE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||||
|
install(FILES ${TRGT_headers} COMPONENT base-dev
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/backports/cpp)
|
||||||
|
|
||||||
|
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||||
|
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
||||||
|
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
43
src/myx/backports/cpp/helpers.hpp
Normal file
43
src/myx/backports/cpp/helpers.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef MYX_BACKPORTS_CPP_HELPERS_HPP_
|
||||||
|
#define MYX_BACKPORTS_CPP_HELPERS_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if ( __cplusplus >= 201103L )
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( __cplusplus >= 201103L ) && ( __cplusplus < 201402L )
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
using underlying_type_t = typename std::underlying_type< T >::type;
|
||||||
|
|
||||||
|
template< typename T, typename ... Args >
|
||||||
|
std::unique_ptr< T > make_unique( Args&&... args )
|
||||||
|
{
|
||||||
|
return( std::unique_ptr< T >( new T( std::forward< Args >( args )... ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( ( __cplusplus >= 201103L ) && ( __cplusplus < 201402L ) ) || \
|
||||||
|
( ( __cplusplus >= 201402L ) && ( __cplusplus < 201702L ) && defined( __STRICT_ANSI__ ) )
|
||||||
|
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
template< typename ... Ts > struct make_void { typedef void type; };
|
||||||
|
template< typename ... Ts > using void_t = typename make_void< Ts... >::type;
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ifndef MYX_BACKPORTS_CPP_HELPERS_HPP_
|
240
src/myx/backports/cpp/span.hpp
Normal file
240
src/myx/backports/cpp/span.hpp
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// Official repository: https://github.com/boostorg/beast
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MYX_BACKPORTS_CPP_SPAN_HPP_
|
||||||
|
#define MYX_BACKPORTS_CPP_SPAN_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if ( __cplusplus >= 201103L ) && ( __cplusplus < 201703L )
|
||||||
|
|
||||||
|
#include <myx/backports/cpp/helpers.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template< class T, class E, class = void >
|
||||||
|
struct is_contiguous_container : std::false_type {}; // NOLINT
|
||||||
|
|
||||||
|
template< class T, class E >
|
||||||
|
struct is_contiguous_container< T, E, void_t<
|
||||||
|
decltype(
|
||||||
|
std::declval< std::size_t& >() = std::declval< T const& >().size(),
|
||||||
|
std::declval< E*& >() = std::declval< T& >().data() ),
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
typename std::remove_cv< E >::type,
|
||||||
|
typename std::remove_cv<
|
||||||
|
typename std::remove_pointer<
|
||||||
|
decltype( std::declval< T& >().data() )
|
||||||
|
>::type
|
||||||
|
>::type
|
||||||
|
>::value
|
||||||
|
>::type > > : std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
/** A range of bytes expressed as a ContiguousContainer
|
||||||
|
|
||||||
|
This class implements a non-owning reference to a storage
|
||||||
|
area of a certain size and having an underlying integral
|
||||||
|
type with size of 1.
|
||||||
|
|
||||||
|
@tparam T The type pointed to by span iterators
|
||||||
|
*/
|
||||||
|
template< class T >
|
||||||
|
class span // NOLINT
|
||||||
|
{
|
||||||
|
T* m_data = nullptr;
|
||||||
|
std::size_t m_size = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// The type of value, including cv qualifiers
|
||||||
|
using ElementType = T;
|
||||||
|
|
||||||
|
/// The type of value of each span element
|
||||||
|
using ValueType = typename std::remove_const< T >::type;
|
||||||
|
|
||||||
|
/// The type of integer used to index the span
|
||||||
|
using IndexType = std::ptrdiff_t;
|
||||||
|
|
||||||
|
/// A pointer to a span element
|
||||||
|
using Pointer = T*;
|
||||||
|
|
||||||
|
/// A reference to a span element
|
||||||
|
using Reference = T&;
|
||||||
|
|
||||||
|
/// The iterator used by the container
|
||||||
|
using Iterator = Pointer;
|
||||||
|
|
||||||
|
/// The const pointer used by the container
|
||||||
|
using ConstPointer = T const*;
|
||||||
|
|
||||||
|
/// The const reference used by the container
|
||||||
|
using ConstReference = T const&;
|
||||||
|
|
||||||
|
/// The const iterator used by the container
|
||||||
|
using ConstIterator = ConstPointer;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
span() = default;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
span( span const& ) = default;
|
||||||
|
|
||||||
|
/// Assignment
|
||||||
|
span& operator=( span const& ) = default;
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
* @param data A pointer to the beginning of the range of elements
|
||||||
|
* @param size The number of elements pointed to by `data`
|
||||||
|
*/
|
||||||
|
span( T* data, std::size_t size ) :
|
||||||
|
m_data( data ),
|
||||||
|
m_size( size )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
* @param container The container to construct from
|
||||||
|
*/
|
||||||
|
template< class ContiguousContainer,
|
||||||
|
class = typename std::enable_if<
|
||||||
|
is_contiguous_container<
|
||||||
|
ContiguousContainer, T >::value >::type
|
||||||
|
>
|
||||||
|
explicit
|
||||||
|
span( ContiguousContainer&& container ) :
|
||||||
|
m_data( container.data() ),
|
||||||
|
m_size( container.size() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< class CharT, class Traits, class Allocator >
|
||||||
|
explicit
|
||||||
|
span( std::basic_string< CharT, Traits, Allocator >& s ) :
|
||||||
|
m_data( &s[0] ),
|
||||||
|
m_size( s.size() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< class CharT, class Traits, class Allocator >
|
||||||
|
explicit
|
||||||
|
span( std::basic_string< CharT, Traits, Allocator > const& s ) :
|
||||||
|
m_data( s.data() ),
|
||||||
|
m_size( s.size() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Assignment
|
||||||
|
* @param container The container to assign from
|
||||||
|
*/
|
||||||
|
template< class ContiguousContainer >
|
||||||
|
typename std::enable_if< is_contiguous_container< //NOLINT
|
||||||
|
ContiguousContainer, T >::value,
|
||||||
|
span& >::type
|
||||||
|
operator=( ContiguousContainer&& container )
|
||||||
|
{
|
||||||
|
m_data = container.data();
|
||||||
|
m_size = container.size();
|
||||||
|
return( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< class CharT, class Traits, class Allocator >
|
||||||
|
span&
|
||||||
|
operator=( std::basic_string<
|
||||||
|
CharT, Traits, Allocator >& s )
|
||||||
|
{
|
||||||
|
m_data = &s[0];
|
||||||
|
m_size = s.size();
|
||||||
|
return( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< class CharT, class Traits, class Allocator >
|
||||||
|
span&
|
||||||
|
operator=( std::basic_string<
|
||||||
|
CharT, Traits, Allocator > const& s )
|
||||||
|
{
|
||||||
|
m_data = s.data();
|
||||||
|
m_size = s.size();
|
||||||
|
return( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns `true` if the span is empty
|
||||||
|
bool
|
||||||
|
empty() const
|
||||||
|
{
|
||||||
|
return( m_size == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns a pointer to the beginning of the span
|
||||||
|
T*
|
||||||
|
data() const
|
||||||
|
{
|
||||||
|
return( m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns the number of elements in the span
|
||||||
|
std::size_t
|
||||||
|
size() const
|
||||||
|
{
|
||||||
|
return( m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns an iterator to the beginning of the span
|
||||||
|
Iterator
|
||||||
|
begin() const
|
||||||
|
{
|
||||||
|
return( m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns an iterator to the beginning of the span
|
||||||
|
ConstIterator
|
||||||
|
cbegin() const
|
||||||
|
{
|
||||||
|
return( m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns an iterator to one past the end of the span
|
||||||
|
Iterator
|
||||||
|
end() const
|
||||||
|
{
|
||||||
|
return( m_data + m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns an iterator to one past the end of the span
|
||||||
|
ConstIterator
|
||||||
|
cend() const
|
||||||
|
{
|
||||||
|
return( m_data + m_size );
|
||||||
|
}
|
||||||
|
}; // class span
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // if ( __cplusplus >= 201103L ) && ( __cplusplus < 201703L )
|
||||||
|
|
||||||
|
#endif // ifndef MYX_BACKPORTS_CPP_SPAN_HPP_
|
42
src/myx/backports/qt/CMakeLists.txt
Normal file
42
src/myx/backports/qt/CMakeLists.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Название основной цели и имя библиотеки в текущем каталоге
|
||||||
|
set(TRGT backports-qt)
|
||||||
|
|
||||||
|
# cmake-format: off
|
||||||
|
# Список файлов исходных текстов
|
||||||
|
set(TRGT_cpp)
|
||||||
|
|
||||||
|
# Список заголовочных файлов
|
||||||
|
set(TRGT_hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/common.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(TRGT_headers ${TRGT_hpp})
|
||||||
|
# cmake-format: on
|
||||||
|
|
||||||
|
add_library(${TRGT} INTERFACE)
|
||||||
|
target_sources(${TRGT} INTERFACE ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clazy
|
||||||
|
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для автоматического форматирования кода
|
||||||
|
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
target_include_directories(${TRGT} INTERFACE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
install(FILES ${TRGT_headers} COMPONENT base-dev
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/backports/qt)
|
||||||
|
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||||
|
|
||||||
|
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||||
|
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
||||||
|
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
@ -1,14 +1,13 @@
|
|||||||
#ifndef MYX_QT_BACKPORTS_HPP_
|
#ifndef MYX_BACKPORTS_QT_COMMON_HPP_
|
||||||
#define MYX_QT_BACKPORTS_HPP_
|
#define MYX_BACKPORTS_QT_COMMON_HPP_
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if ( defined ( TARGET_LSB_ID_AstraLinuxSE ) && defined ( TARGET_LSB_CODENAME_smolensk ) )
|
#if !defined( QT_VERSION )
|
||||||
|
|
||||||
#define override
|
|
||||||
|
|
||||||
#if QT_VERSION <= 0x050700
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( QT_VERSION <= 0x050700 )
|
||||||
template< typename ... Args >
|
template< typename ... Args >
|
||||||
struct QOverload
|
struct QOverload
|
||||||
{
|
{
|
||||||
@ -31,8 +30,6 @@ Q_DECL_CONSTEXPR typename std::add_const< T >::type& qAsConst( T& t ) noexcept
|
|||||||
template < typename T >
|
template < typename T >
|
||||||
void qAsConst( const T&& ) = delete;
|
void qAsConst( const T&& ) = delete;
|
||||||
|
|
||||||
|
|
||||||
#endif // if QT_VERSION <= 0x050700
|
#endif // if QT_VERSION <= 0x050700
|
||||||
#endif // if ( defined ( TARGET_LSB_ID_AstraLinuxSE ) && defined ( TARGET_LSB_CODENAME_smolensk ) )
|
|
||||||
|
|
||||||
#endif // MYX_QT_BACKPORTS_HPP_
|
#endif // MYX_BACKPORTS_QT_COMMON_HPP_
|
@ -1,59 +0,0 @@
|
|||||||
# Название основной цели и имя библиотеки в текущем каталоге
|
|
||||||
set(TRGT base)
|
|
||||||
|
|
||||||
# cmake-format: off
|
|
||||||
# Список файлов исходных текстов
|
|
||||||
set(TRGT_cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/config.cpp)
|
|
||||||
|
|
||||||
# Список заголовочных файлов
|
|
||||||
set(TRGT_hpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/limits.hpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/enum_bitmask_operations.hpp)
|
|
||||||
|
|
||||||
set(TRGT_headers ${TRGT_hpp})
|
|
||||||
# cmake-format: on
|
|
||||||
|
|
||||||
add_library(${TRGT}-header-only INTERFACE)
|
|
||||||
target_include_directories(
|
|
||||||
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
|
|
||||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
|
||||||
|
|
||||||
if(MYXLIB_BUILD_LIBRARIES)
|
|
||||||
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
|
|
||||||
common_target_properties(${TRGT})
|
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clang-tidy
|
|
||||||
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clang-analyze
|
|
||||||
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clazy
|
|
||||||
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
|
||||||
|
|
||||||
# Создание цели для проверки утилитой pvs-studio
|
|
||||||
add_pvs_check(${TRGT})
|
|
||||||
|
|
||||||
# Создание цели для автоматического форматирования кода
|
|
||||||
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
|
||||||
|
|
||||||
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
|
|
||||||
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
||||||
|
|
||||||
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
install(FILES ${TRGT_cpp} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
|
||||||
install(FILES ${TRGT_headers} ${CMAKE_BINARY_DIR}/include/myx/base/compiler_features.hpp COMPONENT base-dev
|
|
||||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
|
||||||
|
|
||||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
|
||||||
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
|
||||||
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef MYX_BASE_CONFIG_CPP_
|
|
||||||
#define MYX_BASE_CONFIG_CPP_
|
|
||||||
|
|
||||||
#ifndef MYXLIB_HEADER_ONLY
|
|
||||||
#include <myx/base/config.hpp>
|
|
||||||
#else
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MYX_BASE_CONFIG_CPP_
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef MYX_BASE_CONFIG_HPP_
|
|
||||||
#define MYX_BASE_CONFIG_HPP_
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef MYXLIB_BUILD_LIBRARIES
|
|
||||||
#undef MYXLIB_HEADER_ONLY
|
|
||||||
|
|
||||||
#if defined( _WIN32 ) && defined( MYXLIB_SHARED_LIB )
|
|
||||||
#ifdef myxlib_EXPORTS
|
|
||||||
#define MYXLIB_API __declspec( dllexport )
|
|
||||||
#else
|
|
||||||
#define MYXLIB_API __declspec( dllimport )
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define MYXLIB_API
|
|
||||||
#endif
|
|
||||||
#define MYXLIB_INLINE
|
|
||||||
#else
|
|
||||||
#define MYXLIB_HEADER_ONLY
|
|
||||||
#define MYXLIB_API
|
|
||||||
#define MYXLIB_INLINE inline
|
|
||||||
#endif // ifdef MYXLIB_BUILD_LIBRARIES
|
|
||||||
|
|
||||||
#ifdef MYXLIB_HEADER_ONLY
|
|
||||||
#include "config.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MYX_BASE_CONFIG_HPP_
|
|
@ -1,57 +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 k_Enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename Enum >
|
|
||||||
typename std::enable_if< EnableBitMaskOperators< Enum >::k_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 k_Enable = true; \
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ifndef MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_
|
|
44
src/myx/core/CMakeLists.txt
Normal file
44
src/myx/core/CMakeLists.txt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Название основной цели и имя библиотеки в текущем каталоге
|
||||||
|
set(TRGT core)
|
||||||
|
|
||||||
|
# cmake-format: off
|
||||||
|
# Список файлов исходных текстов
|
||||||
|
set(TRGT_cpp)
|
||||||
|
|
||||||
|
# Список заголовочных файлов
|
||||||
|
set(TRGT_hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/limits.hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/endian_types.hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/enum_bitmask_operations.hpp)
|
||||||
|
|
||||||
|
set(TRGT_headers ${TRGT_hpp})
|
||||||
|
# cmake-format: on
|
||||||
|
|
||||||
|
add_library(${TRGT} INTERFACE)
|
||||||
|
target_sources(${TRGT} INTERFACE ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой clazy
|
||||||
|
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
|
# Создание цели для автоматического форматирования кода
|
||||||
|
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
|
target_include_directories(${TRGT} INTERFACE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||||
|
install(FILES ${TRGT_headers} ${CMAKE_BINARY_DIR}/include/myx/core/compiler_features.hpp COMPONENT base-dev
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||||
|
|
||||||
|
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||||
|
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
||||||
|
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
17
src/myx/core/config.hpp
Normal file
17
src/myx/core/config.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef MYX_CORE_CONFIG_HPP_
|
||||||
|
#define MYX_CORE_CONFIG_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined( _WIN32 ) && defined( MYXLIB_SHARED_LIB )
|
||||||
|
#ifdef myxlib_EXPORTS
|
||||||
|
#define MYXLIB_API __declspec( dllexport )
|
||||||
|
#else
|
||||||
|
#define MYXLIB_API __declspec( dllimport )
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define MYXLIB_API
|
||||||
|
#endif
|
||||||
|
#define MYXLIB_INLINE
|
||||||
|
|
||||||
|
#endif // MYX_CORE_CONFIG_HPP_
|
192
src/myx/core/endian_types.hpp
Normal file
192
src/myx/core/endian_types.hpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
#ifndef MYX_BASE_ENDIAN_TYPES_HPP_
|
||||||
|
#define MYX_BASE_ENDIAN_TYPES_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <myx/backports/cpp/span.hpp>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef QT_CORE_LIB
|
||||||
|
#include <QDebug>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Основа здесь: https://github.com/tatewake/endian-template/
|
||||||
|
|
||||||
|
namespace myx {
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
class EndianTypesBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
#if defined ( _MSC_VER )
|
||||||
|
#pragma warning ( push )
|
||||||
|
#endif
|
||||||
|
static T swapBytes( const T& b )
|
||||||
|
{
|
||||||
|
T n;
|
||||||
|
std::span< uint8_t > sn( reinterpret_cast< uint8_t* >( &n ), sizeof( T ) ); //NOLINT
|
||||||
|
std::span< const uint8_t > sb( reinterpret_cast< const uint8_t* >( &b ), sizeof( T ) ); //NOLINT
|
||||||
|
std::reverse_copy( sb.begin(), sb.end(), sn.begin() );
|
||||||
|
return( n );
|
||||||
|
} // swapBytes
|
||||||
|
|
||||||
|
|
||||||
|
#if defined( _MSC_VER )
|
||||||
|
#pragma warning ( pop )
|
||||||
|
#endif
|
||||||
|
}; // class EndianTypesBase
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
class LittleEndianType : public EndianTypesBase< T >
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
T m_data; //NOLINT
|
||||||
|
|
||||||
|
static T transform( const T& b )
|
||||||
|
{
|
||||||
|
const uint16_t k_i = 1;
|
||||||
|
return( ( reinterpret_cast< const char& >( k_i ) == 1 ) ? b : EndianTypesBase< T >::swapBytes( b ) ); //NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
LittleEndianType() = default;
|
||||||
|
|
||||||
|
// If we endian swap, it happens in two places:
|
||||||
|
// 1. Set an OE from a PE
|
||||||
|
// 2. Get a PE from an OE
|
||||||
|
// Storage in
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
LittleEndianType( const T& b ) :
|
||||||
|
m_data( transform( b ) )
|
||||||
|
{}
|
||||||
|
template < typename U > explicit LittleEndianType( U const& b ) :
|
||||||
|
m_data( transform( T( b ) ) )
|
||||||
|
{}
|
||||||
|
// Storage out
|
||||||
|
template < typename U > explicit operator U() const { return( U( transform( m_data ) ) ); }
|
||||||
|
explicit operator T() const { return( transform( m_data ) ); }
|
||||||
|
|
||||||
|
template < typename U > bool operator ==( U const& o ) { return( U( *this ) == o ); }
|
||||||
|
template < typename U > bool operator !=( U const& o ) { return( U( *this ) != o ); }
|
||||||
|
|
||||||
|
// Arithmetic assignment operators
|
||||||
|
LittleEndianType& operator ++() /* prefix */ { *this = T( *this ) + T( 1 ); return( *this ); }
|
||||||
|
LittleEndianType operator ++( int ) /* suffix */ { LittleEndianType t( *this ); *this = T( *this ) + T( 1 ); return( t ); }
|
||||||
|
LittleEndianType& operator --() /* prefix */ { *this = T( *this ) - T( 1 ); return( *this ); }
|
||||||
|
LittleEndianType operator --( int ) /* suffix */ { LittleEndianType t( *this ); *this = T( *this ) - T( 1 ); return( t ); }
|
||||||
|
|
||||||
|
// Compound assignment operators
|
||||||
|
LittleEndianType& operator +=( const T& b ) { *this = T( *this ) + b; return( *this ); }
|
||||||
|
LittleEndianType& operator -=( const T& b ) { *this = T( *this ) - b; return( *this ); }
|
||||||
|
LittleEndianType& operator *=( const T& b ) { *this = T( *this ) * b; return( *this ); }
|
||||||
|
LittleEndianType& operator /=( const T& b ) { *this = T( *this ) / b; return( *this ); }
|
||||||
|
LittleEndianType& operator %=( const T& b ) { *this = T( *this ) % b; return( *this ); }
|
||||||
|
LittleEndianType& operator &=( const T& b ) { *this = T( *this ) & b; return( *this ); }
|
||||||
|
LittleEndianType& operator |=( const T& b ) { *this = T( *this ) | b; return( *this ); }
|
||||||
|
LittleEndianType& operator ^=( const T& b ) { *this = T( *this ) ^ b; return( *this ); }
|
||||||
|
LittleEndianType& operator <<=( const T& b ) { *this = T( T( *this ) << b ); return( *this ); }
|
||||||
|
LittleEndianType& operator >>=( const T& b ) { *this = T( T( *this ) >> b ); return( *this ); }
|
||||||
|
friend std::ostream& operator <<( std::ostream& out, const LittleEndianType b ) { out << T( b ); return( out ); }
|
||||||
|
friend std::istream& operator >>( std::istream& in, LittleEndianType& b ) { T val; in >> val; b = val; return( in ); }
|
||||||
|
std::string toStdString() { return( std::to_string( transform( m_data ) ) ); }
|
||||||
|
#ifdef QT_CORE_LIB
|
||||||
|
friend QDebug& operator <<( QDebug& out, const LittleEndianType< T > b ) { out << T( b ); return( out ); }
|
||||||
|
QString toQString() { return( QString::number( transform( m_data ) ) ); }
|
||||||
|
#endif
|
||||||
|
}; // class LittleEndianType
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
class BigEndianType : public EndianTypesBase< T >
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
T m_data; //NOLINT
|
||||||
|
|
||||||
|
static T transform( const T& b )
|
||||||
|
{
|
||||||
|
const uint16_t k_i = 1;
|
||||||
|
return( ( reinterpret_cast< const char& >( k_i ) == 1 ) ? EndianTypesBase< T >::swapBytes( b ) : b ); //NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
BigEndianType() = default;
|
||||||
|
|
||||||
|
// If we endian swap, it happens in two places:
|
||||||
|
// 1. Set an OE from a PE
|
||||||
|
// 2. Get a PE from an OE
|
||||||
|
// Storage in
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
BigEndianType( const T& b ) :
|
||||||
|
m_data( transform( b ) )
|
||||||
|
{}
|
||||||
|
template < typename U > explicit BigEndianType( U const& b ) :
|
||||||
|
m_data( transform( T( b ) ) )
|
||||||
|
{}
|
||||||
|
// Storage out
|
||||||
|
template < typename U > explicit operator U() const { return( U( transform( m_data ) ) ); }
|
||||||
|
explicit operator T() const { return( transform( m_data ) ); }
|
||||||
|
|
||||||
|
template < typename U > bool operator ==( U const& o ) { return( U( *this ) == o ); }
|
||||||
|
template < typename U > bool operator !=( U const& o ) { return( U( *this ) != o ); }
|
||||||
|
|
||||||
|
// Arithmetic assignment operators
|
||||||
|
BigEndianType& operator ++() /* prefix */ { *this = T( *this ) + 1; return( *this ); }
|
||||||
|
BigEndianType operator ++( int ) /* suffix */ { BigEndianType t( *this ); *this = T( *this ) + 1; return( t ); }
|
||||||
|
BigEndianType& operator --() /* prefix */ { *this = T( *this ) - 1; return( *this ); }
|
||||||
|
BigEndianType operator --( int ) /* suffix */ { BigEndianType t( *this ); *this = T( *this ) - 1; return( t ); }
|
||||||
|
|
||||||
|
// Compound assignment operators
|
||||||
|
BigEndianType& operator +=( const T& b ) { *this = T( *this ) + b; return( *this ); }
|
||||||
|
BigEndianType& operator -=( const T& b ) { *this = T( *this ) - b; return( *this ); }
|
||||||
|
BigEndianType& operator *=( const T& b ) { *this = T( *this ) * b; return( *this ); }
|
||||||
|
BigEndianType& operator /=( const T& b ) { *this = T( *this ) / b; return( *this ); }
|
||||||
|
BigEndianType& operator %=( const T& b ) { *this = T( *this ) % b; return( *this ); }
|
||||||
|
BigEndianType& operator &=( const T& b ) { *this = T( *this ) & b; return( *this ); }
|
||||||
|
BigEndianType& operator |=( const T& b ) { *this = T( *this ) | b; return( *this ); }
|
||||||
|
BigEndianType& operator ^=( const T& b ) { *this = T( *this ) ^ b; return( *this ); }
|
||||||
|
BigEndianType& operator <<=( const T& b ) { *this = T( T( *this ) << b ); return( *this ); }
|
||||||
|
BigEndianType& operator >>=( const T& b ) { *this = T( T( *this ) >> b ); return( *this ); }
|
||||||
|
friend std::ostream& operator <<( std::ostream& out, const BigEndianType b ) { out << T( b ); return( out ); }
|
||||||
|
friend std::istream& operator >>( std::istream& in, BigEndianType& b ) { T val; in >> val; b = val; return( in ); }
|
||||||
|
std::string toStdString() { return( std::to_string( transform( m_data ) ) ); }
|
||||||
|
#ifdef QT_CORE_LIB
|
||||||
|
friend QDebug& operator <<( QDebug& out, const BigEndianType< T > b ) { out << T( b ); return( out ); }
|
||||||
|
QString toQString() { return( QString::number( transform( m_data ) ) ); }
|
||||||
|
#endif
|
||||||
|
}; // class BigEndianType
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
|
||||||
|
} // namespace myx
|
||||||
|
|
||||||
|
using leint16 = myx::core::LittleEndianType< int16_t >; //NOLINT
|
||||||
|
using leint32 = myx::core::LittleEndianType< int32_t >; //NOLINT
|
||||||
|
using leint64 = myx::core::LittleEndianType< int64_t >; //NOLINT
|
||||||
|
|
||||||
|
using leuint16 = myx::core::LittleEndianType< uint16_t >; //NOLINT
|
||||||
|
using leuint32 = myx::core::LittleEndianType< uint32_t >; //NOLINT
|
||||||
|
using leuint64 = myx::core::LittleEndianType< uint64_t >; //NOLINT
|
||||||
|
|
||||||
|
using lefloat = myx::core::LittleEndianType< float >; //NOLINT
|
||||||
|
using ledouble = myx::core::LittleEndianType< double >; //NOLINT
|
||||||
|
|
||||||
|
using beint16 = myx::core::BigEndianType< int16_t >; //NOLINT
|
||||||
|
using beint32 = myx::core::BigEndianType< int32_t >; //NOLINT
|
||||||
|
using beint64 = myx::core::BigEndianType< int64_t >; //NOLINT
|
||||||
|
|
||||||
|
using beuint16 = myx::core::BigEndianType< uint16_t >; //NOLINT
|
||||||
|
using beuint32 = myx::core::BigEndianType< uint32_t >; //NOLINT
|
||||||
|
using beuint64 = myx::core::BigEndianType< uint64_t >; //NOLINT
|
||||||
|
|
||||||
|
using befloat = myx::core::BigEndianType< float >; //NOLINT
|
||||||
|
using bedouble = myx::core::BigEndianType< double >; //NOLINT
|
||||||
|
|
||||||
|
#endif // MYX_BASE_ENDIAN_TYPES_HPP_
|
93
src/myx/core/enum_bitmask_operations.hpp
Normal file
93
src/myx/core/enum_bitmask_operations.hpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#ifndef MYX_CORE_ENUM_BITWISE_OPERATIONS_HPP_
|
||||||
|
#define MYX_CORE_ENUM_BITWISE_OPERATIONS_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace myx {
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
template< typename Enum >
|
||||||
|
struct EnableBitMaskOperators
|
||||||
|
{
|
||||||
|
static const bool kEnable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename Enum >
|
||||||
|
typename std::enable_if< EnableBitMaskOperators< Enum >::kEnable, Enum >::type
|
||||||
|
operator ~( Enum e )
|
||||||
|
{
|
||||||
|
using Underlying = typename std::underlying_type< Enum >::type;
|
||||||
|
return( static_cast< Enum >( ~static_cast< Underlying >( e ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< typename Enum >
|
||||||
|
typename std::enable_if< EnableBitMaskOperators< Enum >::kEnable, 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 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< typename Enum >
|
||||||
|
typename std::enable_if< EnableBitMaskOperators< Enum >::kEnable, typename std::add_lvalue_reference< Enum >::type >::type
|
||||||
|
operator |=( Enum& lhs, Enum rhs )
|
||||||
|
{
|
||||||
|
using Underlying = typename std::underlying_type< Enum >::type;
|
||||||
|
lhs = static_cast< Enum >( static_cast< Underlying >( lhs ) | static_cast< Underlying >( rhs ) );
|
||||||
|
return( lhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< typename Enum >
|
||||||
|
typename std::enable_if< EnableBitMaskOperators< Enum >::kEnable, 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 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template< typename Enum >
|
||||||
|
typename std::enable_if< EnableBitMaskOperators< Enum >::kEnable, typename std::add_lvalue_reference< Enum >::type >::type
|
||||||
|
operator &=( Enum& lhs, Enum rhs )
|
||||||
|
{
|
||||||
|
using Underlying = typename std::underlying_type< Enum >::type;
|
||||||
|
lhs = static_cast< Enum >( static_cast< Underlying >( lhs ) & static_cast< Underlying >( rhs ) );
|
||||||
|
return( lhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
|
||||||
|
} // 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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||||
|
#define ENABLE_BITMASK_OPERATORS( x ) \
|
||||||
|
template<> \
|
||||||
|
struct myx::core::EnableBitMaskOperators< x > \
|
||||||
|
{ \
|
||||||
|
static const bool kEnable = true; \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ifndef MYX_CORE_ENUM_BITWISE_OPERATIONS_HPP_
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef MYX_BASE_LIMITS_HPP_
|
#ifndef MYX_CORE_LIMITS_HPP_
|
||||||
#define MYX_BASE_LIMITS_HPP_
|
#define MYX_CORE_LIMITS_HPP_
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -7,25 +7,25 @@
|
|||||||
|
|
||||||
namespace myx {
|
namespace myx {
|
||||||
|
|
||||||
namespace base {
|
namespace core {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Константа, представляющая значение, не являющееся числом, для типа float
|
* @brief Константа, представляющая значение, не являющееся числом, для типа float
|
||||||
*/
|
*/
|
||||||
constexpr float k_FloatNAN { std::numeric_limits< float >::quiet_NaN() };
|
constexpr float kFloatNAN { std::numeric_limits< float >::quiet_NaN() };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Константа, представляющая значение, не являющееся числом, для типа double
|
* @brief Константа, представляющая значение, не являющееся числом, для типа double
|
||||||
*/
|
*/
|
||||||
constexpr double k_DoubleNAN { std::numeric_limits< double >::quiet_NaN() };
|
constexpr double kDoubleNAN { std::numeric_limits< double >::quiet_NaN() };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Константа, представляющая значение, не являющееся числом, для типа long double
|
* @brief Константа, представляющая значение, не являющееся числом, для типа long double
|
||||||
*/
|
*/
|
||||||
constexpr double k_LongDoubleNAN { std::numeric_limits< long double >::quiet_NaN() };
|
constexpr double kLongDoubleNAN { std::numeric_limits< long double >::quiet_NaN() };
|
||||||
|
|
||||||
} // namespace base
|
} // namespace core
|
||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
#endif // MYX_BASE_LIMITS_HPP_
|
#endif // MYX_CORE_LIMITS_HPP_
|
@ -3,60 +3,44 @@ set(TRGT filesystem)
|
|||||||
|
|
||||||
# cmake-format: off
|
# cmake-format: off
|
||||||
# Список файлов исходных текстов
|
# Список файлов исходных текстов
|
||||||
set(TRGT_cpp
|
set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.cpp)
|
|
||||||
|
|
||||||
# Список заголовочных файлов
|
# Список заголовочных файлов
|
||||||
set(TRGT_hpp
|
set(TRGT_hpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.hpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp)
|
|
||||||
|
|
||||||
set(TRGT_headers ${TRGT_hpp})
|
set(TRGT_headers ${TRGT_hpp})
|
||||||
# cmake-format: on
|
# cmake-format: on
|
||||||
|
|
||||||
add_library(${TRGT}-header-only INTERFACE)
|
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
|
||||||
target_include_directories(
|
common_target_properties(${TRGT})
|
||||||
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
|
|
||||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
|
||||||
|
|
||||||
if(MYXLIB_BUILD_LIBRARIES)
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
common_target_properties(${TRGT})
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clang-tidy
|
# Создание цели для проверки утилитой clazy
|
||||||
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clang-analyze
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clazy
|
# Создание цели для автоматического форматирования кода
|
||||||
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой pvs-studio
|
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||||
add_pvs_check(${TRGT})
|
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
cotire(${TRGT})
|
||||||
|
|
||||||
# Создание цели для автоматического форматирования кода
|
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
if(BUILD_SHARED_LIBS)
|
||||||
|
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
|
|
||||||
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
|
||||||
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
||||||
cotire(${TRGT})
|
|
||||||
|
|
||||||
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
install(FILES ${TRGT_cpp} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||||
install(FILES ${TRGT_headers} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
install(FILES ${TRGT_headers} COMPONENT base-dev
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||||
|
|
||||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||||
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
#ifndef MYX_BASE_CURRENT_EXECUTABLE_CPP_
|
|
||||||
#define MYX_BASE_CURRENT_EXECUTABLE_CPP_
|
|
||||||
|
|
||||||
#ifndef MYXLIB_HEADER_ONLY
|
|
||||||
#include <myx/filesystem/current_executable.hpp>
|
|
||||||
#else
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
|
||||||
|
|
||||||
#include <paths.h>
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace myx {
|
|
||||||
|
|
||||||
namespace filesystem {
|
|
||||||
|
|
||||||
#if !defined ( __linux__ )
|
|
||||||
error "Class CurrentExecutable is supported only in Linux"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MYXLIB_INLINE CurrentExecutable::CurrentExecutable() :
|
|
||||||
m_procFilePath( QStringLiteral( "/proc/self/exe" ) )
|
|
||||||
{
|
|
||||||
m_canonicalFilePath = m_procFilePath.canonicalFilePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QFileInfo& CurrentExecutable::canonicalFilePath() const
|
|
||||||
{
|
|
||||||
return( m_canonicalFilePath );
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace filesystem
|
|
||||||
|
|
||||||
} // namespace myx
|
|
||||||
|
|
||||||
#endif // MYX_BASE_CURRENT_EXECUTABLE_CPP_
|
|
@ -1,51 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file current_executable.hpp
|
|
||||||
* @brief Параметры исполняемого файла
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_
|
|
||||||
#define MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
|
|
||||||
namespace myx {
|
|
||||||
|
|
||||||
namespace filesystem {
|
|
||||||
|
|
||||||
class CurrentExecutable
|
|
||||||
{
|
|
||||||
/// @brief Путь к символической ссылке, указывающей на текущий исполняемый файл
|
|
||||||
QFileInfo m_procFilePath;
|
|
||||||
|
|
||||||
/// @brief Канонический путь к текущему исполняемому файлу
|
|
||||||
QFileInfo m_canonicalFilePath;
|
|
||||||
|
|
||||||
friend class Paths;
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Конструктор, собирающий информацию о текущем исполняемом файле.
|
|
||||||
*/
|
|
||||||
CurrentExecutable();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Канонический путь к текущему исполняемому файлу
|
|
||||||
*/
|
|
||||||
const QFileInfo& canonicalFilePath() const;
|
|
||||||
}; // class CurrentExecutable
|
|
||||||
|
|
||||||
} // namespace filesystem
|
|
||||||
|
|
||||||
} // namespace myx
|
|
||||||
|
|
||||||
#ifdef MYXLIB_HEADER_ONLY
|
|
||||||
#include "current_executable.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_
|
|
@ -1,14 +1,8 @@
|
|||||||
#ifndef MYX_BASE_PATHS_CPP_
|
#ifndef MYX_CORE_PATHS_CPP_
|
||||||
#define MYX_BASE_PATHS_CPP_
|
#define MYX_CORE_PATHS_CPP_
|
||||||
|
|
||||||
#ifndef MYXLIB_HEADER_ONLY
|
#include <myx/core/config.hpp>
|
||||||
#include <myx/filesystem/paths.hpp>
|
#include <myx/filesystem/paths.hpp>
|
||||||
#else
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
|
||||||
#include <myx/filesystem/current_executable.hpp>
|
|
||||||
|
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
|
|
||||||
@ -19,179 +13,188 @@ namespace myx {
|
|||||||
|
|
||||||
namespace filesystem {
|
namespace filesystem {
|
||||||
|
|
||||||
MYXLIB_INLINE Paths::Paths() = default;
|
MYXLIB_INLINE Paths::Paths()
|
||||||
|
{
|
||||||
|
QFileInfo procSelfExe( QStringLiteral( "/proc/self/exe" ) );
|
||||||
|
QFileInfo currentExecutable = procSelfExe.canonicalFilePath();
|
||||||
|
m_executableName = currentExecutable.fileName();
|
||||||
|
m_executableFilePath = currentExecutable.absoluteFilePath();
|
||||||
|
m_executableDirectory = currentExecutable.absolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MYXLIB_INLINE void Paths::setupSystemDirectories( const QString& defaultPrefixDirectory,
|
||||||
|
const QString& defaultEtcDirectory,
|
||||||
|
const QString& defaultConstDataDirectory,
|
||||||
|
const QString& defaultVarDataDirectory,
|
||||||
|
const QString& defaultLogDirectory )
|
||||||
|
{
|
||||||
|
QFileInfo prefixDirInfo { defaultPrefixDirectory };
|
||||||
|
if ( prefixDirInfo.isDir() && prefixDirInfo.isReadable() )
|
||||||
|
{
|
||||||
|
m_prefixDirectory = defaultPrefixDirectory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_prefixDirectory = ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo etcDirInfo { defaultEtcDirectory };
|
||||||
|
if ( etcDirInfo.isDir() && etcDirInfo.isReadable() )
|
||||||
|
{
|
||||||
|
m_systemConfigDirectory = defaultEtcDirectory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_systemConfigDirectory = m_userConfigDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo constDataDirInfo { defaultConstDataDirectory };
|
||||||
|
if ( constDataDirInfo.isDir() && constDataDirInfo.isReadable() )
|
||||||
|
{
|
||||||
|
m_systemConstDataDirectory = defaultConstDataDirectory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_systemConstDataDirectory = m_userConstDataDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo varDataDirInfo { defaultVarDataDirectory };
|
||||||
|
if ( varDataDirInfo.isDir() && varDataDirInfo.isWritable() )
|
||||||
|
{
|
||||||
|
m_systemVarDataDirectory = defaultVarDataDirectory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_systemVarDataDirectory = m_userVarDataDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo logDirInfo { defaultLogDirectory };
|
||||||
|
if ( logDirInfo.isDir() && logDirInfo.isWritable() )
|
||||||
|
{
|
||||||
|
m_systemLogDirectory = defaultLogDirectory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_systemLogDirectory = m_userLogDirectory;
|
||||||
|
}
|
||||||
|
} // Paths::setupSystemDirectories
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
|
MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
|
||||||
{
|
{
|
||||||
QRegExp binUnityRegexp( "/s*bin/unity$" );
|
QRegExp binUnityRegexp( "/s*bin/unity$" );
|
||||||
QRegExp binRegexp( "/s*bin$" );
|
auto binaryDir = m_executableDirectory;
|
||||||
auto binaryDir = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
|
||||||
|
|
||||||
if ( binUnityRegexp.indexIn( binaryDir ) >= 0 )
|
if ( binUnityRegexp.indexIn( binaryDir ) >= 0 )
|
||||||
{
|
{
|
||||||
binaryDir.remove( binUnityRegexp );
|
binaryDir.remove( binUnityRegexp );
|
||||||
|
setupSystemDirectories( binaryDir,
|
||||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
binaryDir + "/etc",
|
||||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
binaryDir + "/files/data",
|
||||||
|
binaryDir + "/files/lib",
|
||||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
binaryDir + "/files/log" );
|
||||||
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::kDevelopment );
|
return ( HierarchyType::kDevelopment );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRegExp binRegexp( "/s*bin$" );
|
||||||
if ( binRegexp.indexIn( binaryDir ) == -1 )
|
if ( binRegexp.indexIn( binaryDir ) == -1 )
|
||||||
{
|
{
|
||||||
|
m_prefixDirectory = m_executableDirectory;
|
||||||
|
m_systemConstDataDirectory = m_executableDirectory;
|
||||||
|
m_systemVarDataDirectory = m_executableDirectory;
|
||||||
|
m_systemConfigDirectory = m_executableDirectory;
|
||||||
|
m_systemLogDirectory = m_executableDirectory;
|
||||||
|
|
||||||
return ( HierarchyType::kFlat );
|
return ( HierarchyType::kFlat );
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegExp optRegexp( "^/opt(/|/.+/)" + m_projectName + "/" );
|
QRegExp optRegexp( "^/opt(/|/.+/)" + m_projectName + "/" );
|
||||||
|
|
||||||
if ( optRegexp.indexIn( binaryDir ) >= 0 )
|
if ( optRegexp.indexIn( binaryDir ) >= 0 )
|
||||||
{
|
{
|
||||||
binaryDir.remove( binRegexp );
|
binaryDir.remove( binRegexp );
|
||||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
setupSystemDirectories( binaryDir,
|
||||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
binaryDir + "/etc",
|
||||||
|
binaryDir + "/files/data",
|
||||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
binaryDir + "/files/lib",
|
||||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
binaryDir + "/files/log" );
|
||||||
|
|
||||||
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 );
|
return ( HierarchyType::kOpt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( binaryDir.startsWith( QStringLiteral( "/usr/local/rtis" ) ) )
|
||||||
|
{
|
||||||
|
setupSystemDirectories( "/usr/local/rtis",
|
||||||
|
"/usr/local/rtis/etc/" + m_projectName,
|
||||||
|
"/usr/local/rtis/share/" + m_projectName,
|
||||||
|
"/usr/local/rtis/lib/" + m_projectName,
|
||||||
|
"/usr/local/rtis/log/" + m_projectName );
|
||||||
|
|
||||||
|
return ( HierarchyType::kUsrLocalRtis );
|
||||||
|
}
|
||||||
|
|
||||||
if ( binaryDir.startsWith( QStringLiteral( "/usr/local" ) ) )
|
if ( binaryDir.startsWith( QStringLiteral( "/usr/local" ) ) )
|
||||||
{
|
{
|
||||||
QFileInfo etcDirInfo { "/usr/local/etc/" + m_projectName };
|
setupSystemDirectories( "/usr/local",
|
||||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
"/usr/local/etc/" + m_projectName,
|
||||||
|
"/usr/local/share/" + m_projectName,
|
||||||
|
"/var/lib/" + m_projectName,
|
||||||
|
"/var/log/" + m_projectName );
|
||||||
|
|
||||||
QFileInfo constDataDirInfo { "/usr/local/share/" + m_projectName };
|
return ( HierarchyType::kUsrLocal );
|
||||||
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::kUsr );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
|
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
|
||||||
{
|
{
|
||||||
QFileInfo etcDirInfo { "/etc/" + m_projectName };
|
setupSystemDirectories( "/usr",
|
||||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
"/etc/" + m_projectName,
|
||||||
|
"/usr/share/" + m_projectName,
|
||||||
QFileInfo constDataDirInfo { "/usr/share/" + m_projectName };
|
"/var/lib/" + m_projectName,
|
||||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
"/var/log/" + m_projectName );
|
||||||
|
|
||||||
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::kUsr );
|
return ( HierarchyType::kUsr );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/.local/bin" ) ||
|
if ( binaryDir.startsWith( m_homeDirectory + "/.local/bin" ) ||
|
||||||
binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/bin" ) )
|
binaryDir.startsWith( m_homeDirectory + "/bin" ) )
|
||||||
{
|
{
|
||||||
QFileInfo etcDirInfo { m_userConfigDirectory.canonicalPath() };
|
m_prefixDirectory = m_homeDirectory;
|
||||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
m_systemConfigDirectory = m_userConfigDirectory;
|
||||||
|
m_systemConstDataDirectory = m_userConstDataDirectory;
|
||||||
QFileInfo constDataDirInfo { m_userConstDataDirectory.canonicalPath() };
|
m_systemVarDataDirectory = m_userVarDataDirectory;
|
||||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
m_systemLogDirectory = m_userLogDirectory;
|
||||||
|
|
||||||
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 );
|
return( HierarchyType::kHome );
|
||||||
}
|
}
|
||||||
|
|
||||||
binaryDir.remove( binRegexp );
|
binaryDir.remove( binRegexp );
|
||||||
|
setupSystemDirectories( binaryDir,
|
||||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
binaryDir + "/etc",
|
||||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
binaryDir + "/files/data",
|
||||||
|
binaryDir + "/files/lib",
|
||||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
binaryDir + "/files/log" );
|
||||||
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::kDevelopment );
|
return ( HierarchyType::kDevelopment );
|
||||||
} // Paths::getHierarchyType
|
} // Paths::getHierarchyType
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE bool Paths::init( const QString& projectDir, const QString& configFileExtension )
|
MYXLIB_INLINE bool Paths::initCommon()
|
||||||
{
|
{
|
||||||
m_projectName = projectDir.isEmpty() ? m_currentExecutable.m_canonicalFilePath.fileName()
|
|
||||||
: projectDir;
|
|
||||||
m_configFileExtension = configFileExtension.isEmpty() ? QStringLiteral( "conf" )
|
|
||||||
: configFileExtension;
|
|
||||||
m_configFileName = m_projectName + "." + m_configFileExtension;
|
|
||||||
|
|
||||||
m_homeDirectory = QDir::homePath();
|
m_homeDirectory = QDir::homePath();
|
||||||
m_tempDirectory = QDir::tempPath();
|
m_tempDirectory = QDir::tempPath();
|
||||||
|
|
||||||
auto configHome = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) );
|
auto configHome = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) );
|
||||||
if ( configHome.isEmpty() )
|
if ( configHome.isEmpty() )
|
||||||
{
|
{
|
||||||
configHome = m_homeDirectory.canonicalPath() + "/.config";
|
configHome = m_homeDirectory + "/.config";
|
||||||
}
|
}
|
||||||
m_userConfigDirectory = configHome + "/" + m_projectName;
|
m_userConfigDirectory = configHome + "/" + m_projectName;
|
||||||
|
|
||||||
auto dataHome = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) );
|
auto dataHome = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) );
|
||||||
if ( dataHome.isEmpty() )
|
if ( dataHome.isEmpty() )
|
||||||
{
|
{
|
||||||
dataHome = m_homeDirectory.canonicalPath() + "/.local/share";
|
dataHome = m_homeDirectory + "/.local/share";
|
||||||
}
|
}
|
||||||
dataHome += "/" + m_projectName;
|
dataHome += "/" + m_projectName;
|
||||||
m_userConstDataDirectory = dataHome + "/data";
|
m_userConstDataDirectory = dataHome + "/data";
|
||||||
@ -200,28 +203,53 @@ MYXLIB_INLINE bool Paths::init( const QString& projectDir, const QString& config
|
|||||||
|
|
||||||
m_hierarchyType = getHierarchyType();
|
m_hierarchyType = getHierarchyType();
|
||||||
|
|
||||||
if ( m_hierarchyType == HierarchyType::kFlat )
|
m_configFilePath = m_systemConfigDirectory + "/" + m_configFileName;
|
||||||
{
|
|
||||||
m_systemConstDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
|
||||||
m_systemVarDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
|
||||||
m_systemConfigDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
|
||||||
m_systemLogDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_configFilePath = m_systemConfigDirectory.canonicalPath() + "/" + m_configFileName;
|
|
||||||
|
|
||||||
return( true );
|
return( true );
|
||||||
} // Paths::updatePaths
|
} // Paths::updatePaths
|
||||||
|
|
||||||
|
|
||||||
|
MYXLIB_INLINE bool Paths::init()
|
||||||
|
{
|
||||||
|
m_projectName = m_executableName;
|
||||||
|
m_configFileName = m_executableName + ".conf";
|
||||||
|
return( initCommon() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MYXLIB_INLINE bool Paths::init( const QString& configFileName )
|
||||||
|
{
|
||||||
|
m_projectName = m_executableName;
|
||||||
|
m_configFileName = configFileName;
|
||||||
|
return( initCommon() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MYXLIB_INLINE bool Paths::init( const QString& projectName, const QString& configFileExtension )
|
||||||
|
{
|
||||||
|
m_projectName = projectName.isEmpty() ? m_executableName
|
||||||
|
: projectName;
|
||||||
|
auto ext = configFileExtension.isEmpty() ? QStringLiteral( "conf" )
|
||||||
|
: configFileExtension;
|
||||||
|
m_configFileName = m_projectName + "." + ext;
|
||||||
|
return( initCommon() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE bool Paths::makeDefaultDirectories()
|
MYXLIB_INLINE bool Paths::makeDefaultDirectories()
|
||||||
{
|
{
|
||||||
bool status = true;
|
bool status = true;
|
||||||
|
QDir dir;
|
||||||
|
|
||||||
|
if ( dir.mkpath( m_userConfigDirectory ) ) { status = false; }
|
||||||
|
if ( dir.mkpath( m_userVarDataDirectory ) ) { status = false; }
|
||||||
|
if ( dir.mkpath( m_userConstDataDirectory ) ) { status = false; }
|
||||||
|
if ( dir.mkpath( m_userLogDirectory ) ) { status = false; }
|
||||||
|
if ( dir.mkpath( m_systemConfigDirectory ) ) { status = false; }
|
||||||
|
if ( dir.mkpath( m_systemVarDataDirectory ) ) { status = false; }
|
||||||
|
if ( dir.mkpath( m_systemConstDataDirectory ) ) { status = false; }
|
||||||
|
if ( dir.mkpath( m_systemLogDirectory ) ) { status = false; }
|
||||||
|
|
||||||
if ( !m_userConfigDirectory.mkpath( m_userConfigDirectory.absolutePath() ) ) { status = false; }
|
|
||||||
if ( !m_userVarDataDirectory.mkpath( m_userVarDataDirectory.absolutePath() ) ) { status = false; }
|
|
||||||
if ( !m_userConstDataDirectory.mkpath( m_userConstDataDirectory.absolutePath() ) ) { status = false; }
|
|
||||||
if ( !m_userLogDirectory.mkpath( m_userLogDirectory.absolutePath() ) ) { status = false; }
|
|
||||||
return( status );
|
return( status );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,32 +272,26 @@ MYXLIB_INLINE QString Paths::findConfigFile( const QString& defaultConfigFile )
|
|||||||
|
|
||||||
if ( QFileInfo( m_configFilePath ).isReadable() )
|
if ( QFileInfo( m_configFilePath ).isReadable() )
|
||||||
{
|
{
|
||||||
return( m_configFilePath.absoluteFilePath() );
|
return( m_configFilePath );
|
||||||
}
|
}
|
||||||
|
|
||||||
return( QString() );
|
return( QString() );
|
||||||
} // Paths::findConfigFile
|
} // Paths::findConfigFile
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE QDir Paths::executableFileDirectory() const
|
MYXLIB_INLINE const QString& Paths::userConfigDirectory() const
|
||||||
{
|
|
||||||
return( m_currentExecutable.m_canonicalFilePath.dir() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::userConfigDirectory() const
|
|
||||||
{
|
{
|
||||||
return( m_userConfigDirectory );
|
return( m_userConfigDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::systemConfigDirectory() const
|
MYXLIB_INLINE const QString& Paths::systemConfigDirectory() const
|
||||||
{
|
{
|
||||||
return( m_systemConfigDirectory );
|
return( m_systemConfigDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QFileInfo& Paths::configFilePath() const
|
MYXLIB_INLINE const QString& Paths::configFilePath() const
|
||||||
{
|
{
|
||||||
return( m_configFilePath );
|
return( m_configFilePath );
|
||||||
}
|
}
|
||||||
@ -281,55 +303,49 @@ MYXLIB_INLINE const QString& Paths::configFileName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QString& Paths::configFileExtension() const
|
MYXLIB_INLINE const QString& Paths::userVarDataDirectory() const
|
||||||
{
|
|
||||||
return( m_configFileExtension );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::userVarDataDirectory() const
|
|
||||||
{
|
{
|
||||||
return( m_userVarDataDirectory );
|
return( m_userVarDataDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::systemVarDataDirectory() const
|
MYXLIB_INLINE const QString& Paths::systemVarDataDirectory() const
|
||||||
{
|
{
|
||||||
return( m_systemVarDataDirectory );
|
return( m_systemVarDataDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::userConstDataDirectory() const
|
MYXLIB_INLINE const QString& Paths::userConstDataDirectory() const
|
||||||
{
|
{
|
||||||
return( m_userConstDataDirectory );
|
return( m_userConstDataDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::systemConstDataDirectory() const
|
MYXLIB_INLINE const QString& Paths::systemConstDataDirectory() const
|
||||||
{
|
{
|
||||||
return( m_systemConstDataDirectory );
|
return( m_systemConstDataDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::userLogDirectory() const
|
MYXLIB_INLINE const QString& Paths::userLogDirectory() const
|
||||||
{
|
{
|
||||||
return( m_userLogDirectory );
|
return( m_userLogDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::systemLogDirectory() const
|
MYXLIB_INLINE const QString& Paths::systemLogDirectory() const
|
||||||
{
|
{
|
||||||
return( m_systemLogDirectory );
|
return( m_systemLogDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::tempDirectory() const
|
MYXLIB_INLINE const QString& Paths::tempDirectory() const
|
||||||
{
|
{
|
||||||
return( m_tempDirectory );
|
return( m_tempDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QDir& Paths::homeDirectory() const
|
MYXLIB_INLINE const QString& Paths::homeDirectory() const
|
||||||
{
|
{
|
||||||
return( m_homeDirectory );
|
return( m_homeDirectory );
|
||||||
}
|
}
|
||||||
@ -341,19 +357,31 @@ MYXLIB_INLINE const QString& Paths::projectName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE QString Paths::executableFileName() const
|
MYXLIB_INLINE const QString& Paths::executableName() const
|
||||||
{
|
{
|
||||||
return( m_currentExecutable.m_canonicalFilePath.fileName() );
|
return( m_executableName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYXLIB_INLINE const QFileInfo& Paths::executableFilePath() const
|
MYXLIB_INLINE const QString& Paths::executableFilePath() const
|
||||||
{
|
{
|
||||||
return( m_currentExecutable.m_canonicalFilePath );
|
return( m_executableFilePath );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MYXLIB_INLINE const QString& Paths::executableDirectory() const
|
||||||
|
{
|
||||||
|
return( m_executableDirectory );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MYXLIB_INLINE const QString& Paths::prefixDirectory() const
|
||||||
|
{
|
||||||
|
return( m_prefixDirectory );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace filesystem
|
} // namespace filesystem
|
||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
#endif // MYX_BASE_PATHS_CPP_
|
#endif // MYX_CORE_PATHS_CPP_
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
#include <myx/core/config.hpp>
|
||||||
#include <myx/filesystem/current_executable.hpp>
|
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@ -34,62 +33,17 @@ class Paths
|
|||||||
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /opt
|
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /opt
|
||||||
kOpt = 0x02,
|
kOpt = 0x02,
|
||||||
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /usr
|
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /usr
|
||||||
kUsr = 0x04,
|
kUsr = 0x03,
|
||||||
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /usr/local
|
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /usr/local
|
||||||
kUsrLocal = 0x08,
|
kUsrLocal = 0x04,
|
||||||
|
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /usr/local/rtis (используется для работ в проекте Сирена)
|
||||||
|
kUsrLocalRtis = 0x05,
|
||||||
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /home
|
/// @brief Исполняемый файл и сопутствующие каталоги находятся в иерахии /home
|
||||||
kHome = 0x10,
|
kHome = 0x06,
|
||||||
/// @brief Исполняемый файл и сопутствующие каталоги находятся в каталоге программного проекта
|
/// @brief Исполняемый файл и сопутствующие каталоги находятся в каталоге программного проекта
|
||||||
kDevelopment = 0x20
|
kDevelopment = 0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Тип расположения файлов по каталогам
|
|
||||||
HierarchyType m_hierarchyType { HierarchyType::kFlat };
|
|
||||||
|
|
||||||
/// @brief Параметры текущего исполняемого файла
|
|
||||||
CurrentExecutable m_currentExecutable;
|
|
||||||
|
|
||||||
/// @brief Имя проекта, которое используется при формировании имён файлов и каталогов
|
|
||||||
QString m_projectName;
|
|
||||||
|
|
||||||
/// @brief Путь к каталогу с временными файлами
|
|
||||||
QDir m_tempDirectory;
|
|
||||||
/// @brief Путь к домашнему каталогу текущего пользователя
|
|
||||||
QDir m_homeDirectory;
|
|
||||||
|
|
||||||
/// @brief Путь к пользовательскому каталогу с изменяемыми файлами
|
|
||||||
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;
|
|
||||||
/// @brief Имя файла настройки
|
|
||||||
QString m_configFileName;
|
|
||||||
/// @brief Расширение для файла настройки
|
|
||||||
QString m_configFileExtension;
|
|
||||||
|
|
||||||
HierarchyType getHierarchyType();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Paths();
|
|
||||||
~Paths() = default;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Paths( const Paths& ) = delete;
|
Paths( const Paths& ) = delete;
|
||||||
Paths& operator=( const Paths& ) = delete;
|
Paths& operator=( const Paths& ) = delete;
|
||||||
@ -102,15 +56,28 @@ public:
|
|||||||
*/
|
*/
|
||||||
static Paths& instance()
|
static Paths& instance()
|
||||||
{
|
{
|
||||||
static Paths p;
|
static Paths sPaths;
|
||||||
return( p );
|
return( sPaths );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Обновление путей с учётом расположения исполняемого файла
|
* @brief Обновление путей с учётом расположения исполняемого файла
|
||||||
*/
|
*/
|
||||||
bool init( const QString& projectDir, const QString& configFileExtension = QStringLiteral("conf") );
|
bool init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Обновление путей с учётом расположения исполняемого файла
|
||||||
|
* @param configFileName Имя файла настроек
|
||||||
|
*/
|
||||||
|
bool init( const QString& configFileName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Обновление путей с учётом расположения исполняемого файла
|
||||||
|
* @param projectName Имя проекта
|
||||||
|
* @param configFileExtension Расширение для файла настроек
|
||||||
|
*/
|
||||||
|
bool init( const QString& projectName, const QString& configFileExtension );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Создание стандартных каталогов
|
* @brief Создание стандартных каталогов
|
||||||
@ -130,27 +97,22 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Полный путь к базовому каталогу
|
* @brief Полный путь к базовому каталогу
|
||||||
*/
|
*/
|
||||||
const QDir& prefixDirectory() const;
|
const QString& prefixDirectory() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Имя исполняемого файла
|
||||||
|
*/
|
||||||
|
const QString& executableName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Полный путь к исполняемому файлу
|
||||||
|
*/
|
||||||
|
const QString& executableFilePath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к каталогу с исполняемым файлом
|
* @brief Полный путь к каталогу с исполняемым файлом
|
||||||
*/
|
*/
|
||||||
QDir executableFileDirectory() const;
|
const QString& executableDirectory() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Полный путь к пользовательскому каталогу с файлами настройки
|
|
||||||
*/
|
|
||||||
const QDir& userConfigDirectory() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Полный путь к системному каталогу с файлами настройки
|
|
||||||
*/
|
|
||||||
const QDir& systemConfigDirectory() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Полный путь к файлу настройки
|
|
||||||
*/
|
|
||||||
const QFileInfo& configFilePath() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Имя файла настройки
|
* @brief Имя файла настройки
|
||||||
@ -162,68 +124,125 @@ public:
|
|||||||
*/
|
*/
|
||||||
const QString& configFileExtension() const;
|
const QString& configFileExtension() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Полный путь к файлу настройки
|
||||||
|
*/
|
||||||
|
const QString& configFilePath() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Полный путь к пользовательскому каталогу с файлами настройки
|
||||||
|
*/
|
||||||
|
const QString& userConfigDirectory() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Полный путь к системному каталогу с файлами настройки
|
||||||
|
*/
|
||||||
|
const QString& systemConfigDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к пользовательскому каталогу с изменяемыми файлами
|
* @brief Полный путь к пользовательскому каталогу с изменяемыми файлами
|
||||||
*/
|
*/
|
||||||
const QDir& userVarDataDirectory() const;
|
const QString& userVarDataDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к системному каталогу с изменяемыми файлами
|
* @brief Полный путь к системному каталогу с изменяемыми файлами
|
||||||
*/
|
*/
|
||||||
const QDir& systemVarDataDirectory() const;
|
const QString& systemVarDataDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к пользовательскому каталогу с неизменяемыми файлами
|
* @brief Полный путь к пользовательскому каталогу с неизменяемыми файлами
|
||||||
*/
|
*/
|
||||||
const QDir& userConstDataDirectory() const;
|
const QString& userConstDataDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к системному каталогу с неизменяемыми файлами
|
* @brief Полный путь к системному каталогу с неизменяемыми файлами
|
||||||
*/
|
*/
|
||||||
const QDir& systemConstDataDirectory() const;
|
const QString& systemConstDataDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к пользовательскому каталогу с журналами работы
|
* @brief Полный путь к пользовательскому каталогу с журналами работы
|
||||||
*/
|
*/
|
||||||
const QDir& userLogDirectory() const;
|
const QString& userLogDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к системному каталогу с журналами работы
|
* @brief Полный путь к системному каталогу с журналами работы
|
||||||
*/
|
*/
|
||||||
const QDir& systemLogDirectory() const;
|
const QString& systemLogDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к каталогу с временными файлами
|
* @brief Полный путь к каталогу с временными файлами
|
||||||
*/
|
*/
|
||||||
const QDir& tempDirectory() const;
|
const QString& tempDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Полный путь к домашнему каталогу текущего пользователя
|
* @brief Полный путь к домашнему каталогу текущего пользователя
|
||||||
*/
|
*/
|
||||||
const QDir& homeDirectory() const;
|
const QString& homeDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Имя подкаталога для проекта
|
* @brief Имя подкаталога для проекта
|
||||||
*/
|
*/
|
||||||
const QString& projectName() const;
|
const QString& projectName() const;
|
||||||
|
|
||||||
/**
|
protected:
|
||||||
* @brief Имя исполняемого файла
|
Paths();
|
||||||
*/
|
~Paths() = default;
|
||||||
QString executableFileName() const;
|
|
||||||
|
|
||||||
/**
|
private:
|
||||||
* @brief Полный путь к исполняемому файлу
|
/// @brief Тип расположения файлов по каталогам
|
||||||
*/
|
HierarchyType m_hierarchyType { HierarchyType::kFlat };
|
||||||
const QFileInfo& executableFilePath() const;
|
|
||||||
|
/// @brief Имя проекта, которое используется при формировании имён файлов и каталогов
|
||||||
|
QString m_projectName;
|
||||||
|
|
||||||
|
QString m_executableName;
|
||||||
|
QString m_executableFilePath;
|
||||||
|
QString m_executableDirectory;
|
||||||
|
|
||||||
|
/// @brief Общий префикс для файлов проекта
|
||||||
|
QString m_prefixDirectory;
|
||||||
|
|
||||||
|
/// @brief Путь к каталогу с временными файлами
|
||||||
|
QString m_tempDirectory;
|
||||||
|
/// @brief Путь к домашнему каталогу текущего пользователя
|
||||||
|
QString m_homeDirectory;
|
||||||
|
|
||||||
|
/// @brief Путь к пользовательскому каталогу с изменяемыми файлами
|
||||||
|
QString m_userVarDataDirectory;
|
||||||
|
/// @brief Путь к системному каталогу с изменяемыми файлами
|
||||||
|
QString m_systemVarDataDirectory;
|
||||||
|
|
||||||
|
/// @brief Путь к пользовательскому каталогу с неизменяемыми файлами
|
||||||
|
QString m_userConstDataDirectory;
|
||||||
|
/// @brief Путь к системному каталогу с неизменяемыми файлами
|
||||||
|
QString m_systemConstDataDirectory;
|
||||||
|
|
||||||
|
/// @brief Путь к пользовательскому каталогу с журналами работы
|
||||||
|
QString m_userLogDirectory;
|
||||||
|
/// @brief Путь к системному каталогу с журналами работы
|
||||||
|
QString m_systemLogDirectory;
|
||||||
|
|
||||||
|
/// @brief Путь к пользовательскому каталогу с файлами настройки
|
||||||
|
QString m_userConfigDirectory;
|
||||||
|
/// @brief Путь к системному каталогу с файлами настройки
|
||||||
|
QString m_systemConfigDirectory;
|
||||||
|
|
||||||
|
/// @brief Полный путь к файлу настройки
|
||||||
|
QString m_configFilePath;
|
||||||
|
/// @brief Имя файла настройки
|
||||||
|
QString m_configFileName;
|
||||||
|
|
||||||
|
void setupSystemDirectories( const QString& defaultPrefixDirectory,
|
||||||
|
const QString& defaultEtcDirectory,
|
||||||
|
const QString& defaultConstDataDirectory,
|
||||||
|
const QString& defaultVarDataDirectory,
|
||||||
|
const QString& defaultLogDirectory );
|
||||||
|
bool initCommon();
|
||||||
|
HierarchyType getHierarchyType();
|
||||||
}; // class Paths
|
}; // class Paths
|
||||||
|
|
||||||
} // namespace filesystem
|
} // namespace filesystem
|
||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
#ifdef MYXLIB_HEADER_ONLY
|
|
||||||
#include "paths.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MYX_FILESYSTEM_PATHS_HPP_
|
#endif // MYX_FILESYSTEM_PATHS_HPP_
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
#ifndef MYX_BASE_PATHS_MT_CPP_
|
|
||||||
#define MYX_BASE_PATHS_MT_CPP_
|
|
||||||
|
|
||||||
#ifndef MYXLIB_HEADER_ONLY
|
|
||||||
#include <myx/filesystem/paths_mt.hpp>
|
|
||||||
#else
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
|
||||||
#include <myx/filesystem/current_executable.hpp>
|
|
||||||
|
|
||||||
#include <paths.h>
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace myx {
|
|
||||||
|
|
||||||
namespace filesystem {
|
|
||||||
|
|
||||||
MYXLIB_INLINE PathsMT::PathsMT() = default;
|
|
||||||
|
|
||||||
MYXLIB_INLINE PathsMT& PathsMT::instance()
|
|
||||||
{
|
|
||||||
volatile PathsMT* localInstance = 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
|
|
||||||
|
|
||||||
#endif // MYX_BASE_PATHS_MT_CPP_
|
|
@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file paths.hpp
|
|
||||||
* @brief Стандартные пути к каталогам и файлам
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MYX_FILESYSTEM_PATHS_MT_HPP_
|
|
||||||
#define MYX_FILESYSTEM_PATHS_MT_HPP_
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
|
||||||
#include <myx/filesystem/current_executable.hpp>
|
|
||||||
#include <myx/filesystem/paths.hpp>
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <future>
|
|
||||||
#include <mutex>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace myx {
|
|
||||||
|
|
||||||
namespace filesystem {
|
|
||||||
|
|
||||||
/// @brief Потокобезопасная версия класса myx::filesystem::Paths
|
|
||||||
class PathsMT : public Paths
|
|
||||||
{
|
|
||||||
PathsMT();
|
|
||||||
~PathsMT() = default;
|
|
||||||
|
|
||||||
static std::atomic< PathsMT* > mInstance;
|
|
||||||
static std::mutex mMutex;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
PathsMT( const PathsMT& ) = delete;
|
|
||||||
PathsMT& operator=( const PathsMT& ) = delete;
|
|
||||||
PathsMT( PathsMT&& ) = delete;
|
|
||||||
PathsMT& operator=( PathsMT&& ) = delete;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief getInstance
|
|
||||||
* @return Уникальный экземпляр класса PathsMT
|
|
||||||
*/
|
|
||||||
static PathsMT& instance();
|
|
||||||
}; // class PathsMT
|
|
||||||
|
|
||||||
} // namespace filesystem
|
|
||||||
|
|
||||||
} // namespace myx
|
|
||||||
|
|
||||||
#ifdef MYXLIB_HEADER_ONLY
|
|
||||||
#include "paths_mt.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MYX_FILESYSTEM_PATHS_MT_HPP_
|
|
@ -4,55 +4,59 @@ set(TRGT qt)
|
|||||||
# cmake-format: off
|
# cmake-format: off
|
||||||
# Список файлов исходных текстов
|
# Список файлов исходных текстов
|
||||||
set(TRGT_cpp
|
set(TRGT_cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/translators.cpp)
|
${CMAKE_CURRENT_SOURCE_DIR}/posix_signal_watcher.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/translators.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(TRGT_moc_hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/posix_signal_watcher.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(TRGT_moc_private_hpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/posix_signal_watcher_p.hpp
|
||||||
|
)
|
||||||
|
|
||||||
# Список заголовочных файлов (используется для установки)
|
|
||||||
set(TRGT_hpp
|
set(TRGT_hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/backports.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp)
|
)
|
||||||
|
|
||||||
set(TRGT_headers ${TRGT_hpp})
|
set(TRGT_headers ${TRGT_moc_hpp} ${TRGT_hpp})
|
||||||
# cmake-format: on
|
# cmake-format: on
|
||||||
|
|
||||||
add_library(${TRGT}-header-only INTERFACE)
|
qt5_wrap_cpp(TRGT_moc_cpp ${TRGT_moc_private_hpp} ${TRGT_moc_hpp})
|
||||||
target_include_directories(
|
|
||||||
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
|
|
||||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
|
||||||
|
|
||||||
if(MYXLIB_BUILD_LIBRARIES)
|
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_moc_cpp}
|
||||||
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
|
${TRGT_moc_private_hpp} ${TRGT_headers})
|
||||||
common_target_properties(${TRGT})
|
common_target_properties(${TRGT})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clang-tidy
|
# Создание цели для проверки утилитой clang-tidy
|
||||||
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clang-analyze
|
# Создание цели для проверки утилитой clang-analyze
|
||||||
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой clazy
|
# Создание цели для проверки утилитой clazy
|
||||||
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
||||||
|
|
||||||
# Создание цели для проверки утилитой pvs-studio
|
# Создание цели для проверки утилитой pvs-studio
|
||||||
add_pvs_check(${TRGT})
|
add_pvs_check(${TRGT})
|
||||||
|
|
||||||
# Создание цели для автоматического форматирования кода
|
# Создание цели для автоматического форматирования кода
|
||||||
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
|
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers} ${TRGT_moc_private_hpp})
|
||||||
|
|
||||||
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
|
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
||||||
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
target_include_directories(${TRGT} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
cotire(${TRGT})
|
cotire(${TRGT})
|
||||||
|
|
||||||
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
if(BUILD_SHARED_LIBS)
|
if(BUILD_SHARED_LIBS)
|
||||||
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
install(FILES ${TRGT_cpp} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||||
install(FILES ${TRGT_headers} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
install(FILES ${TRGT_headers} COMPONENT base-dev
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||||
|
|
||||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||||
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
||||||
|
131
src/myx/qt/posix_signal_watcher.cpp
Normal file
131
src/myx/qt/posix_signal_watcher.cpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#ifndef MYX_QT_POSIX_SIGNAL_WATCHER_CPP_
|
||||||
|
#define MYX_QT_POSIX_SIGNAL_WATCHER_CPP_
|
||||||
|
|
||||||
|
#include <myx/backports/cpp/helpers.hpp>
|
||||||
|
#include <myx/core/config.hpp>
|
||||||
|
|
||||||
|
#include <myx/qt/posix_signal_watcher.hpp>
|
||||||
|
#include <myx/qt/posix_signal_watcher_p.hpp>
|
||||||
|
|
||||||
|
namespace myx {
|
||||||
|
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
std::array< int, 2 > PosixSignalWatcherPrivate::mSockpair { { 0, 0 } };
|
||||||
|
|
||||||
|
PosixSignalWatcherPrivate::~PosixSignalWatcherPrivate() = default;
|
||||||
|
|
||||||
|
PosixSignalWatcherPrivate::PosixSignalWatcherPrivate( PosixSignalWatcher* q ) :
|
||||||
|
q_ptr( q )
|
||||||
|
{
|
||||||
|
#if MYX_QT_HAS_POSIX_SIGNALS
|
||||||
|
// Create socket pair
|
||||||
|
if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, mSockpair.data() ) != 0 )
|
||||||
|
{
|
||||||
|
qDebug() << "PosixSignalWatcher: socketpair: " << ::strerror( errno );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Create a notifier for the read end of the pair
|
||||||
|
// m_notifier.reset( new QSocketNotifier( mSockpair[1], QSocketNotifier::Read ) );
|
||||||
|
m_notifier = std::make_unique< QSocketNotifier >( mSockpair[1], QSocketNotifier::Read );
|
||||||
|
|
||||||
|
// Called when the signal handler has written to the socket pair.
|
||||||
|
// Emits the Posix signal as a Qt signal.
|
||||||
|
connect( m_notifier.get(), &QSocketNotifier::activated, q, [this]( int sockfd ) {
|
||||||
|
Q_Q( PosixSignalWatcher );
|
||||||
|
|
||||||
|
int signal = 0;
|
||||||
|
Q_UNUSED( !::read( sockfd, &signal, sizeof( signal ) ) );
|
||||||
|
qDebug() << "Caught signal: " << ::strsignal( signal );
|
||||||
|
Q_EMIT q->posixSignal( signal );
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
||||||
|
m_notifier->setEnabled( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Registers a handler for the given Posix \a signal. The handler will write to
|
||||||
|
* a socket pair, the other end of which is connected to a QSocketNotifier.
|
||||||
|
* This provides a way to break out of the asynchronous context from which the
|
||||||
|
* signal handler is called and back into the Qt event loop.
|
||||||
|
*/
|
||||||
|
MYXLIB_INLINE void PosixSignalWatcherPrivate::watchForSignal( int signal )
|
||||||
|
{
|
||||||
|
if ( m_watchedSignals.contains( signal ) )
|
||||||
|
{
|
||||||
|
qDebug() << "Already watching for signal " << signal;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MYX_QT_HAS_POSIX_SIGNALS
|
||||||
|
// Register a sigaction which will write to the socket pair
|
||||||
|
struct sigaction sigact; //NOLINT
|
||||||
|
sigact.sa_handler = PosixSignalWatcherPrivate::signalHandler; //NOLINT
|
||||||
|
sigact.sa_flags = 0;
|
||||||
|
sigemptyset( &sigact.sa_mask );
|
||||||
|
sigact.sa_flags |= SA_RESTART;
|
||||||
|
sigact.sa_restorer = nullptr;
|
||||||
|
if ( ::sigaction( signal, &sigact, nullptr ) != 0 )
|
||||||
|
{
|
||||||
|
qDebug() << "PosixSignalWatcher: sigaction: " << ::strerror( errno );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_watchedSignals.append( signal );
|
||||||
|
} // PosixSignalWatcherPrivate::watchForSignal
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Called when a Posix \a signal is received. Write to the socket to wake up the
|
||||||
|
* QSocketNotifier.
|
||||||
|
*/
|
||||||
|
MYXLIB_INLINE void PosixSignalWatcherPrivate::signalHandler( int signal )
|
||||||
|
{
|
||||||
|
Q_UNUSED( !::write( mSockpair[0], &signal, sizeof( signal ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Create a new PosixSignalWatcher as a child of the given \a parent.
|
||||||
|
*/
|
||||||
|
MYXLIB_INLINE PosixSignalWatcher::PosixSignalWatcher( QObject* parent ) :
|
||||||
|
QObject( parent ),
|
||||||
|
d_ptr ( new PosixSignalWatcherPrivate( this ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Register a signal handler for the given \a signal.
|
||||||
|
*
|
||||||
|
* After calling this method you can \c connect() to the POSIXSignal() Qt signal
|
||||||
|
* to be notified when the Posix signal is received.
|
||||||
|
*/
|
||||||
|
MYXLIB_INLINE void PosixSignalWatcher::watchForSignal( int signal )
|
||||||
|
{
|
||||||
|
Q_D( PosixSignalWatcher );
|
||||||
|
d->watchForSignal( signal );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \fn void PosixSignalWatcher::posixSignal(int signal)
|
||||||
|
* Emitted when the given Posix \a signal is received.
|
||||||
|
*
|
||||||
|
* watchForSignal() must be called for each Posix signal that you want to receive
|
||||||
|
* via the POSIXSignal() Qt signal. If a watcher is watching multiple signals,
|
||||||
|
* POSIXSignal() will be emitted whenever *any* of the watched Posix signals are
|
||||||
|
* received, and the \a signal argument can be inspected to find out which one
|
||||||
|
* was actually received.
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
|
||||||
|
} // namespace myx
|
||||||
|
|
||||||
|
#endif // ifndef MYX_QT_POSIX_SIGNAL_WATCHER_CPP_
|
49
src/myx/qt/posix_signal_watcher.hpp
Normal file
49
src/myx/qt/posix_signal_watcher.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef MYX_QT_POSIX_SIGNAL_WATCHER_HPP_
|
||||||
|
#define MYX_QT_POSIX_SIGNAL_WATCHER_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <myx/core/config.hpp>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
|
namespace myx {
|
||||||
|
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
class PosixSignalWatcherPrivate;
|
||||||
|
|
||||||
|
#if defined( Q_OS_WIN )
|
||||||
|
const int SIGINT = 2;
|
||||||
|
const int SIGTERM = 15;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The PosixSignalWatcher class converts Posix signals to Qt signals.
|
||||||
|
*
|
||||||
|
* To watch for a given signal, e.g. \c SIGINT, call \c watchForSignal(SIGINT)
|
||||||
|
* and \c connect() your handler to posixSignal().
|
||||||
|
*/
|
||||||
|
class PosixSignalWatcher : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PosixSignalWatcher( QObject* parent = nullptr );
|
||||||
|
|
||||||
|
void watchForSignal( int signal );
|
||||||
|
Q_SIGNAL void posixSignal( int signal );
|
||||||
|
|
||||||
|
private:
|
||||||
|
PosixSignalWatcherPrivate* const d_ptr = nullptr;
|
||||||
|
Q_DECLARE_PRIVATE( PosixSignalWatcher ) //NOLINT
|
||||||
|
}; // class PosixSignalWatcher
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
|
||||||
|
} // namespace myx
|
||||||
|
|
||||||
|
#endif // ifndef MYX_QT_POSIX_SIGNAL_WATCHER_HPP_
|
64
src/myx/qt/posix_signal_watcher_p.hpp
Normal file
64
src/myx/qt/posix_signal_watcher_p.hpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef MYX_QT_POSIX_SIGNAL_WATCHER_P_HPP_
|
||||||
|
#define MYX_QT_POSIX_SIGNAL_WATCHER_P_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <myx/core/config.hpp>
|
||||||
|
#include <myx/qt/posix_signal_watcher.hpp>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QSocketNotifier>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#define MYX_QT_HAS_POSIX_SIGNALS 0
|
||||||
|
#else
|
||||||
|
#define MYX_QT_HAS_POSIX_SIGNALS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MYX_QT_HAS_POSIX_SIGNALS
|
||||||
|
#include <csignal>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace myx {
|
||||||
|
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The PosixSignalWatcherPrivate class implements the back-end signal
|
||||||
|
* handling for the PosixSignalWatcher.
|
||||||
|
*
|
||||||
|
* \see http://qt-project.org/doc/qt-5.0/qtdoc/POSIX-signals.html
|
||||||
|
*/
|
||||||
|
class PosixSignalWatcherPrivate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
PosixSignalWatcherPrivate( PosixSignalWatcher* q );
|
||||||
|
~PosixSignalWatcherPrivate();
|
||||||
|
|
||||||
|
void watchForSignal( int signal );
|
||||||
|
static void signalHandler( int signal );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DECLARE_PUBLIC( PosixSignalWatcher )
|
||||||
|
|
||||||
|
PosixSignalWatcher* const q_ptr = nullptr;
|
||||||
|
static std::array< int, 2 > mSockpair;
|
||||||
|
std::unique_ptr< QSocketNotifier > m_notifier;
|
||||||
|
QList< int > m_watchedSignals;
|
||||||
|
}; // class PosixSignalWatcherPrivate
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
|
||||||
|
} // namespace myx
|
||||||
|
|
||||||
|
#endif // ifndef MYX_QT_POSIX_SIGNAL_WATCHER_P_HPP_
|
@ -1,13 +1,10 @@
|
|||||||
#ifndef MYX_QT_TRANSLATORS_CPP_
|
#ifndef MYX_QT_TRANSLATORS_CPP_
|
||||||
#define MYX_QT_TRANSLATORS_CPP_
|
#define MYX_QT_TRANSLATORS_CPP_
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
#include <myx/backports/qt/common.hpp>
|
||||||
|
#include <myx/core/config.hpp>
|
||||||
|
|
||||||
#ifndef MYXLIB_HEADER_ONLY
|
|
||||||
#include <myx/qt/translators.hpp>
|
#include <myx/qt/translators.hpp>
|
||||||
#else
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <myx/base/config.hpp>
|
#include <myx/backports/qt/common.hpp>
|
||||||
#include <myx/qt/backports.hpp>
|
#include <myx/core/config.hpp>
|
||||||
|
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
@ -20,8 +20,4 @@ void append_translators( QTranslatorsList& translators, const QString& appName )
|
|||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
#ifdef MYXLIB_HEADER_ONLY
|
|
||||||
#include "translators.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // ifndef MYX_QT_TRANSLATORS_HPP_
|
#endif // ifndef MYX_QT_TRANSLATORS_HPP_
|
||||||
|
Loading…
Reference in New Issue
Block a user