diff --git a/cmake/cmlib b/cmake/cmlib index 8fbf0a3..5e600ab 160000 --- a/cmake/cmlib +++ b/cmake/cmlib @@ -1 +1 @@ -Subproject commit 8fbf0a3b3d8ef4598fe5c334067e2de321e04dae +Subproject commit 5e600ab490fc789667062e998bb48effb9bf35a0 diff --git a/examples/filesystem/01_paths/paths.cpp b/examples/filesystem/01_paths/paths.cpp index ff87fff..382b5b4 100644 --- a/examples/filesystem/01_paths/paths.cpp +++ b/examples/filesystem/01_paths/paths.cpp @@ -26,9 +26,6 @@ int main( int argc, char** argv ) 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(); diff --git a/src/myx/filesystem/paths.cpp b/src/myx/filesystem/paths.cpp index 31f296e..9772d9f 100644 --- a/src/myx/filesystem/paths.cpp +++ b/src/myx/filesystem/paths.cpp @@ -9,18 +9,13 @@ #include #include -#ifndef QT_NO_DEBUG -#include -#endif - namespace myx { namespace filesystem { MYXLIB_INLINE Paths::Paths() : - m_configFileExtension( ".conf" ), - m_binDirRegex ( "/s*bin$" ), - m_unityBinDirRegex ( "/bin/unity$" ) + m_binDirRegex ( "/s*bin$" ), + m_unityBinDirRegex( "/bin/unity$" ) { QFileInfo procSelfExe( QStringLiteral( "/proc/self/exe" ) ); QFileInfo currentExecutable = procSelfExe.canonicalFilePath(); @@ -30,33 +25,9 @@ MYXLIB_INLINE Paths::Paths() : } -MYXLIB_INLINE bool Paths::init() -{ - m_configFileName = m_executableName + m_configFileExtension; - return( initCommon() ); -} - - -//MYXLIB_INLINE bool Paths::init( const QString& configFileName ) -//{ -// 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::initCommon() +MYXLIB_INLINE bool Paths::init( bool autodetect ) { + m_autodetect = autodetect; m_homeDirectory = QDir::homePath(); m_tempDirectory = QDir::tempPath(); @@ -72,13 +43,15 @@ MYXLIB_INLINE bool Paths::initCommon() m_dataDirectory = m_homeDirectory + "/.local/share"; } + if ( m_projectName.isEmpty() ) + { + m_projectName = m_executableName; + } m_hierarchyType = getHierarchyType(); calculatePaths( m_hierarchyType ); - m_configFilePath = m_systemConfigDirectory + "/" + m_configFileName; - return( true ); -} // Paths::initCommon +} // Paths::init MYXLIB_INLINE void Paths::setupSystemDirectories( const QString& defaultProjectDirectory, @@ -139,12 +112,19 @@ MYXLIB_INLINE void Paths::setupSystemDirectories( const QString& defaultProjectD } // Paths::setupSystemDirectories -MYXLIB_INLINE void Paths::setupUserDirectories( const QString& prefix ) +MYXLIB_INLINE void Paths::setupUserDirectories() { - m_userConfigDirectory = m_configDirectory + "/" + prefix; - m_userConstDataDirectory = m_dataDirectory + "/" + prefix + "/share"; - m_userVarDataDirectory = m_dataDirectory + "/" + prefix + "/var"; - m_userLogDirectory = m_dataDirectory + "/" + prefix + "/log"; + QString prefix; + if ( !m_organizationName.isEmpty() ) + { + prefix = "/" + m_organizationName; + if ( !m_themeName.isEmpty() ) { prefix.append( "-" + m_themeName ); } + } + prefix.append( "/" + m_projectName ); + m_userConfigDirectory = m_configDirectory + prefix; + m_userConstDataDirectory = m_dataDirectory + prefix + "/share"; + m_userVarDataDirectory = m_dataDirectory + prefix + "/var"; + m_userLogDirectory = m_dataDirectory + prefix + "/log"; } @@ -193,51 +173,17 @@ MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType() MYXLIB_INLINE void Paths::calculatePaths( HierarchyType hType ) { auto directory = m_executableDirectory; + setupUserDirectories(); switch ( hType ) { case HierarchyType::kFlat: setupSystemDirectories( directory, directory, directory, directory, directory ); - return; + break; case HierarchyType::kOpt: - if ( m_organizationName.isEmpty() || m_themeName.isEmpty() ) - { - QRegularExpression regex( "^/opt/(.+?)-(.+?)/" ); - QRegularExpressionMatch match = regex.match( m_executableDirectory ); - if ( match.hasMatch() ) - { - m_organizationName = match.captured( 1 ); - m_themeName = match.captured( 2 ); - - QRegularExpression vr( "(.+?)\\.(.+)" ); - QRegularExpressionMatch vm = vr.match( m_themeName ); - if ( vm.hasMatch() ) - { - m_themeName = vm.captured( 1 ); - m_version = vm.captured( 2 ); - } - } - } - - if ( m_projectName.isEmpty() ) - { - QRegularExpression regex( "^/opt/.+/(.+?)/" ); - QRegularExpressionMatch match = regex.match( m_executableDirectory ); - if ( match.hasMatch() ) - { - m_projectName = match.captured( 1 ); - } - } - directory.remove( m_binDirRegex ); - - setupSystemDirectories( directory, - directory + "/etc", - directory + "/share", - directory + "/var", - directory + "/log" ); - setupUserDirectories( m_organizationName + "-" + m_themeName + "/" + m_projectName ); - return; + processOptHierarhy(); + break; case HierarchyType::kUsr: setupSystemDirectories( QStringLiteral( "/usr" ), @@ -245,7 +191,7 @@ MYXLIB_INLINE void Paths::calculatePaths( HierarchyType hType ) "/usr/share/" + m_projectName, "/var/lib/" + m_projectName, "/var/log/" + m_projectName ); - return; + break; case HierarchyType::kUsrLocal: setupSystemDirectories( QStringLiteral( "/usr/local" ), @@ -253,7 +199,7 @@ MYXLIB_INLINE void Paths::calculatePaths( HierarchyType hType ) "/usr/local/share/" + m_projectName, "/var/lib/" + m_projectName, "/var/log/" + m_projectName ); - return; + break; case HierarchyType::kUsrLocalOrg: directory.remove( m_binDirRegex ); @@ -262,7 +208,7 @@ MYXLIB_INLINE void Paths::calculatePaths( HierarchyType hType ) directory + "/share", directory + "/var", directory + "/log" ); - return; + break; case HierarchyType::kHome: m_projectDirectory = m_homeDirectory; @@ -270,7 +216,7 @@ MYXLIB_INLINE void Paths::calculatePaths( HierarchyType hType ) m_systemConstDataDirectory = m_userConstDataDirectory; m_systemVarDataDirectory = m_userVarDataDirectory; m_systemLogDirectory = m_userLogDirectory; - return; + break; case HierarchyType::kDevelopment: directory.remove( m_unityBinDirRegex ); @@ -280,14 +226,59 @@ MYXLIB_INLINE void Paths::calculatePaths( HierarchyType hType ) directory + "/share", directory + "/var", directory + "/log" ); - return; + break; case HierarchyType::kUndefined: ; } // switch + setupUserDirectories(); } // Paths::calculatePaths +MYXLIB_INLINE void Paths::processOptHierarhy() +{ + auto directory = m_executableDirectory; + + if ( m_autodetect ) + { + QRegularExpression regex( "^/opt/(.+?)-(.+?)/(.+?)/" ); + QRegularExpressionMatch match = regex.match( m_executableDirectory ); + if ( match.hasMatch() ) + { + m_organizationName = match.captured( 1 ); + m_themeName = match.captured( 2 ); + m_projectName = match.captured( 3 ); + + QRegularExpression vr( "(.+?)\\.(.+)" ); + QRegularExpressionMatch vm = vr.match( m_themeName ); + if ( vm.hasMatch() ) + { + m_themeName = vm.captured( 1 ); + m_version = vm.captured( 2 ); + } + } + else + { + regex.setPattern( "^/opt/(.+?)/(.+?)/" ); + match = regex.match( m_executableDirectory ); + if ( match.hasMatch() ) + { + m_organizationName = match.captured( 1 ); + m_projectName = match.captured( 2 ); + } + } + } + + directory.remove( m_binDirRegex ); + setupSystemDirectories( directory, + directory + "/etc", + directory + "/share", + directory + "/var", + directory + "/log" ); + setupUserDirectories(); +} // Paths::processOptHierarhy + + MYXLIB_INLINE bool Paths::makeDefaultSystemDirectories() { bool status = true; @@ -322,25 +313,24 @@ MYXLIB_INLINE bool Paths::makeDefaultDirectories() } -MYXLIB_INLINE QString Paths::findConfigFile( const QString& defaultConfigFile ) +MYXLIB_INLINE QString Paths::findConfigFile( const QString& configFileName ) { - if ( !defaultConfigFile.isEmpty() && QFileInfo( defaultConfigFile ).isReadable() ) + if ( !configFileName.isEmpty() && QFileInfo( configFileName ).isReadable() ) { - m_configFilePath = defaultConfigFile; - return( defaultConfigFile ); + return( configFileName ); } auto fileName = QString::fromLocal8Bit( qgetenv( QCoreApplication::applicationName() .toUpper().toUtf8() + "_CONFIG" ) ); if ( QFileInfo( fileName ).isReadable() ) { - m_configFilePath = fileName; return( fileName ); } - if ( QFileInfo( m_configFilePath ).isReadable() ) + QString autoConfigFile = m_systemConfigDirectory + "/" + m_executableName; + if ( QFileInfo( autoConfigFile ).isReadable() ) { - return( m_configFilePath ); + return( configFileName ); } return( QString() ); @@ -359,30 +349,6 @@ MYXLIB_INLINE const QString& Paths::systemConfigDirectory() const } -MYXLIB_INLINE const QString& Paths::configFilePath() const -{ - return( m_configFilePath ); -} - - -MYXLIB_INLINE const QString& Paths::configFileName() const -{ - return( m_configFileName ); -} - - -const QString& Paths::configFileExtension() const -{ - return( m_configFileExtension ); -} - - -void Paths::setConfigFileExtension( const QString& name ) -{ - m_configFileExtension = name; -} - - MYXLIB_INLINE const QString& Paths::userVarDataDirectory() const { return( m_userVarDataDirectory ); @@ -437,6 +403,12 @@ MYXLIB_INLINE const QString& Paths::projectName() const } +MYXLIB_INLINE void Paths::setProjectName( const QString& name ) +{ + m_projectName = name; +} + + MYXLIB_INLINE const QString& Paths::organizationName() const { return( m_organizationName ); diff --git a/src/myx/filesystem/paths.hpp b/src/myx/filesystem/paths.hpp index eb2a23a..5cfb0df 100644 --- a/src/myx/filesystem/paths.hpp +++ b/src/myx/filesystem/paths.hpp @@ -62,7 +62,7 @@ public: } /** @brief Обновление путей с учётом расположения исполняемого файла */ - bool init(); + bool init( bool autodetect = true ); /** @brief Создание стандартных системных каталогов */ bool makeDefaultSystemDirectories(); @@ -76,14 +76,11 @@ public: /** @brief Поиск существующего файла настойки. * Поиск выполняется до тех пор пока не будет найден файл в следующем порядке: * 1. Имя файла, указанное в качестве параметра функции - * 2. Имя файла, заданное переменной окружения вида PROJECT_NAME_CONFIG - * 3. Имя файла, полученное из внутренней переменной класса + * 2. Имя файла, заданное переменной окружения вида EXECUTABLE_NAME_CONFIG + * 3. Имя файла, полученное из имени каталога системных настроек и имени исполняемого файла * Если файл настройки не будет найден, то будет возвращена пустая строка */ - QString findConfigFile( const QString& defaultConfigFile = QLatin1String( "" ) ); - - /** @brief Полный путь к базовому каталогу */ - const QString& projectName() const; + QString findConfigFile( const QString& configFileName = QLatin1String( "" ) ); /** @brief Имя исполняемого файла */ const QString& executableName() const; @@ -94,18 +91,6 @@ public: /** @brief Полный путь к каталогу с исполняемым файлом */ const QString& executableDirectory() const; - /** @brief Имя файла настройки */ - const QString& configFileName() const; - - /** @brief Расширение файла настройки */ - const QString& configFileExtension() const; - - /** @brief Установка расширения файла настройки */ - void setConfigFileExtension( const QString& name ); - - /** @brief Полный путь к файлу настройки */ - const QString& configFilePath() const; - /** @brief Полный путь к пользовательскому каталогу с файлами настройки */ const QString& userConfigDirectory() const; @@ -150,6 +135,10 @@ public: const QString& themeName() const; void setThemeName( const QString& name ); + /** @brief Название программного проекта */ + const QString& projectName() const; + void setProjectName( const QString& name ); + protected: Paths(); ~Paths() = default; @@ -158,6 +147,13 @@ private: /** @brief Тип расположения файлов по каталогам */ HierarchyType m_hierarchyType { HierarchyType::kFlat }; + /** @brief Автоматически определять значения organizationName, themeName и projectName + * @detail Если true, то пытаться автоматически определять значения переменных + * на основании полного пути к исполняемому файлу. + * Иначе использовать значения переменных, указанные пользователем. + */ + bool m_autodetect { true }; + /** @brief Название организации */ QString m_organizationName; @@ -209,13 +205,6 @@ private: /** @brief Путь к системному каталогу с файлами настройки */ QString m_systemConfigDirectory; - /** @brief Полный путь к файлу настройки */ - QString m_configFilePath; - /** @brief Имя файла настройки */ - QString m_configFileName; - /** @brief Расширение файла настройки */ - QString m_configFileExtension; - QRegularExpression m_binDirRegex; QRegularExpression m_unityBinDirRegex; @@ -224,11 +213,11 @@ private: const QString& defaultConstDataDirectory, const QString& defaultVarDataDirectory, const QString& defaultLogDirectory ); - void setupUserDirectories( const QString& prefix ); + void setupUserDirectories(); - bool initCommon(); HierarchyType getHierarchyType(); void calculatePaths( HierarchyType hType ); + void processOptHierarhy(); }; // class Paths } // namespace filesystem