5 Commits

Author SHA1 Message Date
Abdelrahman Said
f23f85e305 Update .gitignore 2024-10-07 08:04:47 +01:00
Abdelrahman Said
751192173f Implement very basic Str8 type 2024-10-07 08:03:56 +01:00
Abdelrahman Said
1108ed686e Switch to using snprintf instead of sprintf 2024-10-07 08:01:33 +01:00
36e88ba84d Remove old strings implementation 2024-10-06 22:41:43 +01:00
0617ca2316 Update compile script 2024-10-06 22:06:57 +01:00
80 changed files with 813 additions and 2921 deletions

2
.gitignore vendored
View File

@@ -9,5 +9,3 @@ test.*
compile_commands.json compile_commands.json
libwapp-build libwapp-build
libwapp.so libwapp.so
*.vs
__pycache__

View File

@@ -1,63 +0,0 @@
CC = clang
BUILD_TYPE = debug
CFLAGS = -Wall -Wextra -Werror -pedantic
LIBFLAGS = -fPIC -shared
KERNEL = $(shell uname -s)
MACHINE = $(shell uname -m)
PLATFORM = $(KERNEL)_$(MACHINE)
TEST_INCLUDE = -Isrc $(shell find tests -type d | xargs -I{} echo -n "-I{} ")
TEST_SRC = src/wapp.c $(shell find tests -type f -name "*.c" | xargs -I{} echo -n "{} ")
BUILD_DIR = libwapp-build/$(PLATFORM)-$(BUILD_TYPE)
LIB_OUT = $(BUILD_DIR)/libwapp.so
TEST_OUT = $(BUILD_DIR)/wapptest
ifeq ($(BUILD_TYPE),debug)
CFLAGS += -g -fsanitize=address,undefined
else ifeq ($(BUILD_TYPE),release)
CFLAGS += -O3
else
$(error Invalid BUILD type '$(BUILD_TYPE)'. Use 'debug' or 'release')
endif
ifeq ($(CC),gcc)
# Used to disable the "ASan runtime does not come first in initial library list" error when compiling with gcc
export ASAN_OPTIONS=verify_asan_link_order=0
endif
.PHONY: all clean builddir build-test run-test build-lib full prng testing uuid core containers
all: clean builddir run-test full
clean:
@rm -rf $(BUILD_DIR)
builddir:
@mkdir -p $(BUILD_DIR)
build-test:
$(CC) $(CFLAGS) $(TEST_INCLUDE) $(TEST_SRC) -o $(TEST_OUT)
run-test: build-test
@$(TEST_OUT)
@rm $(TEST_OUT)
build-lib:
$(CC) $(CFLAGS) $(LIBFLAGS) $(LIB_SRC) -o $(LIB_OUT)
full: LIB_SRC = src/wapp.c
full: build-lib
prng: LIB_SRC = src/prng/wapp_prng.c
prng: build-lib
testing: LIB_SRC = src/testing/wapp_testing.c
testing: build-lib
uuid: LIB_SRC = src/uuid/wapp_uuid.c
uuid: build-lib
core: LIB_SRC = src/core/wapp_core.c
core: build-lib
containers: LIB_SRC = src/core/wapp_containers.c
containers: build-lib

19
build
View File

@@ -1,20 +1,3 @@
#!/bin/bash #!/bin/bash
BUILD_TYPE="debug" bear -- ./compile $@
ARGS=""
while [[ $# > 0 ]];do
case $1 in
--release)
BUILD_TYPE="release"
shift
;;
*|-*|--*)
rest=("$@")
ARGS+=" ${rest[0]}"
shift
;;
esac
done
bear -- make BUILD_TYPE=$BUILD_TYPE $ARGS

View File

@@ -1,5 +1,5 @@
Param( Param(
[switch]$Release [switch]$Release
) )
$Compiler = "cl.exe" $Compiler = "cl.exe"
@@ -7,25 +7,21 @@ $Compiler = "cl.exe"
$GeneralFlags = "/Wall /WX /wd4996" $GeneralFlags = "/Wall /WX /wd4996"
$LibraryFlags = "/LD" $LibraryFlags = "/LD"
$Kernel = (Get-ChildItem Env:OS).Value $IncludeDirs = Get-ChildItem -Path src -Recurse -Directory -ErrorAction SilentlyContinue -Force | %{$("/I " + '"' + $_.FullName + '"')}
$Machine = (Get-ChildItem Env:PROCESSOR_ARCHITECTURE).Value $SrcFiles = Get-ChildItem -Path src -Recurse -Filter *.c -ErrorAction SilentlyContinue -Force | %{$('"' + $_.FullName + '"')}
$Platform = "${Kernel}_${Machine}"
$IncludeDirs = "/I src"
$SrcFiles = "src/wapp.c"
$TestIncludeDirs = Get-ChildItem -Path tests -Recurse -Directory -ErrorAction SilentlyContinue -Force | %{$("/I " + '"' + $_.FullName + '"')} $TestIncludeDirs = Get-ChildItem -Path tests -Recurse -Directory -ErrorAction SilentlyContinue -Force | %{$("/I " + '"' + $_.FullName + '"')}
$TestSrcFiles = Get-ChildItem -Path tests -Recurse -Filter *.c -ErrorAction SilentlyContinue -Force | %{$('"' + $_.FullName + '"')} $TestSrcFiles = Get-ChildItem -Path tests -Recurse -Filter *.c -ErrorAction SilentlyContinue -Force | %{$('"' + $_.FullName + '"')}
If ($Release -eq $True) { If ($Release -eq $True) {
$GeneralFlags += " /O2 /Og" $GeneralFlags += " /O2 /Og"
$BuildType = "release" $BuildType = "release"
} Else { } Else {
$GeneralFlags += " /Zi /Od /fsanitize=address" $GeneralFlags += " /Zi /Od /fsanitize=address"
$BuildType = "debug" $BuildType = "debug"
} }
$BuildDir = "./libwapp-build/${Platform}-${BuildType}" $BuildDir = "./libwapp-build/windows-$BuildType"
$ObjDir = "$BuildDir/objects" $ObjDir = "$BuildDir/objects"
$OutDir = "$BuildDir/output" $OutDir = "$BuildDir/output"
$TestsDir = "$BuildDir/tests" $TestsDir = "$BuildDir/tests"
@@ -38,16 +34,13 @@ $TestOutBasename = "wapptest"
$TestOutputs = "/Fo:$TestsDir/ /Fe:$TestsDir/$TestOutBasename" $TestOutputs = "/Fo:$TestsDir/ /Fe:$TestsDir/$TestOutBasename"
If (Test-Path $BuildDir) { If (Test-Path $BuildDir) {
Remove-Item $BuildDir -Recurse -Force Remove-Item $BuildDir -Recurse -Force
} }
mkdir -p $ObjDir > $null mkdir -p $ObjDir > $null
mkdir -p $OutDir > $null mkdir -p $OutDir > $null
mkdir -p $TestsDir > $null mkdir -p $TestsDir > $null
# Run code generation
Invoke-Expression "python3 -m codegen"
# Build and run tests # Build and run tests
Invoke-Expression "$Compiler $GeneralFlags $IncludeDirs $TestIncludeDirs $SrcFiles $TestSrcFiles $TestOutputs" -ErrorAction Stop Invoke-Expression "$Compiler $GeneralFlags $IncludeDirs $TestIncludeDirs $SrcFiles $TestSrcFiles $TestOutputs" -ErrorAction Stop
@@ -57,9 +50,9 @@ $Status = $LASTEXITCODE
Remove-Item $TestsDir -Recurse -Force Remove-Item $TestsDir -Recurse -Force
If ($Status -ne 0) { If ($Status -ne 0) {
Write-Error "Tests failed" Write-Error "Tests failed"
Exit 1 Exit 1
} }
# Build library # Build library
Invoke-Expression "$Compiler $GeneralFlags $LibraryFlags $SrcFiles $Objects $Outputs" Invoke-Expression "$Compiler $GeneralFlags $LibraryFlags $IncludeDirs $SrcFiles $Objects $Outputs"

61
compile Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/bash
BUILD_TYPE="debug"
while [[ $# > 0 ]];do
case $1 in
--release)
BUILD_TYPE="release"
shift
;;
*|-*|--*)
echo "Unknown option $1"
exit 1
;;
esac
done
CC=clang
CFLAGS="-Wall -Werror -pedantic"
LIBFLAGS="-fPIC -shared"
INCLUDE="$(find src -type d | xargs -I{} echo -n "-I{} ")"
SRC="$(find src -type f -name "*.c" | xargs -I{} echo -n "{} ")"
TEST_INCLUDE="$(find tests -type d | xargs -I{} echo -n "-I{} ")"
TEST_SRC="$(find tests -type f -name "*.c" | xargs -I{} echo -n "{} ")"
BUILD_DIR="libwapp-build/posix-$BUILD_TYPE"
if [[ -d $BUILD_DIR ]]; then
rm -rf $BUILD_DIR
fi
mkdir -p $BUILD_DIR
if [[ $BUILD_TYPE == "release" ]]; then
CFLAGS+=" -O3"
else
CFLAGS+=" -g -fsanitize=address -fsanitize=undefined"
fi
OUT="$BUILD_DIR/libwapp.so"
TEST_OUT="$BUILD_DIR/wapptest"
# Compile tests
if [[ $(echo $TEST_SRC | xargs) != "" ]]; then
(set -x ; $CC $CFLAGS $INCLUDE $TEST_INCLUDE $SRC $TEST_SRC -o $TEST_OUT)
fi
# Run tests and exit on failure
if [[ -f $TEST_OUT ]]; then
$TEST_OUT
STATUS="$?"
rm $TEST_OUT
if [[ $STATUS != "0" ]]; then
exit 1
fi
fi
# Compile library
(set -x ; $CC $CFLAGS $LIBFLAGS $INCLUDE $SRC -o $OUT)

View File

@@ -3,29 +3,25 @@
#include <stdint.h> #include <stdint.h>
#define c8 uint8_t #define u8 uint8_t
#define c16 uint16_t
#define c32 uint32_t
#define u8 uint8_t
#define u16 uint16_t #define u16 uint16_t
#define u32 uint32_t #define u32 uint32_t
#define u64 uint64_t #define u64 uint64_t
#define i8 int8_t #define i8 int8_t
#define i16 int16_t #define i16 int16_t
#define i32 int32_t #define i32 int32_t
#define i64 int64_t #define i64 int64_t
#define f32 float #define f32 float
#define f64 double #define f64 double
#define f128 long double #define f128 long double
#define uptr uintptr_t #define uptr uintptr_t
#define iptr intptr_t #define iptr intptr_t
#define external extern #define external extern
#define internal static #define internal static
#define persistent static #define persistent static
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -1,7 +1,7 @@
#ifndef MISC_UTILS_H #ifndef MISC_UTILS_H
#define MISC_UTILS_H #define MISC_UTILS_H
#include "../aliases/aliases.h" #include "aliases.h"
#define KB(SIZE) (SIZE * 1024ull) #define KB(SIZE) (SIZE * 1024ull)
#define MB(SIZE) (KB(SIZE) * 1024) #define MB(SIZE) (KB(SIZE) * 1024)

View File

@@ -1,8 +0,0 @@
#ifndef WAPP_COMMON_H
#define WAPP_COMMON_H
#include "aliases/aliases.h"
#include "misc/misc_utils.h"
#include "platform/platform.h"
#endif // !WAPP_COMMON_H

View File

@@ -1,209 +0,0 @@
#include "./dbl_list.h"
#include "../../common/aliases/aliases.h"
#include <stddef.h>
internal DBL_LIST(void) node_to_list(DBL_NODE(void) *node);
DBL_NODE(void) *_dbl_list_get(const DBL_LIST(void) *list, u64 index) {
if (index >= list->node_count) {
return NULL;
}
DBL_NODE(void) *output = NULL;
DBL_NODE(void) *current = list->first;
for (u64 i = 1; i <= index; ++i) {
current = current->next;
}
output = current;
return output;
}
void _dbl_list_push_front(DBL_LIST(void) *list, DBL_NODE(void) *node) {
if (!list || !node || !(node->item)) {
return;
}
DBL_LIST(void) node_list = node_to_list(node);
if (list->node_count == 0) {
*list = node_list;
return;
}
list->node_count += node_list.node_count;
DBL_NODE(void) *first = list->first;
if (first) {
first->prev = node_list.last;
}
list->first = node_list.first;
node_list.last->next = first;
}
void _dbl_list_push_back(DBL_LIST(void) *list, DBL_NODE(void) *node) {
if (!list || !node || !(node->item)) {
return;
}
DBL_LIST(void) node_list = node_to_list(node);
if (list->node_count == 0) {
*list = node_list;
return;
}
list->node_count += node_list.node_count;
DBL_NODE(void) *last = list->last;
if (last) {
last->next = node_list.first;
}
list->last = node_list.last;
node_list.first->prev = last;
}
void _dbl_list_insert(DBL_LIST(void) *list, DBL_NODE(void) *node, u64 index) {
if (!list || !node || !(node->item)) {
return;
}
if (index == 0) {
_dbl_list_push_front(list, node);
return;
} else if (index == list->node_count) {
_dbl_list_push_back(list, node);
return;
}
DBL_NODE(void) *dst_node = _dbl_list_get(list, index);
if (!dst_node) {
return;
}
DBL_LIST(void) node_list = node_to_list(node);
list->node_count += node_list.node_count;
DBL_NODE(void) *prev = dst_node->prev;
dst_node->prev = node_list.last;
prev->next = node_list.first;
node_list.first->prev = prev;
node_list.last->next = dst_node;
}
DBL_NODE(void) *_dbl_list_pop_front(DBL_LIST(void) *list) {
DBL_NODE(void) *output = NULL;
if (!list || list->node_count == 0) {
goto RETURN_STR8_LIST_POP_FRONT;
}
output = list->first;
if (list->node_count == 1) {
*list = (DBL_LIST(void)){0};
goto RETURN_STR8_LIST_POP_FRONT;
}
--(list->node_count);
list->first = output->next;
output->prev = output->next = NULL;
RETURN_STR8_LIST_POP_FRONT:
return output;
}
DBL_NODE(void) *_dbl_list_pop_back(DBL_LIST(void) *list) {
DBL_NODE(void) *output = NULL;
if (!list || list->node_count == 0) {
goto RETURN_STR8_LIST_POP_BACK;
}
output = list->last;
if (list->node_count == 1) {
*list = (DBL_LIST(void)){0};
goto RETURN_STR8_LIST_POP_BACK;
}
--(list->node_count);
list->last = output->prev;
output->prev = output->next = NULL;
RETURN_STR8_LIST_POP_BACK:
return output;
}
DBL_NODE(void) *_dbl_list_remove(DBL_LIST(void) *list, u64 index) {
DBL_NODE(void) *output = NULL;
if (!list) {
goto RETURN_STR8_LIST_REMOVE;
}
if (index == 0) {
output = _dbl_list_pop_front(list);
goto RETURN_STR8_LIST_REMOVE;
} else if (index == list->node_count) {
output = _dbl_list_pop_back(list);
goto RETURN_STR8_LIST_REMOVE;
}
output = _dbl_list_get(list, index);
if (!output) {
goto RETURN_STR8_LIST_REMOVE;
}
output->prev->next = output->next;
output->next->prev = output->prev;
--(list->node_count);
output->prev = output->next = NULL;
RETURN_STR8_LIST_REMOVE:
return output;
}
void _dbl_list_empty(DBL_LIST(void) *list) {
if (!list) {
return;
}
u64 count = list->node_count;
for (u64 i = 0; i < count; ++i) {
_dbl_list_pop_back(list);
}
}
internal DBL_LIST(void) node_to_list(DBL_NODE(void) *node) {
DBL_LIST(void) output = {.first = node, .last = node, .node_count = 1};
while (output.first->prev != NULL) {
output.first = output.first->prev;
++(output.node_count);
}
while (output.last->next != NULL) {
output.last = output.last->next;
++(output.node_count);
}
return output;
}

View File

@@ -1,75 +0,0 @@
#ifndef DBL_LIST_H
#define DBL_LIST_H
#include "../../common/aliases/aliases.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // !__cplusplus
#define DBL_NODE(T) T##Node
#define DBL_LIST(T) T##List
#define CAST_NODE(NODE) ((DBL_NODE(void))(NODE))
#define CAST_LIST(LIST) ((DBL_LIST(void))(LIST))
#define CAST_NODE_PTR(NODE_PTR) ((DBL_NODE(void)*)(NODE_PTR))
#define CAST_LIST_PTR(LIST_PTR) ((DBL_LIST(void)*)(LIST_PTR))
#define DBL_LIST_DECL(T) typedef struct DBL_NODE(T) DBL_NODE(T); \
struct DBL_NODE(T) { \
T *item; \
DBL_NODE(T) *prev; \
DBL_NODE(T) *next; \
}; \
\
typedef struct DBL_LIST(T) DBL_LIST(T); \
struct DBL_LIST(T) { \
DBL_NODE(T) *first; \
DBL_NODE(T) *last; \
u64 node_count; \
}
DBL_LIST_DECL(void);
#define wapp_dbl_list_node_from_item(T, ITEM_PTR) \
((DBL_NODE(T)){ .item = ITEM_PTR })
#define wapp_dbl_list_get(T, LIST_PTR, INDEX) \
(DBL_NODE(T)*)_dbl_list_get(CAST_LIST_PTR(LIST_PTR), INDEX)
#define wapp_dbl_list_push_front(LIST_PTR, NODE_PTR) \
_dbl_list_push_front(CAST_LIST_PTR(LIST_PTR), CAST_NODE_PTR(NODE_PTR))
#define wapp_dbl_list_push_back(LIST_PTR, NODE_PTR) \
_dbl_list_push_back(CAST_LIST_PTR(LIST_PTR), CAST_NODE_PTR(NODE_PTR))
#define wapp_dbl_list_insert(LIST_PTR, NODE_PTR, INDEX) \
_dbl_list_insert(CAST_LIST_PTR(LIST_PTR), CAST_NODE_PTR(NODE_PTR), INDEX)
#define wapp_dbl_list_pop_front(T, LIST_PTR) \
(DBL_NODE(T)*)_dbl_list_pop_front(CAST_LIST_PTR(LIST_PTR))
#define wapp_dbl_list_pop_back(T, LIST_PTR) \
(DBL_NODE(T)*)_dbl_list_pop_back(CAST_LIST_PTR(LIST_PTR))
#define wapp_dbl_list_remove(T, LIST_PTR, INDEX) \
(DBL_NODE(T)*)_dbl_list_remove(CAST_LIST_PTR(LIST_PTR), INDEX)
#define wapp_dbl_list_empty(LIST_PTR) \
_dbl_list_empty(CAST_LIST_PTR(LIST_PTR))
DBL_NODE(void) *_dbl_list_get(const DBL_LIST(void) *list, u64 index);
void _dbl_list_push_front(DBL_LIST(void) *list, DBL_NODE(void) *node);
void _dbl_list_push_back(DBL_LIST(void) *list, DBL_NODE(void) *node);
void _dbl_list_insert(DBL_LIST(void) *list, DBL_NODE(void) *node, u64 index);
DBL_NODE(void) *_dbl_list_pop_front(DBL_LIST(void) *list);
DBL_NODE(void) *_dbl_list_pop_back(DBL_LIST(void) *list);
DBL_NODE(void) *_dbl_list_remove(DBL_LIST(void) *list, u64 index);
void _dbl_list_empty(DBL_LIST(void) *list);
#ifdef __cplusplus
END_C_LINKAGE
#endif // !__cplusplus
#endif // !DBL_LIST_H

View File

@@ -1,6 +0,0 @@
#ifndef WAPP_CONTAINERS_C
#define WAPP_CONTAINERS_C
#include "dbl_list/dbl_list.c"
#endif // !WAPP_CONTAINERS_C

View File

@@ -1,7 +0,0 @@
#ifndef WAPP_CONTAINERS_H
#define WAPP_CONTAINERS_H
#include "dbl_list/dbl_list.h"
#include "../common/wapp_common.h"
#endif // !WAPP_CONTAINERS_H

View File

@@ -1,7 +1,12 @@
#include "mem_allocator.h" #include "mem_allocator.h"
#include "../../../common/aliases/aliases.h"
#include <stdlib.h> #include <stdlib.h>
/***************************************************************************/ //
////////////////////////////////////////////////////////////////////////////////
////// Allocator API definitions
////////////////////////////////////////////////////////////////////////////////
/***************************************************************************/ //
void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size) { void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size) {
if (!allocator || !(allocator->alloc)) { if (!allocator || !(allocator->alloc)) {
return NULL; return NULL;
@@ -35,10 +40,10 @@ void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr,
return allocator->realloc_aligned(ptr, old_size, new_size, alignment, allocator->obj); return allocator->realloc_aligned(ptr, old_size, new_size, alignment, allocator->obj);
} }
void wapp_mem_allocator_free(const Allocator *allocator, void **ptr, u64 size) { void wapp_mem_allocator_free(const Allocator *allocator, void **ptr) {
if (!allocator || !(allocator->free)) { if (!allocator || !(allocator->free)) {
return; return;
} }
allocator->free(ptr, size, allocator->obj); allocator->free(ptr, allocator->obj);
} }

View File

@@ -1,19 +1,29 @@
#ifndef MEM_ALLOCATOR_H #ifndef MEM_ALLOCATOR_H
#define MEM_ALLOCATOR_H #define MEM_ALLOCATOR_H
#include "../../../common/aliases/aliases.h" #include "aliases.h"
#include <string.h>
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
/***************************************************************************/ //
////////////////////////////////////////////////////////////////////////////////
////// Allocator function pointer types
////////////////////////////////////////////////////////////////////////////////
/***************************************************************************/ //
typedef void *(MemAllocFunc)(u64 size, void *alloc_obj); typedef void *(MemAllocFunc)(u64 size, void *alloc_obj);
typedef void *(MemAllocAlignedFunc)(u64 size, u64 alignment, void *alloc_obj); typedef void *(MemAllocAlignedFunc)(u64 size, u64 alignment, void *alloc_obj);
typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
typedef void *(MemReallocAlignedFunc)(void *ptr, u64 old_size, u64 new_size, u64 alignment, void *alloc_obj); typedef void *(MemReallocAlignedFunc)(void *ptr, u64 old_size, u64 new_size, u64 alignment, void *alloc_obj);
typedef void (MemFreeFunc)(void **ptr, u64 size, void *alloc_obj); typedef void(MemFreeFunc)(void **ptr, void *alloc_obj);
/***************************************************************************/ //
////////////////////////////////////////////////////////////////////////////////
////// Allocator type
////////////////////////////////////////////////////////////////////////////////
/***************************************************************************/ //
typedef struct allocator Allocator; typedef struct allocator Allocator;
struct allocator { struct allocator {
@@ -25,15 +35,18 @@ struct allocator {
MemFreeFunc *free; MemFreeFunc *free;
}; };
#define wapp_mem_allocator_invalid(ALLOCATOR) (memcmp(ALLOCATOR, &((Allocator){0}), sizeof(Allocator)) == 0) /***************************************************************************/ //
////////////////////////////////////////////////////////////////////////////////
////// Allocator API declarations
////////////////////////////////////////////////////////////////////////////////
/***************************************************************************/ //
void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size); void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size);
void *wapp_mem_allocator_alloc_aligned(const Allocator *allocator, u64 size, u64 alignment); void *wapp_mem_allocator_alloc_aligned(const Allocator *allocator, u64 size, u64 alignment);
void *wapp_mem_allocator_realloc(const Allocator *allocator, void *ptr, u64 old_size, u64 new_size); void *wapp_mem_allocator_realloc(const Allocator *allocator, void *ptr, u64 old_size, u64 new_size);
void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 old_size, void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 old_size,
u64 new_size, u64 alignment); u64 new_size, u64 alignment);
void wapp_mem_allocator_free(const Allocator *allocator, void **ptr, u64 size); void wapp_mem_allocator_free(const Allocator *allocator, void **ptr);
#ifdef __cplusplus #ifdef __cplusplus
END_C_LINKAGE END_C_LINKAGE

View File

@@ -1,7 +1,7 @@
#include "mem_arena.h" #include "mem_arena.h"
#include "../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../common/misc/misc_utils.h" #include "misc_utils.h"
#include "../../os/mem/mem_os.h" #include "mem_utils.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -73,13 +73,13 @@ void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
if (!(arena->committed)) { if (!(arena->committed)) {
wapp_mem_util_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start), output = (u8 *)wapp_mem_util_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start),
WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT, WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_UNINITIALISED); WAPP_MEM_INIT_INITIALISED);
} }
#endif // ifdef WAPP_PLATFORM_WINDOWS #else
memset(output, 0, size); memset(output, 0, size);
#endif // ifdef WAPP_PLATFORM_WINDOWS
return (void *)output; return (void *)output;
} }

View File

@@ -1,8 +1,8 @@
#ifndef MEM_ARENA_H #ifndef MEM_ARENA_H
#define MEM_ARENA_H #define MEM_ARENA_H
#include "../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../os/mem/mem_os.h" #include "mem_utils.h"
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -1,7 +1,11 @@
#include "mem_arena_allocator.h" #include "mem_arena_allocator.h"
#include "mem_arena.h" #include "mem_arena.h"
#include "../../../common/aliases/aliases.h"
#include "../../os/mem/mem_os.h" /***************************************************************************/ //
////////////////////////////////////////////////////////////////////////////////
////// Arena Allocator wrappers declarations
////////////////////////////////////////////////////////////////////////////////
/***************************************************************************/ //
internal inline void *mem_arena_alloc(u64 size, void *alloc_obj); internal inline void *mem_arena_alloc(u64 size, void *alloc_obj);
internal inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj); internal inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj);
@@ -9,6 +13,11 @@ internal inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, v
internal inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, internal inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj); void *alloc_obj);
/***************************************************************************/ //
////////////////////////////////////////////////////////////////////////////////
////// Arena Allocator API definitions
////////////////////////////////////////////////////////////////////////////////
/***************************************************************************/ //
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, bool zero_buffer) { Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, bool zero_buffer) {
Allocator allocator = {0}; Allocator allocator = {0};
@@ -34,6 +43,11 @@ void wapp_mem_arena_allocator_destroy(Allocator *allocator) {
*allocator = (Allocator){0}; *allocator = (Allocator){0};
} }
/***************************************************************************/ //
////////////////////////////////////////////////////////////////////////////////
////// Arena Allocator wrappers definitions
////////////////////////////////////////////////////////////////////////////////
/***************************************************************************/ //
internal inline void *mem_arena_alloc(u64 size, void *alloc_obj) { internal inline void *mem_arena_alloc(u64 size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;

View File

@@ -1,9 +1,9 @@
#ifndef MEM_ARENA_ALLOCATOR_H #ifndef MEM_ARENA_ALLOCATOR_H
#define MEM_ARENA_ALLOCATOR_H #define MEM_ARENA_ALLOCATOR_H
#include "../../../common/aliases/aliases.h" #include "aliases.h"
#include "../allocator/mem_allocator.h" #include "mem_utils.h"
#include "../../os/mem/mem_os.h" #include "mem_allocator.h"
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -0,0 +1,62 @@
#include "mem_libc_allocator.h"
#include "aliases.h"
#include "mem_allocator.h"
#include <stdlib.h>
#include <string.h>
internal inline void *mem_libc_alloc(u64 size, void *alloc_obj);
// TODO (Abdelrahman): aligned_alloc isn't implemented on Windows. Revisit later
#if 0
internal inline void *mem_libc_alloc_aligned(u64 size, u64 alignment, void *alloc_obj);
#endif
internal inline void *mem_libc_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
internal inline void mem_libc_free(void **ptr, void *alloc_obj);
Allocator wapp_mem_libc_allocator(void) {
return (Allocator){
.obj = NULL,
.alloc = mem_libc_alloc,
.alloc_aligned = NULL,
.realloc = mem_libc_realloc,
.realloc_aligned = NULL,
.free = mem_libc_free,
};
}
internal inline void *mem_libc_alloc(u64 size, void *alloc_obj) {
(void)alloc_obj; // Silence unused warnings
return calloc(1, size);
}
#if 0
internal inline void *mem_libc_alloc_aligned(u64 size, u64 alignment,
void *alloc_obj) {
(void)alloc_obj; // Silence unused warnings
void *output = aligned_alloc(alignment, size);
if (output) {
memset(output, 0, size);
}
return output;
}
#endif
internal inline void *mem_libc_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj) {
// Silence unused warnings
(void)alloc_obj;
(void)new_size;
return realloc(ptr, old_size);
}
internal inline void mem_libc_free(void **ptr, void *alloc_obj) {
(void)alloc_obj; // Silence unused warnings
if (!ptr || !(*ptr)) {
return;
}
free(*ptr);
*ptr = NULL;
}

View File

@@ -0,0 +1,16 @@
#ifndef MEM_LIBC_H
#define MEM_LIBC_H
#include "mem_allocator.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
Allocator wapp_mem_libc_allocator(void);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !MEM_LIBC_H

View File

@@ -1,28 +0,0 @@
#include "mem_utils.h"
#include "../../../common/aliases/aliases.h"
#include <stdbool.h>
#include <stddef.h>
#include <assert.h>
internal bool is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
if (!ptr) {
return NULL;
}
assert(is_power_of_two(alignment));
uptr p = (uptr)ptr;
uptr align = (uptr)alignment;
// Similar to p % align, but it's a faster implementation that works fine
// because align is guaranteed to be a power of 2
uptr modulo = p & (align - 1);
if (modulo != 0) {
p += align - modulo;
}
return (void *)p;
}

View File

@@ -1,16 +0,0 @@
#ifndef MEM_UTILS_H
#define MEM_UTILS_H
#include "../../../common/aliases/aliases.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
void *wapp_mem_util_align_forward(void *ptr, u64 alignment);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !MEM_UTILS_H

View File

@@ -1,134 +0,0 @@
#include "cpath.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/misc/misc_utils.h"
#include "../../mem/allocator/mem_allocator.h"
#include "../../mem/arena/mem_arena_allocator.h"
#include "../../strings/str8/str8.h"
#include "../../strings/str8/str8_list.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
u32 wapp_cpath_join_path(Str8 *dst, const DBL_LIST(Str8) *parts) {
if (!dst || !parts) {
return CPATH_JOIN_INVALID_ARGS;
}
if (parts->node_count == 0) {
return CPATH_JOIN_EMPTY_PARTS;
}
Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP);
u64 required_capacity = parts->node_count * separator.size + wapp_str8_list_total_size(parts);
if (dst->capacity < required_capacity) {
return CPATH_JOIN_INSUFFICIENT_DST_CAPACITY;
}
// Handle first node
const DBL_NODE(Str8) *first_node = wapp_dbl_list_get(Str8, parts, 0);
wapp_str8_copy_str8_capped(dst, first_node->item);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
const DBL_NODE(Str8) *node = first_node;
u64 node_index = 1;
bool running = true;
while (running && node->next) {
node = node->next;
if (node->item->size == 0) {
continue;
}
if (dst->size > 0) {
char dst_last = wapp_str8_get(dst, dst->size - 1);
char node_start = wapp_str8_get(node->item, 0);
bool add_path_sep = dst_last != PATH_SEP && node_start != PATH_SEP;
if (add_path_sep) {
wapp_str8_concat_capped(dst, &separator);
}
}
wapp_str8_concat_capped(dst, node->item);
++node_index;
running = node_index < parts->node_count;
}
return CPATH_JOIN_SUCCESS;
}
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
Str8 *output = NULL;
if (!allocator || !path) {
goto RETURN_DIRUP;
}
bool absolute = wapp_str8_get(path, 0) == PATH_SEP;
Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP);
if (path->size == 0) {
output = wapp_str8_alloc_buf(allocator, 16);
if (!output) {
goto RETURN_DIRUP;
}
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
goto RETURN_DIRUP;
}
if (levels < 1) {
output = wapp_str8_alloc_str8(allocator, path);
goto RETURN_DIRUP;
}
Allocator tmp_arena = wapp_mem_arena_allocator_init(MB(8));
if (wapp_mem_allocator_invalid(&tmp_arena)) {
goto RETURN_DIRUP;
}
DBL_LIST(Str8) *parts = wapp_str8_split(&tmp_arena, path, &separator);
if (!parts) {
goto RETURN_DIRUP;
}
if (levels >= parts->node_count) {
output = wapp_str8_alloc_buf(allocator, 16);
if (!output) {
goto LIST_CLEANUP_DIRUP;
}
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
} else {
for (u64 i = 0; i < levels; ++i) {
wapp_dbl_list_pop_back(Str8, parts);
}
u64 alignment = sizeof(void *) * 2;
u64 alloc_size = wapp_str8_list_total_size(parts) + parts->node_count * separator.size;
u64 modulo = alloc_size & (alignment - 1);
alloc_size += alignment - modulo;
output = wapp_str8_alloc_buf(allocator, alloc_size);
if (output) {
if (absolute) {
wapp_str8_push_back(output, PATH_SEP);
}
Str8 *joined = wapp_str8_join(&tmp_arena, parts, &separator);
if (joined) {
wapp_str8_concat_capped(output, joined);
}
}
}
LIST_CLEANUP_DIRUP:
wapp_mem_arena_allocator_destroy(&tmp_arena);
RETURN_DIRUP:
return output;
}

View File

@@ -1,38 +0,0 @@
#ifndef CPATH_H
#define CPATH_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include "../../mem/allocator/mem_allocator.h"
#include "../../strings/str8/str8.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
#ifdef WAPP_PLATFORM_POSIX
#define PATH_SEP '/'
#elif defined(WAPP_PLATFORM_WINDOWS)
#define PATH_SEP '\\'
#else
#error "Unrecognised platform"
#endif
#define wapp_cpath_dirname(ALLOCATOR, PATH) dirup(ALLOCATOR, PATH, 1)
#define wapp_cpath_dirup(ALLOCATOR, PATH, COUNT) dirup(ALLOCATOR, PATH, COUNT)
enum {
CPATH_JOIN_SUCCESS = 0,
CPATH_JOIN_INVALID_ARGS,
CPATH_JOIN_EMPTY_PARTS,
CPATH_JOIN_INSUFFICIENT_DST_CAPACITY,
};
u32 wapp_cpath_join_path(Str8 *dst, const DBL_LIST(Str8) *parts);
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !CPATH_H

View File

@@ -1,29 +0,0 @@
#include "mem_os.h"
#include "mem_os_ops.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#if defined(WAPP_PLATFORM_WINDOWS)
#include "win/mem_os_win.h"
#elif defined(WAPP_PLATFORM_POSIX)
#include "posix/mem_os_posix.h"
#else
#error "Unrecognised platform"
#endif
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
void *output = mem_util_allocate(addr, size, access, flags, type);
if (type == WAPP_MEM_INIT_INITIALISED) {
memset(output, 0, size);
}
return output;
}
void wapp_mem_util_free(void *ptr, u64 size) {
mem_util_free(ptr, size);
}

View File

@@ -1,99 +0,0 @@
#include "commander.h"
#include "commander_output.h"
#include "../utils/shell_utils.h"
#include "../../../mem/allocator/mem_allocator.h"
#include "../../../mem/arena/mem_arena_allocator.h"
#include "../../../strings/str8/str8.h"
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/misc/misc_utils.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CMD_BUF_LEN 8192
#define OUT_BUF_LEN 4096
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf);
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf);
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const DBL_LIST(Str8) *cmd) {
if (!cmd) {
return CMD_NO_EXIT(SHELL_ERR_INVALID_ARGS);
}
Allocator arena = wapp_mem_arena_allocator_init(KB(500));
Str8 *cmd_str = wapp_str8_join(&arena, cmd, &wapp_str8_lit_ro(" "));
if (!cmd_str) {
wapp_mem_arena_allocator_destroy(&arena);
return CMD_NO_EXIT(SHELL_ERR_ALLOCATION_FAIL);
}
// Redirect output
cmd_str = wapp_str8_alloc_concat(&arena, cmd_str, &wapp_str8_lit_ro(" 2>&1"));
CMDResult output = execute_command(cmd_str, out_handling, out_buf);
wapp_mem_arena_allocator_destroy(&arena);
return output;
}
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) {
char cmd_buf[CMD_BUF_LEN] = {0};
wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN);
FILE *fp = wapp_shell_utils_popen(cmd_buf, "r");
if (!fp) {
return CMD_NO_EXIT(SHELL_ERR_PROC_START_FAIL);
}
CMDResult output;
CMDError err = get_command_output(fp, out_handling, out_buf);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
i32 st = EXIT_SUCCESS;
err = get_output_status(fp, &st);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
// Process is already closed in get_output_status
fp = NULL;
output = (CMDResult){
.exited = true,
.exit_code = st,
.error = SHELL_ERR_NO_ERROR,
};
EXECUTE_COMMAND_CLOSE:
if (fp) {
wapp_shell_utils_pclose(fp);
}
return output;
}
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) {
Str8 out = wapp_str8_buf(OUT_BUF_LEN);
out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp);
if (out_handling == SHELL_OUTPUT_CAPTURE && out_buf != NULL) {
if (out.size >= out_buf->capacity) {
return SHELL_ERR_OUT_BUF_FULL;
}
wapp_str8_concat_capped(out_buf, &out);
} else if (out_handling == SHELL_OUTPUT_PRINT) {
printf(WAPP_STR8_SPEC, wapp_str8_varg(out));
}
return SHELL_ERR_NO_ERROR;
}

View File

@@ -1,34 +0,0 @@
#include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h"
#include "../../../../strings/str8/str8.h"
#ifdef WAPP_PLATFORM_POSIX
#include "../terminal_colours.h"
#include <stdio.h>
internal Str8RO colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[30m"),
[WAPP_TERM_COLOUR_FG_RED] = wapp_str8_lit_ro_initialiser_list("\033[31m"),
[WAPP_TERM_COLOUR_FG_GREEN] = wapp_str8_lit_ro_initialiser_list("\033[32m"),
[WAPP_TERM_COLOUR_FG_BLUE] = wapp_str8_lit_ro_initialiser_list("\033[34m"),
[WAPP_TERM_COLOUR_FG_CYAN] = wapp_str8_lit_ro_initialiser_list("\033[36m"),
[WAPP_TERM_COLOUR_FG_MAGENTA] = wapp_str8_lit_ro_initialiser_list("\033[35m"),
[WAPP_TERM_COLOUR_FG_YELLOW] = wapp_str8_lit_ro_initialiser_list("\033[33m"),
[WAPP_TERM_COLOUR_FG_WHITE] = wapp_str8_lit_ro_initialiser_list("\033[37m"),
[WAPP_TERM_COLOUR_FG_BR_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[90m"),
[WAPP_TERM_COLOUR_FG_BR_RED] = wapp_str8_lit_ro_initialiser_list("\033[91m"),
[WAPP_TERM_COLOUR_FG_BR_GREEN] = wapp_str8_lit_ro_initialiser_list("\033[92m"),
[WAPP_TERM_COLOUR_FG_BR_BLUE] = wapp_str8_lit_ro_initialiser_list("\033[94m"),
[WAPP_TERM_COLOUR_FG_BR_CYAN] = wapp_str8_lit_ro_initialiser_list("\033[96m"),
[WAPP_TERM_COLOUR_FG_BR_MAGENTA] = wapp_str8_lit_ro_initialiser_list("\033[95m"),
[WAPP_TERM_COLOUR_FG_BR_YELLOW] = wapp_str8_lit_ro_initialiser_list("\033[93m"),
[WAPP_TERM_COLOUR_FG_BR_WHITE] = wapp_str8_lit_ro_initialiser_list("\033[97m"),
[WAPP_TERM_COLOUR_CLEAR] = wapp_str8_lit_ro_initialiser_list("\033[0m"),
};
void print_coloured_text(Str8RO *text, TerminalColour colour) {
printf(WAPP_STR8_SPEC WAPP_STR8_SPEC, wapp_str8_varg(colours[colour]), wapp_str8_varg((*text)));
}
#endif // !WAPP_PLATFORM_POSIX

View File

@@ -1,437 +1,27 @@
#include "str8.h" #include "str8.h"
#include "str8_list.h"
#include "../../../common/aliases/aliases.h"
#include "../../../containers/dbl_list/dbl_list.h"
#include "../../mem/allocator/mem_allocator.h"
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#define STR8_BUF_ALLOC_SIZE(CAPACITY) (sizeof(Str8) + sizeof(c8) * CAPACITY) Str8 wapp_str8_lit(char *str) {
Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity) {
Str8 *str = NULL;
if (!allocator) {
goto RETURN_STR8;
}
str = wapp_mem_allocator_alloc(allocator, STR8_BUF_ALLOC_SIZE(capacity));
if (!str) { if (!str) {
goto RETURN_STR8; return (Str8){.capacity = 0, .size = 0, .buf = (u8 *)""};
} }
str->buf = (u8 *)str + sizeof(Str8); u64 size = strlen(str);
str->size = 0; return (Str8){.capacity = size, .size = size, .buf = (u8 *)str};
str->capacity = capacity;
RETURN_STR8:
return str;
} }
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str) { char wapp_str8_get(const Str8 *str, u64 index) {
Str8 *output = NULL;
if (!allocator || !str) {
goto RETURN_ALLOC_CSTR;
}
u64 length = strlen(str);
output = wapp_str8_alloc_buf(allocator, length * 2);
if (!output) {
goto RETURN_ALLOC_CSTR;
}
output->size = length;
memcpy(output->buf, str, length);
RETURN_ALLOC_CSTR:
return output;
}
Str8 *wapp_str8_alloc_str8(const Allocator *allocator, Str8RO *str) {
Str8 *output = NULL;
if (!allocator || !str) {
goto RETURN_ALLOC_STR8;
}
output = wapp_str8_alloc_buf(allocator, str->capacity);
if (!output) {
goto RETURN_ALLOC_STR8;
}
output->size = str->size;
memcpy(output->buf, str->buf, str->size);
RETURN_ALLOC_STR8:
return output;
}
Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end) {
Str8 *output = NULL;
if (!allocator || !str) {
goto RETURN_ALLOC_SUBSTR;
}
if (start >= str->size || start >= end) {
goto RETURN_ALLOC_SUBSTR;
}
if (end > str->size) {
end = str->size;
}
output = wapp_str8_alloc_buf(allocator, str->capacity);
if (!output) {
goto RETURN_ALLOC_SUBSTR;
}
output->size = end - start;
memcpy(output->buf, str->buf + start, output->size);
RETURN_ALLOC_SUBSTR:
return output;
}
void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str) {
if (!allocator || !str || !(*str)) {
return;
}
wapp_mem_allocator_free(allocator, (void **)str, STR8_BUF_ALLOC_SIZE((*str)->capacity));
}
c8 wapp_str8_get(const Str8 *str, u64 index) {
if (index >= str->size) { if (index >= str->size) {
return '\0'; return '\0';
} }
return str->buf[index]; return (char)(str->buf[index]);
} }
void wapp_str8_set(Str8 *str, u64 index, c8 c) { void wapp_str8_set(Str8 *str, u64 index, char c) {
if (index >= str->size) { if (index >= str->size) {
return; return;
} }
str->buf[index] = c; str->buf[index] = (u8)c;
}
void wapp_str8_push_back(Str8 *str, c8 c) {
if (!(str->size < str->capacity)) {
return;
}
u64 index = (str->size)++;
wapp_str8_set(str, index, c);
}
bool wapp_str8_equal(Str8RO *s1, Str8RO *s2) {
if (s1->size != s2->size) {
return false;
}
return wapp_str8_equal_to_count(s1, s2, s1->size);
}
bool wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) {
if (!s1 || !s2) {
return false;
}
return memcmp(s1->buf, s2->buf, count) == 0;
}
Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end) {
if (start >= str->size || start >= end) {
start = str->size;
end = str->size;
}
if (end > str->size) {
end = str->size;
}
return (Str8RO){
.capacity = end - start,
.size = end - start,
.buf = str->buf + start,
};
}
Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src) {
if (!allocator || !dst || !src) {
return NULL;
}
Str8 *output = NULL;
u64 remaining = dst->capacity - dst->size;
if (src->size <= remaining) {
output = dst;
goto COPY_STRING_STR8_CONCAT;
}
u64 capacity = dst->capacity + src->size;
output = wapp_str8_alloc_buf(allocator, capacity);
if (!output) {
goto RETURN_STR8_CONCAT;
}
wapp_str8_concat_capped(output, dst);
COPY_STRING_STR8_CONCAT:
wapp_str8_concat_capped(output, src);
RETURN_STR8_CONCAT:
return output;
}
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) {
if (!dst || !src) {
return;
}
u64 remaining = dst->capacity - dst->size;
u64 to_copy = remaining < src->size ? remaining : src->size;
memcpy(dst->buf + dst->size, src->buf, to_copy);
dst->size += to_copy;
}
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *src) {
if (!dst || !src) {
return;
}
u64 length = strlen(src);
u64 to_copy = length <= dst->capacity ? length : dst->capacity;
memset(dst->buf, 0, dst->size);
memcpy(dst->buf, src, to_copy);
dst->size = to_copy;
}
void wapp_str8_copy_str8_capped(Str8 *dst, Str8RO *src) {
if (!dst || !src) {
return;
}
u64 to_copy = src->size <= dst->capacity ? src->size : dst->capacity;
memset(dst->buf, 0, dst->size);
memcpy(dst->buf, src->buf, to_copy);
dst->size = to_copy;
}
void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity) {
if (!dst || !src) {
return;
}
u64 to_copy = src->size < dst_capacity ? src->size : dst_capacity - 1;
memset(dst, 0, dst_capacity);
memcpy(dst, src->buf, to_copy);
}
void wapp_str8_format(Str8 *dst, const char *format, ...) {
if (!dst || !format) {
return;
}
va_list args1;
va_list args2;
va_start(args1, format);
va_copy(args2, args1);
u64 total_size = vsnprintf(NULL, 0, format, args1);
dst->size = total_size <= dst->capacity ? total_size : dst->capacity;
vsnprintf((char *)(dst->buf), dst->capacity, format, args2);
va_end(args1);
va_end(args2);
}
i64 wapp_str8_find(Str8RO *str, Str8RO substr) {
if (!str || substr.size > str->size) {
return -1;
}
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 char_index = 0;
bool running = true;
while (running) {
const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) {
return char_index;
}
++char_index;
running = char_index < str->size;
}
return -1;
}
i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
if (!str || substr.size > str->size) {
return -1;
}
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
i64 char_index = str->size - substr.size;
bool running = true;
while (running) {
const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) {
return char_index;
}
--char_index;
running = char_index >= 0;
}
return -1;
}
DBL_LIST(Str8) *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
if (!allocator || !str || !delimiter) {
return NULL;
}
DBL_LIST(Str8) *output = wapp_mem_allocator_alloc(allocator, sizeof(DBL_LIST(Str8)));
if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str);
DBL_NODE(Str8) *node = wapp_mem_allocator_alloc(allocator, sizeof(DBL_NODE(Str8)));
if (node) {
node->item = full;
wapp_dbl_list_push_back(output, node);
}
goto RETURN_STR8_SPLIT;
}
i64 start = 0;
i64 end = 0;
i64 splits = 0;
Str8 *rest = wapp_str8_alloc_str8(allocator, str);
Str8 *before_str;
while ((end = wapp_str8_find(rest, *delimiter)) != -1) {
if (max_splits > 0 && splits >= max_splits) {
break;
}
before_str = wapp_str8_alloc_substr(allocator, str, start, start + end);
DBL_NODE(Str8) *node = wapp_mem_allocator_alloc(allocator, sizeof(DBL_NODE(Str8)));
if (node) {
node->item = before_str;
wapp_dbl_list_push_back(output, node);
}
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
rest = wapp_str8_alloc_substr(allocator, str, start + end + delimiter->size, str->size);
start += end + delimiter->size;
++splits;
}
// Ensure the last part of the string after the delimiter is added to the list
rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
DBL_NODE(Str8) *node = wapp_mem_allocator_alloc(allocator, sizeof(DBL_NODE(Str8)));
if (node) {
node->item = rest;
wapp_dbl_list_push_back(output, node);
}
RETURN_STR8_SPLIT:
return output;
}
DBL_LIST(Str8) *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
if (!allocator || !str || !delimiter) {
return NULL;
}
DBL_LIST(Str8) *output = wapp_mem_allocator_alloc(allocator, sizeof(DBL_LIST(Str8)));
if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str);
DBL_NODE(Str8) *node = wapp_mem_allocator_alloc(allocator, sizeof(DBL_NODE(Str8)));
if (node) {
node->item = full;
wapp_dbl_list_push_back(output, node);
}
goto RETURN_STR8_SPLIT;
}
i64 end = 0;
i64 splits = 0;
Str8 *rest = wapp_str8_alloc_str8(allocator, str);
Str8 *after_str;
while ((end = wapp_str8_rfind(rest, *delimiter)) != -1) {
if (max_splits > 0 && splits >= max_splits) {
break;
}
after_str = wapp_str8_alloc_substr(allocator, rest, end + delimiter->size, str->size);
DBL_NODE(Str8) *node = wapp_mem_allocator_alloc(allocator, sizeof(DBL_NODE(Str8)));
if (node) {
node->item = after_str;
wapp_dbl_list_push_front(output, node);
}
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
rest = wapp_str8_alloc_substr(allocator, rest, 0, end);
++splits;
}
rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
DBL_NODE(Str8) *node = wapp_mem_allocator_alloc(allocator, sizeof(DBL_NODE(Str8)));
if (node) {
node->item = rest;
wapp_dbl_list_push_front(output, node);
}
RETURN_STR8_SPLIT:
return output;
}
Str8 *wapp_str8_join(const Allocator *allocator, const DBL_LIST(Str8) *list, Str8RO *delimiter) {
if (!allocator || !list || !delimiter) {
return NULL;
}
u64 capacity = wapp_str8_list_total_size(list) + (delimiter->size * (list->node_count - 1));
Str8 *output = wapp_str8_alloc_buf(allocator, capacity * 2);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
DBL_NODE(Str8) *node;
u64 node_index = 0;
bool running = true;
while (running) {
node = wapp_dbl_list_get(Str8, list, node_index);
wapp_str8_concat_capped(output, node->item);
if (node_index + 1 < list->node_count) {
wapp_str8_concat_capped(output, delimiter);
}
++node_index;
running = node_index < list->node_count;
}
return output;
} }

View File

@@ -1,12 +1,7 @@
#ifndef STR8_H #ifndef STR8_H
#define STR8_H #define STR8_H
#include "./str8_list.h" #include "aliases.h"
#include "../../../common/aliases/aliases.h"
#include "../../../containers/dbl_list/dbl_list.h"
#include "../../mem/allocator/mem_allocator.h"
#include <string.h>
#include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
@@ -16,84 +11,12 @@ typedef struct str8 Str8;
struct str8 { struct str8 {
u64 capacity; u64 capacity;
u64 size; u64 size;
c8 *buf; u8 *buf;
}; };
typedef const Str8 Str8RO; Str8 wapp_str8_lit(char *str);
char wapp_str8_get(const Str8 *str, u64 index);
/** void wapp_str8_set(Str8 *str, u64 index, char c);
* Utilities to be used with printf functions
*/
#define WAPP_STR8_SPEC "%.*s"
#define wapp_str8_varg(STRING) (int)((STRING).size), (STRING).buf
/**
* Str8 stack buffers
*/
#define wapp_str8_buf(CAPACITY) ((Str8){.capacity = CAPACITY, .size = 0, .buf = (c8[CAPACITY]){0}})
// Utilises the fact that memcpy returns pointer to dest buffer and that getting
// address of compound literals is valid in C to create a string on the stack
#define wapp_str8_lit(STRING) ((Str8){.capacity = (sizeof(STRING) - 1) * 2, \
.size = sizeof(STRING) - 1, \
.buf = memcpy(&((c8 [sizeof(STRING) * 2]){0}), STRING, sizeof(STRING))})
#define wapp_str8_lit_ro(STRING) ((Str8RO){.capacity = sizeof(STRING) - 1, \
.size = sizeof(STRING) - 1, \
.buf = (c8 *)STRING})
// To be used only when initialising a static storage variable in compilers that don't support
// initialisers with the syntax of wapp_str8_lit_ro (e.g. gcc). Should only be used when necessary
// and only be assigned to a Str8RO variable to avoid any attempt at modifying the string
#define wapp_str8_lit_ro_initialiser_list(STRING) {.capacity = sizeof(STRING) - 1, \
.size = sizeof(STRING) - 1, \
.buf = (c8 *)STRING}
/**
* Str8 allocated buffers
*/
Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity);
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str);
Str8 *wapp_str8_alloc_str8(const Allocator *allocator, Str8RO *str);
Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end);
Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src);
// Only needed for allocators like malloc where each allocation has to be freed on its own.
// No need to use it for allocators like Arena.
void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str);
/**
* Str8 utilities
*/
c8 wapp_str8_get(Str8RO *str, u64 index);
void wapp_str8_set(Str8 *str, u64 index, c8 c);
void wapp_str8_push_back(Str8 *str, c8 c);
bool wapp_str8_equal(Str8RO *s1, Str8RO *s2);
bool wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count);
Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end);
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *src);
void wapp_str8_copy_str8_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity);
void wapp_str8_format(Str8 *dst, const char *format, ...);
/**
* Str8 find functions
*/
i64 wapp_str8_find(Str8RO *str, Str8RO substr);
i64 wapp_str8_rfind(Str8RO *str, Str8RO substr);
/**
* Str8 split and join
*/
#define wapp_str8_split(ALLOCATOR, STR, DELIMITER) wapp_str8_split_with_max(ALLOCATOR, STR, DELIMITER, -1)
#define wapp_str8_rsplit(ALLOCATOR, STR, DELIMITER) wapp_str8_rsplit_with_max(ALLOCATOR, STR, DELIMITER, -1)
DBL_LIST(Str8) *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits);
DBL_LIST(Str8) *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits);
Str8 *wapp_str8_join(const Allocator *allocator, const DBL_LIST(Str8) *list, Str8RO *delimiter);
/**
* Str8 list utilities
*/
#define wapp_str8_node_from_cstr(STRING) wapp_dbl_list_node_from_item(Str8, &wapp_str8_lit(STRING))
#define wapp_str8_node_from_str8(STRING) wapp_dbl_list_node_from_item(Str8, &(STRING))
#ifdef __cplusplus #ifdef __cplusplus
END_C_LINKAGE END_C_LINKAGE

View File

@@ -1,18 +0,0 @@
#include "./str8_list.h"
#include "./str8.h"
#include "../../../common/aliases/aliases.h"
#include "../../../containers/dbl_list/dbl_list.h"
u64 wapp_str8_list_total_size(const DBL_LIST(Str8) *list) {
if (!list) {
return 0;
}
u64 output = 0;
for (u64 i = 0; i < list->node_count; ++i) {
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, list, i);
output += node->item->size;
}
return output;
}

View File

@@ -1,25 +0,0 @@
/**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN
*/
#ifndef STR8_LIST_H
#define STR8_LIST_H
#include "../../../common/aliases/aliases.h"
#include "../../../containers/dbl_list/dbl_list.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // !__cplusplus
typedef struct str8 Str8;
DBL_LIST_DECL(Str8);
u64 wapp_str8_list_total_size(const DBL_LIST(Str8) *list);
#ifdef __cplusplus
END_C_LINKAGE
#endif // !__cplusplus
#endif // !STR8_LIST_H

View File

@@ -1,22 +0,0 @@
#ifndef WAPP_CORE_C
#define WAPP_CORE_C
#include "wapp_core.h"
#include "strings/str8/str8.c"
#include "strings/str8/str8_list.c"
#include "os/shell/termcolour/posix/termcolour_posix.c"
#include "os/shell/termcolour/win/termcolour_win.c"
#include "os/shell/termcolour/termcolour.c"
#include "os/shell/commander/posix/commander_posix.c"
#include "os/shell/commander/win/commander_win.c"
#include "os/shell/commander/commander.c"
#include "os/cpath/cpath.c"
#include "os/mem/posix/mem_os_posix.c"
#include "os/mem/win/mem_os_win.c"
#include "os/mem/mem_os.c"
#include "mem/utils/mem_utils.c"
#include "mem/allocator/mem_allocator.c"
#include "mem/arena/mem_arena.c"
#include "mem/arena/mem_arena_allocator.c"
#endif // !WAPP_CORE_C

View File

@@ -1,22 +0,0 @@
#ifndef WAPP_CORE_H
#define WAPP_CORE_H
#include "strings/str8/str8.h"
#include "strings/str8/str8_list.h"
#include "os/shell/termcolour/termcolour.h"
#include "os/shell/termcolour/terminal_colours.h"
#include "os/shell/commander/commander.h"
#include "os/shell/commander/commander_output.h"
#include "os/shell/utils/shell_utils.h"
#include "os/cpath/cpath.h"
#include "os/mem/posix/mem_os_posix.h"
#include "os/mem/win/mem_os_win.h"
#include "os/mem/mem_os_ops.h"
#include "os/mem/mem_os.h"
#include "mem/utils/mem_utils.h"
#include "mem/allocator/mem_allocator.h"
#include "mem/arena/mem_arena_allocator.h"
#include "mem/arena/mem_arena.h"
#include "../common/wapp_common.h"
#endif // !WAPP_CORE_H

92
src/os/cpath/cpath.c Normal file
View File

@@ -0,0 +1,92 @@
#include "cpath.h"
#include "aliases.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
void join_root_and_leaf(const char *root, const char *leaf, char *dst);
void join_path(char *dst, u64 count, ...) {
va_list args;
va_start(args, count);
for (u64 i = 0; i < count; ++i) {
join_root_and_leaf(dst, va_arg(args, const char *), dst);
}
va_end(args);
}
void dirup(char *dst, u64 levels, const char *path) {
if (levels < 1) {
return;
}
u64 copy_count = 0;
u64 sep_count = 0;
u64 full_length;
u64 length;
length = full_length = strlen(path);
if (length > 1 && path[length - 1] == PATH_SEP) {
--length;
}
for (i64 i = length - 1; i >= 0; --i) {
if (path[i] == PATH_SEP) {
++sep_count;
copy_count = i + 1;
if (sep_count == levels) {
break;
}
}
}
char tmp[256];
snprintf(tmp, 2, "%c", PATH_SEP);
// NOTE (Abdelrahman): Conditions stored in variables to silence MSVC warning C5045
bool insufficient_levels = sep_count < levels;
bool path_to_copy_is_separator = strncmp(path, tmp, copy_count) != 0;
if (insufficient_levels && path_to_copy_is_separator) {
copy_count = 0;
}
if (dst == path) {
memset(&dst[copy_count], 0, full_length - copy_count);
} else {
u64 dst_length = strlen(dst);
memset(dst, 0, dst_length);
strncpy(dst, path, copy_count);
}
u64 final_length = strlen(dst);
if (final_length > 1) {
dst[final_length - 1] = '\0';
} else if (final_length == 0) {
dst[0] = '.';
}
}
void join_root_and_leaf(const char *root, const char *leaf, char *dst) {
u64 root_length = strlen(root);
u64 leaf_length = strlen(leaf);
memcpy(dst, root, root_length);
if (leaf_length == 0) {
return;
}
u64 copy_start = root_length;
if (root_length > 0 && root[root_length - 1] != PATH_SEP && leaf[0] != PATH_SEP) {
dst[root_length] = PATH_SEP;
++copy_start;
}
memcpy(&(dst[copy_start]), leaf, leaf_length);
}

32
src/os/cpath/cpath.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef CPATH_H
#define CPATH_H
#include "aliases.h"
#include "platform.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
#ifdef WAPP_PLATFORM_POSIX
#define PATH_SEP '/'
#elif defined(WAPP_PLATFORM_WINDOWS)
#define PATH_SEP '\\'
#else
#error "Unrecognised platform"
#endif
#define NUMPARTS(...) (sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1)
#define wapp_cpath_join_path(DST, ...) join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__)
#define wapp_cpath_dirname(DST, PATH) dirup(DST, 1, PATH)
#define wapp_cpath_dirup(DST, COUNT, PATH) dirup(DST, COUNT, PATH)
void join_path(char *dst, u64 count, ...);
void dirup(char *dst, u64 levels, const char *path);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !CPATH_H

53
src/os/mem/mem_utils.c Normal file
View File

@@ -0,0 +1,53 @@
#include "mem_utils.h"
#include "mem_utils_ops.h"
#include "aliases.h"
#include "platform.h"
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#if defined(WAPP_PLATFORM_WINDOWS)
#include "mem_utils_win.h"
#elif defined(WAPP_PLATFORM_POSIX)
#include "mem_utils_posix.h"
#else
#error "Unrecognised platform"
#endif
internal bool is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
if (!ptr) {
return NULL;
}
assert(is_power_of_two(alignment));
uptr p = (uptr)ptr;
uptr align = (uptr)alignment;
// Similar to p % align, but it's a faster implementation that works fine
// because align is guaranteed to be a power of 2
uptr modulo = p & (align - 1);
if (modulo != 0) {
p += align - modulo;
}
return (void *)p;
}
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
void *output = mem_util_allocate(addr, size, access, flags, type);
if (type == WAPP_MEM_INIT_INITIALISED) {
memset(output, 0, size);
}
return output;
}
void wapp_mem_util_free(void *ptr, u64 size) {
mem_util_free(ptr, size);
}

View File

@@ -1,19 +1,19 @@
#ifndef MEM_OS_H #ifndef MEM_UTILS_H
#define MEM_OS_H #define MEM_UTILS_H
#include "../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../common/platform/platform.h" #include "platform.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
#include "mem_os_ops.h" #include "mem_utils_ops.h"
#if defined(WAPP_PLATFORM_WINDOWS) #if defined(WAPP_PLATFORM_WINDOWS)
#include "win/mem_os_win.h" #include "mem_utils_win.h"
#elif defined(WAPP_PLATFORM_POSIX) #elif defined(WAPP_PLATFORM_POSIX)
#include "posix/mem_os_posix.h" #include "mem_utils_posix.h"
#else #else
#error "Unrecognised platform" #error "Unrecognised platform"
#endif #endif
@@ -29,4 +29,4 @@ external void mem_util_free(void *ptr, u64 size);
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
#endif // !MEM_OS_H #endif // !MEM_UTILS_H

View File

@@ -1,5 +1,5 @@
#ifndef MEM_OS_OPS_H #ifndef MEM_UTILS_OPS_H
#define MEM_OS_OPS_H #define MEM_UTILS_OPS_H
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
@@ -23,4 +23,4 @@ typedef enum mem_init_type {
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
#endif // !MEM_OS_OPS_H #endif // !MEM_UTILS_OPS_H

View File

@@ -1,10 +1,10 @@
#include "../../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../../common/platform/platform.h" #include "platform.h"
#ifdef WAPP_PLATFORM_POSIX #ifdef WAPP_PLATFORM_POSIX
#include "mem_os_posix.h" #include "mem_utils_ops.h"
#include "../mem_os_ops.h" #include "mem_utils_posix.h"
#include <sys/mman.h> #include <sys/mman.h>
internal const i32 access_types[] = { internal const i32 access_types[] = {
@@ -17,7 +17,6 @@ internal const i32 access_types[] = {
}; };
void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) { void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
(void)type;
i32 alloc_flags = flags | MAP_ANON | MAP_PRIVATE; i32 alloc_flags = flags | MAP_ANON | MAP_PRIVATE;
#if defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU) || defined(WAPP_PLATFORM_NET_BSD) #if defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU) || defined(WAPP_PLATFORM_NET_BSD)

View File

@@ -1,7 +1,7 @@
#ifndef MEM_OS_POSIX_H #ifndef MEM_UTILS_POSIX_H
#define MEM_OS_POSIX_H #define MEM_UTILS_POSIX_H
#include "../../../../common/platform/platform.h" #include "platform.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
@@ -30,4 +30,4 @@ typedef enum mem_alloc_flags {
END_C_LINKAGE END_C_LINKAGE
#endif // !__cplusplus #endif // !__cplusplus
#endif // !MEM_OS_POSIX_H #endif // !MEM_UTILS_POSIX_H

View File

@@ -1,10 +1,10 @@
#include "../../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../../common/platform/platform.h" #include "platform.h"
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#include "mem_os_win.h" #include "mem_utils_ops.h"
#include "../mem_os_ops.h" #include "mem_utils_win.h"
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>

View File

@@ -1,7 +1,7 @@
#ifndef MEM_OS_WIN_H #ifndef MEM_UTILS_WIN_H
#define MEM_OS_WIN_H #define MEM_UTILS_WIN_H
#include "../../../../common/platform/platform.h" #include "platform.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
@@ -24,4 +24,4 @@ typedef enum mem_alloc_flags {
END_C_LINKAGE END_C_LINKAGE
#endif // !__cplusplus #endif // !__cplusplus
#endif // !MEM_OS_WIN_H #endif // !MEM_UTILS_WIN_H

View File

@@ -0,0 +1,118 @@
#include "commander.h"
#include "aliases.h"
#include "shell_utils.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CMD_BUF_LEN 8192
#define OUT_BUF_LEN 4096
internal inline CMDError build_command_from_args(char *cmd, u64 buf_len, va_list args);
internal inline CMDResult execute_command(const char *cmd, CMDOutHandling out_handling, char *out_buf,
u64 buf_size);
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, char *out_buf,
u64 buf_size);
CMDResult run_command(CMDOutHandling out_handling, char *out_buf, u64 buf_size, ...) {
va_list args;
va_start(args, buf_size);
char cmd[CMD_BUF_LEN] = {0};
CMDError err = build_command_from_args(cmd, CMD_BUF_LEN, args);
if (err > SHELL_ERR_NO_ERROR) {
va_end(args);
return CMD_NO_EXIT(err);
}
va_end(args);
return execute_command(cmd, out_handling, out_buf, buf_size);
}
internal inline CMDError build_command_from_args(char *cmd, u64 buf_len,
va_list args) {
u64 size = 0;
u64 arg_len = 0;
const char *arg = va_arg(args, const char *);
while (arg) {
arg_len = strlen(arg);
if (arg_len >= buf_len - size) {
return SHELL_ERR_CMD_BUF_FULL;
}
strcat(cmd, arg);
cmd[size + arg_len] = ' ';
size += arg_len + 1;
arg = va_arg(args, const char *);
}
return SHELL_ERR_NO_ERROR;
}
internal inline CMDResult execute_command(const char *cmd,
CMDOutHandling out_handling,
char *out_buf, u64 buf_size) {
FILE *fp = wapp_shell_utils_popen(cmd, "r");
if (!fp) {
return CMD_NO_EXIT(SHELL_ERR_PROC_START_FAIL);
}
CMDResult output;
CMDError err = get_command_output(fp, out_handling, out_buf, buf_size);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
i32 st = EXIT_SUCCESS;
err = get_output_status(fp, &st);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
// Process is already closed in get_output_status
fp = NULL;
output = (CMDResult){
.exited = true,
.exit_code = st,
.error = SHELL_ERR_NO_ERROR,
};
EXECUTE_COMMAND_CLOSE:
if (fp) {
wapp_shell_utils_pclose(fp);
}
return output;
}
internal inline CMDError get_command_output(FILE *fp,
CMDOutHandling out_handling,
char *out_buf, u64 buf_size) {
char out[OUT_BUF_LEN] = {0};
u64 max_out_length = OUT_BUF_LEN - 1;
u64 buf_filled = 0;
while (fgets(out, (i32)max_out_length, fp)) {
if (out_handling == SHELL_OUTPUT_CAPTURE && out_buf != NULL) {
buf_filled += strlen(out);
if (buf_filled >= buf_size) {
return SHELL_ERR_OUT_BUF_FULL;
}
strcat(out_buf, out);
} else if (out_handling == SHELL_OUTPUT_PRINT) {
printf("%s", out);
}
}
return SHELL_ERR_NO_ERROR;
}

View File

@@ -1,9 +1,8 @@
#ifndef COMMANDER_H #ifndef COMMANDER_H
#define COMMANDER_H #define COMMANDER_H
#include "aliases.h"
#include "commander_output.h" #include "commander_output.h"
#include "../../../../common/aliases/aliases.h"
#include "../../../strings/str8/str8.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -13,8 +12,10 @@ BEGIN_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
#define CMD_NO_EXIT(ERR) ((CMDResult){.exited = false, .exit_code = EXIT_FAILURE, .error = ERR}) #define CMD_NO_EXIT(ERR) ((CMDResult){.exited = false, .exit_code = EXIT_FAILURE, .error = ERR})
#define wapp_shell_commander_execute(HANDLE_OUTPUT, OUT_BUF, BUF_SIZE, ...) \
run_command(HANDLE_OUTPUT, OUT_BUF, BUF_SIZE, __VA_ARGS__, "2>&1", NULL)
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const DBL_LIST(Str8) *cmd); CMDResult run_command(CMDOutHandling out_handling, char *out_buf, u64 buf_size, ...);
external CMDError get_output_status(FILE *fp, i32 *status_out); external CMDError get_output_status(FILE *fp, i32 *status_out);

View File

@@ -1,8 +1,8 @@
#ifndef COMMANDER_OUTPUT_H #ifndef COMMANDER_OUTPUT_H
#define COMMANDER_OUTPUT_H #define COMMANDER_OUTPUT_H
#include "../../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../../common/platform/platform.h" #include "platform.h"
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
@@ -17,8 +17,7 @@ typedef enum {
typedef enum { typedef enum {
SHELL_ERR_NO_ERROR, SHELL_ERR_NO_ERROR,
SHELL_ERR_INVALID_ARGS, SHELL_ERR_CMD_BUF_FULL,
SHELL_ERR_ALLOCATION_FAIL,
SHELL_ERR_PROC_START_FAIL, SHELL_ERR_PROC_START_FAIL,
SHELL_ERR_OUT_BUF_FULL, SHELL_ERR_OUT_BUF_FULL,
SHELL_ERR_PROC_EXIT_FAIL, SHELL_ERR_PROC_EXIT_FAIL,

View File

@@ -1,10 +1,10 @@
#include "../../../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../../../common/platform/platform.h" #include "platform.h"
#ifdef WAPP_PLATFORM_POSIX #ifdef WAPP_PLATFORM_POSIX
#include "../commander_output.h" #include "commander_output.h"
#include "../../utils/shell_utils.h" #include "shell_utils.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@@ -1,10 +1,10 @@
#include "../../../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../../../common/platform/platform.h" #include "platform.h"
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#include "../commander_output.h" #include "commander_output.h"
#include "../../utils/shell_utils.h" #include "shell_utils.h"
#include <stdio.h> #include <stdio.h>
CMDError get_output_status(FILE *fp, i32 *status_out) { CMDError get_output_status(FILE *fp, i32 *status_out) {

View File

@@ -0,0 +1,33 @@
#include "aliases.h"
#include "platform.h"
#ifdef WAPP_PLATFORM_POSIX
#include "terminal_colours.h"
#include <stdio.h>
internal const char *colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = "\033[30m",
[WAPP_TERM_COLOUR_FG_RED] = "\033[31m",
[WAPP_TERM_COLOUR_FG_GREEN] = "\033[32m",
[WAPP_TERM_COLOUR_FG_BLUE] = "\033[34m",
[WAPP_TERM_COLOUR_FG_CYAN] = "\033[36m",
[WAPP_TERM_COLOUR_FG_MAGENTA] = "\033[35m",
[WAPP_TERM_COLOUR_FG_YELLOW] = "\033[33m",
[WAPP_TERM_COLOUR_FG_WHITE] = "\033[37m",
[WAPP_TERM_COLOUR_FG_BR_BLACK] = "\033[90m",
[WAPP_TERM_COLOUR_FG_BR_RED] = "\033[91m",
[WAPP_TERM_COLOUR_FG_BR_GREEN] = "\033[92m",
[WAPP_TERM_COLOUR_FG_BR_BLUE] = "\033[94m",
[WAPP_TERM_COLOUR_FG_BR_CYAN] = "\033[96m",
[WAPP_TERM_COLOUR_FG_BR_MAGENTA] = "\033[95m",
[WAPP_TERM_COLOUR_FG_BR_YELLOW] = "\033[93m",
[WAPP_TERM_COLOUR_FG_BR_WHITE] = "\033[97m",
[WAPP_TERM_COLOUR_CLEAR] = "\033[0m",
};
void print_coloured_text(const char *text, TerminalColour colour) {
printf("%s%s", colours[colour], text);
}
#endif // !WAPP_PLATFORM_POSIX

View File

@@ -1,8 +1,7 @@
#include "termcolour.h" #include "termcolour.h"
#include "terminal_colours.h" #include "terminal_colours.h"
#include "../../../strings/str8/str8.h"
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour) { void wapp_shell_termcolour_print_text(const char *text, TerminalColour colour) {
if (colour < WAPP_TERM_COLOUR_FG_BLACK || colour > WAPP_TERM_COLOUR_FG_BR_WHITE) { if (colour < WAPP_TERM_COLOUR_FG_BLACK || colour > WAPP_TERM_COLOUR_FG_BR_WHITE) {
return; return;
} }
@@ -11,6 +10,5 @@ void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour) {
} }
void wapp_shell_termcolour_clear_colour(void) { void wapp_shell_termcolour_clear_colour(void) {
Str8RO empty = wapp_str8_lit_ro(""); print_coloured_text("", WAPP_TERM_COLOUR_CLEAR);
print_coloured_text(&empty, WAPP_TERM_COLOUR_CLEAR);
} }

View File

@@ -1,18 +1,17 @@
#ifndef TERM_COLOUR_H #ifndef TERM_COLOUR_H
#define TERM_COLOUR_H #define TERM_COLOUR_H
#include "aliases.h"
#include "terminal_colours.h" #include "terminal_colours.h"
#include "../../../../common/aliases/aliases.h"
#include "../../../strings/str8/str8.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour); void wapp_shell_termcolour_print_text(const char *text, TerminalColour colour);
void wapp_shell_termcolour_clear_colour(void); void wapp_shell_termcolour_clear_colour(void);
external void print_coloured_text(Str8RO *text, TerminalColour colour); external void print_coloured_text(const char *text, TerminalColour colour);
#ifdef __cplusplus #ifdef __cplusplus
END_C_LINKAGE END_C_LINKAGE

View File

@@ -1,11 +1,10 @@
#include "../../../../../common/aliases/aliases.h" #include "aliases.h"
#include "../../../../../common/platform/platform.h" #include "platform.h"
#include "../../../../strings/str8/str8.h"
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#include "../terminal_colours.h" #include "misc_utils.h"
#include "../../../../../common/misc/misc_utils.h" #include "terminal_colours.h"
#include <stdio.h> #include <stdio.h>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@@ -41,7 +40,7 @@ internal WORD colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, [WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
}; };
void print_coloured_text(Str8RO *text, TerminalColour colour) { void print_coloured_text(const char *text, TerminalColour colour) {
persistent TermcolourData data = {0}; persistent TermcolourData data = {0};
if (data.handle == 0) { if (data.handle == 0) {
init_data(&data); init_data(&data);
@@ -54,7 +53,7 @@ void print_coloured_text(Str8RO *text, TerminalColour colour) {
} }
SetConsoleTextAttribute(data.handle, data.current_colour); SetConsoleTextAttribute(data.handle, data.current_colour);
printf(WAPP_STR8_SPEC, wapp_str8_varg((*text))); printf("%s", text);
} }
internal void init_data(TermcolourData *data) { internal void init_data(TermcolourData *data) {

View File

@@ -1,7 +1,7 @@
#ifndef SHELL_UTILS_H #ifndef SHELL_UTILS_H
#define SHELL_UTILS_H #define SHELL_UTILS_H
#include "../../../../common/platform/platform.h" #include "platform.h"
#include <stdio.h> #include <stdio.h>
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS

View File

@@ -1,6 +0,0 @@
#ifndef WAPP_PRNG_C
#define WAPP_PRNG_C
#include "xorshift/xorshift.c"
#endif // !WAPP_PRNG_C

View File

@@ -1,7 +0,0 @@
#ifndef WAPP_PRNG_H
#define WAPP_PRNG_H
#include "xorshift/xorshift.h"
#include "../common/wapp_common.h"
#endif // !WAPP_PRNG_H

View File

@@ -1,89 +0,0 @@
#include "xorshift.h"
#include "../../common/aliases/aliases.h"
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
typedef struct split_mix_64_state SplitMix64State;
struct split_mix_64_state {
u64 seed;
};
internal u64 rol64(u64 x, u64 bits);
internal u64 split_mix_64(SplitMix64State *state);
XOR256State wapp_prng_xorshift_init_state(void) {
persistent bool seeded = false;
if (!seeded) {
seeded = true;
struct timespec ts = {0};
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
srand48(ts.tv_nsec);
}
SplitMix64State sm64 = {.seed = lrand48()};
return (XOR256State){
.x = split_mix_64(&sm64),
.y = split_mix_64(&sm64),
.z = split_mix_64(&sm64),
.w = split_mix_64(&sm64),
};
}
u64 wapp_prng_xorshift_256(XOR256State *state) {
u64 t = state->x ^ (state->x << 11);
state->x = state->y;
state->y = state->z;
state->z = state->w;
state->w = (state->w ^ (state->w >> 19)) ^ (t ^ (t >> 8));
return state->w;
}
u64 wapp_prng_xorshift_256ss(XOR256State *state) {
const u64 result = rol64(state->z * 5, 7) * 9;
const u64 t = state->z << 17;
state->y ^= state->w;
state->x ^= state->z;
state->z ^= state->y;
state->w ^= state->x;
state->y ^= t;
state->x = rol64(state->x, 45);
return result;
}
u64 wapp_prng_xorshift_256p(XOR256State *state) {
const u64 result = state->w + state->x;
const u64 t = state->z << 17;
state->y ^= state->w;
state->x ^= state->z;
state->z ^= state->y;
state->w ^= state->x;
state->y ^= t;
state->x = rol64(state->x, 45);
return result;
}
internal u64 rol64(u64 x, u64 bits) {
return (x << bits) | (x >> (64 - bits));
}
internal u64 split_mix_64(SplitMix64State *state) {
state->seed += 0x9E3779B97f4A7C15;
u64 result = state->seed;
result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
return result ^ (result >> 31);
}

View File

@@ -1,27 +0,0 @@
#ifndef XORSHIFT_H
#define XORSHIFT_H
#include "../../common/aliases/aliases.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
typedef struct xor_256_state XOR256State;
struct xor_256_state {
u64 x;
u64 y;
u64 z;
u64 w;
};
XOR256State wapp_prng_xorshift_init_state(void);
u64 wapp_prng_xorshift_256(XOR256State *state);
u64 wapp_prng_xorshift_256ss(XOR256State *state);
u64 wapp_prng_xorshift_256p(XOR256State *state);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !XORSHIFT_H

View File

@@ -1,7 +1,6 @@
#include "tester.h" #include "tester.h"
#include "../../common/aliases/aliases.h" #include "aliases.h"
#include "../../core/os/shell/termcolour/termcolour.h" #include "termcolour.h"
#include "../../core/strings/str8/str8.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -32,20 +31,20 @@ void run_tests(TestFunc *func1, ...) {
internal void handle_test_result(TestFuncResult result) { internal void handle_test_result(TestFuncResult result) {
TerminalColour colour; TerminalColour colour;
Str8 result_text = wapp_str8_buf(64); const char *result_text;
if (result.passed) { if (result.passed) {
colour = WAPP_TERM_COLOUR_FG_BR_GREEN; colour = WAPP_TERM_COLOUR_FG_BR_GREEN;
wapp_str8_copy_cstr_capped(&result_text, "PASSED"); result_text = "PASSED";
} else { } else {
colour = WAPP_TERM_COLOUR_FG_BR_RED; colour = WAPP_TERM_COLOUR_FG_BR_RED;
wapp_str8_copy_cstr_capped(&result_text, "FAILED"); result_text = "FAILED";
} }
printf("["); printf("[");
wapp_shell_termcolour_print_text(&result_text, colour); wapp_shell_termcolour_print_text(result_text, colour);
wapp_shell_termcolour_clear_colour(); wapp_shell_termcolour_clear_colour();
printf("] " WAPP_STR8_SPEC "\n", wapp_str8_varg(result.name)); printf("] %s\n", result.name);
if (!result.passed) { if (!result.passed) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@@ -1,25 +1,24 @@
#ifndef TESTER_H #ifndef TESTER_H
#define TESTER_H #define TESTER_H
#include "../../common/misc/misc_utils.h" #include "misc_utils.h"
#include "../../common/platform/platform.h" #include "platform.h"
#include "../../core/strings/str8/str8.h"
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
#define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED}) #define wapp_tester_result(PASSED) ((TestFuncResult){.name = __func__, .passed = PASSED})
#define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL) #define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL)
typedef struct test_func_result TestFuncResult; typedef struct test_func_result TestFuncResult;
struct test_func_result { struct test_func_result {
Str8RO name; const char *name;
bool passed; bool passed;
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_padding_size(sizeof(Str8RO) + sizeof(bool)); wapp_misc_utils_padding_size(sizeof(const char *) + sizeof(bool));
#endif // WAPP_PLATFORM_WINDOWS #endif // WAPP_PLATFORM_WINDOWS
}; };

View File

@@ -1,8 +0,0 @@
#ifndef WAPP_TESTING_C
#define WAPP_TESTING_C
#include "wapp_testing.h"
#include "tester/tester.c"
#include "../core/wapp_core.c"
#endif // !WAPP_TESTING_C

View File

@@ -1,8 +0,0 @@
#ifndef WAPP_TESTING_H
#define WAPP_TESTING_H
#include "tester/tester.h"
#include "../common/wapp_common.h"
#include "../core/wapp_core.h"
#endif // !WAPP_TESTING_H

View File

@@ -1,59 +0,0 @@
#include "uuid.h"
#include "../common/aliases/aliases.h"
#include "../core/strings/str8/str8.h"
#include "../prng/xorshift/xorshift.h"
#include <stdbool.h>
#include <inttypes.h>
#define UUID_STR_FORMAT ("%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64)
typedef struct uuid4 UUID4;
struct uuid4 {
u64 high;
u64 low;
};
internal UUID4 generate_uuid4(void);
internal void uuid4_to_uuid(const UUID4* uuid4, UUID *uuid);
UUID *wapp_uuid_init_uuid4(UUID *uuid) {
if (!uuid) {
goto RETURN_INIT_UUID4;
}
UUID4 uuid4 = generate_uuid4();
uuid4_to_uuid(&uuid4, uuid);
RETURN_INIT_UUID4:
return uuid;
}
internal UUID4 generate_uuid4(void) {
persistent XOR256State state = {0};
persistent bool initialised = false;
if (!initialised) {
initialised = true;
state = wapp_prng_xorshift_init_state();
}
UUID4 uuid = (UUID4){
.high = wapp_prng_xorshift_256(&state),
.low = wapp_prng_xorshift_256(&state),
};
uuid.high = (uuid.high & 0xffffffffffff0fff) | 0x0000000000004000;
uuid.low = (uuid.low & 0x3fffffffffffffff) | 0x8000000000000000;
return uuid;
}
internal void uuid4_to_uuid(const UUID4* uuid4, UUID *uuid) {
u64 grp1 = uuid4->high >> 32;
u64 grp2 = (uuid4->high << 32) >> 48;
u64 grp3 = (uuid4->high << 48) >> 48;
u64 grp4 = uuid4->low >> 48;
u64 grp5 = (uuid4->low << 16) >> 16;
wapp_str8_format(&(uuid->uuid), UUID_STR_FORMAT, grp1, grp2, grp3, grp4, grp5);
}

View File

@@ -1,34 +0,0 @@
#ifndef UUID_H
#define UUID_H
#include "../common/aliases/aliases.h"
#include "../core/strings/str8/str8.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
#define UUID_BUF_LENGTH 48
#define WAPP_UUID_SPEC WAPP_STR8_SPEC
#define wapp_uuid_varg(UUID) wapp_str8_varg((UUID).uuid)
typedef struct uuid UUID;
struct uuid {
Str8 uuid;
};
#define wapp_uuid_gen_uuid4() *(wapp_uuid_init_uuid4(&wapp_uuid_create()))
/* Low level UUID API */
#define wapp_uuid_create() ((UUID){.uuid = wapp_str8_buf(UUID_BUF_LENGTH)})
// Just returns the same pointer that was passed in with the UUID initialised.
// If the pointer is NULL, it skips initialisation.
UUID *wapp_uuid_init_uuid4(UUID *uuid);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !UUID_H

View File

@@ -1,8 +0,0 @@
#ifndef WAPP_UUID_C
#define WAPP_UUID_C
#include "uuid.c"
#include "../core/wapp_core.c"
#include "../prng/wapp_prng.c"
#endif // !WAPP_UUID_C

View File

@@ -1,9 +0,0 @@
#ifndef WAPP_UUID_H
#define WAPP_UUID_H
#include "uuid.h"
#include "../common/wapp_common.h"
#include "../core/wapp_core.h"
#include "../prng/wapp_prng.h"
#endif // !WAPP_UUID_H

View File

@@ -1,11 +0,0 @@
#ifndef WAPP_C
#define WAPP_C
#include "wapp.h"
#include "containers/wapp_containers.c"
#include "core/wapp_core.c"
#include "prng/wapp_prng.c"
#include "uuid/uuid.c"
#include "testing/wapp_testing.c"
#endif // !WAPP_C

View File

@@ -1,11 +0,0 @@
#ifndef WAPP_H
#define WAPP_H
#include "common/wapp_common.h"
#include "containers/wapp_containers.h"
#include "core/wapp_core.h"
#include "prng/wapp_prng.h"
#include "uuid/wapp_uuid.h"
#include "testing/wapp_testing.h"
#endif // !WAPP_H

View File

@@ -1,8 +1,27 @@
#include "test_allocator.h" #include "test_allocator.h"
#include "wapp.h" #include "libc/mem_libc_allocator.h"
#include "mem_allocator.h"
#include "mem_arena_allocator.h"
#include "tester.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
TestFuncResult test_libc_allocator(void) {
Allocator allocator = wapp_mem_libc_allocator();
bool result = allocator.obj == NULL && allocator.alloc != NULL &&
allocator.alloc_aligned == NULL && allocator.realloc != NULL &&
allocator.realloc_aligned == NULL && allocator.free != NULL;
void *ptr = wapp_mem_allocator_alloc(&allocator, 20);
result = result && (ptr != NULL);
if (ptr != NULL) {
wapp_mem_allocator_free(&allocator, &ptr);
result = result && (ptr == NULL);
}
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator(void) { TestFuncResult test_arena_allocator(void) {
Allocator allocator = wapp_mem_arena_allocator_init(4096); Allocator allocator = wapp_mem_arena_allocator_init(4096);
bool result = allocator.obj != NULL && allocator.alloc != NULL && bool result = allocator.obj != NULL && allocator.alloc != NULL &&

View File

@@ -1,12 +1,13 @@
#ifndef TEST_ALLOCATOR_H #ifndef TEST_ALLOCATOR_H
#define TEST_ALLOCATOR_H #define TEST_ALLOCATOR_H
#include "wapp.h" #include "tester.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // __cplusplus
TestFuncResult test_libc_allocator(void);
TestFuncResult test_arena_allocator(void); TestFuncResult test_arena_allocator(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -1,5 +1,8 @@
#include "test_arena.h" #include "test_arena.h"
#include "wapp.h" #include "aliases.h"
#include "mem_arena.h"
#include "misc_utils.h"
#include "tester.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>

View File

@@ -1,7 +1,7 @@
#ifndef TEST_ARENA_H #ifndef TEST_ARENA_H
#define TEST_ARENA_H #define TEST_ARENA_H
#include "wapp.h" #include "tester.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE

View File

@@ -1,5 +1,6 @@
#include "test_cpath.h" #include "test_cpath.h"
#include "wapp.h" #include "cpath.h"
#include "tester.h"
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
@@ -8,175 +9,175 @@
#define TMP_BUF_SIZE 1024 #define TMP_BUF_SIZE 1024
TestFuncResult test_cpath_join_path(void) { TestFuncResult test_cpath_join_path(void) {
bool result; char expected[MAIN_BUF_SIZE] = {0};
char out[MAIN_BUF_SIZE] = {0};
char tmp[TMP_BUF_SIZE] = {0};
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); snprintf(expected, MAIN_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
Str8 out = wapp_str8_buf(MAIN_BUF_SIZE); snprintf(tmp, 2, "%c", PATH_SEP);
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); wapp_cpath_join_path(out, tmp, "home", "abdelrahman", "Documents");
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); bool result = strcmp(out, expected) == 0;
wapp_str8_format(&tmp, "%c", PATH_SEP); if (!result) {
goto TEST_JOIN_PATH_EXIT;
}
DBL_LIST(Str8) parts = {0}; memset(out, 0, strlen(out));
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_str8(tmp)); snprintf(expected, MAIN_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_cstr("home")); wapp_cpath_join_path(out, "home", "abdelrahman", "Documents");
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_cstr("abdelrahman"));
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_cstr("Documents"));
wapp_cpath_join_path(&out, &parts); result = result && strcmp(out, expected) == 0;
result = wapp_str8_equal(&out, &expected); if (!result) {
goto TEST_JOIN_PATH_EXIT;
}
wapp_dbl_list_pop_front(Str8, &parts); memset(out, 0, strlen(out));
memset(tmp, 0, strlen(tmp));
snprintf(expected, MAIN_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
snprintf(tmp, TMP_BUF_SIZE, "%chome", PATH_SEP);
wapp_cpath_join_path(out, tmp, "abdelrahman", "Documents");
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); result = result && strcmp(out, expected) == 0;
if (!result) {
goto TEST_JOIN_PATH_EXIT;
}
wapp_cpath_join_path(&out, &parts); memset(out, 0, strlen(out));
result = result && wapp_str8_equal(&out, &expected); memset(tmp, 0, strlen(tmp));
snprintf(expected, MAIN_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
snprintf(tmp, TMP_BUF_SIZE, "home%c", PATH_SEP);
wapp_cpath_join_path(out, tmp, "abdelrahman", "Documents");
wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("home")); result = result && strcmp(out, expected) == 0;
wapp_dbl_list_pop_front(Str8, &parts); if (!result) {
wapp_dbl_list_push_front(&parts, &wapp_str8_node_from_str8(tmp)); goto TEST_JOIN_PATH_EXIT;
}
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); memset(out, 0, strlen(out));
memset(tmp, 0, strlen(tmp));
snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
snprintf(tmp, TMP_BUF_SIZE, "%chome", PATH_SEP);
wapp_cpath_join_path(out, tmp, "");
wapp_cpath_join_path(&out, &parts); result = result && strcmp(out, expected) == 0;
result = result && wapp_str8_equal(&out, &expected); if (!result) {
goto TEST_JOIN_PATH_EXIT;
}
wapp_str8_format(&tmp, "home%c", PATH_SEP); memset(out, 0, strlen(out));
wapp_dbl_list_pop_front(Str8, &parts); snprintf(expected, 1, "");
wapp_dbl_list_push_front(&parts, &wapp_str8_node_from_cstr("home")); wapp_cpath_join_path(out, "", "");
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); result = result && strcmp(out, expected) == 0;
if (!result) {
goto TEST_JOIN_PATH_EXIT;
}
wapp_cpath_join_path(&out, &parts); memset(out, 0, strlen(out));
result = result && wapp_str8_equal(&out, &expected); snprintf(expected, MAIN_BUF_SIZE, "home");
wapp_cpath_join_path(out, "", "home");
wapp_dbl_list_empty(&parts); result = result && strcmp(out, expected) == 0;
wapp_str8_format(&tmp, "%chome", PATH_SEP);
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_str8(tmp));
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_cstr(""));
wapp_str8_format(&expected, "%chome", PATH_SEP);
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, &parts);
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_cstr(""));
wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_back(Str8, &parts);
wapp_dbl_list_push_back(&parts, &wapp_str8_node_from_cstr("home"));
wapp_str8_copy_cstr_capped(&expected, "home");
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
TEST_JOIN_PATH_EXIT:
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_cpath_dirname(void) { TestFuncResult test_cpath_dirname(void) {
Allocator arena = wapp_mem_arena_allocator_init(MB(8)); char dst[MAIN_BUF_SIZE] = {0};
if (wapp_mem_allocator_invalid(&arena)) { char expected[MAIN_BUF_SIZE] = {0};
return wapp_tester_result(false); char tmp[TMP_BUF_SIZE] = {0};
snprintf(tmp, 2, "%c", PATH_SEP);
wapp_cpath_dirname(dst, tmp);
bool result = strcmp(dst, tmp) == 0;
if (!result) {
goto TEST_DIRNAME_EXIT;
} }
bool result; memset(dst, 0, strlen(dst));
Str8 *output = NULL; wapp_cpath_dirname(dst, "home");
result = strcmp(dst, ".") == 0;
if (!result) {
goto TEST_DIRNAME_EXIT;
}
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); memset(dst, 0, strlen(dst));
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); wapp_cpath_dirname(dst, "");
result = strcmp(dst, ".") == 0;
if (!result) {
goto TEST_DIRNAME_EXIT;
}
// CASE 1 memset(dst, 0, strlen(dst));
wapp_str8_format(&tmp, "%c", PATH_SEP); snprintf(tmp, TMP_BUF_SIZE, "%chome%ctest", PATH_SEP, PATH_SEP);
wapp_str8_format(&expected, "%c", PATH_SEP); snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
wapp_cpath_dirname(dst, tmp);
result = strcmp(dst, expected) == 0;
if (!result) {
goto TEST_DIRNAME_EXIT;
}
output = wapp_cpath_dirname(&arena, &tmp); memset(dst, 0, strlen(dst));
result = output != NULL && wapp_str8_equal(output, &expected); memset(tmp, 0, strlen(tmp));
memset(expected, 0, strlen(expected));
// CASE 2 snprintf(tmp, TMP_BUF_SIZE, "%chome%ctest%c", PATH_SEP, PATH_SEP, PATH_SEP);
wapp_str8_format(&expected, "%s", "."); snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
wapp_cpath_dirname(dst, tmp);
output = wapp_cpath_dirname(&arena, &wapp_str8_lit("home")); result = strcmp(dst, expected) == 0;
result = result && output != NULL && wapp_str8_equal(output, &expected);
// CASE 3
output = wapp_cpath_dirname(&arena, &wapp_str8_lit(""));
result = result && output != NULL && wapp_str8_equal(output, &expected);
// CASE 4
wapp_str8_format(&tmp, "%chome%ctest", PATH_SEP, PATH_SEP);
wapp_str8_format(&expected, "%chome", PATH_SEP);
output = wapp_cpath_dirname(&arena, &tmp);
result = result && output != NULL && wapp_str8_equal(output, &expected);
// CASE 5
wapp_str8_format(&tmp, "%chome%ctest%c", PATH_SEP, PATH_SEP, PATH_SEP);
wapp_str8_format(&expected, "%chome", PATH_SEP);
output = wapp_cpath_dirname(&arena, &tmp);
result = result && output != NULL && wapp_str8_equal(output, &expected);
wapp_mem_arena_allocator_destroy(&arena);
TEST_DIRNAME_EXIT:
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_cpath_dirup(void) { TestFuncResult test_cpath_dirup(void) {
Allocator arena = wapp_mem_arena_allocator_init(MB(8)); char dst[MAIN_BUF_SIZE] = {0};
if (wapp_mem_allocator_invalid(&arena)) { char expected[MAIN_BUF_SIZE] = {0};
return wapp_tester_result(false); char tmp[TMP_BUF_SIZE] = {0};
snprintf(tmp, 2, "%c", PATH_SEP);
wapp_cpath_dirup(dst, 3, tmp);
bool result = strcmp(dst, tmp) == 0;
if (!result) {
goto TEST_DIRUP_EXIT;
} }
bool result; memset(dst, 0, strlen(dst));
Str8 *output = NULL; memset(tmp, 0, strlen(tmp));
snprintf(tmp, TMP_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
snprintf(expected, MAIN_BUF_SIZE, "%c", PATH_SEP);
wapp_cpath_dirup(dst, 3, tmp);
result = strcmp(dst, expected) == 0;
if (!result) {
goto TEST_DIRUP_EXIT;
}
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); memset(dst, 0, strlen(dst));
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); memset(tmp, 0, strlen(tmp));
snprintf(tmp, TMP_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
wapp_cpath_dirup(dst, 3, tmp);
result = strcmp(dst, ".") == 0;
if (!result) {
goto TEST_DIRUP_EXIT;
}
// CASE 1 memset(dst, 0, strlen(dst));
wapp_str8_format(&tmp, "%c", PATH_SEP); memset(tmp, 0, strlen(tmp));
wapp_str8_format(&expected, "%c", PATH_SEP); memset(expected, 0, strlen(expected));
snprintf(tmp, TMP_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
wapp_cpath_dirup(dst, 2, tmp);
result = strcmp(dst, expected) == 0;
if (!result) {
goto TEST_DIRUP_EXIT;
}
output = wapp_cpath_dirup(&arena, &tmp, 3); memset(dst, 0, strlen(dst));
result = output != NULL && wapp_str8_equal(output, &expected); memset(tmp, 0, strlen(tmp));
snprintf(tmp, TMP_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
// CASE 2 wapp_cpath_dirup(dst, 2, tmp);
wapp_str8_format(&tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); result = strcmp(dst, "home") == 0;
wapp_str8_format(&expected, "%c", PATH_SEP);
output = wapp_cpath_dirup(&arena, &tmp, 3);
result = result && output != NULL && wapp_str8_equal(output, &expected);
// CASE 3
wapp_str8_format(&tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
wapp_str8_copy_cstr_capped(&expected, ".");
output = wapp_cpath_dirup(&arena, &tmp, 3);
result = result && output != NULL && wapp_str8_equal(output, &expected);
// CASE 4
wapp_str8_format(&tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
wapp_str8_format(&expected, "%chome", PATH_SEP);
output = wapp_cpath_dirup(&arena, &tmp, 2);
result = result && output != NULL && wapp_str8_equal(output, &expected);
// CASE 5
wapp_str8_format(&tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
wapp_str8_copy_cstr_capped(&expected, "home");
output = wapp_cpath_dirup(&arena, &tmp, 2);
result = result && output != NULL && wapp_str8_equal(output, &expected);
wapp_mem_arena_allocator_destroy(&arena);
TEST_DIRUP_EXIT:
return wapp_tester_result(result); return wapp_tester_result(result);
} }

View File

@@ -1,7 +1,7 @@
#ifndef TEST_CPATH_H #ifndef TEST_CPATH_H
#define TEST_CPATH_H #define TEST_CPATH_H
#include "wapp.h" #include "tester.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE

View File

@@ -1,16 +1,13 @@
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "commander.h"
#include "tester.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
TestFuncResult test_commander_cmd_success(void) { TestFuncResult test_commander_cmd_success(void) {
DBL_LIST(Str8) cmd = {0}; CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, 0, "echo", "hello world");
wapp_dbl_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo"));
wapp_dbl_list_push_back(&cmd, &wapp_str8_node_from_cstr("hello world"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS && bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR; result.error == SHELL_ERR_NO_ERROR;
@@ -18,10 +15,7 @@ TestFuncResult test_commander_cmd_success(void) {
} }
TestFuncResult test_commander_cmd_failure(void) { TestFuncResult test_commander_cmd_failure(void) {
DBL_LIST(Str8) cmd = {0}; CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, 0, "grep");
wapp_dbl_list_push_back(&cmd, &wapp_str8_node_from_cstr("grep"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
bool failed = result.exited && result.exit_code != EXIT_SUCCESS && bool failed = result.exited && result.exit_code != EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR; result.error == SHELL_ERR_NO_ERROR;
@@ -29,35 +23,27 @@ TestFuncResult test_commander_cmd_failure(void) {
} }
TestFuncResult test_commander_cmd_out_buf_success(void) { TestFuncResult test_commander_cmd_out_buf_success(void) {
Str8 buf = wapp_str8_buf(64); char buf[64] = {0};
Str8 expected = wapp_str8_buf(64); char expected_output[64] = {0};
char msg[] = "hello world"; const char *msg = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg); u64 length = strlen(msg);
snprintf(expected_output, length + 2, "%s\n", msg);
DBL_LIST(Str8) cmd = {0}; CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, buf, 64, "echo", msg);
wapp_dbl_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo"));
wapp_dbl_list_push_back(&cmd, &wapp_str8_node_from_cstr(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS && bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR && wapp_str8_equal_to_count(&buf, &expected, strlen(msg)); result.error == SHELL_ERR_NO_ERROR &&
strncmp(buf, expected_output, length) == 0;
return wapp_tester_result(succeeded); return wapp_tester_result(succeeded);
} }
TestFuncResult test_commander_cmd_out_buf_failure(void) { TestFuncResult test_commander_cmd_out_buf_failure(void) {
Str8 buf = wapp_str8_buf(4); char buf[4] = {0};
Str8 expected = wapp_str8_buf(64); const char *msg = "hello world";
char msg[] = "hello world"; u64 length = strlen(msg);
wapp_str8_copy_cstr_capped(&expected, msg); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, buf, 4, "echo", msg);
DBL_LIST(Str8) cmd = {0};
wapp_dbl_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo"));
wapp_dbl_list_push_back(&cmd, &wapp_str8_node_from_cstr(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
bool failed = !result.exited && result.exit_code != EXIT_SUCCESS && bool failed = !result.exited && result.exit_code != EXIT_SUCCESS &&
result.error == SHELL_ERR_OUT_BUF_FULL && !wapp_str8_equal(&buf, &expected); result.error == SHELL_ERR_OUT_BUF_FULL && strncmp(buf, msg, length) != 0;
return wapp_tester_result(failed); return wapp_tester_result(failed);
} }

View File

@@ -1,7 +1,7 @@
#ifndef TEST_SHELL_COMMANDER_H #ifndef TEST_SHELL_COMMANDER_H
#define TEST_SHELL_COMMANDER_H #define TEST_SHELL_COMMANDER_H
#include "wapp.h" #include "tester.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE

View File

@@ -1,614 +0,0 @@
#include "test_str8.h"
#include "wapp.h"
#include <stdbool.h>
#define ARRLEN(ARR) (sizeof(ARR) / sizeof(ARR[0]))
TestFuncResult test_str8_lit(void) {
bool result;
Str8 s1 = wapp_str8_lit("Hello world");
result = s1.capacity == 22 && s1.capacity != s1.size;
Str8 s2 = wapp_str8_lit("Different strokes for different folks");
result = result && s2.capacity == 74 && s2.capacity != s2.size;
Str8 s3 = wapp_str8_lit("Discretion is the better part of valour");
result = result && s3.capacity == 78 && s3.capacity != s3.size;
Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view");
result = result && s4.capacity == 76 && s4.capacity != s4.size;
Str8 s5 = wapp_str8_lit("Do as I say, not as I do");
result = result && s5.capacity == 48 && s5.capacity != s5.size;
Str8 s6 = wapp_str8_lit("Do as you would be done by");
result = result && s6.capacity == 52 && s6.capacity != s6.size;
Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you");
result = result && s7.capacity == 94 && s7.capacity != s7.size;
return wapp_tester_result(result);
}
TestFuncResult test_str8_lit_ro(void) {
bool result;
Str8RO s1 = wapp_str8_lit_ro("Hello world");
result = s1.capacity == 11 && s1.capacity == s1.size;
Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks");
result = result && s2.capacity == 37 && s2.capacity == s2.size;
Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour");
result = result && s3.capacity == 39 && s3.capacity == s3.size;
Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view");
result = result && s4.capacity == 38 && s4.capacity == s4.size;
Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do");
result = result && s5.capacity == 24 && s5.capacity == s5.size;
Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by");
result = result && s6.capacity == 26 && s6.capacity == s6.size;
Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you");
result = result && s7.capacity == 47 && s7.capacity == s7.size;
return wapp_tester_result(result);
}
TestFuncResult test_str8_buf(void) {
bool result;
Str8 s1 = wapp_str8_buf(1024);
result = s1.capacity == 1024 && s1.size == 0;
Str8 s2 = wapp_str8_buf(2048);
result = result && s2.capacity == 2048 && s2.size == 0;
Str8 s3 = wapp_str8_buf(4096);
result = result && s3.capacity == 4096 && s3.size == 0;
Str8 s4 = wapp_str8_buf(8192);
result = result && s4.capacity == 8192 && s4.size == 0;
return wapp_tester_result(result);
}
TestFuncResult test_str8_alloc_buf(void) {
bool result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false);
}
u64 capacity = 4096;
Str8 *s = wapp_str8_alloc_buf(&allocator, capacity);
if (!s) {
result = false;
goto TEST_ALLOC_BUF_CLEANUP;
}
result = s->capacity == capacity;
const char *cstr = "My name is Abdelrahman";
wapp_str8_copy_cstr_capped(s, cstr);
result = result && s->capacity == capacity && s->size == strlen(cstr) && memcmp(s->buf, cstr, s->size) == 0;
TEST_ALLOC_BUF_CLEANUP:
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_str8_alloc_cstr(void) {
bool result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false);
}
char *str = "Abdelrahman";
u64 length = strlen(str);
Str8 *s = wapp_str8_alloc_cstr(&allocator, str);
if (!s) {
return wapp_tester_result(false);
}
result = s->size == length && memcmp(s->buf, str, length) == 0;
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_str8_alloc_str8(void) {
bool result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false);
}
Str8 str = wapp_str8_lit("Abdelrahman");
Str8 *s = wapp_str8_alloc_str8(&allocator, &str);
if (!s) {
return wapp_tester_result(false);
}
result = wapp_str8_equal(s, &str);
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_str8_alloc_substr(void) {
bool result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false);
}
Str8 str = wapp_str8_lit("Abdelrahman");
Str8 *s = wapp_str8_alloc_substr(&allocator, &str, 3, 8);
if (!s) {
return wapp_tester_result(false);
}
result = s->size == 5 && memcmp(s->buf, "elrah", s->size) == 0;
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_str8_get_index_within_bounds(void) {
bool result;
Str8RO s1 = wapp_str8_lit_ro("Hello world");
result = wapp_str8_get(&s1, 4) == 'o';
Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks");
result = result && wapp_str8_get(&s2, 0) == 'D';
Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour");
result = result && wapp_str8_get(&s3, 13) == ' ';
Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view");
result = result && wapp_str8_get(&s4, 20) == 'n';
Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do");
result = result && wapp_str8_get(&s5, 11) == ',';
Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by");
result = result && wapp_str8_get(&s6, 25) == 'y';
Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you");
result = result && wapp_str8_get(&s7, 16) == 's';
return wapp_tester_result(result);
}
TestFuncResult test_str8_get_index_out_of_bounds(void) {
Str8 s1 = wapp_str8_lit("Hello world");
bool result = wapp_str8_get(&s1, 20) == '\0';
return wapp_tester_result(result);
}
TestFuncResult test_str8_set(void) {
bool result;
Str8 s1 = wapp_str8_lit("Hello world");
wapp_str8_set(&s1, 4, 'f');
result = wapp_str8_get(&s1, 4) == 'f';
Str8 s2 = wapp_str8_lit("Different strokes for different folks");
wapp_str8_set(&s2, 0, 'A');
result = result && wapp_str8_get(&s2, 0) == 'A';
Str8 s3 = wapp_str8_lit("Discretion is the better part of valour");
wapp_str8_set(&s3, 13, 'u');
result = result && wapp_str8_get(&s3, 13) == 'u';
Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view");
wapp_str8_set(&s4, 20, 'R');
result = result && wapp_str8_get(&s4, 20) == 'R';
Str8 s5 = wapp_str8_lit("Do as I say, not as I do");
wapp_str8_set(&s5, 11, '.');
result = result && wapp_str8_get(&s5, 11) == '.';
Str8 s6 = wapp_str8_lit("Do as you would be done by");
wapp_str8_set(&s6, 25, 'w');
result = result && wapp_str8_get(&s6, 25) == 'w';
Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you");
wapp_str8_set(&s7, 16, 'i');
result = result && wapp_str8_get(&s7, 16) == 'i';
return wapp_tester_result(result);
}
TestFuncResult test_str8_push_back(void) {
bool result;
Str8 expected = wapp_str8_lit("Abdelrahman");
Str8 buf = wapp_str8_buf(64);
wapp_str8_push_back(&buf, 'A');
wapp_str8_push_back(&buf, 'b');
wapp_str8_push_back(&buf, 'd');
wapp_str8_push_back(&buf, 'e');
wapp_str8_push_back(&buf, 'l');
wapp_str8_push_back(&buf, 'r');
wapp_str8_push_back(&buf, 'a');
wapp_str8_push_back(&buf, 'h');
wapp_str8_push_back(&buf, 'm');
wapp_str8_push_back(&buf, 'a');
wapp_str8_push_back(&buf, 'n');
result = wapp_str8_equal(&buf, &expected);
return wapp_tester_result(result);
}
TestFuncResult test_str8_equal(void) {
bool result;
Str8RO s1 = wapp_str8_lit_ro("hello");
Str8RO s2 = wapp_str8_lit_ro("hell");
Str8RO s3 = wapp_str8_lit_ro("hello");
Str8RO s4 = wapp_str8_lit_ro("goodbye");
result = wapp_str8_equal(&s1, &s2) == false;
result = result && wapp_str8_equal(&s1, &s3) == true;
result = result && wapp_str8_equal(&s1, &s4) == false;
return wapp_tester_result(result);
}
TestFuncResult test_str8_slice(void) {
bool result;
Str8 s = wapp_str8_lit("Different strokes for different folks");
Str8RO sub1 = wapp_str8_slice(&s, 3, 9);
result = sub1.size == 6 && sub1.capacity == 6;
Str8RO sub2 = wapp_str8_slice(&s, 18, 21);
result = result && sub2.size == 3 && sub2.capacity == 3;
Str8RO sub3 = wapp_str8_slice(&s, 5, 1);
result = result && sub3.size == 0 && sub3.capacity == 0;
Str8RO sub4 = wapp_str8_slice(&s, 70, 80);
result = result && sub4.size == 0 && sub4.capacity == 0;
return wapp_tester_result(result);
}
TestFuncResult test_str8_alloc_concat(void) {
bool result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100));
Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me.");
Str8 suffix2 = wapp_str8_lit(" This is my code.");
Str8 concat1 = wapp_str8_lit("Hello world from me.");
Str8 concat2 = wapp_str8_lit("Hello world from me. This is my code.");
Str8 *output;
output = wapp_str8_alloc_concat(&arena, &str, &suffix1);
result = output->size == concat1.size && wapp_str8_equal(output, &concat1);
output = wapp_str8_alloc_concat(&arena, output, &suffix2);
result = result && output->size == concat2.size && wapp_str8_equal(output, &concat2);
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_str8_concat_capped(void) {
bool result;
Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me.");
Str8 suffix2 = wapp_str8_lit(" This is my code.");
Str8 concat1 = wapp_str8_lit("Hello world from me.");
Str8 concat2 = wapp_str8_lit("Hello world from me. T");
wapp_str8_concat_capped(&str, &suffix1);
result = str.size == concat1.size && wapp_str8_equal(&str, &concat1);
wapp_str8_concat_capped(&str, &suffix2);
result = result && str.size == concat2.size && wapp_str8_equal(&str, &concat2);
return wapp_tester_result(result);
}
TestFuncResult test_str8_copy_cstr_capped(void) {
bool result;
Str8 buf = wapp_str8_buf(32);
const char *src1 = "Hello world";
const char *src2 = "Hello world from the Wizard Apprentice standard library";
Str8RO src1_cp = wapp_str8_lit_ro("Hello world");
Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr");
wapp_str8_copy_cstr_capped(&buf, src1);
result = buf.size == src1_cp.size && wapp_str8_equal(&buf, &src1_cp);
wapp_str8_copy_cstr_capped(&buf, src2);
result = result && buf.size == src2_cp.size && buf.size == buf.capacity && wapp_str8_equal(&buf, &src2_cp);
return wapp_tester_result(result);
}
TestFuncResult test_str8_copy_str8_capped(void) {
bool result;
Str8 buf = wapp_str8_buf(32);
Str8RO src1 = wapp_str8_lit_ro("Hello world");
Str8RO src2 = wapp_str8_lit_ro("Hello world from the Wizard Apprentice standard library");
Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr");
wapp_str8_copy_str8_capped(&buf, &src1);
result = buf.size == src1.size && wapp_str8_equal(&buf, &src1);
wapp_str8_copy_str8_capped(&buf, &src2);
result = result && buf.size < src2.size && buf.size == buf.capacity && wapp_str8_equal(&buf, &src2_cp);
return wapp_tester_result(result);
}
TestFuncResult test_str8_format(void) {
bool result;
Str8 buf = wapp_str8_buf(128);
Str8 expected = wapp_str8_lit("My name is Abdelrahman and I am 35 years old");
wapp_str8_format(&buf, "My name is %s and I am %u years old", "Abdelrahman", 35);
result = wapp_str8_equal(&buf, &expected);
return wapp_tester_result(result);
}
TestFuncResult test_str8_find(void) {
bool result;
Str8RO s = wapp_str8_lit("Do as I say, not as I do");
result = wapp_str8_find(&s, wapp_str8_lit_ro("d")) != -1;
result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("not")) != -1);
result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("as I say")) != -1);
result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("f")) == -1);
result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("hello")) == -1);
result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("not sa I")) == -1);
result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("Do unto others as you would have them do to you")) == -1);
return wapp_tester_result(result);
}
TestFuncResult test_str8_rfind(void) {
bool result;
Str8RO s = wapp_str8_lit("Do as I say, not as I do");
result = wapp_str8_rfind(&s, wapp_str8_lit_ro("d")) != -1;
result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("not")) != -1);
result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("as I say")) != -1);
result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("f")) == -1);
result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("hello")) == -1);
result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("not sa I")) == -1);
result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("Do unto others as you would have them do to you")) == -1);
return wapp_tester_result(result);
}
TestFuncResult test_str8_split(void) {
bool result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100));
Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from");
DBL_LIST(Str8) *list1 = wapp_str8_split(&arena, &str, &delim1);
DBL_LIST(Str8) *list2 = wapp_str8_split(&arena, &str, &delim2);
Str8RO splits1[] = {
wapp_str8_slice(&str, 0, 5),
wapp_str8_slice(&str, 6, 11),
wapp_str8_slice(&str, 12, 16),
wapp_str8_slice(&str, 17, 19),
};
Str8RO splits2[] = {
wapp_str8_slice(&str, 0, 12),
wapp_str8_slice(&str, 16, 19),
};
u64 index1 = 0;
u64 count1 = ARRLEN(splits1);
bool running1 = true;
u64 index2 = 0;
u64 count2 = ARRLEN(splits2);
bool running2 = true;
result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3;
result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running1) {
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1]));
++index1;
running1 = index1 < count1;
}
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running2) {
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2]));
++index2;
running2 = index2 < count2;
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_str8_split_with_max(void) {
bool result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100));
Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" ");
DBL_LIST(Str8) *list = wapp_str8_split_with_max(&arena, &str, &delim, 2);
Str8RO splits[] = {
wapp_str8_slice(&str, 0, 5),
wapp_str8_slice(&str, 6, 11),
wapp_str8_slice(&str, 12, 19),
};
u64 index = 0;
u64 count = ARRLEN(splits);
bool running = true;
result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running) {
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index]));
++index;
running = index < count;
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_str8_rsplit(void) {
bool result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100));
Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from");
DBL_LIST(Str8) *list1 = wapp_str8_rsplit(&arena, &str, &delim1);
DBL_LIST(Str8) *list2 = wapp_str8_rsplit(&arena, &str, &delim2);
Str8RO splits1[] = {
wapp_str8_slice(&str, 0, 5),
wapp_str8_slice(&str, 6, 11),
wapp_str8_slice(&str, 12, 16),
wapp_str8_slice(&str, 17, 19),
};
Str8RO splits2[] = {
wapp_str8_slice(&str, 0, 12),
wapp_str8_slice(&str, 16, 19),
};
u64 index1 = 0;
u64 count1 = ARRLEN(splits1);
bool running1 = true;
u64 index2 = 0;
u64 count2 = ARRLEN(splits2);
bool running2 = true;
result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3;
result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running1) {
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1]));
++index1;
running1 = index1 < count1;
}
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running2) {
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2]));
++index2;
running2 = index2 < count2;
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_str8_rsplit_with_max(void) {
bool result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100));
Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" ");
DBL_LIST(Str8) *list = wapp_str8_rsplit_with_max(&arena, &str, &delim, 2);
Str8RO splits[] = {
wapp_str8_slice(&str, 0, 11),
wapp_str8_slice(&str, 12, 16),
wapp_str8_slice(&str, 17, 19),
};
u64 index = 0;
u64 count = ARRLEN(splits);
bool running = true;
result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running) {
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index]));
++index;
running = index < count;
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_str8_join(void) {
bool result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100));
Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from");
DBL_LIST(Str8) *list1 = wapp_str8_rsplit(&arena, &str, &delim1);
DBL_LIST(Str8) *list2 = wapp_str8_rsplit(&arena, &str, &delim2);
Str8 *join1 = wapp_str8_join(&arena, list1, &delim1);
Str8 *join2 = wapp_str8_join(&arena, list2, &delim2);
result = join1->size == str.size && wapp_str8_equal(join1, &str);
result = result && join2->size == str.size && wapp_str8_equal(join2, &str);
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}

View File

@@ -1,40 +0,0 @@
#ifndef TEST_STR8_H
#define TEST_STR8_H
#include "wapp.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
TestFuncResult test_str8_lit(void);
TestFuncResult test_str8_lit_ro(void);
TestFuncResult test_str8_buf(void);
TestFuncResult test_str8_alloc_buf(void);
TestFuncResult test_str8_alloc_cstr(void);
TestFuncResult test_str8_alloc_str8(void);
TestFuncResult test_str8_alloc_substr(void);
TestFuncResult test_str8_alloc_concat(void);
TestFuncResult test_str8_get_index_within_bounds(void);
TestFuncResult test_str8_get_index_out_of_bounds(void);
TestFuncResult test_str8_set(void);
TestFuncResult test_str8_push_back(void);
TestFuncResult test_str8_equal(void);
TestFuncResult test_str8_slice(void);
TestFuncResult test_str8_concat_capped(void);
TestFuncResult test_str8_copy_cstr_capped(void);
TestFuncResult test_str8_copy_str8_capped(void);
TestFuncResult test_str8_format(void);
TestFuncResult test_str8_find(void);
TestFuncResult test_str8_rfind(void);
TestFuncResult test_str8_split(void);
TestFuncResult test_str8_split_with_max(void);
TestFuncResult test_str8_rsplit(void);
TestFuncResult test_str8_rsplit_with_max(void);
TestFuncResult test_str8_join(void);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !TEST_STR8_H

View File

@@ -1,263 +0,0 @@
#include "test_str8_list.h"
#include "wapp.h"
TestFuncResult test_str8_list_get(void) {
bool result;
Str8 s1 = wapp_str8_lit("1");
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
DBL_LIST(Str8) list = {0};
DBL_NODE(Str8) n1 = { .item = &s1 };
DBL_NODE(Str8) n2 = { .item = &s2 };
DBL_NODE(Str8) n3 = { .item = &s3 };
DBL_NODE(Str8) n4 = { .item = &s4 };
DBL_NODE(Str8) n5 = { .item = &s5 };
wapp_dbl_list_push_back(&list, &n1);
wapp_dbl_list_push_back(&list, &n2);
wapp_dbl_list_push_back(&list, &n3);
wapp_dbl_list_push_back(&list, &n4);
wapp_dbl_list_push_back(&list, &n5);
DBL_NODE(Str8) *node = wapp_dbl_list_get(Str8, &list, 0);
result = node->item == &s1 && wapp_str8_equal(node->item, &s1);
node = wapp_dbl_list_get(Str8, &list, 1);
result = result && node->item == &s2 && wapp_str8_equal(node->item, &s2);
node = wapp_dbl_list_get(Str8, &list, 2);
result = result && node->item == &s3 && wapp_str8_equal(node->item, &s3);
node = wapp_dbl_list_get(Str8, &list, 3);
result = result && node->item == &s4 && wapp_str8_equal(node->item, &s4);
node = wapp_dbl_list_get(Str8, &list, 4);
result = result && node->item == &s5 && wapp_str8_equal(node->item, &s5);
return wapp_tester_result(result);
}
TestFuncResult test_str8_list_push_front(void) {
bool result;
Str8 s1 = wapp_str8_lit("1");
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
DBL_LIST(Str8) list = {0};
DBL_NODE(Str8) n1 = { .item = &s1 };
DBL_NODE(Str8) n2 = { .item = &s2 };
DBL_NODE(Str8) n3 = { .item = &s3 };
wapp_dbl_list_push_front(&list, &n1);
result = list.first == list.last && list.first == &n1 && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_front(&list, &n2);
result = result && list.first == &n2 && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_front(&list, &n3);
result = result && list.first == &n3 && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result);
}
TestFuncResult test_str8_list_push_back(void) {
bool result;
Str8 s1 = wapp_str8_lit("1");
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
DBL_LIST(Str8) list = {0};
DBL_NODE(Str8) n1 = { .item = &s1 };
DBL_NODE(Str8) n2 = { .item = &s2 };
DBL_NODE(Str8) n3 = { .item = &s3 };
wapp_dbl_list_push_back(&list, &n1);
result = list.first == list.last && list.last == &n1 && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_back(&list, &n2);
result = result && list.last == &n2 && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_back(&list, &n3);
result = result && list.last == &n3 && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result);
}
TestFuncResult test_str8_list_insert(void) {
bool result;
Str8 s1 = wapp_str8_lit("1");
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8 s6 = wapp_str8_lit("6");
Str8 s7 = wapp_str8_lit("7");
DBL_LIST(Str8) list = {0};
DBL_NODE(Str8) n1 = { .item = &s1 };
DBL_NODE(Str8) n2 = { .item = &s2 };
DBL_NODE(Str8) n3 = { .item = &s3 };
DBL_NODE(Str8) n4 = { .item = &s4 };
DBL_NODE(Str8) n5 = { .item = &s5 };
DBL_NODE(Str8) n6 = { .item = &s6 };
DBL_NODE(Str8) n7 = { .item = &s7 };
wapp_dbl_list_push_back(&list, &n1);
wapp_dbl_list_push_back(&list, &n2);
wapp_dbl_list_push_back(&list, &n3);
wapp_dbl_list_push_back(&list, &n4);
wapp_dbl_list_push_back(&list, &n5);
DBL_NODE(Str8) *node;
wapp_dbl_list_insert(&list, &n6, 2);
node = wapp_dbl_list_get(Str8, &list, 2);
result = node != NULL && node->item == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6;
wapp_dbl_list_insert(&list, &n7, 5);
node = wapp_dbl_list_get(Str8, &list, 5);
result = result && node != NULL && node->item == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7;
return wapp_tester_result(result);
}
TestFuncResult test_str8_list_pop_front(void) {
bool result;
Str8 s1 = wapp_str8_lit("1");
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
DBL_LIST(Str8) list = {0};
DBL_NODE(Str8) n1 = { .item = &s1 };
DBL_NODE(Str8) n2 = { .item = &s2 };
DBL_NODE(Str8) n3 = { .item = &s3 };
DBL_NODE(Str8) n4 = { .item = &s4 };
DBL_NODE(Str8) n5 = { .item = &s5 };
wapp_dbl_list_push_back(&list, &n1);
wapp_dbl_list_push_back(&list, &n2);
wapp_dbl_list_push_back(&list, &n3);
wapp_dbl_list_push_back(&list, &n4);
wapp_dbl_list_push_back(&list, &n5);
DBL_NODE(Str8) *node = wapp_dbl_list_pop_front(Str8, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
TestFuncResult test_str8_list_pop_back(void) {
bool result;
Str8 s1 = wapp_str8_lit("1");
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
DBL_LIST(Str8) list = {0};
DBL_NODE(Str8) n1 = { .item = &s1 };
DBL_NODE(Str8) n2 = { .item = &s2 };
DBL_NODE(Str8) n3 = { .item = &s3 };
DBL_NODE(Str8) n4 = { .item = &s4 };
DBL_NODE(Str8) n5 = { .item = &s5 };
wapp_dbl_list_push_front(&list, &n1);
wapp_dbl_list_push_front(&list, &n2);
wapp_dbl_list_push_front(&list, &n3);
wapp_dbl_list_push_front(&list, &n4);
wapp_dbl_list_push_front(&list, &n5);
DBL_NODE(Str8) *node = wapp_dbl_list_pop_back(Str8, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
TestFuncResult test_str8_list_remove(void) {
bool result;
Str8 s1 = wapp_str8_lit("1");
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
DBL_LIST(Str8) list = {0};
DBL_NODE(Str8) n1 = { .item = &s1 };
DBL_NODE(Str8) n2 = { .item = &s2 };
DBL_NODE(Str8) n3 = { .item = &s3 };
DBL_NODE(Str8) n4 = { .item = &s4 };
DBL_NODE(Str8) n5 = { .item = &s5 };
wapp_dbl_list_push_back(&list, &n1);
wapp_dbl_list_push_back(&list, &n2);
wapp_dbl_list_push_back(&list, &n3);
wapp_dbl_list_push_back(&list, &n4);
wapp_dbl_list_push_back(&list, &n5);
DBL_NODE(Str8) *node = wapp_dbl_list_remove(Str8, &list, 0);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
TestFuncResult test_str8_list_empty(void) {
bool result;
DBL_LIST(Str8) list = {0};
wapp_dbl_list_push_back(&list, &wapp_str8_node_from_cstr("Hello"));
wapp_dbl_list_push_back(&list, &wapp_str8_node_from_cstr("from"));
wapp_dbl_list_push_back(&list, &wapp_str8_node_from_cstr("wizapp"));
wapp_dbl_list_push_back(&list, &wapp_str8_node_from_cstr("stdlib"));
wapp_dbl_list_empty(&list);
result = list.first == NULL && list.last == NULL && list.node_count == 0 && wapp_str8_list_total_size(&list) == 0;
return wapp_tester_result(result);
}

View File

@@ -1,23 +0,0 @@
#ifndef TEST_STR8_LIST_H
#define TEST_STR8_LIST_H
#include "wapp.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
TestFuncResult test_str8_list_get(void);
TestFuncResult test_str8_list_push_front(void);
TestFuncResult test_str8_list_push_back(void);
TestFuncResult test_str8_list_insert(void);
TestFuncResult test_str8_list_pop_front(void);
TestFuncResult test_str8_list_pop_back(void);
TestFuncResult test_str8_list_remove(void);
TestFuncResult test_str8_list_empty(void);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !TEST_STR8_LIST_H

View File

@@ -1,61 +1,18 @@
#include "test_str8.h"
#include "test_str8_list.h"
#include "test_allocator.h" #include "test_allocator.h"
#include "test_arena.h" #include "test_arena.h"
#include "test_cpath.h" #include "test_cpath.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "tester.h"
#include <stdlib.h> #include <stdlib.h>
int main(void) { int main(void) {
wapp_tester_run_tests(test_arena_allocator, wapp_tester_run_tests(test_libc_allocator, test_arena_allocator, test_arena_init,
test_arena_init, test_arena_init_succeeds_when_reserving_very_large_size, test_cpath_join_path,
test_arena_init_succeeds_when_reserving_very_large_size, test_cpath_dirname, test_cpath_dirup, test_arena_alloc_succeeds_when_within_capacity,
test_arena_alloc_succeeds_when_within_capacity, test_arena_alloc_fails_when_over_capacity, test_arena_realloc_bigger_size,
test_arena_alloc_fails_when_over_capacity, test_arena_realloc_smaller_size, test_arena_clear, test_arena_destroy,
test_arena_realloc_bigger_size, test_commander_cmd_success, test_commander_cmd_failure,
test_arena_realloc_smaller_size, test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_failure);
test_arena_clear,
test_arena_destroy,
test_str8_lit,
test_str8_lit_ro,
test_str8_buf,
test_str8_alloc_buf,
test_str8_alloc_cstr,
test_str8_alloc_str8,
test_str8_alloc_substr,
test_str8_alloc_concat,
test_str8_get_index_within_bounds,
test_str8_get_index_out_of_bounds,
test_str8_set,
test_str8_equal,
test_str8_slice,
test_str8_concat_capped,
test_str8_copy_cstr_capped,
test_str8_copy_str8_capped,
test_str8_format,
test_str8_find,
test_str8_rfind,
test_str8_split,
test_str8_split_with_max,
test_str8_rsplit,
test_str8_rsplit_with_max,
test_str8_join,
test_str8_list_get,
test_str8_list_push_front,
test_str8_list_push_back,
test_str8_list_insert,
test_str8_list_pop_front,
test_str8_list_pop_back,
test_str8_list_remove,
test_str8_list_empty,
test_cpath_join_path,
test_cpath_dirname,
test_cpath_dirup,
test_commander_cmd_success,
test_commander_cmd_failure,
test_commander_cmd_out_buf_success,
test_commander_cmd_out_buf_failure);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }