From 72ba1ce627fe1648b77a25013cba6151eb1e0001 Mon Sep 17 00:00:00 2001 From: Andrey Astafyev Date: Sat, 5 Oct 2019 13:21:42 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20?= =?UTF-8?q?=D0=B2=20whereami?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 + CMakeLists.txt | 7 + examples/filesystem/01_minimal/CMakeLists.txt | 5 +- src/filesystem/CMakeLists.txt | 11 +- src/filesystem/paths.cpp | 118 +-- src/filesystem/paths.hpp | 20 +- src/log/spdlog.cpp | 50 +- thirdparty/whereami | 1 + thirdparty/whereami/README.md | 132 ---- thirdparty/whereami/whereami.c | 679 ------------------ thirdparty/whereami/whereami.h | 67 -- 11 files changed, 124 insertions(+), 969 deletions(-) create mode 160000 thirdparty/whereami delete mode 100644 thirdparty/whereami/README.md delete mode 100644 thirdparty/whereami/whereami.c delete mode 100644 thirdparty/whereami/whereami.h diff --git a/.gitmodules b/.gitmodules index 6c3ddd7..9d64d59 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "cmake/generators"] path = cmake/generators url = ../../f1x1t/cmake-generators +[submodule "thirdparty/whereami"] + path = thirdparty/whereami + url = ../../f1x1t/whereami.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d18bb9..c4c2ca7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,13 @@ if (BUILD_EXAMPLES) add_subdirectory(examples/log) endif() +ExternalProject_Add(whereami + SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/whereami + INSTALL_DIR ${CMAKE_BINARY_DIR} + DOWNLOAD_COMMAND "" + CONFIGURE_COMMAND ${CMAKE_COMMAND} -"G${CMAKE_GENERATOR}" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF + ) + add_breathe_target( TARGET_NAME doc-breathe SOURCE_DIR ${CMAKE_SOURCE_DIR}/doc/html diff --git a/examples/filesystem/01_minimal/CMakeLists.txt b/examples/filesystem/01_minimal/CMakeLists.txt index 00c428f..896dbfe 100644 --- a/examples/filesystem/01_minimal/CMakeLists.txt +++ b/examples/filesystem/01_minimal/CMakeLists.txt @@ -7,7 +7,7 @@ set(current_target_sources ) # Путь поиска библиотек внутри проекта -link_directories(${CMAKE_INSTALL_LIBDIR}) +link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) link_directories(${CMAKE_BINARY_DIR}/src/filesystem/lib) # Цель для создания исполняемого файла @@ -21,6 +21,7 @@ add_pvs_check(${current_target}) add_dependencies(${current_target} base) add_dependencies(${current_target} filesystem) +add_dependencies(${current_target} whereami) # Qt5 # qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU) @@ -31,6 +32,8 @@ target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIR target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") target_link_libraries(${current_target} myx-filesystem) +target_link_libraries(${current_target} whereamipp) +target_link_libraries(${current_target} whereami) target_link_libraries(${current_target} Qt5::Core) # Имя выходного файла для цели diff --git a/src/filesystem/CMakeLists.txt b/src/filesystem/CMakeLists.txt index 23ec1dd..508709d 100644 --- a/src/filesystem/CMakeLists.txt +++ b/src/filesystem/CMakeLists.txt @@ -11,10 +11,13 @@ set(current_target_headers ${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp ) -add_common_library(TARGET ${current_target} OUTPUT_NAME myx-${current_target} - SOURCES ${current_target_sources} - ${CMAKE_SOURCE_DIR}/thirdparty/whereami/whereami.c) +add_common_library(TARGET ${current_target} + OUTPUT_NAME myx-${current_target} + SOURCES ${current_target_sources}) common_target_properties(${current_target}) +add_dependencies(${current_target} whereami) + + add_clang_tidy_check(${current_target} ${current_target_sources}) add_clang_analyze_check(${current_target} ${current_target_sources}) add_clazy_check(${current_target} ${current_target_sources}) @@ -25,7 +28,7 @@ target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIR target_include_directories(${current_target} SYSTEM PUBLIC ${FMT_INCLUDE_DIRS}) target_include_directories(${current_target} SYSTEM PUBLIC ${SPDLOG_INCLUDE_DIRS}) target_include_directories(${current_target} PRIVATE ${CMAKE_SOURCE_DIR}/src/base) -target_include_directories(${current_target} PRIVATE ${CMAKE_SOURCE_DIR}/thirdparty/whereami) +target_include_directories(${current_target} PRIVATE ${CMAKE_BINARY_DIR}/include) # Цель, используемая только для установки заголовочных файлов без компиляции проекта add_custom_target(${current_target}-install-headers diff --git a/src/filesystem/paths.cpp b/src/filesystem/paths.cpp index 4b0d38f..5fca0c3 100644 --- a/src/filesystem/paths.cpp +++ b/src/filesystem/paths.cpp @@ -1,13 +1,62 @@ #include "paths.hpp" #include "config.hpp" -#include "whereami.h" +#include "whereami++.h" #include +#include namespace myx { namespace filesystem { +QString Paths::executableFileName() const +{ + return( m_executableFileName ); +} + + +void Paths::setExecutableFileName( const QString& executableFileName ) +{ + m_executableFileName = executableFileName; +} + + +QString Paths::configFileName() const +{ + return( m_configFileName ); +} + + +void Paths::setConfigFileName( const QString& configFileName ) +{ + m_configFileName = configFileName; +} + + +QFileInfo Paths::executableFilePath() const +{ + return( m_executableFilePath ); +} + + +void Paths::setExecutableFilePath( const QFileInfo& executableFilePath ) +{ + m_executableFilePath = executableFilePath; +} + + +QFileInfo Paths::configFilePath() const +{ + return( m_configFilePath ); +} + + +void Paths::setConfigFilePath( const QFileInfo& configFilePath ) +{ + m_configFilePath = configFilePath; +} + + Paths::Paths() : m_prefixDirectory( "/opt/" ORGANIZATION_NAME_LOWER "/" PROJECT_NAME_LOWER ), m_binaryDirectory( m_prefixDirectory.absolutePath() + "/bin" ), @@ -16,8 +65,10 @@ Paths::Paths() : m_tempDirectory( QString::fromLocal8Bit( qgetenv( qPrintable( "TMPDIR" ) ) ) ), m_dataDirectory( m_prefixDirectory.absolutePath() + "/share" ), m_homeDirectory( QString::fromLocal8Bit( qgetenv( qPrintable( "HOME" ) ) ) ), - m_executableFile( m_binaryDirectory.absolutePath() + "/" + PROJECT_NAME_LOWER ), - m_configFile( m_configDirectory.absolutePath() + "/" + PROJECT_NAME_LOWER + ".conf" ) + m_executableFileName( PROJECT_NAME_LOWER ), + m_configFileName( PROJECT_NAME_LOWER ".conf" ), + m_executableFilePath( m_binaryDirectory.absolutePath() + "/" + m_executableFileName ), + m_configFilePath( m_binaryDirectory.absolutePath() + "/" + m_configFileName ) { if ( m_tempDirectory.isEmpty() || ( m_tempDirectory.path() == "." ) ) { @@ -98,56 +149,13 @@ void Paths::setDataDirectory( const QString& dataDirectory ) } -QFileInfo Paths::executableFile() const -{ - return( m_executableFile ); -} - - -void Paths::setExecutableFile( const QString& executableFile ) -{ - m_executableFile = executableFile; -} - - -QFileInfo Paths::configFile() const -{ - return( m_configFile ); -} - - -void Paths::setConfigFile( const QString& configFile ) -{ - m_configFile = configFile; -} - - bool Paths::updatePaths() { - char* path = nullptr; - int fullPathLength; - int dirNameLength; + whereami::whereami_path_t executablePath = whereami::getExecutablePath(); - fullPathLength = wai_getExecutablePath( nullptr, 0, &dirNameLength ); - if ( fullPathLength > 0 ) - { - path = new( std::nothrow ) char[static_cast< size_t >( fullPathLength ) + 1 ]; - if ( path == nullptr ) - { - return( false ); - } - wai_getExecutablePath( path, fullPathLength, &dirNameLength ); - path[fullPathLength] = '\0'; - } - else - { - return( false ); - } - - m_executableFile = QFile( path ); - path[dirNameLength] = '\0'; - m_binaryDirectory = path; - delete [] path; + m_executableFileName = QString::fromStdString( executablePath.basename() ); + m_binaryDirectory = QString::fromStdString( executablePath.dirname() ); + m_executableFilePath = QFile( m_binaryDirectory.absolutePath() + "/" + m_executableFileName ); if ( m_binaryDirectory.absolutePath().endsWith( "/bin" ) ) { @@ -155,7 +163,7 @@ bool Paths::updatePaths() m_configDirectory = m_prefixDirectory.absolutePath() + "/etc"; m_cacheDirectory = m_prefixDirectory.absolutePath() + "/var"; m_dataDirectory = m_prefixDirectory.absolutePath() + "/share"; - m_configFile = m_configDirectory.absolutePath() + "/" + PROJECT_NAME_LOWER + ".conf"; + m_configFilePath = QFile( m_configDirectory.absolutePath() + "/" + PROJECT_NAME_LOWER + ".conf" ); } if ( m_prefixDirectory.absolutePath().startsWith( "/opt" ) || @@ -202,22 +210,24 @@ QString Paths::findConfigFile( const QString& defaultConfigFile ) { if ( QFileInfo( defaultConfigFile ).isReadable() ) { + m_configFilePath = defaultConfigFile; return( defaultConfigFile ); } auto fileName = QString::fromLocal8Bit( qgetenv( qPrintable( PROJECT_NAME_UPPER "_CONFIG" ) ) ); if ( QFileInfo( fileName ).isReadable() ) { + m_configFilePath = fileName; return( fileName ); } - if ( QFileInfo( m_configFile ).isReadable() ) + if ( QFileInfo( m_configFilePath ).isReadable() ) { - return( m_configFile.absoluteFilePath() ); + return( m_configFilePath.absoluteFilePath() ); } return( QString() ); -} +} // Paths::findConfigFile } // namespace filesystem diff --git a/src/filesystem/paths.hpp b/src/filesystem/paths.hpp index ccd22c7..675c960 100644 --- a/src/filesystem/paths.hpp +++ b/src/filesystem/paths.hpp @@ -18,8 +18,10 @@ class Paths QDir m_tempDirectory; QDir m_dataDirectory; QDir m_homeDirectory; - QFileInfo m_executableFile; - QFileInfo m_configFile; + QString m_executableFileName; + QString m_configFileName; + QFileInfo m_executableFilePath; + QFileInfo m_configFilePath; public: Paths(); @@ -35,14 +37,18 @@ public: void setTempDirectory( const QString& tempDirectory ); QDir dataDirectory() const; void setDataDirectory( const QString& dataDirectory ); - QFileInfo executableFile() const; - void setExecutableFile( const QString& executableFile ); - QFileInfo configFile() const; - void setConfigFile( const QString& configFile ); + QString executableFileName() const; + void setExecutableFileName( const QString& executableFileName ); + QString configFileName() const; + void setConfigFileName( const QString& configFileName ); + QFileInfo executableFilePath() const; + void setExecutableFilePath( const QFileInfo& executableFilePath ); + QFileInfo configFilePath() const; + void setConfigFilePath( const QFileInfo& configFilePath ); bool updatePaths(); bool makePaths(); - QString findConfigFile( const QString& defaultConfigFile = QLatin1String("") ); + QString findConfigFile( const QString& defaultConfigFile = "" ); }; // class Paths } // namespace filesystem diff --git a/src/log/spdlog.cpp b/src/log/spdlog.cpp index bd38dc7..ae1c089 100644 --- a/src/log/spdlog.cpp +++ b/src/log/spdlog.cpp @@ -8,6 +8,31 @@ namespace log { Logger default_logger( "default" ); +Logger::Logger( std::string name ) : + m_logger( nullptr ), + m_name( std::move( name ) ), + m_outputPattern( "[%H:%M:%S %z] [%n] [%^---%L---%$] %v" ), + m_baseFileName( fmt::format( "{}_{}", PROJECT_NAME, "st" ) ), + m_maxRotatingFileSize( rotatingFileSize ), + m_maxRotatingFilesCount( 3 ), + m_outputLevel( spdlog::level::trace ), + m_flushLevel( spdlog::level::warn ), + m_nullSink( nullptr ), + m_stdoutSink( nullptr ), + m_stderrSink( nullptr ), + m_syslogSink( nullptr ), + m_basicFileSink( nullptr ), + m_rotatingFileSink( nullptr ), + m_dailyFileSink( nullptr ) +{ + m_logger = std::make_shared< spdlog::logger >( m_name, nullptr ); + m_logger->sinks().clear(); + m_logger->flush_on( m_flushLevel ); + m_logger->set_level( m_outputLevel ); + m_logger->set_pattern( m_outputPattern ); +} + + spdlog::level::level_enum Logger::outputLevel() const { return( m_outputLevel ); @@ -44,31 +69,6 @@ void Logger::setOutputPattern( const std::string& outputPattern ) } -Logger::Logger( std::string name ) : - m_logger( nullptr ), - m_name( std::move( name ) ), - m_outputPattern( "[%H:%M:%S %z] [%n] [%^---%L---%$] %v" ), - m_baseFileName( fmt::format( "{}_{}", PROJECT_NAME, "st" ) ), - m_maxRotatingFileSize( rotatingFileSize ), - m_maxRotatingFilesCount( 3 ), - m_outputLevel( spdlog::level::trace ), - m_flushLevel( spdlog::level::warn ), - m_nullSink( nullptr ), - m_stdoutSink( nullptr ), - m_stderrSink( nullptr ), - m_syslogSink( nullptr ), - m_basicFileSink( nullptr ), - m_rotatingFileSink( nullptr ), - m_dailyFileSink( nullptr ) -{ - m_logger = std::make_shared< spdlog::logger >( m_name, nullptr ); - m_logger->sinks().clear(); - m_logger->flush_on( m_flushLevel ); - m_logger->set_level( m_outputLevel ); - m_logger->set_pattern( m_outputPattern ); -} - - std::shared_ptr< spdlog::logger > Logger::logger() { return( m_logger ); diff --git a/thirdparty/whereami b/thirdparty/whereami new file mode 160000 index 0000000..bd6cff2 --- /dev/null +++ b/thirdparty/whereami @@ -0,0 +1 @@ +Subproject commit bd6cff26dd580251960e7c9aa7e4b9b738212c43 diff --git a/thirdparty/whereami/README.md b/thirdparty/whereami/README.md deleted file mode 100644 index 98c7a3b..0000000 --- a/thirdparty/whereami/README.md +++ /dev/null @@ -1,132 +0,0 @@ -# Where Am I? - -A drop-in two files library to locate the current executable and the current -module on the file system. - -Supported platforms: - -- Windows -- Linux -- Mac -- iOS -- Android -- QNX Neutrino -- FreeBSD -- NetBSD -- DragonFly BSD -- SunOS - -Just drop `whereami.h` and `whereami.c` into your build and get started. (see -also [customizing compilation]) - -[customizing compilation]: #customizing-compilation - --------------------------------------------------------------------------------- - -## Usage - -- `wai_getExecutablePath()` returns the path of the enclosing executable -- `wai_getModulePath()` returns the path of the enclosing module - -Example usage: - -- first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to retrieve - the length of the path -- allocate the destination buffer with `path = (char*)malloc(length + 1);` -- call `wai_getExecutablePath(path, length, &dirname_length)` again to retrieve - the path -- add a terminal `NUL` character with `path[length] = '\0';` - -Here is the output of the example: - - $ make -j -C _gnu-make - $ cp ./bin/mac-x86_64/library.dylib /tmp/ - $ ./bin/mac-x86_64/executable --load-library=/tmp/library.dylib - - executable path: /Users/gregory/Projects/whereami/bin/mac-x86_64/executable - dirname: /Users/gregory/Projects/whereami/bin/mac-x86_64 - basename: executable - module path: /Users/gregory/Projects/whereami/bin/mac-x86_64/executable - dirname: /Users/gregory/Projects/whereami/bin/mac-x86_64 - basename: executable - - library loaded - executable path: /Users/gregory/Projects/whereami/bin/mac-x86_64/executable - dirname: /Users/gregory/Projects/whereami/bin/mac-x86_64 - basename: executable - module path: /private/tmp/library.dylib - dirname: /private/tmp - basename: library.dylib - library unloaded - --------------------------------------------------------------------------------- - -## Customizing compilation - -You can customize the library's behavior by defining the following macros: - -- `WAI_FUNCSPEC` -- `WAI_PREFIX` -- `WAI_MALLOC` -- `WAI_REALLOC` -- `WAI_FREE` - -## Compiling for Windows - -There is a Visual Studio 2015 solution in the `_win-vs14/` folder. - -## Compiling for Linux or Mac - -There is a GNU Make 3.81 `MakeFile` in the `_gnu-make/` folder: - - $ make -j -C _gnu-make/ - -## Compiling for Mac - -See above if you want to compile from command line. Otherwise there is an Xcode -project located in the `_mac-xcode/` folder. - -## Compiling for iOS - -There is an Xcode project located in the `_ios-xcode/` folder. - -If you prefer compiling from command line and deploying to a jailbroken device -through SSH, use: - - $ make -j -C _gnu-make/ binsubdir=ios CC="$(xcrun --sdk iphoneos --find clang) -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch armv7 -arch armv7s -arch arm64" postbuild="codesign -s 'iPhone Developer'" - -## Compiling for Android - -You will have to install the Android NDK, and point the `$NDK_ROOT` environment -variable to the NDK path: e.g. `export NDK_ROOT=/opt/android-ndk` (without a -trailing `/` character). - -Next, the easy way is to make a standalone Android toolchain with the following -command: - - $ $NDK_ROOT/build/tools/make_standalone_toolchain.py --arch=arm --install-dir=/tmp/android-toolchain - -Now you can compile the example by running: - - $ make -j -C _gnu-make/ libsuffix=.so binsubdir=android CC=/tmp/android-toolchain/bin/arm-linux-androideabi-gcc CXX=/tmp/android-toolchain/bin/arm-linux-androideabi-g++ - -Depending on whether you compile for an Android version that requires PIE -executables, add `CFLAGS='-fpie' CXXFLAGS='-fpie' LDFLAGS='-pie'` accordingly. - -Loading page aligned library straight from APKs is supported. To test, use the -following: - - $ zip -Z store app bin/android/library.so - $ zipalign -v -f -p 4 ./app.zip ./app.apk - -Then copy `bin/android/executable` and `app.apk` to your Android device and -there launch: - - $ ./executable --load-library=app.apk!/bin/android/library.so - --------------------------------------------------------------------------------- - -If you find this library useful and decide to use it in your own projects please -drop me a line [@gpakosz]. - -[@gpakosz]: https://twitter.com/gpakosz diff --git a/thirdparty/whereami/whereami.c b/thirdparty/whereami/whereami.c deleted file mode 100644 index 5bc2e5f..0000000 --- a/thirdparty/whereami/whereami.c +++ /dev/null @@ -1,679 +0,0 @@ -// (‑●‑●)> dual licensed under the WTFPL v2 and MIT licenses -// without any warranty. -// by Gregory Pakosz (@gpakosz) -// https://github.com/gpakosz/whereami - -// in case you want to #include "whereami.c" in a larger compilation unit -#if !defined(WHEREAMI_H) -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC) -#include -#endif - -#if !defined(WAI_MALLOC) -#define WAI_MALLOC(size) malloc(size) -#endif - -#if !defined(WAI_FREE) -#define WAI_FREE(p) free(p) -#endif - -#if !defined(WAI_REALLOC) -#define WAI_REALLOC(p, size) realloc(p, size) -#endif - -#ifndef WAI_NOINLINE -#if defined(_MSC_VER) -#define WAI_NOINLINE __declspec(noinline) -#elif defined(__GNUC__) -#define WAI_NOINLINE __attribute__((noinline)) -#else -#error unsupported compiler -#endif -#endif - -#if defined(_MSC_VER) -#define WAI_RETURN_ADDRESS() _ReturnAddress() -#elif defined(__GNUC__) -#define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0)) -#else -#error unsupported compiler -#endif - -#if defined(_WIN32) - -#define WIN32_LEAN_AND_MEAN -#if defined(_MSC_VER) -#pragma warning(push, 3) -#endif -#include -#include -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, int* dirname_length) -{ - wchar_t buffer1[MAX_PATH]; - wchar_t buffer2[MAX_PATH]; - wchar_t* path = NULL; - int length = -1; - - for (;;) - { - DWORD size; - int length_, length__; - - size = GetModuleFileNameW(module, buffer1, sizeof(buffer1) / sizeof(buffer1[0])); - - if (size == 0) - break; - else if (size == (DWORD)(sizeof(buffer1) / sizeof(buffer1[0]))) - { - DWORD size_ = size; - do - { - wchar_t* path_; - - path_ = (wchar_t*)WAI_REALLOC(path, sizeof(wchar_t) * size_ * 2); - if (!path_) - break; - size_ *= 2; - path = path_; - size = GetModuleFileNameW(module, path, size_); - } - while (size == size_); - - if (size == size_) - break; - } - else - path = buffer1; - - if (!_wfullpath(buffer2, path, MAX_PATH)) - break; - length_ = (int)wcslen(buffer2); - length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_ , out, capacity, NULL, NULL); - - if (length__ == 0) - length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_, NULL, 0, NULL, NULL); - if (length__ == 0) - break; - - if (length__ <= capacity && dirname_length) - { - int i; - - for (i = length__ - 1; i >= 0; --i) - { - if (out[i] == '\\') - { - *dirname_length = i; - break; - } - } - } - - length = length__; - - break; - } - - if (path != buffer1) - WAI_FREE(path); - - return length; -} - -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - return WAI_PREFIX(getModulePath_)(NULL, out, capacity, dirname_length); -} - -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - HMODULE module; - int length = -1; - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4054) -#endif - if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module)) -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - { - length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length); - } - - return length; -} - -#elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun) || defined(WAI_USE_PROC_SELF_EXE) - -#include -#include -#include -#if defined(__linux__) -#include -#else -#include -#endif -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif -#include - -#if !defined(WAI_PROC_SELF_EXE) -#if defined(__sun) -#define WAI_PROC_SELF_EXE "/proc/self/path/a.out" -#else -#define WAI_PROC_SELF_EXE "/proc/self/exe" -#endif -#endif - -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; - - for (;;) - { - resolved = realpath(WAI_PROC_SELF_EXE, buffer); - if (!resolved) - break; - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, (size_t)length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - - break; - } - - return length; -} - -#if !defined(WAI_PROC_SELF_MAPS_RETRY) -#define WAI_PROC_SELF_MAPS_RETRY 5 -#endif - -#if !defined(WAI_PROC_SELF_MAPS) -#if defined(__sun) -#define WAI_PROC_SELF_MAPS "/proc/self/map" -#else -#define WAI_PROC_SELF_MAPS "/proc/self/maps" -#endif -#endif - -#if defined(__ANDROID__) || defined(ANDROID) -#include -#include -#include -#endif - -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - int length = -1; - FILE* maps = NULL; - - for (int r = 0; r < WAI_PROC_SELF_MAPS_RETRY; ++r) - { - maps = fopen(WAI_PROC_SELF_MAPS, "r"); - if (!maps) - break; - - for (;;) - { - char buffer[PATH_MAX < 1024 ? 1024 : PATH_MAX]; - uint64_t low, high; - char perms[5]; - uint64_t offset; - uint32_t major, minor; - char path[PATH_MAX]; - uint32_t inode; - - if (!fgets(buffer, sizeof(buffer), maps)) - break; - - if (sscanf(buffer, "%" PRIx64 "-%" PRIx64 " %4s %" PRIx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8) - { - uint64_t addr = (uintptr_t)WAI_RETURN_ADDRESS(); - if (low <= addr && addr <= high) - { - char* resolved; - - resolved = realpath(path, buffer); - if (!resolved) - break; - - length = (int)strlen(resolved); -#if defined(__ANDROID__) || defined(ANDROID) - if (length > 4 - &&buffer[length - 1] == 'k' - &&buffer[length - 2] == 'p' - &&buffer[length - 3] == 'a' - &&buffer[length - 4] == '.') - { - int fd = open(path, O_RDONLY); - char* begin; - char* p; - - begin = (char*)mmap(0, offset, PROT_READ, MAP_SHARED, fd, 0); - p = begin + offset; - - while (p >= begin) // scan backwards - { - if (*((uint32_t*)p) == 0x04034b50UL) // local file header found - { - uint16_t length_ = *((uint16_t*)(p + 26)); - - if (length + 2 + length_ < (int)sizeof(buffer)) - { - memcpy(&buffer[length], "!/", 2); - memcpy(&buffer[length + 2], p + 30, length_); - length += 2 + length_; - } - - break; - } - - p -= 4; - } - - munmap(begin, offset); - close(fd); - } -#endif - if (length <= capacity) - { - memcpy(out, resolved, (size_t)length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - - break; - } - } - } - - fclose(maps); - maps = NULL; - - if (length != -1) - break; - } - - if (maps) - fclose(maps); - - return length; -} - -#elif defined(__APPLE__) - -#define _DARWIN_BETTER_REALPATH -#include -#include -#include -#include -#include - -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer1[PATH_MAX]; - char buffer2[PATH_MAX]; - char* path = buffer1; - char* resolved = NULL; - int length = -1; - - for (;;) - { - uint32_t size = (uint32_t)sizeof(buffer1); - if (_NSGetExecutablePath(path, &size) == -1) - { - path = (char*)WAI_MALLOC(size); - if (!_NSGetExecutablePath(path, &size)) - break; - } - - resolved = realpath(path, buffer2); - if (!resolved) - break; - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - - break; - } - - if (path != buffer1) - WAI_FREE(path); - - return length; -} - -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; - - for(;;) - { - Dl_info info; - - if (dladdr(WAI_RETURN_ADDRESS(), &info)) - { - resolved = realpath(info.dli_fname, buffer); - if (!resolved) - break; - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - } - - break; - } - - return length; -} - -#elif defined(__QNXNTO__) - -#include -#include -#include -#include -#include - -#if !defined(WAI_PROC_SELF_EXE) -#define WAI_PROC_SELF_EXE "/proc/self/exefile" -#endif - -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer1[PATH_MAX]; - char buffer2[PATH_MAX]; - char* resolved = NULL; - FILE* self_exe = NULL; - int length = -1; - - for (;;) - { - self_exe = fopen(WAI_PROC_SELF_EXE, "r"); - if (!self_exe) - break; - - if (!fgets(buffer1, sizeof(buffer1), self_exe)) - break; - - resolved = realpath(buffer1, buffer2); - if (!resolved) - break; - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - - break; - } - - fclose(self_exe); - - return length; -} - -WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; - - for(;;) - { - Dl_info info; - - if (dladdr(WAI_RETURN_ADDRESS(), &info)) - { - resolved = realpath(info.dli_fname, buffer); - if (!resolved) - break; - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - } - - break; - } - - return length; -} - -#elif defined(__DragonFly__) || defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) || defined(__NetBSD__) - -#include -#include -#include -#include -#include -#include - -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer1[PATH_MAX]; - char buffer2[PATH_MAX]; - char* path = buffer1; - char* resolved = NULL; - int length = -1; - - for (;;) - { -#if defined(__NetBSD__) - int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME }; -#else - int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; -#endif - size_t size = sizeof(buffer1); - - if (sysctl(mib, (u_int)(sizeof(mib) / sizeof(mib[0])), path, &size, NULL, 0) != 0) - break; - - resolved = realpath(path, buffer2); - if (!resolved) - break; - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - - break; - } - - if (path != buffer1) - WAI_FREE(path); - - return length; -} - -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; - - for(;;) - { - Dl_info info; - - if (dladdr(WAI_RETURN_ADDRESS(), &info)) - { - resolved = realpath(info.dli_fname, buffer); - if (!resolved) - break; - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); - - if (dirname_length) - { - int i; - - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } - } - } - } - - break; - } - - return length; -} - -#else - -#error unsupported platform - -#endif - -#ifdef __cplusplus -} -#endif diff --git a/thirdparty/whereami/whereami.h b/thirdparty/whereami/whereami.h deleted file mode 100644 index 670db54..0000000 --- a/thirdparty/whereami/whereami.h +++ /dev/null @@ -1,67 +0,0 @@ -// (‑●‑●)> dual licensed under the WTFPL v2 and MIT licenses -// without any warranty. -// by Gregory Pakosz (@gpakosz) -// https://github.com/gpakosz/whereami - -#ifndef WHEREAMI_H -#define WHEREAMI_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef WAI_FUNCSPEC - #define WAI_FUNCSPEC -#endif -#ifndef WAI_PREFIX -#define WAI_PREFIX(function) wai_##function -#endif - -/** - * Returns the path to the current executable. - * - * Usage: - * - first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to - * retrieve the length of the path - * - allocate the destination buffer with `path = (char*)malloc(length + 1);` - * - call `wai_getExecutablePath(path, length, NULL)` again to retrieve the - * path - * - add a terminal NUL character with `path[length] = '\0';` - * - * @param out destination buffer, optional - * @param capacity destination buffer capacity - * @param dirname_length optional recipient for the length of the dirname part - * of the path. - * - * @return the length of the executable path on success (without a terminal NUL - * character), otherwise `-1` - */ -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length); - -/** - * Returns the path to the current module - * - * Usage: - * - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve - * the length of the path - * - allocate the destination buffer with `path = (char*)malloc(length + 1);` - * - call `wai_getModulePath(path, length, NULL)` again to retrieve the path - * - add a terminal NUL character with `path[length] = '\0';` - * - * @param out destination buffer, optional - * @param capacity destination buffer capacity - * @param dirname_length optional recipient for the length of the dirname part - * of the path. - * - * @return the length of the module path on success (without a terminal NUL - * character), otherwise `-1` - */ -WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length); - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef WHEREAMI_H