mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-29 12:15:39 +00:00
152 lines
5.3 KiB
C++
152 lines
5.3 KiB
C++
#include "prx/libc/include/ApplicationHeap.hpp"
|
|
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <cstddef>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <source_location>
|
|
#include <stdexcept>
|
|
#include <vector>
|
|
|
|
struct TestStack {
|
|
int num;
|
|
char** data;
|
|
int sorted;
|
|
int numAlloc;
|
|
void* comp;
|
|
};
|
|
|
|
extern "C" {
|
|
int APS5_VABI sk_num_nid_postfix(const TestStack*);
|
|
void* APS5_VABI sk_value_nid_postfix(const TestStack*, int);
|
|
void* APS5_VABI sk_pop_nid_postfix(TestStack*);
|
|
void APS5_VABI sk_pop_free_nid_postfix(TestStack*, void (APS5_VABI*)(void*));
|
|
void* APS5_VABI malloc_nid_postfix(std::size_t);
|
|
}
|
|
|
|
static void Require(bool condition, std::source_location location = std::source_location::current()) {
|
|
if (condition) return;
|
|
std::fprintf(stderr, "LibreSSL stack check failed at line %u\n", location.line());
|
|
std::abort();
|
|
}
|
|
|
|
template<typename TAction> static void RequireThrows(TAction action, std::source_location location = std::source_location::current()) {
|
|
try { action(); } catch (const std::exception&) { return; }
|
|
Require(false, location);
|
|
}
|
|
|
|
static void InitializeHeap() {
|
|
void* const api[10] {};
|
|
ApplicationHeapRegister_nid_no_patch(api);
|
|
}
|
|
|
|
static void TestNum() {
|
|
char first = 'a';
|
|
Require(sk_num_nid_postfix(nullptr) == -1);
|
|
TestStack stack {3, nullptr, 0, 0, nullptr};
|
|
char* elements[3] {&first, nullptr, &first};
|
|
stack.data = elements;
|
|
Require(sk_num_nid_postfix(&stack) == 3);
|
|
stack.num = 0;
|
|
Require(sk_num_nid_postfix(&stack) == 0);
|
|
stack.num = -2;
|
|
Require(sk_num_nid_postfix(&stack) == -2);
|
|
TestStack detached {2, nullptr, 0, 0, nullptr};
|
|
Require(sk_num_nid_postfix(&detached) == 2);
|
|
}
|
|
|
|
static void TestValue() {
|
|
char first = 'a';
|
|
char second = 'b';
|
|
char third = 'c';
|
|
Require(sk_value_nid_postfix(nullptr, 0) == nullptr);
|
|
char* elements[4] {&first, nullptr, &third, &second};
|
|
TestStack stack {3, elements, 0, 4, nullptr};
|
|
Require(sk_value_nid_postfix(&stack, 0) == &first);
|
|
Require(sk_value_nid_postfix(&stack, 1) == nullptr);
|
|
Require(sk_value_nid_postfix(&stack, 2) == &third);
|
|
Require(sk_value_nid_postfix(&stack, 3) == nullptr);
|
|
Require(sk_value_nid_postfix(&stack, -1) == nullptr);
|
|
stack.num = -2;
|
|
Require(sk_value_nid_postfix(&stack, 0) == nullptr);
|
|
TestStack detached {2, nullptr, 0, 0, nullptr};
|
|
Require(sk_value_nid_postfix(&detached, 2) == nullptr);
|
|
RequireThrows([&] { sk_value_nid_postfix(&detached, 1); });
|
|
}
|
|
|
|
static void TestPop() {
|
|
char first = 'a';
|
|
char third = 'c';
|
|
Require(sk_pop_nid_postfix(nullptr) == nullptr);
|
|
char* elements[8] {&first, nullptr, &third};
|
|
TestStack stack {3, elements, 0, 8, nullptr};
|
|
Require(sk_pop_nid_postfix(&stack) == &third);
|
|
Require(sk_num_nid_postfix(&stack) == 2 && stack.numAlloc == 8 && stack.data == elements && elements[2] == &third);
|
|
Require(sk_value_nid_postfix(&stack, 2) == nullptr);
|
|
Require(sk_pop_nid_postfix(&stack) == nullptr && sk_num_nid_postfix(&stack) == 1);
|
|
Require(sk_pop_nid_postfix(&stack) == &first && sk_num_nid_postfix(&stack) == 0);
|
|
Require(sk_pop_nid_postfix(&stack) == nullptr && sk_num_nid_postfix(&stack) == 0);
|
|
stack.num = -2;
|
|
Require(sk_pop_nid_postfix(&stack) == nullptr && sk_num_nid_postfix(&stack) == -2);
|
|
TestStack detached {2, nullptr, 0, 0, nullptr};
|
|
RequireThrows([&] { sk_pop_nid_postfix(&detached); });
|
|
Require(detached.num == 2);
|
|
}
|
|
|
|
static std::vector<void*> released;
|
|
|
|
static void APS5_VABI Release(void* element) {
|
|
released.push_back(element);
|
|
}
|
|
|
|
static TestStack* NewStack(std::vector<char*> elements, int capacity) {
|
|
auto* stack = static_cast<TestStack*>(malloc_nid_postfix(sizeof(TestStack)));
|
|
Require(stack != nullptr);
|
|
std::memset(stack, 0, sizeof(TestStack));
|
|
stack->data = static_cast<char**>(malloc_nid_postfix(sizeof(char*) * static_cast<std::size_t>(capacity > 0 ? capacity : 1)));
|
|
Require(stack->data != nullptr);
|
|
for (int index = 0; index < capacity; ++index) stack->data[index] = nullptr;
|
|
for (std::size_t index = 0; index < elements.size(); ++index) stack->data[index] = elements[index];
|
|
stack->num = static_cast<int>(elements.size());
|
|
stack->numAlloc = capacity;
|
|
return stack;
|
|
}
|
|
|
|
static void TestPopFree() {
|
|
char first = 'a';
|
|
char second = 'b';
|
|
char third = 'c';
|
|
sk_pop_free_nid_postfix(nullptr, Release);
|
|
sk_pop_free_nid_postfix(nullptr, nullptr);
|
|
Require(released.empty());
|
|
|
|
TestStack* stack = NewStack({&first, nullptr, &second, &third}, 4);
|
|
sk_pop_free_nid_postfix(stack, Release);
|
|
Require(released == std::vector<void*>({&first, &second, &third}));
|
|
released.clear();
|
|
|
|
stack = NewStack({nullptr, nullptr}, 2);
|
|
sk_pop_free_nid_postfix(stack, nullptr);
|
|
stack = NewStack({}, 0);
|
|
sk_pop_free_nid_postfix(stack, nullptr);
|
|
stack = NewStack({&first}, 1);
|
|
stack->num = -2;
|
|
sk_pop_free_nid_postfix(stack, nullptr);
|
|
Require(released.empty());
|
|
|
|
stack = NewStack({&first, &second}, 2);
|
|
RequireThrows([&] { sk_pop_free_nid_postfix(stack, nullptr); });
|
|
stack->data[0] = nullptr;
|
|
stack->data[1] = nullptr;
|
|
sk_pop_free_nid_postfix(stack, nullptr);
|
|
}
|
|
|
|
int main() {
|
|
InitializeHeap();
|
|
TestNum();
|
|
TestValue();
|
|
TestPop();
|
|
TestPopFree();
|
|
std::puts("libSceLibreSsl stack tests passed");
|
|
}
|