Rename cxx directory to cpp

Also update the crate name and references to it. This helps distinguish the C++ wrapper that's built using CXX from CXX itself.
This commit is contained in:
Oliver Hamlet
2025-04-29 17:42:46 +01:00
parent 2b1b67daba
commit 83d9420422
90 changed files with 34 additions and 36 deletions
+6
View File
@@ -0,0 +1,6 @@
# Config for building the CXX wrapper against the debug MSVC runtime, so that it
# can be used from Debug builds of C++ code.
# From <https://github.com/dtolnay/cxx/issues/880#issuecomment-2521375384>
[env]
CFLAGS = "/MDd"
CXXFLAGS = "/MDd"
+15
View File
@@ -0,0 +1,15 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -2
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortIfStatementsOnASingleLine: false
BinPackArguments: false
BinPackParameters: false
BreakConstructorInitializers: AfterColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
FixNamespaceComments: false
SpaceAfterTemplateKeyword: false
Standard: Cpp11
...
+1
View File
@@ -0,0 +1 @@
/build
+321
View File
@@ -0,0 +1,321 @@
cmake_minimum_required(VERSION 3.24)
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
endif()
project(libloot)
include(ExternalProject)
include(FetchContent)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
option(BUILD_SHARED_LIBS "Build a shared library" ON)
option(RUN_CLANG_TIDY "Whether or not to run clang-tidy during build. Has no effect when using CMake's MSVC generator." OFF)
option(LIBLOOT_BUILD_TESTS "Whether or not to build libloot's tests." ON)
option(LIBLOOT_INSTALL_DOCS "Whether or not to install libloot's docs (which need to be built separately)." ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
##############################
# External Projects
##############################
if(MSVC)
set(LIBLOOT_CPP_FILENAME "libloot_cpp.lib")
else()
set(LIBLOOT_CPP_FILENAME "liblibloot_cpp.a")
endif()
if(DEFINED RUST_TARGET)
set(TARGET_PATH "${CMAKE_SOURCE_DIR}/../target/${RUST_TARGET}")
else()
set(TARGET_PATH "${CMAKE_SOURCE_DIR}/../target")
endif()
add_custom_target(libloot-cpp-build
COMMAND cargo build
$<$<NOT:$<CONFIG:Debug>>:--release>
$<$<AND:$<CONFIG:Debug>,$<PLATFORM_ID:Windows>>:--config>
$<$<AND:$<CONFIG:Debug>,$<PLATFORM_ID:Windows>>:${CMAKE_SOURCE_DIR}/.cargo/msvc-debug-config.toml>
$<$<BOOL:${RUST_TARGET}>:--target>
$<$<BOOL:${RUST_TARGET}>:${RUST_TARGET}>
BYPRODUCTS
"${TARGET_PATH}/$<IF:$<CONFIG:Debug>,debug,release>/${LIBLOOT_CPP_FILENAME}"
"${TARGET_PATH}/cxxbridge/libloot-cpp/src/lib.rs.cc"
"${TARGET_PATH}/cxxbridge/libloot-cpp/src/lib.rs.h"
"${TARGET_PATH}/cxxbridge/rust/cxx.h"
)
add_library(libloot-cpp INTERFACE)
add_dependencies(libloot-cpp libloot-cpp-build)
target_link_libraries(libloot-cpp INTERFACE
optimized "${TARGET_PATH}/release/${LIBLOOT_CPP_FILENAME}"
debug "${TARGET_PATH}/debug/${LIBLOOT_CPP_FILENAME}")
target_include_directories(libloot-cpp INTERFACE "${TARGET_PATH}/cxxbridge")
##############################
# General Settings
##############################
set(LIBLOOT_SRC_API_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/api/api.cpp"
"${CMAKE_SOURCE_DIR}/src/api/convert.cpp"
"${CMAKE_SOURCE_DIR}/src/api/database.cpp"
"${CMAKE_SOURCE_DIR}/src/api/error_categories.cpp"
"${CMAKE_SOURCE_DIR}/src/api/exception.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/conditional_metadata.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/file.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/filename.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/group.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/location.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/message.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/message_content.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/plugin_cleaning_data.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/plugin_metadata.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/tag.cpp"
"${CMAKE_SOURCE_DIR}/src/api/game.cpp"
"${CMAKE_SOURCE_DIR}/src/api/plugin.cpp"
"${CMAKE_SOURCE_DIR}/src/api/sorting/cyclic_interaction_error.cpp"
"${CMAKE_SOURCE_DIR}/src/api/sorting/undefined_group_error.cpp"
"${CMAKE_SOURCE_DIR}/src/api/vertex.cpp")
set(LIBLOOT_INCLUDE_H_FILES
"${CMAKE_SOURCE_DIR}/include/loot/api.h"
"${CMAKE_SOURCE_DIR}/include/loot/api_decorator.h"
"${CMAKE_SOURCE_DIR}/include/loot/database_interface.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/error_categories.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/condition_syntax_error.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/cyclic_interaction_error.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/file_access_error.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/undefined_group_error.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/edge_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/game_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/log_level.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/message_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/game_interface.h"
"${CMAKE_SOURCE_DIR}/include/loot/loot_version.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/conditional_metadata.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/file.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/filename.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/group.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/location.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/message.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/message_content.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/plugin_cleaning_data.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/plugin_metadata.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/tag.h"
"${CMAKE_SOURCE_DIR}/include/loot/plugin_interface.h"
"${CMAKE_SOURCE_DIR}/include/loot/vertex.h")
set(LIBLOOT_SRC_API_H_FILES
"${CMAKE_SOURCE_DIR}/src/api/convert.h"
"${CMAKE_SOURCE_DIR}/src/api/database.h"
"${CMAKE_SOURCE_DIR}/src/api/exception.h"
"${CMAKE_SOURCE_DIR}/src/api/game.h"
"${CMAKE_SOURCE_DIR}/src/api/plugin.h")
source_group(TREE "${CMAKE_SOURCE_DIR}/src/api"
PREFIX "Source Files"
FILES ${LIBLOOT_SRC_API_CPP_FILES})
source_group(TREE "${CMAKE_SOURCE_DIR}/include"
PREFIX "Header Files"
FILES ${LIBLOOT_INCLUDE_H_FILES})
source_group(TREE "${CMAKE_SOURCE_DIR}/src/api"
PREFIX "Header Files"
FILES ${LIBLOOT_SRC_API_H_FILES})
set(LIBLOOT_ALL_SOURCES
${LIBLOOT_SRC_API_CPP_FILES}
${LIBLOOT_INCLUDE_H_FILES}
${LIBLOOT_SRC_API_H_FILES}
"${CMAKE_SOURCE_DIR}/src/api/resource.rc")
##############################
# Define Targets
##############################
# Build API.
add_library(loot ${LIBLOOT_ALL_SOURCES})
target_link_libraries(loot PRIVATE libloot-cpp)
##############################
# Set Target-Specific Flags
##############################
set(LIBLOOT_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/src"
"${CMAKE_SOURCE_DIR}/include")
set(LIBLOOT_COMMON_SYSTEM_INCLUDE_DIRS
${LIBLOADORDER_INCLUDE_DIRS}
${ESPLUGIN_INCLUDE_DIRS}
${LCI_INCLUDE_DIRS})
target_include_directories(loot PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_include_directories(loot PRIVATE ${LIBLOOT_INCLUDE_DIRS})
target_include_directories(loot SYSTEM PRIVATE
${LIBLOOT_COMMON_SYSTEM_INCLUDE_DIRS})
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_definitions(loot PRIVATE UNICODE _UNICODE LOOT_EXPORT)
set(LOOT_LIBS ntdll ws2_32 bcrypt)
target_link_libraries(loot PRIVATE ${LOOT_LIBS})
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(loot PRIVATE "-Wall" "-Wextra")
endif()
if(MSVC)
# Turn off permissive mode to be more standards-compliant and avoid compiler errors.
target_compile_options(loot PRIVATE "/permissive-" "/W4" "/Zc:__cplusplus" "/GL")
target_link_options(loot PRIVATE "/LTCG")
endif()
##############################
# Configure clang-tidy
##############################
if(RUN_CLANG_TIDY)
set(CLANG_TIDY_COMMON_CHECKS
"cppcoreguidelines-avoid-c-arrays"
"cppcoreguidelines-c-copy-assignment-signature"
"cppcoreguidelines-explicit-virtual-functions"
"cppcoreguidelines-init-variables"
"cppcoreguidelines-interfaces-global-init"
"cppcoreguidelines-macro-usage"
"cppcoreguidelines-narrowing-conventions"
"cppcoreguidelines-no-malloc"
"cppcoreguidelines-pro-bounds-array-to-pointer-decay"
"cppcoreguidelines-pro-bounds-constant-array-index"
"cppcoreguidelines-pro-bounds-pointer-arithmetic"
"cppcoreguidelines-pro-type-const-cast"
"cppcoreguidelines-pro-type-cstyle-cast"
"cppcoreguidelines-pro-type-member-init"
"cppcoreguidelines-pro-type-reinterpret-cast"
"cppcoreguidelines-pro-type-static-cast-downcast"
"cppcoreguidelines-pro-type-union-access"
"cppcoreguidelines-pro-type-vararg"
"cppcoreguidelines-pro-type-slicing")
set(CLANG_TIDY_LIB_CHECKS
${CLANG_TIDY_COMMON_CHECKS}
"cppcoreguidelines-avoid-goto"
"cppcoreguidelines-avoid-magic-numbers"
"cppcoreguidelines-non-private-member-variables-in-classes"
"cppcoreguidelines-special-member-functions")
list(JOIN CLANG_TIDY_LIB_CHECKS "," CLANG_TIDY_LIB_CHECKS_JOINED)
set(CLANG_TIDY_LIB
clang-tidy "-header-filter=.*" "-checks=${CLANG_TIDY_LIB_CHECKS_JOINED}")
set_target_properties(loot
PROPERTIES
CXX_CLANG_TIDY "${CLANG_TIDY_LIB}")
endif()
##############################
# Tests
##############################
if(LIBLOOT_BUILD_TESTS)
include("cmake/tests.cmake")
endif()
########################################
# Install
########################################
set(LIBLOOT_VERSION "0.26.0")
set_property(TARGET loot PROPERTY VERSION ${LIBLOOT_VERSION})
set_property(TARGET loot PROPERTY SOVERSION 0)
set_property(TARGET loot PROPERTY INTERFACE_libloot_MAJOR_VERSION 0)
set_property(TARGET loot APPEND PROPERTY COMPATIBLE_INTERFACE_STRING libloot_MAJOR_VERSION)
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/liblootConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libloot
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/liblootConfigVersion.cmake"
VERSION "${LIBLOOT_VERSION}"
COMPATIBILITY AnyNewerVersion
)
install(TARGETS loot
EXPORT liblootTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(MSVC)
install(FILES $<TARGET_PDB_FILE:loot>
DESTINATION ${CMAKE_INSTALL_LIBDIR}
OPTIONAL
CONFIGURATIONS RelWithDebInfo)
endif()
install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# TODO: Copy across the docs into this repository?
# if(LIBLOOT_INSTALL_DOCS)
# install(DIRECTORY "${CMAKE_BINARY_DIR}/docs/html/"
# DESTINATION ${CMAKE_INSTALL_DOCDIR})
# endif()
install(EXPORT liblootTargets
FILE liblootTargets.cmake
NAMESPACE libloot::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libloot)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/liblootConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/liblootConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libloot)
########################################
# CPack
########################################
if(NOT DEFINED CPACK_PACKAGE_VERSION)
find_package(Git)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --long --always --abbrev=7
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DESCRIBE_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
set(GIT_DESCRIBE_STRING "unknown-version")
endif()
set(CPACK_PACKAGE_VERSION ${GIT_DESCRIBE_STRING})
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(CPACK_GENERATOR "7Z")
else()
set(CPACK_GENERATOR "TXZ")
endif()
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package")
include(CPack)
+18
View File
@@ -0,0 +1,18 @@
[package]
name = "libloot-cpp"
version = "0.26.0"
edition = "2024"
license = "GPL-3.0"
[dependencies]
cxx = { version = "1.0", features = ["c++17"] }
delegate = "0.13.2"
libloot = { path = ".." }
libloot-ffi-errors = { path = "../ffi-errors" }
unicase = "2.8.1"
[build-dependencies]
cxx-build = "1.0"
[lib]
crate-type = ["staticlib"]
+77
View File
@@ -0,0 +1,77 @@
# libloot-rs C++ wrapper
This is an **experimental** wrapper around the Rust reimplementation of libloot that provides a C++ interface that's ABI-compatible with libloot v0.26.0.
The wrapper has two layers:
- a static library built using Cargo, which provides a C++ interface
- a shared library built using CMake, which wraps that C++ interface to provide another that is ABI-compatible with C++ libloot.
## Building
### Windows
To build a release build with debug info:
```
cmake -B build .
cmake --build build --parallel --config RelWithDebInfo
```
To build a debug build:
```
cmake -B build .
cmake --build build --parallel --config Debug
```
### Linux
To build a release build with debug info:
```
cmake -B build . -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build --parallel
```
to build a debug build:
```
cargo build
cmake -B build . -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel
```
### Tests & Packaging
The build process also builds a copy of the public API tests from C++ libloot v0.26.0 by default. To skip building the tests, pass `-DLIBLOOT_BUILD_TESTS=OFF` when first running CMake.
If built, the tests can be run using:
```
ctest --test-dir build --output-on-failure --parallel -V
```
To package the build:
```
cpack --config build/CPackConfig.cmake -C RelWithDebInfo
```
This repository (and so the created package) doesn't currently include any of libloot's documentation, besides the API documentation included in the Rust source code.
## Usage notes
For the first layer of the wrapper, built using Cargo:
- `LIBLOOT_VERSION_MAJOR`, `LIBLOOT_VERSION_MINOR` and `LIBLOOT_VERSION_PATCH` are exposed as `extern "C"` `static unsigned int` globals.
- CXX doesn't provide integration between Rust's `Option<_>` and C++'s `std::optional<T>`, so sentinel values are used to communicate the absence of a value in the wrapper's API:
- For `Option<&str>`, `None` is represented using an empty string, which is how it's already done for many metadata object fields in the C++ implementation of libloot.
- For `Option<f32>`, `None` is represented using `NaN`, since the C++ implementation of libloot's public API already says that `NaN` values get converted to `None`.
- Plugin CRCs (which are `Option<u32>` in Rust) are represented as `int64_t`, with `-1` representing `None`, since all `uint32_t` values are possibly valid CRCs.
- All Rust errors are converted to `::rust::Error` exceptions that have a `what()` string that is the concatenation of the error's display string and all its recursive source error display strings. For some errors the `what()` string also includes some data that is parsed by the wrapper's second layer to differentiate certain error types.
For the ABI-compatible second layer of the wrapper, built using CMake:
- Some exceptions have changed type: they all still derive from `std::exception`, but for example some `std::logic_error` and `std::invalid_argument` exceptions have become `std::runtime_error` and `FileAccessError` exceptions, some `YAML::RepresentationException` exceptions have become `FileAccessError` exceptions, etc.
- Exception messages are generally not expected to be the same between the two implementations.
+20
View File
@@ -0,0 +1,20 @@
fn main() {
cxx_build::bridge("src/lib.rs")
.std("c++17")
.flag_if_supported("/Zc:__cplusplus")
.flag_if_supported("/permissive-")
.compile("libloot-cpp");
// From <https://github.com/dtolnay/cxx/issues/880#issuecomment-2521375384>
if std::env::var("TARGET").is_ok_and(|s| s.contains("windows-msvc")) {
// MSVC compiler suite
if std::env::var("CFLAGS").is_ok_and(|s| s.contains("/MDd")) {
// debug runtime flag is set
// Don't link the default CRT
println!("cargo::rustc-link-arg=/nodefaultlib:msvcrt");
// Link the debug CRT instead
println!("cargo::rustc-link-arg=/defaultlib:msvcrtd");
}
}
}
+5
View File
@@ -0,0 +1,5 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/liblootTargets.cmake")
check_required_components(libloot)
+210
View File
@@ -0,0 +1,210 @@
##############################
# Dependencies
##############################
include(FetchContent)
include(GoogleTest)
set(BUILD_GMOCK OFF)
set(gtest_force_shared_crt ON)
set(INSTALL_GTEST OFF)
# Google Test doesn't have a scoped equivalent to BUILD_SHARED_LIBS, so set the
# global value and then set it back to the original value once Google Test has
# been configured.
set(BUILD_SHARED_LIBS_INITIAL ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF)
FetchContent_Declare(
GTest
URL "https://github.com/google/googletest/archive/refs/tags/v1.15.2.tar.gz"
URL_HASH "SHA256=7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926"
FIND_PACKAGE_ARGS)
FetchContent_Declare(
testing-plugins
URL "https://github.com/Ortham/testing-plugins/archive/1.6.2.tar.gz"
URL_HASH "SHA256=f6e5b55e2669993ab650ba470424b725d1fab71ace979134a77de3373bd55620")
FetchContent_MakeAvailable(GTest testing-plugins)
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_INITIAL})
##############################
# General Settings
##############################
set(LIBLOOT_SRC_TESTS_INTERNALS_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/main.cpp")
set(LIBLOOT_SRC_TESTS_INTERNALS_H_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/conditional_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/file_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/group_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/location_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/message_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/message_content_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_cleaning_data_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/tag_test.h")
set(LIBLOOT_SRC_TESTS_INTERFACE_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/main.cpp")
set(LIBLOOT_SRC_TESTS_INTERFACE_H_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/api_game_operations_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/create_game_handle_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/database_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/game_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/is_compatible_test.h")
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/internals"
PREFIX "Source Files"
FILES ${LIBLOOT_SRC_TESTS_INTERNALS_CPP_FILES})
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/internals"
PREFIX "Header Files"
FILES ${LIBLOOT_SRC_TESTS_INTERNALS_H_FILES})
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/interface"
PREFIX "Source Files"
FILES ${LIBLOOT_SRC_TESTS_INTERFACE_CPP_FILES})
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/interface"
PREFIX "Header Files"
FILES ${LIBLOOT_SRC_TESTS_INTERFACE_H_FILES})
set(LIBLOOT_INTERNALS_TESTS_ALL_SOURCES
${LIBLOOT_ALL_SOURCES}
${LIBLOOT_SRC_TESTS_INTERNALS_CPP_FILES}
${LIBLOOT_SRC_TESTS_INTERNALS_H_FILES}
"${CMAKE_SOURCE_DIR}/src/tests/common_game_test_fixture.h"
"${CMAKE_SOURCE_DIR}/src/tests/test_helpers.h"
"${CMAKE_SOURCE_DIR}/src/tests/printers.h")
set(LIBLOOT_INTERFACE_TESTS_ALL_SOURCES
${LIBLOOT_SRC_TESTS_INTERFACE_CPP_FILES}
${LIBLOOT_SRC_TESTS_INTERFACE_H_FILES}
"${CMAKE_SOURCE_DIR}/src/tests/common_game_test_fixture.h"
"${CMAKE_SOURCE_DIR}/src/tests/test_helpers.h"
"${CMAKE_SOURCE_DIR}/src/tests/printers.h")
##############################
# Define Targets
##############################
# Build tests.
add_executable(libloot_internals_tests ${LIBLOOT_INTERNALS_TESTS_ALL_SOURCES})
target_link_libraries(libloot_internals_tests PRIVATE
libloot-cpp
GTest::gtest_main)
# Build API tests.
add_executable(libloot_tests ${LIBLOOT_INTERFACE_TESTS_ALL_SOURCES})
add_dependencies(libloot_tests loot)
target_link_libraries(libloot_tests PRIVATE loot GTest::gtest_main)
enable_testing()
gtest_discover_tests(libloot_tests DISCOVERY_TIMEOUT 10)
##############################
# Set Target-Specific Flags
##############################
target_include_directories(libloot_internals_tests PRIVATE
${LIBLOOT_INCLUDE_DIRS})
target_include_directories(libloot_internals_tests SYSTEM PRIVATE
${LIBLOOT_COMMON_SYSTEM_INCLUDE_DIRS})
target_include_directories(libloot_tests PRIVATE ${LIBLOOT_INCLUDE_DIRS})
target_include_directories(libloot_tests SYSTEM PRIVATE
${LIBLOOT_COMMON_SYSTEM_INCLUDE_DIRS})
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_definitions(libloot_internals_tests PRIVATE
UNICODE _UNICODE LOOT_STATIC)
target_compile_definitions(libloot_tests PRIVATE UNICODE _UNICODE)
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
target_compile_definitions(libloot_tests PRIVATE LOOT_STATIC)
endif()
target_link_libraries(libloot_internals_tests PRIVATE ${LOOT_LIBS})
target_link_libraries(libloot_tests PRIVATE ${LOOT_LIBS})
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(libloot_internals_tests PRIVATE "-Wall" "-Wextra")
target_compile_options(libloot_tests PRIVATE "-Wall" "-Wextra")
endif()
if(MSVC)
# Turn off permissive mode to be more standards-compliant and avoid compiler errors.
target_compile_options(libloot_tests PRIVATE "/permissive-" "/W4" "/Zc:__cplusplus")
# Set /bigobj to allow building Debug and RelWithDebInfo tests
target_compile_options(libloot_internals_tests PRIVATE
"/permissive-"
"/W4"
"$<$<OR:$<CONFIG:DEBUG>,$<CONFIG:RelWithDebInfo>>:/bigobj>"
"/Zc:__cplusplus")
endif()
##############################
# Configure clang-tidy
##############################
if(RUN_CLANG_TIDY)
set(CLANG_TIDY_COMMON_CHECKS
"cppcoreguidelines-avoid-c-arrays"
"cppcoreguidelines-c-copy-assignment-signature"
"cppcoreguidelines-explicit-virtual-functions"
"cppcoreguidelines-init-variables"
"cppcoreguidelines-interfaces-global-init"
"cppcoreguidelines-macro-usage"
"cppcoreguidelines-narrowing-conventions"
"cppcoreguidelines-no-malloc"
"cppcoreguidelines-pro-bounds-array-to-pointer-decay"
"cppcoreguidelines-pro-bounds-constant-array-index"
"cppcoreguidelines-pro-bounds-pointer-arithmetic"
"cppcoreguidelines-pro-type-const-cast"
"cppcoreguidelines-pro-type-cstyle-cast"
"cppcoreguidelines-pro-type-member-init"
"cppcoreguidelines-pro-type-reinterpret-cast"
"cppcoreguidelines-pro-type-static-cast-downcast"
"cppcoreguidelines-pro-type-union-access"
"cppcoreguidelines-pro-type-vararg"
"cppcoreguidelines-pro-type-slicing")
# Skip some checks for tests because they're not worth the noise (e.g. GTest
# happens to use goto).
set(CLANG_TIDY_TEST_CHECKS ${CLANG_TIDY_COMMON_CHECKS})
list(JOIN CLANG_TIDY_TEST_CHECKS "," CLANG_TIDY_TEST_CHECKS_JOINED)
set(CLANG_TIDY_TEST
clang-tidy "-header-filter=.*" "-checks=${CLANG_TIDY_TEST_CHECKS_JOINED}")
set_target_properties(libloot_internals_tests libloot_tests
PROPERTIES
CXX_CLANG_TIDY "${CLANG_TIDY_TEST}")
endif()
##############################
# Post-Build Steps
##############################
# Copy testing plugins
add_custom_command(TARGET libloot_internals_tests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${testing-plugins_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/testing-plugins)
add_custom_command(TARGET libloot_tests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${testing-plugins_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/testing-plugins)
+124
View File
@@ -0,0 +1,124 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2013-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_API_H
#define LOOT_API_H
#include <filesystem>
#include <functional>
#include <memory>
#include <string>
#include <string_view>
#include "loot/api_decorator.h"
#include "loot/enum/game_type.h"
#include "loot/enum/log_level.h"
#include "loot/exception/condition_syntax_error.h"
#include "loot/exception/cyclic_interaction_error.h"
#include "loot/exception/error_categories.h"
#include "loot/exception/file_access_error.h"
#include "loot/exception/undefined_group_error.h"
#include "loot/game_interface.h"
#include "loot/loot_version.h"
namespace loot {
/**
* @}
* @name Logging Functions
* @{
*/
/**
* @brief Set the callback function that is called when logging.
* @param callback
* The function called when logging. The first parameter is the
* level of the message being logged, and the second is the message.
*/
LOOT_API void SetLoggingCallback(
std::function<void(LogLevel, std::string_view)> callback);
/**
* @brief Set the log severity level.
* @details The default level setting is trace. This function has no effect if
* no logging callback has been set.
* @param level
* Messages of this severity level and higher will be logged.
*/
LOOT_API void SetLogLevel(LogLevel level);
/**
* @}
* @name Version Functions
* @{
*/
/**
* @brief Checks for API compatibility.
* @details Checks whether the loaded API is compatible with the given
* version of the API, abstracting API stability policy away from
* clients. The version numbering used is major.minor.patch.
* @param major
* The major version number to check.
* @param minor
* The minor version number to check.
* @param patch
* The patch version number to check.
* @returns True if the API versions are compatible, false otherwise.
*/
LOOT_API bool IsCompatible(const unsigned int major,
const unsigned int minor,
const unsigned int patch);
/**
* @}
* @name Lifecycle Management Functions
* @{
*/
/**
* @brief Initialise a new game handle.
* @details Creates a handle for a game, which is then used by all
* game-specific functions.
* @param game
* A game code for which to create the handle.
* @param game_path
* The relative or absolute path to the directory containing the
* game's executable.
* @param game_local_path
* The relative or absolute path to the game's local data folder, or an
* empty path. The local data folder is usually in `%%LOCALAPPDATA%`, but
* Morrowind has no local data folder and OpenMW's is in the user's
* My Games folder on Windows and in `$HOME/.config` on Linux. If an
* empty path is provided, the API will attempt to look up the relevant
* local data path, which may fail in some situations (e.g. when running
* libloot natively on Linux for a game other than Morrowind or OpenMW).
* @returns The new game handle.
*/
LOOT_API std::unique_ptr<GameInterface> CreateGameHandle(
const GameType game,
const std::filesystem::path& game_path,
const std::filesystem::path& game_local_path = "");
}
#endif
+44
View File
@@ -0,0 +1,44 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2013-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_API_DECORATOR
#define LOOT_API_DECORATOR
/* set up dll import/export decorators
when compiling the dll on windows, ensure LOOT_EXPORT is defined. clients
that use this header do not need to define anything to import the symbols
properly. */
#if defined(_WIN32)
#ifdef LOOT_STATIC
#define LOOT_API
#elif defined LOOT_EXPORT
#define LOOT_API __declspec(dllexport)
#else
#define LOOT_API __declspec(dllimport)
#endif
#else
#define LOOT_API
#endif
#endif
+257
View File
@@ -0,0 +1,257 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_DATABASE_INTERFACE
#define LOOT_DATABASE_INTERFACE
#include <filesystem>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "loot/exception/cyclic_interaction_error.h"
#include "loot/metadata/group.h"
#include "loot/metadata/message.h"
#include "loot/metadata/plugin_metadata.h"
namespace loot {
/** @brief The interface provided by API's database handle. */
class DatabaseInterface {
public:
virtual ~DatabaseInterface() = default;
/**
* @name Data Reading & Writing
* @{
*/
/**
* @brief Loads the masterlist from the path specified.
* @details Can be called multiple times, each time replacing the
* previously-loaded data.
* @param masterlist_path
* The relative or absolute path to the masterlist file that should be
* loaded.
*/
virtual void LoadMasterlist(
const std::filesystem::path& masterlistPath) = 0;
/**
* @brief Loads the masterlist and masterlist prelude from the paths
specified.
* @details Can be called multiple times, each time replacing the
* previously-loaded data.
* @param masterlist_path
* The relative or absolute path to the masterlist file that should be
* loaded.
* @param masterlist_prelude_path
* The relative or absolute path to the masterlist prelude file that
* should be loaded.
*/
virtual void LoadMasterlistWithPrelude(
const std::filesystem::path& masterlistPath,
const std::filesystem::path& masterlistPreludePath) = 0;
/**
* @brief Loads the userlist from the path specified.
* @details Can be called multiple times, each time replacing the
* previously-loaded data.
* @param userlist_path
* The relative or absolute path to the userlist file that should be
* loaded.
*/
virtual void LoadUserlist(const std::filesystem::path& userlistPath) = 0;
/**
* Writes a metadata file containing all loaded user-added metadata.
* @param outputFile
* The path to which the file shall be written.
* @param overwrite
* If `false` and `outputFile` already exists, no data will be
* written. Otherwise, data will be written.
*/
virtual void WriteUserMetadata(const std::filesystem::path& outputFile,
const bool overwrite) const = 0;
/**
* @brief Writes a minimal metadata file that only contains plugins with
* Bash Tag suggestions and/or dirty info, plus the suggestions and
* info themselves.
* @param outputFile
* The path to which the file shall be written.
* @param overwrite
* If `false` and `outputFile` already exists, no data will be
* written. Otherwise, data will be written.
*/
virtual void WriteMinimalList(const std::filesystem::path& outputFile,
const bool overwrite) const = 0;
/**
* @brief Evaluate the given condition string.
* @param condition A condition string.
*/
virtual bool Evaluate(const std::string& condition) const = 0;
/**
* @}
* @name Non-plugin Data Access
* @{
*/
/**
* @brief Gets the Bash Tags that are listed in the loaded metadata lists.
* @details Bash Tag suggestions can include Bash Tags not in this list.
* @returns A set of Bash Tag names.
*/
virtual std::vector<std::string> GetKnownBashTags() const = 0;
/**
* @brief Get all general messages listen in the loaded metadata lists.
* @param evaluateConditions
* If true, any metadata conditions are evaluated before the metadata
* is returned, otherwise unevaluated metadata is returned. Evaluating
* general message conditions also clears the condition cache before
* evaluating conditions.
* @returns A vector of messages supplied in the metadata lists but not
* attached to any particular plugin.
*/
virtual std::vector<Message> GetGeneralMessages(
bool evaluateConditions = false) const = 0;
/**
* @brief Gets the groups that are defined in the loaded metadata lists.
* @param includeUserMetadata
* If true, any group metadata present in the userlist is included in
* the returned metadata, otherwise the metadata returned only includes
* metadata from the masterlist.
* @returns An vector of Group objects. Each Group's name is unique, if a
* group has masterlist and user metadata the two are merged into a
* single group object.
*/
virtual std::vector<Group> GetGroups(
bool includeUserMetadata = true) const = 0;
/**
* @brief Gets the groups that are defined or extended in the loaded userlist.
* @returns An unordered set of Group objects.
*/
virtual std::vector<Group> GetUserGroups() const = 0;
/**
* @brief Sets the group definitions to store in the userlist, overwriting any
* existing definitions there.
* @param groups
* The unordered set of Group objects to set.
*/
virtual void SetUserGroups(const std::vector<Group>& groups) = 0;
/**
* @brief Get the "shortest" path between the two given groups according to
* their load after metadata.
* @details The "shortest" path is defined as the path that maximises the
* amount of user metadata involved while minimising the amount of
* masterlist metadata involved. It's not the path involving the
* fewest groups.
* @param fromGroupName
* The name of the source group, that loads earlier.
* @param toGroupName
* The name of the destination group, that loads later.
* @returns A vector of Vertex elements representing the path from the source
* group to the destination group, or an empty vector if no path
* exists.
*/
virtual std::vector<Vertex> GetGroupsPath(
std::string_view fromGroupName,
std::string_view toGroupName) const = 0;
/**
* @}
* @name Plugin Data Access
* @{
*/
/**
* @brief Get all a plugin's loaded metadata.
* @param plugin
* The filename of the plugin to look up metadata for.
* @param includeUserMetadata
* If true, any user metadata the plugin has is included in the
* returned metadata, otherwise the metadata returned only includes
* metadata from the masterlist.
* @param evaluateConditions
* If true, any metadata conditions are evaluated before the metadata
* is returned, otherwise unevaluated metadata is returned. Evaluating
* plugin metadata conditions does not clear the condition cache.
* @returns If the plugin has metadata, an optional containing that metadata,
* otherwise an optional containing no value.
*/
virtual std::optional<PluginMetadata> GetPluginMetadata(
std::string_view plugin,
bool includeUserMetadata = true,
bool evaluateConditions = false) const = 0;
/**
* @brief Get a plugin's metadata loaded from the given userlist.
* @param plugin
* The filename of the plugin to look up user-added metadata for.
* @param evaluateConditions
* If true, any metadata conditions are evaluated before the metadata
* is returned, otherwise unevaluated metadata is returned. Evaluating
* plugin metadata conditions does not clear the condition cache.
* @returns If the plugin has user-added metadata, an optional containing
* that metadata, otherwise an optional containing no value.
*/
virtual std::optional<PluginMetadata> GetPluginUserMetadata(
std::string_view plugin,
bool evaluateConditions = false) const = 0;
/**
* @brief Sets a plugin's user metadata, overwriting any existing user
* metadata.
* @param pluginMetadata
* The user metadata you want to set, with plugin.Name() being the
* filename of the plugin the metadata is for.
*/
virtual void SetPluginUserMetadata(const PluginMetadata& pluginMetadata) = 0;
/**
* @brief Discards all loaded user metadata for the plugin with the given
* filename.
* @param plugin
* The filename of the plugin for which all user-added metadata
* should be deleted.
*/
virtual void DiscardPluginUserMetadata(std::string_view plugin) = 0;
/**
* @brief Discards all loaded user metadata for all plugins, and any
* user-added general messages and known bash tags.
*/
virtual void DiscardAllUserMetadata() = 0;
/** @} */
};
}
#endif
+53
View File
@@ -0,0 +1,53 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_EDGE_TYPE
#define LOOT_EDGE_TYPE
/**
* The namespace used by libloot.
*/
namespace loot {
/**
* @brief An enum representing the different possible types of interactions
* between plugins or groups.
*/
enum struct EdgeType : unsigned int {
hardcoded,
masterFlag,
master,
masterlistRequirement,
userRequirement,
masterlistLoadAfter,
userLoadAfter,
masterlistGroup,
userGroup,
recordOverlap,
assetOverlap,
tieBreak,
blueprintMaster,
};
}
#endif
+59
View File
@@ -0,0 +1,59 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_GAME_TYPE
#define LOOT_GAME_TYPE
/**
* The namespace used by libloot.
*/
namespace loot {
/** @brief Codes used to create database handles for specific games. */
enum struct GameType : unsigned int {
/** The Elder Scrolls IV: Oblivion */
tes4,
/** The Elder Scrolls V: Skyrim */
tes5,
/** Fallout 3 */
fo3,
/** Fallout: New Vegas */
fonv,
/** Fallout 4 */
fo4,
/** The Elder Scrolls V: Skyrim Special Edition */
tes5se,
/** Fallout 4 VR */
fo4vr,
/** Skyrim VR */
tes5vr,
/** The Elder Scrolls III: Morrowind */
tes3,
/** Starfield */
starfield,
/** OpenMW */
openmw
};
}
#endif
+45
View File
@@ -0,0 +1,45 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_LOG_LEVEL
#define LOOT_LOG_LEVEL
/**
* The namespace used by libloot.
*/
namespace loot {
/**
* @brief Codes used to specify different levels of API logging.
*/
enum struct LogLevel : unsigned int {
trace,
debug,
info,
warning,
error,
fatal
};
}
#endif
+49
View File
@@ -0,0 +1,49 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_MESSAGE_TYPE
#define LOOT_MESSAGE_TYPE
/**
* The namespace used by libloot.
*/
namespace loot {
/** @brief Codes used to indicate the type of a message. */
enum struct MessageType : unsigned int {
/** A notification message that is of no significant severity. */
say,
/**
* A warning message, used to indicate that an issue may be present that the
* user may wish to act on.
*/
warn,
/**
* An error message, used to indicate that an issue that requires user action
* is present.
*/
error,
};
}
#endif
@@ -0,0 +1,41 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_EXCEPTION_CONDITION_SYNTAX_ERROR
#define LOOT_EXCEPTION_CONDITION_SYNTAX_ERROR
#include <system_error>
namespace loot {
/**
* @brief An exception class thrown if invalid syntax is encountered when
* parsing a metadata condition.
*/
class ConditionSyntaxError : public std::system_error {
public:
using std::system_error::system_error;
};
}
#endif
@@ -0,0 +1,61 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_EXCEPTION_CYCLIC_INTERACTION_ERROR
#define LOOT_EXCEPTION_CYCLIC_INTERACTION_ERROR
#include <stdexcept>
#include <vector>
#include "loot/api_decorator.h"
#include "loot/vertex.h"
namespace loot {
/**
* @brief An exception class thrown if a cyclic interaction is detected when
* sorting a load order.
*/
class CyclicInteractionError : public std::runtime_error {
public:
/**
* @brief Construct an exception detailing a plugin or group graph cycle.
* @param cycle A representation of the cyclic path.
*/
LOOT_API CyclicInteractionError(std::vector<Vertex> cycle);
/**
* @brief Get a representation of the cyclic path.
* @details Each Vertex is the name of a graph element (plugin or group) and
* the type of the edge going to the next Vertex. The last Vertex
* has an edge going to the first Vertex.
* @return A vector of Vertex elements representing the cyclic path.
*/
LOOT_API std::vector<Vertex> GetCycle() const;
private:
std::vector<Vertex> cycle_;
};
}
#endif
@@ -0,0 +1,58 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_ERROR_CATEGORIES
#define LOOT_ERROR_CATEGORIES
#include <system_error>
#include "loot/api_decorator.h"
namespace loot {
/**
* @brief Get the error category that can be used to identify system_error
* exceptions that are due to esplugin errors.
* @returns A reference to the static object of unspecified runtime type,
* derived from std::error_category.
*/
LOOT_API const std::error_category& esplugin_category();
/**
* @brief Get the error category that can be used to identify system_error
* exceptions that are due to libloadorder errors.
* @returns A reference to the static object of unspecified runtime type,
* derived from std::error_category.
*/
LOOT_API const std::error_category& libloadorder_category();
/**
* @brief Get the error category that can be used to identify system_error
* exceptions that are due to loot condition interpreter errors.
* @returns A reference to the static object of unspecified runtime type,
* derived from std::error_category.
*/
LOOT_API const std::error_category& loot_condition_interpreter_category();
}
#endif
@@ -0,0 +1,41 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_EXCEPTION_FILE_ACCESS_ERROR
#define LOOT_EXCEPTION_FILE_ACCESS_ERROR
#include <stdexcept>
namespace loot {
/**
* @brief An exception class thrown if an error is encountered while reading or
* writing a file.
*/
class FileAccessError : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show More