parent
0c915c05d3
commit
4af07664ce
@ -0,0 +1 @@
|
|||||||
|
*.inc linguist-language=C
|
@ -0,0 +1 @@
|
|||||||
|
github: flobernd
|
@ -0,0 +1,69 @@
|
|||||||
|
name: GitHub Actions CI
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: "Build Zydis (${{ matrix.image_name }}, ${{ matrix.no_libc }})"
|
||||||
|
runs-on: "${{ matrix.image_name }}"
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
image_name: ["macOS-latest", "windows-2016", "ubuntu-18.04"]
|
||||||
|
no_libc: ["", "-DZYAN_NO_LIBC=ON"]
|
||||||
|
include:
|
||||||
|
- image_name: "ubuntu-16.04"
|
||||||
|
no_libc: "-DCMAKE_BUILD_TYPE=Release"
|
||||||
|
dev_mode: "-DZYAN_DEV_MODE=ON"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v1"
|
||||||
|
- name: "Cloning submodules"
|
||||||
|
run: |
|
||||||
|
git submodule update --init
|
||||||
|
- name: "Configuring"
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ${{ matrix.dev_mode }} ${{ matrix.no_libc }} ..
|
||||||
|
- name: "Building"
|
||||||
|
run: |
|
||||||
|
cmake --build build --config Release
|
||||||
|
- name: "Running regression tests"
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
python3 regression.py test ../build/ZydisInfo
|
||||||
|
if: "!matrix.no_libc && matrix.image_name != 'windows-2016'"
|
||||||
|
- name: "Running regression tests"
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
python regression.py test ..\\build\\Release\\ZydisInfo.exe
|
||||||
|
if: "!matrix.no_libc && matrix.image_name == 'windows-2016'"
|
||||||
|
|
||||||
|
fuzzing:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
sanitizer: [address, undefined, memory]
|
||||||
|
steps:
|
||||||
|
- name: Build Fuzzers (${{ matrix.sanitizer }})
|
||||||
|
id: build
|
||||||
|
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||||
|
with:
|
||||||
|
oss-fuzz-project-name: 'zydis'
|
||||||
|
dry-run: false
|
||||||
|
sanitizer: ${{ matrix.sanitizer }}
|
||||||
|
- name: Run Fuzzers (${{ matrix.sanitizer }})
|
||||||
|
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||||
|
with:
|
||||||
|
oss-fuzz-project-name: 'zydis'
|
||||||
|
fuzz-seconds: 600
|
||||||
|
dry-run: false
|
||||||
|
sanitizer: ${{ matrix.sanitizer }}
|
||||||
|
- name: Upload Crash
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
if: failure() && steps.build.outcome == 'success'
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.sanitizer }}-artifacts
|
||||||
|
path: ./out/artifacts
|
@ -0,0 +1,101 @@
|
|||||||
|
# Created by https://www.gitignore.io/api/c,c++,cmake
|
||||||
|
|
||||||
|
### C ###
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
|
||||||
|
|
||||||
|
### C++ ###
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
|
||||||
|
### CMake ###
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
CTestTestfile.cmake
|
||||||
|
|
||||||
|
|
||||||
|
# MacOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
build*
|
||||||
|
|
||||||
|
# MSVC
|
||||||
|
.vs
|
||||||
|
*.vcxproj.user
|
||||||
|
*.suo
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.VC.db
|
||||||
|
*.VC.opendb
|
||||||
|
msvc/**/*.user
|
||||||
|
msvc/**/obj/
|
||||||
|
msvc/**/bin/
|
||||||
|
|
||||||
|
doc/html
|
||||||
|
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
cmake-build-debug
|
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "dependencies/zycore"]
|
||||||
|
path = dependencies/zycore
|
||||||
|
url = https://github.com/zyantific/zycore-c
|
@ -0,0 +1,296 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
||||||
|
|
||||||
|
project(Zydis VERSION 3.1.0.0 LANGUAGES C CXX)
|
||||||
|
|
||||||
|
include(GenerateExportHeader)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Overridable options #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
# Features
|
||||||
|
option(ZYDIS_MINIMAL_MODE
|
||||||
|
"Enable minimal mode (forces ZYDIS_DECODER_MODE_MINIMAL runtime option)"
|
||||||
|
OFF)
|
||||||
|
option(ZYDIS_FEATURE_DECODER
|
||||||
|
"Enable instruction decoding functionality"
|
||||||
|
ON)
|
||||||
|
option(ZYDIS_FEATURE_FORMATTER
|
||||||
|
"Enable instruction formatting functionality"
|
||||||
|
ON)
|
||||||
|
option(ZYDIS_FEATURE_AVX512
|
||||||
|
"Enable support for AVX-512 instructions"
|
||||||
|
ON)
|
||||||
|
option(ZYDIS_FEATURE_KNC
|
||||||
|
"Enable support for KNC instructions"
|
||||||
|
ON)
|
||||||
|
|
||||||
|
# Build configuration
|
||||||
|
option(ZYDIS_BUILD_SHARED_LIB
|
||||||
|
"Build shared library"
|
||||||
|
OFF)
|
||||||
|
option(ZYDIS_BUILD_EXAMPLES
|
||||||
|
"Build examples"
|
||||||
|
ON)
|
||||||
|
option(ZYDIS_BUILD_TOOLS
|
||||||
|
"Build tools"
|
||||||
|
ON)
|
||||||
|
option(ZYDIS_FUZZ_AFL_FAST
|
||||||
|
"Enables AFL persistent mode and reduces prints in ZydisFuzzIn"
|
||||||
|
OFF)
|
||||||
|
option(ZYDIS_LIBFUZZER
|
||||||
|
"Enables LLVM libfuzzer mode and reduces prints in ZydisFuzzIn"
|
||||||
|
OFF)
|
||||||
|
set(ZYDIS_ZYCORE_PATH
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/dependencies/zycore"
|
||||||
|
CACHE
|
||||||
|
PATH
|
||||||
|
"The path to look for Zycore")
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Dependencies #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
# Try to initialize the Zycore submodule using Git
|
||||||
|
if (NOT EXISTS "${ZYDIS_ZYCORE_PATH}/CMakeLists.txt" AND
|
||||||
|
"${ZYDIS_ZYCORE_PATH}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}/dependencies/zycore")
|
||||||
|
find_package(Git QUIET)
|
||||||
|
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT EXISTS "${ZYDIS_ZYCORE_PATH}/CMakeLists.txt")
|
||||||
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
"Can't find zycore submodule. Please make sure to clone the repo recursively.\n"
|
||||||
|
"You can fix this by running\n"
|
||||||
|
" git submodule update --init\n"
|
||||||
|
"or by cloning using\n"
|
||||||
|
" git clone --recursive <url>\n"
|
||||||
|
"Alternatively, you can manually clone zycore to some path and set ZYDIS_ZYCORE_PATH."
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_subdirectory(${ZYDIS_ZYCORE_PATH} "zycore" EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Library configuration #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
if (ZYDIS_BUILD_SHARED_LIB)
|
||||||
|
add_library("Zydis" SHARED)
|
||||||
|
else ()
|
||||||
|
add_library("Zydis" STATIC)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries("Zydis" PUBLIC "Zycore")
|
||||||
|
target_include_directories("Zydis"
|
||||||
|
PUBLIC "include" ${PROJECT_BINARY_DIR}
|
||||||
|
PRIVATE "src")
|
||||||
|
target_compile_definitions("Zydis" PRIVATE "_CRT_SECURE_NO_WARNINGS" "ZYDIS_EXPORTS")
|
||||||
|
zyan_set_common_flags("Zydis")
|
||||||
|
zyan_maybe_enable_wpo_for_lib("Zydis")
|
||||||
|
generate_export_header("Zydis" BASE_NAME "ZYDIS" EXPORT_FILE_NAME "ZydisExportConfig.h")
|
||||||
|
|
||||||
|
if (ZYDIS_FEATURE_FORMATTER AND NOT ZYDIS_FEATURE_DECODER)
|
||||||
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
"\nZYDIS_FEATURE_FORMATTER requires ZYDIS_FEATURE_DECODER to be enabled"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (ZYDIS_MINIMAL_MODE)
|
||||||
|
target_compile_definitions("Zydis" PUBLIC "ZYDIS_MINIMAL_MODE")
|
||||||
|
endif ()
|
||||||
|
if (NOT ZYDIS_FEATURE_DECODER)
|
||||||
|
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_DECODER")
|
||||||
|
endif ()
|
||||||
|
if (NOT ZYDIS_FEATURE_FORMATTER)
|
||||||
|
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_FORMATTER")
|
||||||
|
endif ()
|
||||||
|
if (NOT ZYDIS_FEATURE_AVX512)
|
||||||
|
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_AVX512")
|
||||||
|
endif ()
|
||||||
|
if (NOT ZYDIS_FEATURE_KNC)
|
||||||
|
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_KNC")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_sources("Zydis"
|
||||||
|
PRIVATE
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/MetaInfo.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Mnemonic.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/SharedTypes.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/ShortString.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Utils.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/SharedData.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/String.h"
|
||||||
|
"src/MetaInfo.c"
|
||||||
|
"src/Mnemonic.c"
|
||||||
|
"src/Register.c"
|
||||||
|
"src/SharedData.c"
|
||||||
|
"src/String.c"
|
||||||
|
"src/Utils.c"
|
||||||
|
"src/Zydis.c")
|
||||||
|
|
||||||
|
if (ZYDIS_FEATURE_DECODER)
|
||||||
|
target_sources("Zydis"
|
||||||
|
PRIVATE
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Decoder.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/DecoderTypes.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/DecoderData.h"
|
||||||
|
"src/Decoder.c"
|
||||||
|
"src/DecoderData.c")
|
||||||
|
if (ZYDIS_FEATURE_FORMATTER AND (NOT ZYDIS_MINIMAL_MODE))
|
||||||
|
target_sources("Zydis"
|
||||||
|
PRIVATE
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/FormatterBuffer.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/FormatterATT.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/FormatterBase.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/FormatterIntel.h"
|
||||||
|
"src/Formatter.c"
|
||||||
|
"src/FormatterBuffer.c"
|
||||||
|
"src/FormatterATT.c"
|
||||||
|
"src/FormatterBase.c"
|
||||||
|
"src/FormatterIntel.c")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (ZYDIS_BUILD_SHARED_LIB AND WIN32)
|
||||||
|
target_sources("Zydis" PRIVATE "resources/VersionInfo.rc")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
zyan_set_source_group("Zydis")
|
||||||
|
|
||||||
|
configure_package_config_file(cmake/zydis-config.cmake.in
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/zydis-config.cmake"
|
||||||
|
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
|
||||||
|
)
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/zydis-config.cmake"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS "Zydis"
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
install(FILES
|
||||||
|
"${PROJECT_BINARY_DIR}/ZydisExportConfig.h"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
|
install(DIRECTORY "include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
|
function (_maybe_set_emscripten_cfg target)
|
||||||
|
if (EMSCRIPTEN)
|
||||||
|
# Yep, that madness below is how Emscripten likes its quotes.
|
||||||
|
set_target_properties("${target}"
|
||||||
|
PROPERTIES COMPILE_FLAGS
|
||||||
|
"-s \"EXPORT_NAME='${target}'\" -s MODULARIZE=1")
|
||||||
|
set_target_properties("${target}"
|
||||||
|
PROPERTIES LINK_FLAGS_RELEASE
|
||||||
|
"-s \"EXPORT_NAME='${target}'\" -s MODULARIZE=1")
|
||||||
|
endif ()
|
||||||
|
endfunction ()
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Examples #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
if (ZYDIS_BUILD_EXAMPLES AND NOT ZYAN_NO_LIBC)
|
||||||
|
if (ZYDIS_FEATURE_DECODER AND ZYDIS_FEATURE_FORMATTER AND (NOT ZYDIS_MINIMAL_MODE))
|
||||||
|
add_executable("Formatter01" "examples/Formatter01.c")
|
||||||
|
target_link_libraries("Formatter01" "Zydis")
|
||||||
|
set_target_properties("Formatter01" PROPERTIES FOLDER "Examples/Formatter")
|
||||||
|
target_compile_definitions("Formatter01" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("Formatter01")
|
||||||
|
zyan_maybe_enable_wpo("Formatter01")
|
||||||
|
_maybe_set_emscripten_cfg("Formatter01")
|
||||||
|
|
||||||
|
add_executable("Formatter02" "examples/Formatter02.c")
|
||||||
|
target_link_libraries("Formatter02" "Zydis")
|
||||||
|
set_target_properties("Formatter02" PROPERTIES FOLDER "Examples/Formatter")
|
||||||
|
target_compile_definitions("Formatter02" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("Formatter02")
|
||||||
|
zyan_maybe_enable_wpo("Formatter02")
|
||||||
|
_maybe_set_emscripten_cfg("Formatter02")
|
||||||
|
|
||||||
|
add_executable("Formatter03" "examples/Formatter03.c")
|
||||||
|
target_link_libraries("Formatter03" "Zydis")
|
||||||
|
set_target_properties("Formatter03" PROPERTIES FOLDER "Examples/Formatter")
|
||||||
|
target_compile_definitions("Formatter03" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("Formatter03")
|
||||||
|
zyan_maybe_enable_wpo("Formatter03")
|
||||||
|
_maybe_set_emscripten_cfg("Formatter03")
|
||||||
|
|
||||||
|
add_executable("ZydisPerfTest" "examples/ZydisPerfTest.c")
|
||||||
|
target_link_libraries("ZydisPerfTest" "Zydis")
|
||||||
|
set_target_properties("ZydisPerfTest" PROPERTIES FOLDER "Examples")
|
||||||
|
target_compile_definitions("ZydisPerfTest" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("ZydisPerfTest")
|
||||||
|
zyan_maybe_enable_wpo("ZydisPerfTest")
|
||||||
|
_maybe_set_emscripten_cfg("ZydisPerfTest")
|
||||||
|
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux"
|
||||||
|
OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||||
|
target_compile_definitions("ZydisPerfTest" PRIVATE "_GNU_SOURCE")
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries("ZydisPerfTest" Threads::Threads)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Tools #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
if (ZYDIS_BUILD_TOOLS AND NOT ZYAN_NO_LIBC)
|
||||||
|
if (ZYDIS_FEATURE_DECODER AND ZYDIS_FEATURE_FORMATTER AND (NOT ZYDIS_MINIMAL_MODE))
|
||||||
|
add_executable("ZydisDisasm" "tools/ZydisDisasm.c")
|
||||||
|
target_link_libraries("ZydisDisasm" "Zydis")
|
||||||
|
set_target_properties ("ZydisDisasm" PROPERTIES FOLDER "Tools")
|
||||||
|
target_compile_definitions("ZydisDisasm" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("ZydisDisasm")
|
||||||
|
zyan_maybe_enable_wpo("ZydisDisasm")
|
||||||
|
_maybe_set_emscripten_cfg("ZydisDisasm")
|
||||||
|
install(TARGETS "ZydisDisasm" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
add_executable("ZydisFuzzIn" "tools/ZydisFuzzIn.c")
|
||||||
|
target_link_libraries("ZydisFuzzIn" "Zydis")
|
||||||
|
set_target_properties("ZydisFuzzIn" PROPERTIES FOLDER "Tools")
|
||||||
|
target_compile_definitions("ZydisFuzzIn" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("ZydisFuzzIn")
|
||||||
|
zyan_maybe_enable_wpo("ZydisFuzzIn")
|
||||||
|
_maybe_set_emscripten_cfg("ZydisFuzzIn")
|
||||||
|
if (ZYDIS_FUZZ_AFL_FAST)
|
||||||
|
target_compile_definitions("ZydisFuzzIn" PRIVATE "ZYDIS_FUZZ_AFL_FAST")
|
||||||
|
endif ()
|
||||||
|
if (ZYDIS_LIBFUZZER)
|
||||||
|
target_compile_definitions("ZydisFuzzIn" PRIVATE "ZYDIS_LIBFUZZER")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_executable("ZydisInfo" "tools/ZydisInfo.c")
|
||||||
|
target_link_libraries("ZydisInfo" "Zydis")
|
||||||
|
set_target_properties ("ZydisInfo" PROPERTIES FOLDER "Tools")
|
||||||
|
target_compile_definitions("ZydisInfo" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("ZydisInfo")
|
||||||
|
zyan_maybe_enable_wpo("ZydisInfo")
|
||||||
|
_maybe_set_emscripten_cfg("ZydisInfo")
|
||||||
|
install(TARGETS "ZydisInfo" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
add_executable("ZydisPE" "tools/ZydisPE.c")
|
||||||
|
target_link_libraries("ZydisPE" "Zydis")
|
||||||
|
set_target_properties ("ZydisPE" PROPERTIES FOLDER "Tools")
|
||||||
|
target_compile_definitions("ZydisPE" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_set_common_flags("ZydisPE")
|
||||||
|
zyan_maybe_enable_wpo("ZydisPE")
|
||||||
|
_maybe_set_emscripten_cfg("ZydisPE")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
|||||||
|
@INCLUDE = Doxyfile
|
||||||
|
GENERATE_HTML = NO
|
||||||
|
GENERATE_XML = YES
|
||||||
|
XML_PROGRAMLISTING = NO
|
||||||
|
##!M_LINKS_NAVBAR1 = modules files
|
||||||
|
##!M_LINKS_NAVBAR2 =
|
||||||
|
##!M_FILE_TREE_EXPAND_LEVELS = 2
|
@ -0,0 +1,23 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2020 Florian Bernd
|
||||||
|
Copyright (c) 2014-2020 Joel Höner
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
@ -0,0 +1,175 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img alt="zydis logo" src="https://zydis.re/img/logo.svg" width="400px">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT">
|
||||||
|
<a href="https://github.com/zyantific/zydis/actions"><img src="https://github.com/zyantific/zydis/workflows/GitHub%20Actions%20CI/badge.svg" alt="GitHub Actions"></a>
|
||||||
|
<a href="https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zydis"><img src="https://oss-fuzz-build-logs.storage.googleapis.com/badges/zydis.svg" alt="Fuzzing Status"></a>
|
||||||
|
<a href="https://gitter.im/zyantific/zydis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/zyantific/zyan-disassembler-engine.svg" alt="Gitter"></a>
|
||||||
|
<a href="https://discord.zyantific.com/"><img src="https://img.shields.io/discord/390136917779415060.svg?logo=discord&label=Discord" alt="Discord"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">Fast and lightweight x86/x86-64 disassembler library.</p>
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Supports all x86 and x86-64 (AMD64) instructions and [extensions](./include/Zydis/Generated/EnumISAExt.h)
|
||||||
|
- Optimized for high performance
|
||||||
|
- No dynamic memory allocation ("malloc")
|
||||||
|
- Thread-safe by design
|
||||||
|
- Very small file-size overhead compared to other common disassembler libraries
|
||||||
|
- [Complete doxygen documentation](https://zydis.re/doc/3/)
|
||||||
|
- Absolutely no third party dependencies — not even libc
|
||||||
|
- Should compile on any platform with a working C99 compiler
|
||||||
|
- Tested on Windows, macOS, FreeBSD, Linux and UEFI, both user and kernel mode
|
||||||
|
|
||||||
|
## Quick Example
|
||||||
|
The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console ([more examples here](./examples/)).
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <Zydis/Zydis.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
ZyanU8 data[] =
|
||||||
|
{
|
||||||
|
0x51, 0x8D, 0x45, 0xFF, 0x50, 0xFF, 0x75, 0x0C, 0xFF, 0x75,
|
||||||
|
0x08, 0xFF, 0x15, 0xA0, 0xA5, 0x48, 0x76, 0x85, 0xC0, 0x0F,
|
||||||
|
0x88, 0xFC, 0xDA, 0x02, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize decoder context
|
||||||
|
ZydisDecoder decoder;
|
||||||
|
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
|
||||||
|
|
||||||
|
// Initialize formatter. Only required when you actually plan to do instruction
|
||||||
|
// formatting ("disassembling"), like we do here
|
||||||
|
ZydisFormatter formatter;
|
||||||
|
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
|
||||||
|
|
||||||
|
// Loop over the instructions in our buffer.
|
||||||
|
// The runtime-address (instruction pointer) is chosen arbitrary here in order to better
|
||||||
|
// visualize relative addressing
|
||||||
|
ZyanU64 runtime_address = 0x007FFFFFFF400000;
|
||||||
|
ZyanUSize offset = 0;
|
||||||
|
const ZyanUSize length = sizeof(data);
|
||||||
|
ZydisDecodedInstruction instruction;
|
||||||
|
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, data + offset, length - offset,
|
||||||
|
&instruction)))
|
||||||
|
{
|
||||||
|
// Print current instruction pointer.
|
||||||
|
printf("%016" PRIX64 " ", runtime_address);
|
||||||
|
|
||||||
|
// Format & print the binary instruction structure to human readable format
|
||||||
|
char buffer[256];
|
||||||
|
ZydisFormatterFormatInstruction(&formatter, &instruction, buffer, sizeof(buffer),
|
||||||
|
runtime_address);
|
||||||
|
puts(buffer);
|
||||||
|
|
||||||
|
offset += instruction.length;
|
||||||
|
runtime_address += instruction.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sample Output
|
||||||
|
The above example program generates the following output:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
007FFFFFFF400000 push rcx
|
||||||
|
007FFFFFFF400001 lea eax, [rbp-0x01]
|
||||||
|
007FFFFFFF400004 push rax
|
||||||
|
007FFFFFFF400005 push qword ptr [rbp+0x0C]
|
||||||
|
007FFFFFFF400008 push qword ptr [rbp+0x08]
|
||||||
|
007FFFFFFF40000B call [0x008000007588A5B1]
|
||||||
|
007FFFFFFF400011 test eax, eax
|
||||||
|
007FFFFFFF400013 js 0x007FFFFFFF42DB15
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
#### Unix
|
||||||
|
Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C99 compiler.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone --recursive 'https://github.com/zyantific/zydis.git'
|
||||||
|
cd zydis
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
Either use the [Visual Studio 2017 project](./msvc/) or build Zydis using [CMake](https://cmake.org/download/) ([video guide](https://www.youtube.com/watch?v=fywLDK1OAtQ)).
|
||||||
|
|
||||||
|
#### Building Zydis - Using vcpkg
|
||||||
|
|
||||||
|
You can download and install Zydis using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
|
cd vcpkg
|
||||||
|
./bootstrap-vcpkg.sh
|
||||||
|
./vcpkg integrate install
|
||||||
|
vcpkg install zydis
|
||||||
|
```
|
||||||
|
The Zydis port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||||
|
|
||||||
|
## Using Zydis in a CMake project
|
||||||
|
An example on how to use Zydis in your own CMake based project [can be found in this repo](https://github.com/zyantific/zydis-submodule-example).
|
||||||
|
|
||||||
|
## `ZydisInfo` tool
|
||||||
|
![ZydisInfo](./assets/screenshots/ZydisInfo.png)
|
||||||
|
|
||||||
|
## Bindings
|
||||||
|
Official bindings exist for a selection of languages:
|
||||||
|
- [Pascal](https://github.com/zyantific/zydis-pascal)
|
||||||
|
- [Python 3](https://github.com/zyantific/zydis-py)
|
||||||
|
- [Rust](https://github.com/zyantific/zydis-rs)
|
||||||
|
|
||||||
|
Unofficial but actively maintained bindings:
|
||||||
|
- [Go](https://github.com/jpap/go-zydis)
|
||||||
|
- [LuaJIT](https://github.com/Wiladams/lj2zydis)
|
||||||
|
- [Haskell](https://github.com/nerded1337/zydiskell)
|
||||||
|
|
||||||
|
## Versions
|
||||||
|
|
||||||
|
#### Scheme
|
||||||
|
Versions follow the [semantic versioning scheme](https://semver.org/). All stability guarantees apply to the API only — ABI stability between patches cannot be assumed unless explicitly mentioned in the release notes.
|
||||||
|
|
||||||
|
#### Branches & Tags
|
||||||
|
- `master` holds the bleeding edge code of the next, unreleased Zydis version. Elevated amounts of bugs and issues must be expected, API stability is not guaranteed outside of tagged commits.
|
||||||
|
- Stable and preview versions are annotated with git tags
|
||||||
|
- beta and other preview versions have `-beta`, `-rc`, etc. suffixes
|
||||||
|
- `maintenance/v2` contains the code of the latest legacy release of v2
|
||||||
|
- v2 is now deprecated, but will receive security fixes until 2021
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
- Intel (for open-sourcing [XED](https://github.com/intelxed/xed), allowing for automatic comparision of our tables against theirs, improving both)
|
||||||
|
- [LLVM](https://llvm.org) (for providing pretty solid instruction data as well)
|
||||||
|
- Christian Ludloff (http://sandpile.org, insanely helpful)
|
||||||
|
- [LekoArts](https://www.lekoarts.de/) (for creating the project logo)
|
||||||
|
- Our [contributors on GitHub](https://github.com/zyantific/zydis/graphs/contributors)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
#### `-fPIC` for shared library builds
|
||||||
|
|
||||||
|
```
|
||||||
|
/usr/bin/ld: ./libfoo.a(foo.c.o): relocation R_X86_64_PC32 against symbol `bar' can not be used when making a shared object; recompile with -fPIC
|
||||||
|
```
|
||||||
|
|
||||||
|
Under some circumstances (e.g. when building Zydis as a static library using
|
||||||
|
CMake and then using Makefiles to manually link it into a shared library), CMake
|
||||||
|
might fail to detect that relocation information must be emitted. This can be forced
|
||||||
|
by passing `-DCMAKE_POSITION_INDEPENDENT_CODE=ON` to the CMake invocation.
|
||||||
|
|
||||||
|
## Donations
|
||||||
|
|
||||||
|
Since GitHub Sponsors currently doesn't support sponsoring teams directly, donations are collected and distributed using [flobernd](https://github.com/users/flobernd/sponsorship)s account.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Zydis is licensed under the MIT license.
|
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
#ifndef ZYDIS_EXPORT_H
|
||||||
|
#define ZYDIS_EXPORT_H
|
||||||
|
|
||||||
|
#ifdef ZYDIS_STATIC_DEFINE
|
||||||
|
# define ZYDIS_EXPORT
|
||||||
|
# define ZYDIS_NO_EXPORT
|
||||||
|
#else
|
||||||
|
# ifndef ZYDIS_EXPORT
|
||||||
|
# ifdef Zydis_EXPORTS
|
||||||
|
/* We are building this library */
|
||||||
|
# define ZYDIS_EXPORT
|
||||||
|
# else
|
||||||
|
/* We are using this library */
|
||||||
|
# define ZYDIS_EXPORT
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef ZYDIS_NO_EXPORT
|
||||||
|
# define ZYDIS_NO_EXPORT
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZYDIS_DEPRECATED
|
||||||
|
# define ZYDIS_DEPRECATED __attribute__ ((__deprecated__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZYDIS_DEPRECATED_EXPORT
|
||||||
|
# define ZYDIS_DEPRECATED_EXPORT ZYDIS_EXPORT ZYDIS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZYDIS_DEPRECATED_NO_EXPORT
|
||||||
|
# define ZYDIS_DEPRECATED_NO_EXPORT ZYDIS_NO_EXPORT ZYDIS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFINE_NO_DEPRECATED 0
|
||||||
|
#if DEFINE_NO_DEPRECATED
|
||||||
|
# define ZYDIS_NO_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
@ -0,0 +1,4 @@
|
|||||||
|
- CMakeLists (VERSION)
|
||||||
|
- Doxyfile
|
||||||
|
- resources/VersionInfo.rc (4 locations)
|
||||||
|
- include/Zydis/Zydis.h (ZYDIS_VERSION macro)
|
@ -0,0 +1,8 @@
|
|||||||
|
set(zydis_VERSION @PROJECT_VERSION@)
|
||||||
|
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
set_and_check(zydis_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
|
||||||
|
set_and_check(zydis_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
|
||||||
|
|
||||||
|
check_required_components(zydis)
|
@ -0,0 +1,100 @@
|
|||||||
|
# Created by https://www.gitignore.io/api/c,c++,cmake
|
||||||
|
|
||||||
|
### C ###
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
|
||||||
|
|
||||||
|
### C++ ###
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
|
||||||
|
### CMake ###
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
CTestTestfile.cmake
|
||||||
|
|
||||||
|
|
||||||
|
# MacOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
build*
|
||||||
|
|
||||||
|
# MSVC
|
||||||
|
.vs
|
||||||
|
*.vcxproj.user
|
||||||
|
*.suo
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.VC.db
|
||||||
|
*.VC.opendb
|
||||||
|
msvc/**/obj/
|
||||||
|
msvc/**/bin/
|
||||||
|
|
||||||
|
doc/html
|
||||||
|
|
||||||
|
/.vscode
|
||||||
|
/.idea
|
||||||
|
/cmake-build-*
|
@ -0,0 +1,266 @@
|
|||||||
|
if (TARGET Zycore)
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
||||||
|
include(GenerateExportHeader)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
project(Zycore VERSION 1.0.0.0 LANGUAGES C CXX)
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Overridable options #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
# Global configuration
|
||||||
|
option(ZYAN_WHOLE_PROGRAM_OPTIMIZATION
|
||||||
|
"Enable whole program optimization (all targets)"
|
||||||
|
OFF)
|
||||||
|
option(ZYAN_NO_LIBC
|
||||||
|
"Don't use any C standard library functions (for exotic build-envs like kernel drivers)"
|
||||||
|
OFF)
|
||||||
|
option(ZYAN_DEV_MODE
|
||||||
|
"Enable developer mode (-Wall, -Werror, ...)"
|
||||||
|
OFF)
|
||||||
|
|
||||||
|
# Build configuration
|
||||||
|
option(ZYCORE_BUILD_SHARED_LIB
|
||||||
|
"Build shared library"
|
||||||
|
OFF)
|
||||||
|
option(ZYCORE_BUILD_EXAMPLES
|
||||||
|
"Build examples"
|
||||||
|
OFF)
|
||||||
|
option(ZYCORE_BUILD_TESTS
|
||||||
|
"Build tests"
|
||||||
|
OFF)
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# GoogleTest #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
# Download and unpack googletest
|
||||||
|
if (ZYCORE_BUILD_TESTS)
|
||||||
|
if (NOT DEFINED ZYCORE_DOWNLOADED_GTEST)
|
||||||
|
configure_file("CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/gtest/download/CMakeLists.txt")
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
|
||||||
|
if (result)
|
||||||
|
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
|
||||||
|
endif()
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} --build .
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
|
||||||
|
if (result)
|
||||||
|
message(FATAL_ERROR "Build step for googletest failed: ${result}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ZYCORE_DOWNLOADED_GTEST TRUE CACHE BOOL "")
|
||||||
|
mark_as_advanced(ZYCORE_DOWNLOADED_GTEST)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
add_subdirectory("${CMAKE_BINARY_DIR}/gtest/src" "${CMAKE_BINARY_DIR}/gtest/build"
|
||||||
|
EXCLUDE_FROM_ALL)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Exported functions #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
function (zyan_set_common_flags target)
|
||||||
|
if (NOT MSVC)
|
||||||
|
target_compile_options("${target}" PRIVATE "-std=c99")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (ZYAN_DEV_MODE)
|
||||||
|
# If in developer mode, be pedantic.
|
||||||
|
if (MSVC)
|
||||||
|
target_compile_options("${target}" PUBLIC "/WX" "/W4")
|
||||||
|
else ()
|
||||||
|
target_compile_options("${target}" PUBLIC "-Wall" "-pedantic" "-Wextra" "-Werror")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endfunction ()
|
||||||
|
|
||||||
|
function (zyan_set_source_group target)
|
||||||
|
if (ZYAN_DEV_MODE)
|
||||||
|
if (((CMAKE_MAJOR_VERSION GREATER 3) OR (CMAKE_MAJOR_VERSION EQUAL 3)) AND
|
||||||
|
((CMAKE_MINOR_VERSION GREATER 8) OR (CMAKE_MINOR_VERSION EQUAL 8)))
|
||||||
|
# Mirror directory structure in project files
|
||||||
|
get_property("TARGET_SOURCE_FILES" TARGET "${target}" PROPERTY SOURCES)
|
||||||
|
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${TARGET_SOURCE_FILES})
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endfunction ()
|
||||||
|
|
||||||
|
function (zyan_maybe_enable_wpo target)
|
||||||
|
if (ZYAN_WHOLE_PROGRAM_OPTIMIZATION AND MSVC)
|
||||||
|
set_target_properties("${target}" PROPERTIES COMPILE_FLAGS "/GL")
|
||||||
|
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE "/LTCG")
|
||||||
|
endif ()
|
||||||
|
endfunction ()
|
||||||
|
|
||||||
|
function (zyan_maybe_enable_wpo_for_lib target)
|
||||||
|
if (ZYAN_WHOLE_PROGRAM_OPTIMIZATION AND MSVC)
|
||||||
|
set_target_properties("${target}" PROPERTIES COMPILE_FLAGS "/GL")
|
||||||
|
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE "/LTCG")
|
||||||
|
set_target_properties("${target}" PROPERTIES STATIC_LIBRARY_FLAGS_RELEASE "/LTCG")
|
||||||
|
endif ()
|
||||||
|
endfunction ()
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Library configuration #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
if (ZYCORE_BUILD_SHARED_LIB)
|
||||||
|
add_library("Zycore" SHARED)
|
||||||
|
else ()
|
||||||
|
add_library("Zycore" STATIC)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set_target_properties("Zycore" PROPERTIES LINKER_LANGUAGE C)
|
||||||
|
target_include_directories("Zycore"
|
||||||
|
PUBLIC "include" ${PROJECT_BINARY_DIR}
|
||||||
|
PRIVATE "src")
|
||||||
|
target_compile_definitions("Zycore" PRIVATE "_CRT_SECURE_NO_WARNINGS" "ZYCORE_EXPORTS")
|
||||||
|
zyan_set_common_flags("Zycore")
|
||||||
|
zyan_maybe_enable_wpo_for_lib("Zycore")
|
||||||
|
generate_export_header("Zycore" BASE_NAME "ZYCORE" EXPORT_FILE_NAME "ZycoreExportConfig.h")
|
||||||
|
|
||||||
|
if (ZYAN_NO_LIBC)
|
||||||
|
target_compile_definitions("Zycore" PUBLIC "ZYAN_NO_LIBC")
|
||||||
|
if (UNIX)
|
||||||
|
set_target_properties("Zycore" PROPERTIES LINK_FLAGS "-nostdlib -nodefaultlibs")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_sources("Zycore"
|
||||||
|
PRIVATE
|
||||||
|
# API
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Memory.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Process.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Synchronization.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Terminal.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Thread.h"
|
||||||
|
# Common
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Allocator.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/ArgParse.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Bitset.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Comparison.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Defines.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Format.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/LibC.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/List.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Object.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Status.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/String.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Types.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Vector.h"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Zycore.h"
|
||||||
|
# Common
|
||||||
|
"src/Allocator.c"
|
||||||
|
"src/ArgParse.c"
|
||||||
|
"src/Bitset.c"
|
||||||
|
"src/Format.c"
|
||||||
|
"src/List.c"
|
||||||
|
"src/String.c"
|
||||||
|
"src/Vector.c"
|
||||||
|
"src/Zycore.c")
|
||||||
|
|
||||||
|
if (NOT ZYAN_NO_LIBC)
|
||||||
|
target_sources("Zycore"
|
||||||
|
PRIVATE
|
||||||
|
# API
|
||||||
|
"src/API/Memory.c"
|
||||||
|
"src/API/Process.c"
|
||||||
|
"src/API/Synchronization.c"
|
||||||
|
"src/API/Terminal.c"
|
||||||
|
"src/API/Thread.c")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (ZYCORE_BUILD_SHARED_LIB AND WIN32)
|
||||||
|
target_sources("Zycore" PRIVATE "resources/VersionInfo.rc")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
zyan_set_source_group("Zycore")
|
||||||
|
|
||||||
|
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT ZYAN_NO_LIBC)
|
||||||
|
target_compile_definitions("Zycore" PRIVATE "_GNU_SOURCE")
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries("Zycore" Threads::Threads)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
configure_package_config_file(cmake/zycore-config.cmake.in
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.cmake"
|
||||||
|
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
|
||||||
|
)
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.cmake"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS "Zycore"
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
install(FILES
|
||||||
|
"${PROJECT_BINARY_DIR}/ZycoreExportConfig.h"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
|
install(DIRECTORY "include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Developer mode #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
if (ZYAN_DEV_MODE)
|
||||||
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Examples #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
if (ZYCORE_BUILD_EXAMPLES)
|
||||||
|
add_executable("String" "examples/String.c")
|
||||||
|
zyan_set_common_flags("String" "Zycore")
|
||||||
|
target_link_libraries("String" "Zycore")
|
||||||
|
set_target_properties("String" PROPERTIES FOLDER "Examples")
|
||||||
|
target_compile_definitions("String" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_maybe_enable_wpo("String")
|
||||||
|
|
||||||
|
add_executable("Vector" "examples/Vector.c")
|
||||||
|
zyan_set_common_flags("Vector" "Zycore")
|
||||||
|
target_link_libraries("Vector" "Zycore")
|
||||||
|
set_target_properties("Vector" PROPERTIES FOLDER "Examples")
|
||||||
|
target_compile_definitions("Vector" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_maybe_enable_wpo("Vector")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
||||||
|
# Tests #
|
||||||
|
# =============================================================================================== #
|
||||||
|
|
||||||
|
function (zyan_add_test test)
|
||||||
|
add_executable("Test${test}" "tests/${test}.cpp")
|
||||||
|
|
||||||
|
if (NOT MSVC)
|
||||||
|
target_compile_options("Test${test}" PRIVATE "-std=c++17")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries("Test${test}" "Zycore")
|
||||||
|
target_link_libraries("Test${test}" "gtest")
|
||||||
|
set_target_properties("Test${test}" PROPERTIES FOLDER "Tests")
|
||||||
|
target_compile_definitions("Test${test}" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
|
zyan_maybe_enable_wpo("Test${test}")
|
||||||
|
endfunction ()
|
||||||
|
|
||||||
|
if (ZYCORE_BUILD_TESTS)
|
||||||
|
zyan_add_test("String")
|
||||||
|
zyan_add_test("Vector")
|
||||||
|
zyan_add_test("ArgParse")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# =============================================================================================== #
|
@ -0,0 +1,15 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8.2)
|
||||||
|
|
||||||
|
project(googletest-download NONE)
|
||||||
|
|
||||||
|
include(ExternalProject)
|
||||||
|
ExternalProject_Add(googletest
|
||||||
|
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||||
|
GIT_TAG ee3aa831172090fd5442820f215cb04ab6062756
|
||||||
|
SOURCE_DIR "${CMAKE_BINARY_DIR}/gtest/src"
|
||||||
|
BINARY_DIR "${CMAKE_BINARY_DIR}/gtest/build"
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
TEST_COMMAND ""
|
||||||
|
)
|
@ -0,0 +1,23 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2018-2020 Florian Bernd
|
||||||
|
Copyright (c) 2018-2020 Joel Höner
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
# Zyan Core Library for C
|
||||||
|
|
||||||
|
Internal library providing platform independent types, macros and a fallback for environments without LibC.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Platform independent types
|
||||||
|
- Integer types (`ZyanU8`, `ZyanI32`, `ZyanUSize`, ...)
|
||||||
|
- `ZyanBool` (+ `ZYAN_FALSE`, `ZYAN_TRUE`)
|
||||||
|
- `ZYAN_NULL`
|
||||||
|
- Macros
|
||||||
|
- Compiler/Platform/Architecture detection
|
||||||
|
- Asserts and static asserts
|
||||||
|
- Utils (`ARRAY_LENGTH`, `FALLTHROUGH`, `UNUSED`, ...)
|
||||||
|
- Common types
|
||||||
|
- `ZyanBitset`
|
||||||
|
- `ZyanString`/`ZyanStringView`
|
||||||
|
- Container types
|
||||||
|
- `ZyanVector`
|
||||||
|
- `ZyanList`
|
||||||
|
- LibC abstraction (WiP)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Zycore is licensed under the MIT license.
|
@ -0,0 +1,8 @@
|
|||||||
|
set(zycore_VERSION @PROJECT_VERSION@)
|
||||||
|
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
set_and_check(zycore_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
|
||||||
|
set_and_check(zycore_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
|
||||||
|
|
||||||
|
check_required_components(zycore)
|
@ -0,0 +1,192 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Core Library (Zycore-C)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Demonstrates the `String` implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <Zycore/Allocator.h>
|
||||||
|
#include <Zycore/Defines.h>
|
||||||
|
#include <Zycore/LibC.h>
|
||||||
|
#include <Zycore/String.h>
|
||||||
|
#include <Zycore/Types.h>
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Enums and types */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Helper functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Tests */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Basic tests */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs some basic test on the given `ZyanString` instance.
|
||||||
|
*
|
||||||
|
* @param string A pointer to the `ZyanString` instance.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus PerformBasicTests(ZyanString* string)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(string);
|
||||||
|
ZYAN_UNUSED(string);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs basic tests on a string that dynamically manages memory.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus TestDynamic(void)
|
||||||
|
{
|
||||||
|
PerformBasicTests(ZYAN_NULL);
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs basic tests on a string that uses a static buffer.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus TestStatic(void)
|
||||||
|
{
|
||||||
|
PerformBasicTests(ZYAN_NULL);
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Custom allocator */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//static ZyanStatus AllocatorAllocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
|
||||||
|
// ZyanUSize n)
|
||||||
|
//{
|
||||||
|
// ZYAN_ASSERT(allocator);
|
||||||
|
// ZYAN_ASSERT(p);
|
||||||
|
// ZYAN_ASSERT(element_size);
|
||||||
|
// ZYAN_ASSERT(n);
|
||||||
|
//
|
||||||
|
// ZYAN_UNUSED(allocator);
|
||||||
|
//
|
||||||
|
// *p = ZYAN_MALLOC(element_size * n);
|
||||||
|
// if (!*p)
|
||||||
|
// {
|
||||||
|
// return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return ZYAN_STATUS_SUCCESS;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//static ZyanStatus AllocatorReallocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
|
||||||
|
// ZyanUSize n)
|
||||||
|
//{
|
||||||
|
// ZYAN_ASSERT(allocator);
|
||||||
|
// ZYAN_ASSERT(p);
|
||||||
|
// ZYAN_ASSERT(element_size);
|
||||||
|
// ZYAN_ASSERT(n);
|
||||||
|
//
|
||||||
|
// ZYAN_UNUSED(allocator);
|
||||||
|
//
|
||||||
|
// void* const x = ZYAN_REALLOC(*p, element_size * n);
|
||||||
|
// if (!x)
|
||||||
|
// {
|
||||||
|
// return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
|
||||||
|
// }
|
||||||
|
// *p = x;
|
||||||
|
//
|
||||||
|
// return ZYAN_STATUS_SUCCESS;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//static ZyanStatus AllocatorDeallocate(ZyanAllocator* allocator, void* p, ZyanUSize element_size,
|
||||||
|
// ZyanUSize n)
|
||||||
|
//{
|
||||||
|
// ZYAN_ASSERT(allocator);
|
||||||
|
// ZYAN_ASSERT(p);
|
||||||
|
// ZYAN_ASSERT(element_size);
|
||||||
|
// ZYAN_ASSERT(n);
|
||||||
|
//
|
||||||
|
// ZYAN_UNUSED(allocator);
|
||||||
|
// ZYAN_UNUSED(element_size);
|
||||||
|
// ZYAN_UNUSED(n);
|
||||||
|
//
|
||||||
|
// ZYAN_FREE(p);
|
||||||
|
//
|
||||||
|
// return ZYAN_STATUS_SUCCESS;
|
||||||
|
//}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs basic tests on a vector that dynamically manages memory using a custom
|
||||||
|
* allocator and modified growth-factor/shrink-threshold.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus TestAllocator(void)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Entry point */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (!ZYAN_SUCCESS(TestDynamic()))
|
||||||
|
{
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (!ZYAN_SUCCESS(TestStatic()))
|
||||||
|
{
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (!ZYAN_SUCCESS(TestAllocator()))
|
||||||
|
{
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
@ -0,0 +1,395 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Core Library (Zycore-C)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Demonstrates the `ZyanVector` implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <Zycore/Allocator.h>
|
||||||
|
#include <Zycore/Defines.h>
|
||||||
|
#include <Zycore/LibC.h>
|
||||||
|
#include <Zycore/Types.h>
|
||||||
|
#include <Zycore/Vector.h>
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Enums and types */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the `TestStruct` struct that represents a single element in the vector.
|
||||||
|
*/
|
||||||
|
typedef struct TestStruct_
|
||||||
|
{
|
||||||
|
ZyanU32 u32;
|
||||||
|
ZyanU64 u64;
|
||||||
|
float f;
|
||||||
|
} TestStruct;
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Helper functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the given `TestStruct` struct.
|
||||||
|
*
|
||||||
|
* @param data A pointer to the `TestStruct` struct.
|
||||||
|
* @param n The number to initialize the struct with.
|
||||||
|
*/
|
||||||
|
static void InitTestdata(TestStruct* data, ZyanU32 n)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(data);
|
||||||
|
|
||||||
|
data->u32 = n;
|
||||||
|
data->u64 = n;
|
||||||
|
data->f = (float)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Tests */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Basic tests */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs some basic test on the given `ZyanVector` instance.
|
||||||
|
*
|
||||||
|
* @param vector A pointer to the `ZyanVector` instance.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus PerformBasicTests(ZyanVector* vector)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(vector);
|
||||||
|
|
||||||
|
static TestStruct e_v;
|
||||||
|
static const TestStruct* e_p;
|
||||||
|
|
||||||
|
// Insert `20` elements. The vector automatically manages its size
|
||||||
|
for (ZyanU32 i = 0; i < 20; ++i)
|
||||||
|
{
|
||||||
|
InitTestdata(&e_v, i);
|
||||||
|
ZYAN_CHECK(ZyanVectorPushBack(vector, &e_v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove elements `#05..#09`
|
||||||
|
ZYAN_CHECK(ZyanVectorDeleteRange(vector, 5, 5));
|
||||||
|
|
||||||
|
// Insert a new element at index `#05`
|
||||||
|
InitTestdata(&e_v, 12345678);
|
||||||
|
ZYAN_CHECK(ZyanVectorInsert(vector, 5, &e_v));
|
||||||
|
|
||||||
|
// Change value of element `#15`
|
||||||
|
InitTestdata(&e_v, 87654321);
|
||||||
|
ZYAN_CHECK(ZyanVectorSet(vector, 10, &e_v));
|
||||||
|
|
||||||
|
// Print `u64` of all vector elements
|
||||||
|
ZyanUSize value;
|
||||||
|
ZYAN_CHECK(ZyanVectorGetSize(vector, &value));
|
||||||
|
puts("ELEMENTS");
|
||||||
|
for (ZyanUSize i = 0; i < value; ++i)
|
||||||
|
{
|
||||||
|
ZYAN_CHECK(ZyanVectorGetPointer(vector, i, (const void**)&e_p));
|
||||||
|
printf(" Element #%02" PRIuPTR ": %08" PRIu64 "\n", i, e_p->u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print infos
|
||||||
|
puts("INFO");
|
||||||
|
printf(" Size : %08" PRIuPTR "\n", value);
|
||||||
|
ZYAN_CHECK(ZyanVectorGetCapacity(vector, &value));
|
||||||
|
printf(" Capacity : %08" PRIuPTR "\n\n", value);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A dummy comparison function for the `TestStruct` that uses the `u32` field as key
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* @param left A pointer to the first element.
|
||||||
|
* @param right A pointer to the second element.
|
||||||
|
*
|
||||||
|
* @return Returns values in the following range:
|
||||||
|
* `left == right -> result == 0`
|
||||||
|
* `left < right -> result < 0`
|
||||||
|
* `left > right -> result > 0`
|
||||||
|
*/
|
||||||
|
static ZyanI32 TestDataComparison(const TestStruct* left, const TestStruct* right)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(left);
|
||||||
|
ZYAN_ASSERT(right);
|
||||||
|
|
||||||
|
if (left->u32 < right->u32)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (left->u32 > right->u32)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the binary-search functionality of the given `ZyanVector` instance.
|
||||||
|
*
|
||||||
|
* @param vector A pointer to the `ZyanVector` instance.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus PerformBinarySearchTest(ZyanVector* vector)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(vector);
|
||||||
|
|
||||||
|
static TestStruct e_v;
|
||||||
|
static const TestStruct* e_p;
|
||||||
|
|
||||||
|
ZyanUSize value;
|
||||||
|
ZYAN_CHECK(ZyanVectorGetCapacity(vector, &value));
|
||||||
|
|
||||||
|
// Create a sorted test vector
|
||||||
|
for (ZyanUSize i = 0; i < value; ++i)
|
||||||
|
{
|
||||||
|
const ZyanU32 n = rand() % 100;
|
||||||
|
InitTestdata(&e_v, n);
|
||||||
|
|
||||||
|
ZyanUSize found_index;
|
||||||
|
ZYAN_CHECK(ZyanVectorBinarySearch(vector, &e_v, &found_index,
|
||||||
|
(ZyanComparison)&TestDataComparison));
|
||||||
|
ZYAN_CHECK(ZyanVectorInsert(vector, found_index, &e_v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print `u32` of all vector elements
|
||||||
|
ZYAN_CHECK(ZyanVectorGetSize(vector, &value));
|
||||||
|
puts("ELEMENTS");
|
||||||
|
for (ZyanUSize i = 0; i < value; ++i)
|
||||||
|
{
|
||||||
|
ZYAN_CHECK(ZyanVectorGetPointer(vector, i, (const void**)&e_p));
|
||||||
|
printf(" Element #%02" PRIuPTR ": %08" PRIu32 "\n", i, e_p->u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs basic tests on a vector that dynamically manages memory.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus TestDynamic(void)
|
||||||
|
{
|
||||||
|
// Initialize vector with a base capacity of `10` elements
|
||||||
|
ZyanVector vector;
|
||||||
|
ZYAN_CHECK(ZyanVectorInit(&vector, sizeof(TestStruct), 10, ZYAN_NULL));
|
||||||
|
|
||||||
|
ZYAN_CHECK(PerformBasicTests(&vector));
|
||||||
|
ZYAN_CHECK(ZyanVectorClear(&vector));
|
||||||
|
ZYAN_CHECK(ZyanVectorReserve(&vector, 20));
|
||||||
|
ZYAN_CHECK(PerformBinarySearchTest(&vector));
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
return ZyanVectorDestroy(&vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs basic tests on a vector that uses a static buffer.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus TestStatic(void)
|
||||||
|
{
|
||||||
|
static TestStruct buffer[20];
|
||||||
|
|
||||||
|
// Initialize vector to use a static buffer with a total capacity of `20` elements.
|
||||||
|
ZyanVector vector;
|
||||||
|
ZYAN_CHECK(ZyanVectorInitCustomBuffer(&vector, sizeof(TestStruct), buffer,
|
||||||
|
ZYAN_ARRAY_LENGTH(buffer), ZYAN_NULL));
|
||||||
|
|
||||||
|
// Compare elements
|
||||||
|
ZyanUSize size;
|
||||||
|
ZYAN_CHECK(ZyanVectorGetSize(&vector, &size));
|
||||||
|
for (ZyanUSize i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
static TestStruct* element;
|
||||||
|
ZYAN_CHECK(ZyanVectorGetPointer(&vector, i, (const void**)&element));
|
||||||
|
if (element->u64 != buffer[i].u64)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZYAN_CHECK(PerformBasicTests(&vector));
|
||||||
|
ZYAN_CHECK(ZyanVectorClear(&vector));
|
||||||
|
ZYAN_CHECK(PerformBinarySearchTest(&vector));
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
return ZyanVectorDestroy(&vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Custom allocator */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static ZyanStatus AllocatorAllocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
|
||||||
|
ZyanUSize n)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(allocator);
|
||||||
|
ZYAN_ASSERT(p);
|
||||||
|
ZYAN_ASSERT(element_size);
|
||||||
|
ZYAN_ASSERT(n);
|
||||||
|
|
||||||
|
ZYAN_UNUSED(allocator);
|
||||||
|
|
||||||
|
*p = ZYAN_MALLOC(element_size * n);
|
||||||
|
if (!*p)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZyanStatus AllocatorReallocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
|
||||||
|
ZyanUSize n)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(allocator);
|
||||||
|
ZYAN_ASSERT(p);
|
||||||
|
ZYAN_ASSERT(element_size);
|
||||||
|
ZYAN_ASSERT(n);
|
||||||
|
|
||||||
|
ZYAN_UNUSED(allocator);
|
||||||
|
|
||||||
|
void* const x = ZYAN_REALLOC(*p, element_size * n);
|
||||||
|
if (!x)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
*p = x;
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZyanStatus AllocatorDeallocate(ZyanAllocator* allocator, void* p, ZyanUSize element_size,
|
||||||
|
ZyanUSize n)
|
||||||
|
{
|
||||||
|
ZYAN_ASSERT(allocator);
|
||||||
|
ZYAN_ASSERT(p);
|
||||||
|
ZYAN_ASSERT(element_size);
|
||||||
|
ZYAN_ASSERT(n);
|
||||||
|
|
||||||
|
ZYAN_UNUSED(allocator);
|
||||||
|
ZYAN_UNUSED(element_size);
|
||||||
|
ZYAN_UNUSED(n);
|
||||||
|
|
||||||
|
ZYAN_FREE(p);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs basic tests on a vector that dynamically manages memory using a custom
|
||||||
|
* allocator and modified growth-factor/shrink-threshold.
|
||||||
|
*
|
||||||
|
* @return A zyan status code.
|
||||||
|
*/
|
||||||
|
static ZyanStatus TestAllocator(void)
|
||||||
|
{
|
||||||
|
ZyanAllocator allocator;
|
||||||
|
ZYAN_CHECK(ZyanAllocatorInit(&allocator, &AllocatorAllocate, &AllocatorReallocate,
|
||||||
|
&AllocatorDeallocate));
|
||||||
|
|
||||||
|
// Initialize vector with a base capacity of `10` elements. Growth-factor is set to 10 and
|
||||||
|
// dynamic shrinking is disabled
|
||||||
|
ZyanVector vector;
|
||||||
|
ZYAN_CHECK(ZyanVectorInitEx(&vector, sizeof(TestStruct), 5, ZYAN_NULL, &allocator,
|
||||||
|
10.0f, 0.0f));
|
||||||
|
|
||||||
|
static TestStruct e_v;
|
||||||
|
|
||||||
|
// Insert `10` elements. The vector automatically manages its size
|
||||||
|
for (ZyanU32 i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
InitTestdata(&e_v, i);
|
||||||
|
ZYAN_CHECK(ZyanVectorPushBack(&vector, &e_v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check capacity
|
||||||
|
ZyanUSize value;
|
||||||
|
ZYAN_CHECK(ZyanVectorGetCapacity(&vector, &value));
|
||||||
|
if (value != 60) // (5 + 1) * 10.0f
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all elements
|
||||||
|
ZYAN_CHECK(ZyanVectorClear(&vector));
|
||||||
|
|
||||||
|
// Print infos
|
||||||
|
puts("INFO");
|
||||||
|
ZYAN_CHECK(ZyanVectorGetSize(&vector, &value));
|
||||||
|
printf(" Size : %08" PRIuPTR "\n", value);
|
||||||
|
ZYAN_CHECK(ZyanVectorGetCapacity(&vector, &value));
|
||||||
|
printf(" Capacity : %08" PRIuPTR "\n\n", value);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
return ZyanVectorDestroy(&vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Entry point */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
time_t t;
|
||||||
|
srand((unsigned)time(&t));
|
||||||
|
|
||||||
|
if (!ZYAN_SUCCESS(TestDynamic()))
|
||||||
|
{
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (!ZYAN_SUCCESS(TestStatic()))
|
||||||
|
{
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (!ZYAN_SUCCESS(TestAllocator()))
|
||||||
|
{
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
Binary file not shown.
@ -0,0 +1,128 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Core Library (Zycore-C)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
#include <Zycore/API/Memory.h>
|
||||||
|
|
||||||
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
#elif defined(ZYAN_POSIX)
|
||||||
|
# include <unistd.h>
|
||||||
|
#else
|
||||||
|
# error "Unsupported platform detected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Exported functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* General */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanU32 ZyanMemoryGetSystemPageSize()
|
||||||
|
{
|
||||||
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
SYSTEM_INFO system_info;
|
||||||
|
GetSystemInfo(&system_info);
|
||||||
|
|
||||||
|
return system_info.dwPageSize;
|
||||||
|
|
||||||
|
#elif defined(ZYAN_POSIX)
|
||||||
|
|
||||||
|
return sysconf(_SC_PAGE_SIZE);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanU32 ZyanMemoryGetSystemAllocationGranularity()
|
||||||
|
{
|
||||||
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
SYSTEM_INFO system_info;
|
||||||
|
GetSystemInfo(&system_info);
|
||||||
|
|
||||||
|
return system_info.dwAllocationGranularity;
|
||||||
|
|
||||||
|
#elif defined(ZYAN_POSIX)
|
||||||
|
|
||||||
|
return sysconf(_SC_PAGE_SIZE);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Memory management */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanMemoryVirtualProtect(void* address, ZyanUSize size,
|
||||||
|
ZyanMemoryPageProtection protection)
|
||||||
|
{
|
||||||
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
DWORD old;
|
||||||
|
if (!VirtualProtect(address, size, protection, &old))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(ZYAN_POSIX)
|
||||||
|
|
||||||
|
if (mprotect(address, size, protection))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanMemoryVirtualFree(void* address, ZyanUSize size)
|
||||||
|
{
|
||||||
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
ZYAN_UNUSED(size);
|
||||||
|
if (!VirtualFree(address, 0, MEM_RELEASE))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(ZYAN_POSIX)
|
||||||
|
|
||||||
|
if (munmap(address, size))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
@ -0,0 +1,68 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Core Library (Zycore-C)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
#include <Zycore/Defines.h>
|
||||||
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
# include <windows.h>
|
||||||
|
#elif defined(ZYAN_POSIX)
|
||||||
|
# include <sys/mman.h>
|
||||||
|
#else
|
||||||
|
# error "Unsupported platform detected"
|
||||||
|
#endif
|
||||||
|
#include <Zycore/API/Process.h>
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Exported functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* General */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanProcessFlushInstructionCache(void* address, ZyanUSize size)
|
||||||
|
{
|
||||||
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
if (!FlushInstructionCache(GetCurrentProcess(), address, size))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(ZYAN_POSIX)
|
||||||
|
|
||||||
|
if (msync(address, size, MS_SYNC | MS_INVALIDATE))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
@ -0,0 +1,200 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Core Library (Zycore-C)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
#include <Zycore/API/Synchronization.h>
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Internal functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Exported functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#if defined(ZYAN_POSIX)
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Critical Section */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionInitialize(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
pthread_mutexattr_t attribute;
|
||||||
|
|
||||||
|
int error = pthread_mutexattr_init(&attribute);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
if (error == ENOMEM)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
pthread_mutexattr_settype(&attribute, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
|
||||||
|
error = pthread_mutex_init(critical_section, &attribute);
|
||||||
|
pthread_mutexattr_destroy(&attribute);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
if (error == EAGAIN)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
if (error == ENOMEM)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
if (error == EPERM)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
if ((error == EBUSY) || (error == EINVAL))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionEnter(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
const int error = pthread_mutex_lock(critical_section);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
if (error == EINVAL)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
if (error == EAGAIN)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanBool ZyanCriticalSectionTryEnter(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
// No fine grained error handling for this one
|
||||||
|
return pthread_mutex_trylock(critical_section) ? ZYAN_FALSE : ZYAN_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionLeave(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
const int error = pthread_mutex_unlock(critical_section);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
if (error == EINVAL)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
if (error == EPERM)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionDelete(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
const int error = pthread_mutex_destroy(critical_section);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
if ((error == EBUSY) || (error == EINVAL))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#elif defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* General */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionInitialize(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
InitializeCriticalSection(critical_section);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionEnter(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(critical_section);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanBool ZyanCriticalSectionTryEnter(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
return TryEnterCriticalSection(critical_section) ? ZYAN_TRUE : ZYAN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionLeave(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(critical_section);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanCriticalSectionDelete(ZyanCriticalSection* critical_section)
|
||||||
|
{
|
||||||
|
DeleteCriticalSection(critical_section);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#else
|
||||||
|
# error "Unsupported platform detected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
@ -0,0 +1,156 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Core Library (Zycore-C)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
#include <Zycore/API/Terminal.h>
|
||||||
|
|
||||||
|
#if defined(ZYAN_POSIX)
|
||||||
|
# include <unistd.h>
|
||||||
|
#elif defined(ZYAN_WINDOWS)
|
||||||
|
# include <windows.h>
|
||||||
|
# include <io.h>
|
||||||
|
#else
|
||||||
|
# error "Unsupported platform detected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Provide fallback for old SDK versions
|
||||||
|
#ifdef ZYAN_WINDOWS
|
||||||
|
# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||||
|
# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Exported functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
ZyanStatus ZyanTerminalEnableVT100(ZyanStandardStream stream)
|
||||||
|
{
|
||||||
|
if ((stream != ZYAN_STDSTREAM_OUT) && (stream != ZYAN_STDSTREAM_ERR))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ZYAN_WINDOWS
|
||||||
|
// Get file descriptor
|
||||||
|
int file;
|
||||||
|
switch (stream)
|
||||||
|
{
|
||||||
|
case ZYAN_STDSTREAM_OUT:
|
||||||
|
file = _fileno(ZYAN_STDOUT);
|
||||||
|
break;
|
||||||
|
case ZYAN_STDSTREAM_ERR:
|
||||||
|
file = _fileno(ZYAN_STDERR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ZYAN_UNREACHABLE;
|
||||||
|
}
|
||||||
|
if (file < 0)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE const handle = (HANDLE)_get_osfhandle(file);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD mode;
|
||||||
|
if (!GetConsoleMode(handle, &mode))
|
||||||
|
{
|
||||||
|
// The given standard stream is not bound to a terminal
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
|
if (!SetConsoleMode(handle, mode))
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanTerminalIsTTY(ZyanStandardStream stream)
|
||||||
|
{
|
||||||
|
// Get file descriptor
|
||||||
|
int file;
|
||||||
|
#ifdef ZYAN_WINDOWS
|
||||||
|
switch (stream)
|
||||||
|
{
|
||||||
|
case ZYAN_STDSTREAM_IN:
|
||||||
|
file = _fileno(ZYAN_STDIN);
|
||||||
|
break;
|
||||||
|
case ZYAN_STDSTREAM_OUT:
|
||||||
|
file = _fileno(ZYAN_STDOUT);
|
||||||
|
break;
|
||||||
|
case ZYAN_STDSTREAM_ERR:
|
||||||
|
file = _fileno(ZYAN_STDERR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ZYAN_UNREACHABLE;
|
||||||
|
}
|
||||||
|
if (file < 0)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
switch (stream)
|
||||||
|
{
|
||||||
|
case ZYAN_STDSTREAM_IN:
|
||||||
|
file = STDIN_FILENO;
|
||||||
|
break;
|
||||||
|
case ZYAN_STDSTREAM_OUT:
|
||||||
|
file = STDOUT_FILENO;
|
||||||
|
break;
|
||||||
|
case ZYAN_STDSTREAM_ERR:
|
||||||
|
file = STDERR_FILENO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ZYAN_UNREACHABLE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ZYAN_WINDOWS
|
||||||
|
if (_isatty(file))
|
||||||
|
#else
|
||||||
|
if ( isatty(file))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_TRUE;
|
||||||
|
}
|
||||||
|
if (ZYAN_ERRNO == EBADF)
|
||||||
|
{
|
||||||
|
// Invalid file descriptor
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
//ZYAN_ASSERT((errno == EINVAL) || (errno == ENOTTY));
|
||||||
|
|
||||||
|
return ZYAN_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
@ -0,0 +1,194 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Core Library (Zycore-C)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
#include <Zycore/API/Thread.h>
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Internal functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Exported functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#if defined(ZYAN_POSIX)
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* General */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadGetCurrentThread(ZyanThread* thread)
|
||||||
|
{
|
||||||
|
*thread = pthread_self();
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZYAN_STATIC_ASSERT(sizeof(ZyanThreadId) <= sizeof(ZyanU64));
|
||||||
|
ZyanStatus ZyanThreadGetCurrentThreadId(ZyanThreadId* thread_id)
|
||||||
|
{
|
||||||
|
// TODO: Use `pthread_getthreadid_np` on platforms where it is available
|
||||||
|
|
||||||
|
pthread_t ptid = pthread_self();
|
||||||
|
*thread_id = *(ZyanThreadId*)ptid;
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Thread Local Storage */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsAlloc(ZyanThreadTlsIndex* index, ZyanThreadTlsCallback destructor)
|
||||||
|
{
|
||||||
|
ZyanThreadTlsIndex value;
|
||||||
|
const int error = pthread_key_create(&value, destructor);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
if (error == EAGAIN)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
if (error == ENOMEM)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*index = value;
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsFree(ZyanThreadTlsIndex index)
|
||||||
|
{
|
||||||
|
return !pthread_key_delete(index) ? ZYAN_STATUS_SUCCESS : ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsGetValue(ZyanThreadTlsIndex index, void** data)
|
||||||
|
{
|
||||||
|
*data = pthread_getspecific(index);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsSetValue(ZyanThreadTlsIndex index, void* data)
|
||||||
|
{
|
||||||
|
const int error = pthread_setspecific(index, data);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
if (error == EINVAL)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#elif defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* General */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadGetCurrentThread(ZyanThread* thread)
|
||||||
|
{
|
||||||
|
*thread = GetCurrentThread();
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadGetCurrentThreadId(ZyanThreadId* thread_id)
|
||||||
|
{
|
||||||
|
*thread_id = GetCurrentThreadId();
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Thread Local Storage (TLS) */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsAlloc(ZyanThreadTlsIndex* index, ZyanThreadTlsCallback destructor)
|
||||||
|
{
|
||||||
|
const ZyanThreadTlsIndex value = FlsAlloc(destructor);
|
||||||
|
if (value == FLS_OUT_OF_INDEXES)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
*index = value;
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsFree(ZyanThreadTlsIndex index)
|
||||||
|
{
|
||||||
|
return FlsFree(index) ? ZYAN_STATUS_SUCCESS : ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsGetValue(ZyanThreadTlsIndex index, void** data)
|
||||||
|
{
|
||||||
|
*data = FlsGetValue(index);
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZyanStatus ZyanThreadTlsSetValue(ZyanThreadTlsIndex index, void* data)
|
||||||
|
{
|
||||||
|
if (!FlsSetValue(index, data))
|
||||||
|
{
|
||||||
|
const DWORD error = GetLastError();
|
||||||
|
if (error == ERROR_INVALID_PARAMETER)
|
||||||
|
{
|
||||||
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
return ZYAN_STATUS_BAD_SYSTEMCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZYAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#else
|
||||||
|
# error "Unsupported platform detected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue