build: Switch to GCC on MacOS (#552)
* build: Experimentally switch to gcc on macOS * build: Corrected gcc paths * build: Enable objective c support on macOS * build: Enable ObjC and ObjC++ on macOS * build: Add ObjC and ObjC++ flags * build: Try compiling objc with clang * build: Remove invalid flags again * fix: Let's not include objc headers in C++ code * sys: Move macos utils code to its own file * fix: Missing unistd include on mac * sys: Removed loader script stuff since it's currently unused and broken * fix: Missing include * fix: Another missing include * fix: CFURLCreateWithBytes wants a pointer to mutable data * fix: Try disabling name mangling of ObjC functions * sys: Move macos utils declarations to its own header file * fix: C Linkage * fix: Move objc function prototypes to C++ headers * fix: More missing includes * fix: Warning error * sys: Call ObjC with C ABI instead of trying to use C++ * build: Update libraries * sys: Fixed build errors * sys: No const correctness I guess * sys: Fixed prototypes * sys: This is C now * sys: More nullptr -> NULL * sys: Fix crash on exit * sys: Try using proper std concepts instead of custom ones * sys: Replaced another hex::is_signed * build: Upgrade to gcc 12 and MacOS Monterey * build: Fixed MacOS runner name * build: Cache correct ccache folder on macOS
This commit is contained in:
parent
546d0a4922
commit
3471b314dd
4
.github/workflows/analysis.yml
vendored
4
.github/workflows/analysis.yml
vendored
@ -7,7 +7,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
codeql:
|
codeql:
|
||||||
name: 🐛 CodeQL
|
name: 🐛 CodeQL
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
actions: read
|
actions: read
|
||||||
contents: read
|
contents: read
|
||||||
@ -41,7 +41,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
CC=gcc-11 CXX=g++-11 cmake \
|
CC=gcc-12 CXX=g++-12 cmake \
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@ -106,8 +106,8 @@ jobs:
|
|||||||
|
|
||||||
# MacOS build
|
# MacOS build
|
||||||
macos:
|
macos:
|
||||||
runs-on: macos-11.0
|
runs-on: macos-12
|
||||||
name: 🍎 macOS 11.0
|
name: 🍎 macOS 12.0
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: 🧰 Checkout
|
- name: 🧰 Checkout
|
||||||
@ -122,8 +122,7 @@ jobs:
|
|||||||
- name: 📜 Restore cache
|
- name: 📜 Restore cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: ~/Library/Caches/ccache
|
||||||
~/.ccache
|
|
||||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||||
|
|
||||||
@ -131,16 +130,20 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
CC=$(brew --prefix llvm)/bin/clang \
|
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
|
||||||
CXX=$(brew --prefix llvm)/bin/clang++ \
|
CXX=$(brew --prefix gcc@12)/bin/g++-12 \
|
||||||
|
OBJC=$(brew --prefix llvm)/bin/clang \
|
||||||
|
OBJCXX=$(brew --prefix llvm)/bin/clang++ \
|
||||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||||
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
||||||
cmake \
|
cmake \
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||||
-DCREATE_BUNDLE=ON \
|
-DCREATE_BUNDLE=ON \
|
||||||
-DCREATE_PACKAGE=ON \
|
-DCREATE_PACKAGE=ON \
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||||
..
|
..
|
||||||
make -j4 package
|
make -j4 package
|
||||||
|
|
||||||
@ -196,7 +199,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
CC=gcc-11 CXX=g++-11 cmake \
|
CC=gcc-12 CXX=g++-12 cmake \
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@ -9,7 +9,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
name: 🧪 Unit Tests
|
name: 🧪 Unit Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
actions: read
|
actions: read
|
||||||
contents: read
|
contents: read
|
||||||
@ -38,7 +38,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
CC=gcc-11 CXX=g++-11 cmake \
|
CC=gcc-12 CXX=g++-12 cmake \
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
@ -77,6 +77,8 @@ macro(detectOS)
|
|||||||
set(CMAKE_INSTALL_LIBDIR ".")
|
set(CMAKE_INSTALL_LIBDIR ".")
|
||||||
set(PLUGINS_INSTALL_LOCATION "plugins")
|
set(PLUGINS_INSTALL_LOCATION "plugins")
|
||||||
set(MAGIC_INSTALL_LOCATION "magic")
|
set(MAGIC_INSTALL_LOCATION "magic")
|
||||||
|
enable_language(OBJC)
|
||||||
|
enable_language(OBJCXX)
|
||||||
elseif (UNIX AND NOT APPLE)
|
elseif (UNIX AND NOT APPLE)
|
||||||
add_compile_definitions(OS_LINUX)
|
add_compile_definitions(OS_LINUX)
|
||||||
set(CMAKE_INSTALL_BINDIR "bin")
|
set(CMAKE_INSTALL_BINDIR "bin")
|
||||||
|
3
dist/Brewfile
vendored
3
dist/Brewfile
vendored
@ -7,6 +7,5 @@ brew "python3"
|
|||||||
brew "freetype2"
|
brew "freetype2"
|
||||||
brew "libmagic"
|
brew "libmagic"
|
||||||
brew "pkg-config"
|
brew "pkg-config"
|
||||||
|
|
||||||
# TODO: Remove this when XCode version of clang will support the same level as LLVM 10
|
|
||||||
brew "llvm"
|
brew "llvm"
|
||||||
|
brew "gcc@12"
|
||||||
|
13
dist/get_deps_debian.sh
vendored
13
dist/get_deps_debian.sh
vendored
@ -1,9 +1,5 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
echo "As of 2020-12, Debian stable does not include g++-10, needs debian testing or unstable."
|
|
||||||
|
|
||||||
# Tested on 2020-12-09 with Docker image bitnami/minideb:unstable
|
|
||||||
|
|
||||||
# Install pkgconf (adds minimum dependencies) only if the equivalent pkf-config is not already installed.
|
# Install pkgconf (adds minimum dependencies) only if the equivalent pkf-config is not already installed.
|
||||||
if ! which pkg-config
|
if ! which pkg-config
|
||||||
then
|
then
|
||||||
@ -12,8 +8,8 @@ fi
|
|||||||
|
|
||||||
apt install -y \
|
apt install -y \
|
||||||
build-essential \
|
build-essential \
|
||||||
gcc-11 \
|
gcc-12 \
|
||||||
g++-11 \
|
g++-12 \
|
||||||
lld \
|
lld \
|
||||||
${PKGCONF:-} \
|
${PKGCONF:-} \
|
||||||
cmake \
|
cmake \
|
||||||
@ -25,7 +21,4 @@ apt install -y \
|
|||||||
libmbedtls-dev \
|
libmbedtls-dev \
|
||||||
python3-dev \
|
python3-dev \
|
||||||
libfreetype-dev \
|
libfreetype-dev \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev
|
||||||
|
|
||||||
echo "Please consider this before running cmake (useful on e.g. Ubuntu 20.04):"
|
|
||||||
echo "export CXX=g++-11"
|
|
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f14e88a72759f7121cb611abb7afa6d6a126c7cf
|
Subproject commit 12063078f081694442a274d0e925b2ab204752c4
|
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
@ -1 +1 @@
|
|||||||
Subproject commit d399836b693feaab3b323acd4374c1371164c0eb
|
Subproject commit 3717689c374cd5e8645de258c09c15ebf7a8a91a
|
@ -123,7 +123,6 @@ set(LIBIMHEX_SOURCES
|
|||||||
source/helpers/patches.cpp
|
source/helpers/patches.cpp
|
||||||
source/helpers/project_file_handler.cpp
|
source/helpers/project_file_handler.cpp
|
||||||
source/helpers/encoding_file.cpp
|
source/helpers/encoding_file.cpp
|
||||||
source/helpers/loader_script_handler.cpp
|
|
||||||
source/helpers/logger.cpp
|
source/helpers/logger.cpp
|
||||||
source/helpers/tar.cpp
|
source/helpers/tar.cpp
|
||||||
|
|
||||||
@ -143,7 +142,9 @@ if (APPLE)
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/fs_macos.mm)
|
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES}
|
||||||
|
source/helpers/fs_macos.m
|
||||||
|
source/helpers/utils_macos.m)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||||
|
@ -156,7 +156,7 @@ namespace hex {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<hex::derived_from<View> T, typename... Args>
|
template<std::derived_from<View> T, typename... Args>
|
||||||
void add(Args &&...args) {
|
void add(Args &&...args) {
|
||||||
return impl::add(new T(std::forward<Args>(args)...));
|
return impl::add(new T(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<hex::derived_from<dp::Node> T, typename... Args>
|
template<std::derived_from<dp::Node> T, typename... Args>
|
||||||
void add(const std::string &unlocalizedCategory, const std::string &unlocalizedName, Args &&...args) {
|
void add(const std::string &unlocalizedCategory, const std::string &unlocalizedName, Args &&...args) {
|
||||||
add(impl::Entry { unlocalizedCategory.c_str(), unlocalizedName.c_str(), [=] {
|
add(impl::Entry { unlocalizedCategory.c_str(), unlocalizedName.c_str(), [=] {
|
||||||
auto node = new T(std::forward<Args>(args)...);
|
auto node = new T(std::forward<Args>(args)...);
|
||||||
@ -326,7 +326,7 @@ namespace hex {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<hex::derived_from<hex::prv::Provider> T>
|
template<std::derived_from<hex::prv::Provider> T>
|
||||||
void add(const std::string &unlocalizedName, bool addToList = true) {
|
void add(const std::string &unlocalizedName, bool addToList = true) {
|
||||||
(void)EventManager::subscribe<RequestCreateProvider>([expectedName = unlocalizedName](const std::string &name, hex::prv::Provider **provider) {
|
(void)EventManager::subscribe<RequestCreateProvider>([expectedName = unlocalizedName](const std::string &name, hex::prv::Provider **provider) {
|
||||||
if (name != expectedName) return;
|
if (name != expectedName) return;
|
||||||
@ -415,7 +415,7 @@ namespace hex {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<hex::derived_from<DataVisualizer> T, typename... Args>
|
template<std::derived_from<DataVisualizer> T, typename... Args>
|
||||||
void addDataVisualizer(const std::string &unlocalizedName, Args &&...args) {
|
void addDataVisualizer(const std::string &unlocalizedName, Args &&...args) {
|
||||||
return impl::addDataVisualizer(unlocalizedName, new T(std::forward<Args>(args)...));
|
return impl::addDataVisualizer(unlocalizedName, new T(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ namespace hex {
|
|||||||
|
|
||||||
void add(prv::Provider *provider);
|
void add(prv::Provider *provider);
|
||||||
|
|
||||||
template<hex::derived_from<prv::Provider> T>
|
template<std::derived_from<prv::Provider> T>
|
||||||
void add(auto &&...args) {
|
void add(auto &&...args) {
|
||||||
add(new T(std::forward<decltype(args)>(args)...));
|
add(new T(std::forward<decltype(args)>(args)...));
|
||||||
}
|
}
|
||||||
|
@ -5,151 +5,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace hex {
|
#include <concepts>
|
||||||
|
|
||||||
template<typename>
|
|
||||||
struct is_integral_helper : public std::false_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<u8> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<i8> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<u16> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<i16> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<u32> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<i32> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<u64> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<i64> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<u128> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<i128> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<bool> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<char> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<char8_t> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<char16_t> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<char32_t> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_integral_helper<wchar_t> : public std::true_type { };
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_integral : public is_integral_helper<std::remove_cvref_t<T>>::type { };
|
|
||||||
|
|
||||||
|
|
||||||
template<typename>
|
|
||||||
struct is_signed_helper : public std::false_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<i8> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<i16> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<i32> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<i64> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<i128> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<char> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<float> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<double> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_signed_helper<long double> : public std::true_type { };
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_signed : public is_signed_helper<std::remove_cvref_t<T>>::type { };
|
|
||||||
|
|
||||||
|
|
||||||
template<typename>
|
|
||||||
struct is_floating_point_helper : public std::false_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_floating_point_helper<float> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_floating_point_helper<double> : public std::true_type { };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_floating_point_helper<long double> : public std::true_type { };
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_floating_point : public is_floating_point_helper<std::remove_cvref_t<T>>::type { };
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 12000
|
|
||||||
#if __has_include(<concepts>)
|
|
||||||
// Make sure we break when derived_from is implemented in libc++. Then we can fix a compatibility version above
|
|
||||||
#include <concepts>
|
|
||||||
#endif
|
|
||||||
// libcxx 12 still doesn't have many default concepts implemented, as a result we need to define it ourself using clang built-ins.
|
|
||||||
// [concept.derived] (patch from https://reviews.llvm.org/D74292)
|
|
||||||
namespace hex {
|
|
||||||
template<class _Dp, class _Bp>
|
|
||||||
concept derived_from =
|
|
||||||
__is_base_of(_Bp, _Dp) && __is_convertible_to(const volatile _Dp *, const volatile _Bp *);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
// Assume supported
|
|
||||||
#include <concepts>
|
|
||||||
namespace hex {
|
|
||||||
using std::derived_from;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// [concepts.arithmetic]
|
|
||||||
namespace hex {
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
concept integral = hex::is_integral<T>::value;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
concept signed_integral = integral<T> && hex::is_signed<T>::value;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
concept unsigned_integral = integral<T> && !signed_integral<T>;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
concept floating_point = std::is_floating_point<T>::value;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
@ -159,11 +15,6 @@ namespace hex {
|
|||||||
template<typename T, size_t Size>
|
template<typename T, size_t Size>
|
||||||
concept has_size = sizeof(T) == Size;
|
concept has_size = sizeof(T) == Size;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace hex {
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Cloneable {
|
class Cloneable {
|
||||||
public:
|
public:
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined(OS_MACOS)
|
|
||||||
#include <hex/helpers/fs.hpp>
|
|
||||||
|
|
||||||
namespace hex {
|
|
||||||
std::string getMacExecutableDirectoryPath();
|
|
||||||
std::string getMacApplicationSupportDirectoryPath();
|
|
||||||
}
|
|
||||||
#endif
|
|
12
lib/libimhex/include/hex/helpers/fs_macos.hpp
Normal file
12
lib/libimhex/include/hex/helpers/fs_macos.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(OS_MACOS)
|
||||||
|
|
||||||
|
#include <hex/helpers/fs.hpp>
|
||||||
|
|
||||||
|
extern "C" char * getMacExecutableDirectoryPath();
|
||||||
|
extern "C" char * getMacApplicationSupportDirectoryPath();
|
||||||
|
|
||||||
|
extern "C" void macFree(void *ptr);
|
||||||
|
|
||||||
|
#endif
|
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
#include <hex/helpers/fs.hpp>
|
|
||||||
|
|
||||||
struct _object;
|
|
||||||
typedef struct _object PyObject;
|
|
||||||
|
|
||||||
namespace hex {
|
|
||||||
|
|
||||||
namespace prv {
|
|
||||||
class Provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoaderScript {
|
|
||||||
public:
|
|
||||||
LoaderScript() = delete;
|
|
||||||
|
|
||||||
static bool processFile(const std::fs::path &scriptPath);
|
|
||||||
|
|
||||||
static void setFilePath(const std::fs::path &filePath) { LoaderScript::s_filePath = filePath; }
|
|
||||||
static void setDataProvider(prv::Provider *provider) { LoaderScript::s_dataProvider = provider; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
static inline std::fs::path s_filePath;
|
|
||||||
static inline prv::Provider *s_dataProvider;
|
|
||||||
|
|
||||||
static PyObject *Py_getFilePath(PyObject *self, PyObject *args);
|
|
||||||
static PyObject *Py_addPatch(PyObject *self, PyObject *args);
|
|
||||||
static PyObject *Py_addBookmark(PyObject *self, PyObject *args);
|
|
||||||
|
|
||||||
static PyObject *Py_addStruct(PyObject *self, PyObject *args);
|
|
||||||
static PyObject *Py_addUnion(PyObject *self, PyObject *args);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -43,7 +43,7 @@ namespace hex {
|
|||||||
std::string encodeByteString(const std::vector<u8> &bytes);
|
std::string encodeByteString(const std::vector<u8> &bytes);
|
||||||
std::vector<u8> decodeByteString(const std::string &string);
|
std::vector<u8> decodeByteString(const std::string &string);
|
||||||
|
|
||||||
[[nodiscard]] constexpr inline u64 extract(u8 from, u8 to, const hex::unsigned_integral auto &value) {
|
[[nodiscard]] constexpr inline u64 extract(u8 from, u8 to, const std::unsigned_integral auto &value) {
|
||||||
if (from < to) std::swap(from, to);
|
if (from < to) std::swap(from, to);
|
||||||
|
|
||||||
using ValueType = std::remove_cvref_t<decltype(value)>;
|
using ValueType = std::remove_cvref_t<decltype(value)>;
|
||||||
@ -72,7 +72,7 @@ namespace hex {
|
|||||||
return (value ^ mask) - mask;
|
return (value ^ mask) - mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<hex::integral T>
|
template<std::integral T>
|
||||||
constexpr inline T swapBitOrder(size_t numBits, T value) {
|
constexpr inline T swapBitOrder(size_t numBits, T value) {
|
||||||
T result = 0x00;
|
T result = 0x00;
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ namespace hex {
|
|||||||
return T(1) << bit_width(T(x - 1));
|
return T(1) << bit_width(T(x - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<hex::integral T, hex::integral U>
|
template<std::integral T, std::integral U>
|
||||||
auto powi(T base, U exp) {
|
auto powi(T base, U exp) {
|
||||||
using ResultType = decltype(T{} * U{});
|
using ResultType = decltype(T{} * U{});
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ namespace hex {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string toBinaryString(hex::unsigned_integral auto number) {
|
inline std::string toBinaryString(std::unsigned_integral auto number) {
|
||||||
if (number == 0) return "0";
|
if (number == 0) return "0";
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
@ -317,7 +317,7 @@ namespace hex {
|
|||||||
return *value;
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<hex::integral T>
|
template<std::integral T>
|
||||||
T alignTo(T value, T alignment) {
|
T alignTo(T value, T alignment) {
|
||||||
T remainder = value % alignment;
|
T remainder = value % alignment;
|
||||||
|
|
||||||
|
9
lib/libimhex/include/hex/helpers/utils_macos.hpp
Normal file
9
lib/libimhex/include/hex/helpers/utils_macos.hpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(OS_MACOS)
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
extern "C" void openWebpageMacos(const char *url);
|
||||||
|
|
||||||
|
#endif
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <hex/providers/provider.hpp>
|
#include <hex/providers/provider.hpp>
|
||||||
#include <hex/helpers/utils.hpp>
|
#include <hex/helpers/utils.hpp>
|
||||||
|
#include <hex/helpers/concepts.hpp>
|
||||||
|
|
||||||
#include <mbedtls/version.h>
|
#include <mbedtls/version.h>
|
||||||
#include <mbedtls/base64.h>
|
#include <mbedtls/base64.h>
|
||||||
@ -15,7 +16,6 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <concepts>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <hex/helpers/fs.hpp>
|
#include <hex/helpers/fs.hpp>
|
||||||
|
|
||||||
#include <hex/api/content_registry.hpp>
|
#include <hex/api/content_registry.hpp>
|
||||||
#include <hex/helpers/fs_macos.h>
|
#include <hex/helpers/fs_macos.hpp>
|
||||||
#include <hex/helpers/file.hpp>
|
#include <hex/helpers/file.hpp>
|
||||||
#include <hex/helpers/intrinsics.hpp>
|
#include <hex/helpers/intrinsics.hpp>
|
||||||
|
|
||||||
@ -34,7 +34,15 @@ namespace hex::fs {
|
|||||||
|
|
||||||
return exePath;
|
return exePath;
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
return getMacExecutableDirectoryPath();
|
std::string result;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto string = getMacExecutableDirectoryPath();
|
||||||
|
result = string;
|
||||||
|
macFree(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
#endif
|
#endif
|
||||||
@ -183,25 +191,31 @@ namespace hex::fs {
|
|||||||
}
|
}
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
// Get path to special directories
|
// Get path to special directories
|
||||||
const std::fs::path applicationSupportDir(getMacApplicationSupportDirectoryPath());
|
std::string applicationSupportDir;
|
||||||
|
{
|
||||||
|
auto string = getMacApplicationSupportDirectoryPath();
|
||||||
|
applicationSupportDir = string;
|
||||||
|
macFree(string);
|
||||||
|
}
|
||||||
|
const std::fs::path applicationSupportDirPath(applicationSupportDir);
|
||||||
|
|
||||||
std::vector<std::fs::path> paths = { applicationSupportDir };
|
std::vector<std::fs::path> paths = { applicationSupportDirPath };
|
||||||
|
|
||||||
if (exePath.has_value())
|
if (exePath.has_value())
|
||||||
paths.push_back(exePath.value());
|
paths.push_back(exePath.value());
|
||||||
|
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case ImHexPath::Patterns:
|
case ImHexPath::Patterns:
|
||||||
result.push_back((applicationSupportDir / "patterns").string());
|
result.push_back((applicationSupportDirPath / "patterns").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::PatternsInclude:
|
case ImHexPath::PatternsInclude:
|
||||||
result.push_back((applicationSupportDir / "includes").string());
|
result.push_back((applicationSupportDirPath / "includes").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Magic:
|
case ImHexPath::Magic:
|
||||||
result.push_back((applicationSupportDir / "magic").string());
|
result.push_back((applicationSupportDirPath / "magic").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Python:
|
case ImHexPath::Python:
|
||||||
result.push_back((applicationSupportDir / "python").string());
|
result.push_back((applicationSupportDirPath / "python").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Plugins:
|
case ImHexPath::Plugins:
|
||||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||||
@ -209,22 +223,22 @@ namespace hex::fs {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Yara:
|
case ImHexPath::Yara:
|
||||||
result.push_back((applicationSupportDir / "yara").string());
|
result.push_back((applicationSupportDirPath / "yara").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Config:
|
case ImHexPath::Config:
|
||||||
result.push_back((applicationSupportDir / "config").string());
|
result.push_back((applicationSupportDirPath / "config").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Resources:
|
case ImHexPath::Resources:
|
||||||
result.push_back((applicationSupportDir / "resources").string());
|
result.push_back((applicationSupportDirPath / "resources").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Constants:
|
case ImHexPath::Constants:
|
||||||
result.push_back((applicationSupportDir / "constants").string());
|
result.push_back((applicationSupportDirPath / "constants").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Encodings:
|
case ImHexPath::Encodings:
|
||||||
result.push_back((applicationSupportDir / "encodings").string());
|
result.push_back((applicationSupportDirPath / "encodings").string());
|
||||||
break;
|
break;
|
||||||
case ImHexPath::Logs:
|
case ImHexPath::Logs:
|
||||||
result.push_back((applicationSupportDir / "logs").string());
|
result.push_back((applicationSupportDirPath / "logs").string());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
hex::unreachable();
|
hex::unreachable();
|
||||||
|
44
lib/libimhex/source/helpers/fs_macos.m
Normal file
44
lib/libimhex/source/helpers/fs_macos.m
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#if defined(OS_MACOS)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
char* getMacExecutableDirectoryPath() {
|
||||||
|
@autoreleasepool {
|
||||||
|
const char *pathString = [[[[[NSBundle mainBundle] executableURL] URLByDeletingLastPathComponent] path] UTF8String];
|
||||||
|
|
||||||
|
char *result = malloc(strlen(pathString) + 1);
|
||||||
|
strcpy(result, pathString);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getMacApplicationSupportDirectoryPath() {
|
||||||
|
@autoreleasepool {
|
||||||
|
NSError* error = nil;
|
||||||
|
NSURL* dirUrl = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
|
||||||
|
inDomain:NSUserDomainMask
|
||||||
|
appropriateForURL:nil
|
||||||
|
create:YES
|
||||||
|
error:&error];
|
||||||
|
|
||||||
|
if (error != nil) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pathString = [[[dirUrl URLByAppendingPathComponent:(@"imhex")] path] UTF8String];
|
||||||
|
|
||||||
|
char *result = malloc(strlen(pathString) + 1);
|
||||||
|
strcpy(result, pathString);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void macFree(void *ptr) {
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,30 +0,0 @@
|
|||||||
#if defined(OS_MACOS)
|
|
||||||
#include <hex/helpers/fs_macos.h>
|
|
||||||
|
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
namespace hex {
|
|
||||||
std::string getMacExecutableDirectoryPath() {
|
|
||||||
@autoreleasepool {
|
|
||||||
return {[[[[[NSBundle mainBundle] executableURL] URLByDeletingLastPathComponent] path] UTF8String]};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getMacApplicationSupportDirectoryPath() {
|
|
||||||
@autoreleasepool {
|
|
||||||
NSError* error = nil;
|
|
||||||
NSURL* dirUrl = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
|
|
||||||
inDomain:NSUserDomainMask
|
|
||||||
appropriateForURL:nil
|
|
||||||
create:YES
|
|
||||||
error:&error];
|
|
||||||
|
|
||||||
if (error != nil) {
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {[[[dirUrl URLByAppendingPathComponent:(@"imhex")] path] UTF8String]};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,248 +0,0 @@
|
|||||||
#include <hex/helpers/loader_script_handler.hpp>
|
|
||||||
|
|
||||||
#include <hex/helpers/utils.hpp>
|
|
||||||
#include <hex/helpers/fs.hpp>
|
|
||||||
#include <hex/helpers/file.hpp>
|
|
||||||
#include <hex/ui/view.hpp>
|
|
||||||
#include <hex/providers/provider.hpp>
|
|
||||||
#include <hex/helpers/intrinsics.hpp>
|
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
|
||||||
#include <Python.h>
|
|
||||||
#include <structmember.h>
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
using namespace std::literals::string_literals;
|
|
||||||
|
|
||||||
namespace hex {
|
|
||||||
|
|
||||||
PyObject *LoaderScript::Py_getFilePath(PyObject *self, PyObject *args) {
|
|
||||||
hex::unused(self, args);
|
|
||||||
|
|
||||||
return PyUnicode_FromString(LoaderScript::s_filePath.string().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *LoaderScript::Py_addPatch(PyObject *self, PyObject *args) {
|
|
||||||
hex::unused(self);
|
|
||||||
|
|
||||||
u64 address;
|
|
||||||
u8 *patches;
|
|
||||||
Py_ssize_t count;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "K|y#", &address, &patches, &count)) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (patches == nullptr || count == 0) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Invalid patch provided");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (address >= LoaderScript::s_dataProvider->getActualSize()) {
|
|
||||||
PyErr_SetString(PyExc_IndexError, "address out of range");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoaderScript::s_dataProvider->write(address, patches, count);
|
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *LoaderScript::Py_addBookmark(PyObject *self, PyObject *args) {
|
|
||||||
hex::unused(self);
|
|
||||||
|
|
||||||
u64 address;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
char *name = nullptr;
|
|
||||||
char *comment = nullptr;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "K|n|s|s", &address, &size, &name, &comment)) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == nullptr || comment == nullptr) {
|
|
||||||
PyErr_SetString(PyExc_IndexError, "address out of range");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImHexApi::Bookmarks::add(address, size, name, comment);
|
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *createStructureType(const std::string &keyword, PyObject *args) {
|
|
||||||
if (args == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto type = PyTuple_GetItem(args, 0);
|
|
||||||
if (type == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto instance = PyObject_CallObject(type, nullptr);
|
|
||||||
if (instance == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ON_SCOPE_EXIT { Py_DECREF(instance); };
|
|
||||||
|
|
||||||
if (instance->ob_type->tp_base == nullptr || instance->ob_type->tp_base->tp_name != "ImHexType"s) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "class type must extend from ImHexType");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dict = instance->ob_type->tp_dict;
|
|
||||||
if (dict == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto annotations = PyDict_GetItemString(dict, "__annotations__");
|
|
||||||
if (annotations == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto list = PyDict_Items(annotations);
|
|
||||||
if (list == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ON_SCOPE_EXIT { Py_DECREF(list); };
|
|
||||||
|
|
||||||
std::string code = keyword + " " + instance->ob_type->tp_name + " {\n";
|
|
||||||
|
|
||||||
for (Py_ssize_t i = 0; i < PyList_Size(list); i++) {
|
|
||||||
auto item = PyList_GetItem(list, i);
|
|
||||||
if (item == nullptr) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "failed to get item from list");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto memberName = PyUnicode_AsUTF8(PyTuple_GetItem(item, 0));
|
|
||||||
if (memberName == nullptr) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "invalid member name");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto memberType = PyTuple_GetItem(item, 1);
|
|
||||||
if (!PyTuple_Check(memberType) || memberType == nullptr) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "member needs to have a annotation extending from ImHexType");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array already is an object
|
|
||||||
if (memberType->ob_type->tp_name == "array"s) {
|
|
||||||
|
|
||||||
auto arrayType = PyObject_GetAttrString(memberType, "array_type");
|
|
||||||
if (arrayType == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
code += " "s + arrayType->ob_type->tp_name + " " + memberName;
|
|
||||||
|
|
||||||
auto arraySize = PyObject_GetAttrString(memberType, "size");
|
|
||||||
if (arraySize == nullptr) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PyUnicode_Check(arraySize))
|
|
||||||
code += "["s + PyUnicode_AsUTF8(arraySize) + "];\n";
|
|
||||||
else if (PyLong_Check(arraySize))
|
|
||||||
code += "["s + std::to_string(PyLong_AsLong(arraySize)) + "];\n";
|
|
||||||
} else {
|
|
||||||
auto memberTypeInstance = PyObject_CallObject(memberType, nullptr);
|
|
||||||
if (memberTypeInstance == nullptr || memberTypeInstance->ob_type->tp_base == nullptr || memberTypeInstance->ob_type->tp_base->tp_name != "ImHexType"s) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "member needs to have a annotation extending from ImHexType");
|
|
||||||
if (memberTypeInstance != nullptr)
|
|
||||||
Py_DECREF(memberTypeInstance);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
code += " "s + memberTypeInstance->ob_type->tp_name + " "s + memberName + ";\n";
|
|
||||||
|
|
||||||
Py_DECREF(memberTypeInstance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
code += "};\n";
|
|
||||||
|
|
||||||
EventManager::post<RequestSetPatternLanguageCode>(code);
|
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *LoaderScript::Py_addStruct(PyObject *self, PyObject *args) {
|
|
||||||
hex::unused(self);
|
|
||||||
|
|
||||||
return createStructureType("struct", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *LoaderScript::Py_addUnion(PyObject *self, PyObject *args) {
|
|
||||||
hex::unused(self);
|
|
||||||
|
|
||||||
return createStructureType("union", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LoaderScript::processFile(const std::fs::path &scriptPath) {
|
|
||||||
Py_SetProgramName(Py_DecodeLocale("ImHex", nullptr));
|
|
||||||
|
|
||||||
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Python)) {
|
|
||||||
if (fs::exists(std::fs::path(dir / "lib" / "python" PYTHON_VERSION_MAJOR_MINOR))) {
|
|
||||||
Py_SetPythonHome(Py_DecodeLocale(dir.string().c_str(), nullptr));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PyImport_AppendInittab("_imhex", []() -> PyObject * {
|
|
||||||
static PyMethodDef ImHexMethods[] = {
|
|
||||||
{"get_file_path", &LoaderScript::Py_getFilePath, METH_NOARGS, "Returns the path of the file being loaded."},
|
|
||||||
{ "patch", &LoaderScript::Py_addPatch, METH_VARARGS, "Patches a region of memory" },
|
|
||||||
{ "add_bookmark", &LoaderScript::Py_addBookmark, METH_VARARGS, "Adds a bookmark" },
|
|
||||||
{ "add_struct", &LoaderScript::Py_addStruct, METH_VARARGS, "Adds a struct" },
|
|
||||||
{ "add_union", &LoaderScript::Py_addUnion, METH_VARARGS, "Adds a union" },
|
|
||||||
{ nullptr, nullptr, 0, nullptr }
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyModuleDef ImHexModule = {
|
|
||||||
PyModuleDef_HEAD_INIT, "imhex", nullptr, -1, ImHexMethods, nullptr, nullptr, nullptr, nullptr
|
|
||||||
};
|
|
||||||
|
|
||||||
auto module = PyModule_Create(&ImHexModule);
|
|
||||||
if (module == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return module;
|
|
||||||
});
|
|
||||||
|
|
||||||
Py_Initialize();
|
|
||||||
|
|
||||||
{
|
|
||||||
auto sysPath = PySys_GetObject("path");
|
|
||||||
auto path = PyUnicode_FromString("lib");
|
|
||||||
|
|
||||||
PyList_Insert(sysPath, 0, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::File scriptFile(scriptPath, fs::File::Mode::Read);
|
|
||||||
PyRun_SimpleFile(scriptFile.getHandle(), scriptFile.getPath().string().c_str());
|
|
||||||
|
|
||||||
Py_Finalize();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <locale>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include <hex/api/imhex_api.hpp>
|
#include <hex/api/imhex_api.hpp>
|
||||||
|
|
||||||
@ -18,13 +16,10 @@
|
|||||||
#elif defined(OS_LINUX)
|
#elif defined(OS_LINUX)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
#include <CoreFoundation/CFBundle.h>
|
#include <hex/helpers/utils_macos.hpp>
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <hex/helpers/logger.hpp>
|
|
||||||
#include <hex/helpers/file.hpp>
|
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
long double operator""_scaled(long double value) {
|
long double operator""_scaled(long double value) {
|
||||||
@ -252,13 +247,14 @@ namespace hex {
|
|||||||
|
|
||||||
void runCommand(const std::string &command) {
|
void runCommand(const std::string &command) {
|
||||||
|
|
||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
auto result = system(hex::format("start {0}", command).c_str());
|
auto result = system(hex::format("start {0}", command).c_str());
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
auto result = system(hex::format("open {0}", command).c_str());
|
auto result = system(hex::format("open {0}", command).c_str());
|
||||||
#elif defined(OS_LINUX)
|
#elif defined(OS_LINUX)
|
||||||
auto result = system(hex::format("xdg-open {0}", command).c_str());
|
auto result = system(hex::format("xdg-open {0}", command).c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hex::unused(result);
|
hex::unused(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,18 +263,16 @@ namespace hex {
|
|||||||
if (url.find("://") == std::string::npos)
|
if (url.find("://") == std::string::npos)
|
||||||
url = "https://" + url;
|
url = "https://" + url;
|
||||||
|
|
||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
ShellExecute(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
ShellExecute(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
CFURLRef urlRef = CFURLCreateWithBytes(nullptr, reinterpret_cast<u8 *>(url.data()), url.length(), kCFStringEncodingASCII, nullptr);
|
openWebpageMacos(url.c_str());
|
||||||
LSOpenCFURLRef(urlRef, nullptr);
|
#elif defined(OS_LINUX)
|
||||||
CFRelease(urlRef);
|
auto result = system(hex::format("xdg-open {0}", url).c_str());
|
||||||
#elif defined(OS_LINUX)
|
hex::unused(result);
|
||||||
auto result = system(hex::format("xdg-open {0}", url).c_str());
|
#else
|
||||||
hex::unused(result);
|
#warning "Unknown OS, can't open webpages"
|
||||||
#else
|
#endif
|
||||||
#warning "Unknown OS, can't open webpages"
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encodeByteString(const std::vector<u8> &bytes) {
|
std::string encodeByteString(const std::vector<u8> &bytes) {
|
||||||
|
16
lib/libimhex/source/helpers/utils_macos.m
Normal file
16
lib/libimhex/source/helpers/utils_macos.m
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#if defined(OS_MACOS)
|
||||||
|
|
||||||
|
#include <CoreFoundation/CFBundle.h>
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void openWebpageMacos(const char *url) {
|
||||||
|
CFURLRef urlRef = CFURLCreateWithBytes(NULL, (uint8_t*)(url), strlen(url), kCFStringEncodingASCII, NULL);
|
||||||
|
LSOpenCFURLRef(urlRef, NULL);
|
||||||
|
CFRelease(urlRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -177,16 +177,23 @@ namespace hex::init {
|
|||||||
ImHexApi::HexEditor::impl::getBackgroundHighlightingFunctions().clear();
|
ImHexApi::HexEditor::impl::getBackgroundHighlightingFunctions().clear();
|
||||||
ImHexApi::HexEditor::impl::getForegroundHighlightingFunctions().clear();
|
ImHexApi::HexEditor::impl::getForegroundHighlightingFunctions().clear();
|
||||||
ImHexApi::HexEditor::impl::getTooltips().clear();
|
ImHexApi::HexEditor::impl::getTooltips().clear();
|
||||||
|
ImHexApi::HexEditor::impl::getTooltipFunctions().clear();
|
||||||
|
|
||||||
ContentRegistry::Settings::getEntries().clear();
|
ContentRegistry::Settings::getEntries().clear();
|
||||||
ContentRegistry::Settings::getSettingsData().clear();
|
ContentRegistry::Settings::getSettingsData().clear();
|
||||||
|
|
||||||
ContentRegistry::CommandPaletteCommands::getEntries().clear();
|
ContentRegistry::CommandPaletteCommands::getEntries().clear();
|
||||||
ContentRegistry::PatternLanguage::getFunctions().clear();
|
|
||||||
|
|
||||||
for (auto &[name, view] : ContentRegistry::Views::getEntries())
|
ContentRegistry::PatternLanguage::getFunctions().clear();
|
||||||
delete view;
|
ContentRegistry::PatternLanguage::getPragmas().clear();
|
||||||
ContentRegistry::Views::getEntries().clear();
|
|
||||||
|
{
|
||||||
|
auto &views = ContentRegistry::Views::getEntries();
|
||||||
|
for (auto &[name, view] : views)
|
||||||
|
delete view;
|
||||||
|
views.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ContentRegistry::Tools::getEntries().clear();
|
ContentRegistry::Tools::getEntries().clear();
|
||||||
ContentRegistry::DataInspector::getEntries().clear();
|
ContentRegistry::DataInspector::getEntries().clear();
|
||||||
@ -213,6 +220,13 @@ namespace hex::init {
|
|||||||
ContentRegistry::DataFormatter::getEntries().clear();
|
ContentRegistry::DataFormatter::getEntries().clear();
|
||||||
ContentRegistry::FileHandler::getEntries().clear();
|
ContentRegistry::FileHandler::getEntries().clear();
|
||||||
|
|
||||||
|
{
|
||||||
|
auto &visualizers = ContentRegistry::HexEditor::impl::getVisualizers();
|
||||||
|
for (auto &[name, visualizer] : visualizers)
|
||||||
|
delete visualizer;
|
||||||
|
visualizers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
while (ImHexApi::Provider::isValid())
|
while (ImHexApi::Provider::isValid())
|
||||||
ImHexApi::Provider::remove(ImHexApi::Provider::get());
|
ImHexApi::Provider::remove(ImHexApi::Provider::get());
|
||||||
ContentRegistry::Provider::getEntries().clear();
|
ContentRegistry::Provider::getEntries().clear();
|
||||||
|
@ -22,7 +22,7 @@ namespace hex::plugin::builtin {
|
|||||||
else static_assert(hex::always_false<T>::value, "Invalid data type!");
|
else static_assert(hex::always_false<T>::value, "Invalid data type!");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<hex::integral T>
|
template<std::integral T>
|
||||||
class DataVisualizerHexadecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
class DataVisualizerHexadecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||||
public:
|
public:
|
||||||
DataVisualizerHexadecimal() : DataVisualizer(ByteCount, CharCount) { }
|
DataVisualizerHexadecimal() : DataVisualizer(ByteCount, CharCount) { }
|
||||||
@ -114,7 +114,7 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<hex::integral T>
|
template<std::integral T>
|
||||||
class DataVisualizerDecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
class DataVisualizerDecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||||
public:
|
public:
|
||||||
DataVisualizerDecimal() : DataVisualizer(ByteCount, CharCount) { }
|
DataVisualizerDecimal() : DataVisualizer(ByteCount, CharCount) { }
|
||||||
@ -123,7 +123,7 @@ namespace hex::plugin::builtin {
|
|||||||
hex::unused(address, upperCase);
|
hex::unused(address, upperCase);
|
||||||
|
|
||||||
if (size == ByteCount) {
|
if (size == ByteCount) {
|
||||||
if (hex::is_signed<T>::value)
|
if (std::is_signed<T>::value)
|
||||||
ImGui::Text(getFormatString(), static_cast<i64>(*reinterpret_cast<const T*>(data)));
|
ImGui::Text(getFormatString(), static_cast<i64>(*reinterpret_cast<const T*>(data)));
|
||||||
else
|
else
|
||||||
ImGui::Text(getFormatString(), static_cast<u64>(*reinterpret_cast<const T*>(data)));
|
ImGui::Text(getFormatString(), static_cast<u64>(*reinterpret_cast<const T*>(data)));
|
||||||
@ -153,14 +153,14 @@ namespace hex::plugin::builtin {
|
|||||||
constexpr static inline auto ByteCount = sizeof(T);
|
constexpr static inline auto ByteCount = sizeof(T);
|
||||||
constexpr static inline auto CharCount = std::numeric_limits<T>::digits10 + 2;
|
constexpr static inline auto CharCount = std::numeric_limits<T>::digits10 + 2;
|
||||||
|
|
||||||
const static inline auto FormatString = hex::format("%{}{}", CharCount, hex::is_signed<T>::value ? "lld" : "llu");
|
const static inline auto FormatString = hex::format("%{}{}", CharCount, std::is_signed<T>::value ? "lld" : "llu");
|
||||||
|
|
||||||
const char *getFormatString() {
|
const char *getFormatString() {
|
||||||
return FormatString.c_str();
|
return FormatString.c_str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<hex::floating_point T>
|
template<std::floating_point T>
|
||||||
class DataVisualizerFloatingPoint : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
class DataVisualizerFloatingPoint : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||||
public:
|
public:
|
||||||
DataVisualizerFloatingPoint() : DataVisualizer(ByteCount, CharCount) { }
|
DataVisualizerFloatingPoint() : DataVisualizer(ByteCount, CharCount) { }
|
||||||
|
@ -199,11 +199,7 @@ namespace hex::plugin::builtin {
|
|||||||
reader.seek(this->m_searchPosition.value_or(editor->getSelection().getEndAddress()));
|
reader.seek(this->m_searchPosition.value_or(editor->getSelection().getEndAddress()));
|
||||||
|
|
||||||
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
|
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
|
||||||
#if defined(OS_MACOS)
|
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
|
||||||
return std::search(haystackBegin, haystackEnd, needleBegin, needleEnd);
|
|
||||||
#else
|
|
||||||
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!backwards) {
|
if (!backwards) {
|
||||||
|
@ -117,11 +117,11 @@ namespace hex {
|
|||||||
for (char *pos = prevPos; *pos != 0x00;) {
|
for (char *pos = prevPos; *pos != 0x00;) {
|
||||||
if (std::isdigit(*pos) || *pos == '.') {
|
if (std::isdigit(*pos) || *pos == '.') {
|
||||||
auto number = [&] {
|
auto number = [&] {
|
||||||
if constexpr (hex::floating_point<T>)
|
if constexpr (std::floating_point<T>)
|
||||||
return std::strtold(pos, &pos);
|
return std::strtold(pos, &pos);
|
||||||
else if constexpr (hex::signed_integral<T>)
|
else if constexpr (std::signed_integral<T>)
|
||||||
return std::strtoll(pos, &pos, 10);
|
return std::strtoll(pos, &pos, 10);
|
||||||
else if constexpr (hex::unsigned_integral<T>)
|
else if constexpr (std::unsigned_integral<T>)
|
||||||
return std::strtoull(pos, &pos, 10);
|
return std::strtoull(pos, &pos, 10);
|
||||||
else
|
else
|
||||||
static_assert(hex::always_false<T>::value, "Can't parse literal of this type");
|
static_assert(hex::always_false<T>::value, "Can't parse literal of this type");
|
||||||
@ -440,7 +440,7 @@ namespace hex {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void MathEvaluator<T>::registerStandardFunctions() {
|
void MathEvaluator<T>::registerStandardFunctions() {
|
||||||
if constexpr (hex::floating_point<T>) {
|
if constexpr (std::floating_point<T>) {
|
||||||
this->setFunction(
|
this->setFunction(
|
||||||
"sin", [](auto args) { return std::sin(args[0]); }, 1, 1);
|
"sin", [](auto args) { return std::sin(args[0]); }, 1, 1);
|
||||||
this->setFunction(
|
this->setFunction(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user