72 Commits

Author SHA1 Message Date
0354c7b485 Prefix static macros 2025-10-18 16:17:13 +01:00
9f32891bbc Add test for str8 array 2025-09-28 00:05:17 +01:00
b3ebff3635 Remove ABS_INSTALL_PREFIX 2025-09-20 15:43:36 +01:00
14bd6ce5fd File utilities and datatype implementation for a C-based code generator (#5)
Co-authored-by: Abdelrahman Said <said.abdelrahman@flawlessai.com>
Reviewed-on: #5
Co-authored-by: Abdelrahman <said.abdelrahman89@gmail.com>
Co-committed-by: Abdelrahman <said.abdelrahman89@gmail.com>
2025-09-20 13:48:08 +00:00
09e96f8112 Update Makefile 2025-09-06 21:27:17 +01:00
Abdelrahman Said
9cbd0b29ef Fix build on macOS 2025-09-01 22:10:41 +01:00
26fd329caa Update codegen to support accepting JSON file as input 2025-08-31 20:56:49 +01:00
1e224702a3 Add default target as one of the available targets when make help is run 2025-08-31 14:21:55 +01:00
74cca183e0 Make all the default target 2025-08-31 14:20:44 +01:00
e26bf613a5 Add support for release builds with debug info and using lib externally 2025-08-31 14:17:04 +01:00
Abdelrahman Said
81e3ab2c67 Switch to using intercept build since OSX [SIP](https://en.wikipedia.org/wiki/System_Integrity_Protection) stop bear from working 2025-08-16 13:25:38 +01:00
Abdelrahman Said
8ec0757b34 Add .venv to gitignore 2025-08-16 13:25:28 +01:00
Abdelrahman Said
eb98de7c2b Unify build flags 2025-08-16 13:16:21 +01:00
d3fccd61b5 Reintroduce C++ support and add usage tests for C++ (#4)
Reviewed-on: #4
Co-authored-by: Abdelrahman <said.abdelrahman89@gmail.com>
Co-committed-by: Abdelrahman <said.abdelrahman89@gmail.com>
2025-08-10 22:33:40 +00:00
011083ab83 Replace bool, true and false with aliases 2025-08-09 22:38:03 +01:00
b8c548ee4b Add static, runtime and debug assert utilities 2025-08-09 22:37:55 +01:00
75be2316e0 Add vim encoding and folding marker 2025-08-09 14:35:28 +01:00
Abdelrahman Said
d452225d02 Don't use uchar.h on macos 2025-05-20 16:52:12 +01:00
74164717d0 Fix bug in array codegen 2025-05-05 19:15:58 +01:00
6c8434a530 Use asserts in array 2025-05-05 20:06:58 +01:00
cac66b9dbb Use asserts in dbl_list 2025-05-05 19:55:42 +01:00
175f627f93 Remove text from asserts 2025-05-05 19:29:44 +01:00
be30189d15 Assert uuid argument isn't NULL 2025-05-05 19:12:13 +01:00
3689c17d09 Use asserts to validate arguments for Str8 2025-05-05 19:08:44 +01:00
8e952d9bc8 Use assert to validate inputs to allocator functions 2025-05-05 19:01:10 +01:00
def7576101 Use asserts in arena 2025-05-05 18:57:11 +01:00
3fed536a74 Use assert in wapp_mem_util_align_forward instead of returning NULL 2025-05-05 18:51:10 +01:00
aae39fe656 Fix MSVC errors 2025-05-05 16:41:56 +01:00
4e3945d1d0 Refactor array to avoid having to include external types 2025-05-05 16:33:08 +01:00
98a802e3eb Remove C++ pseudo support 2025-05-05 02:48:35 +01:00
0d4aa7a9c2 Modify README.md 2025-05-05 02:28:29 +01:00
a229f9be8c Run codegen on Linux 2025-05-05 00:04:24 +01:00
2156d2ff3a Fix MSVC Spectre warnings 2025-05-04 23:59:50 +01:00
12f083edb0 Add code generation for array 2025-05-04 23:26:03 +01:00
f444911452 Refactor strings and allocator to primitives 2025-05-04 23:25:27 +01:00
163283f77f Remove unnecessary separate handling for bool type 2025-05-04 22:20:38 +01:00
6064ed346c Ensure arena capacity is a power of 2 2025-05-04 18:02:32 +01:00
77f3c40ebd Add copy array with allocation and finish writing array tests 2025-04-27 19:30:14 +01:00
d3f1686d58 Add testing for i32 array to test array logic 2025-04-21 17:47:33 +01:00
a359331df7 Complete array implementation before moving it to codegen 2025-04-21 17:46:59 +01:00
14115f7e7e Move rounding up and va_args count to misc_utils 2025-04-21 17:46:27 +01:00
12bd3eb489 Add .clangd config file 2025-04-21 14:21:40 +01:00
266d43e262 Update Makefile 2025-04-21 14:16:54 +01:00
a568b30163 Update snippets 2025-04-21 13:52:24 +01:00
b1773746d8 Add missing include 2025-04-21 13:45:29 +01:00
a479a43f4c Reformat 2025-04-20 21:32:38 +01:00
b476ceaeef Fix MSVC Spectre warnings 2025-04-20 20:28:02 +01:00
4d69b97149 Add /std:c11 to Windows build 2025-04-20 20:20:39 +01:00
181c4b8614 Update xorshift 2025-04-20 20:47:20 +01:00
0d541f6ee8 Add aliases.h and platform.h by default in codegen 2025-04-20 20:10:10 +01:00
9e34b37d8d Update codegen with WAPP_PLATFORM_CPP 2025-04-20 19:57:57 +01:00
b884d0e6a6 Switch to using WAPP_PLATFORM_CPP instead of __cplusplus 2025-04-20 19:52:33 +01:00
494bbeb398 Update platform cracking 2025-04-20 19:42:45 +01:00
7605eb4e57 Add C and CPP version macros 2025-04-20 19:39:16 +01:00
037b0fe698 Enforce C11 with GNU extensions on POSIX platforms 2025-04-20 18:28:17 +01:00
b13274cd81 Add compiler detection macros 2025-04-20 18:27:57 +01:00
4f9f632362 Update windows build script 2025-04-20 17:28:38 +01:00
6b039aeac0 Use posix path separator for codegen even on Windows 2025-04-20 16:47:11 +01:00
2ab3bfc2e1 Fix wrong include 2025-04-20 16:46:31 +01:00
bf99bef291 Support multiple python versions for code generation 2025-04-20 16:23:23 +01:00
50e23d8a13 Testing ideas for array implementation 2025-04-20 00:21:22 +01:00
3a49dba366 Generate dbl_list for default C types 2025-04-19 22:17:26 +01:00
1cfc52b35e Handle pointer types properly in dbl_list codegen 2025-04-19 21:27:00 +01:00
25395553d7 Fix codegen hidden bugs 2025-04-19 21:11:10 +01:00
9a651665ba Remove forward declaration from dbl_list source 2025-04-19 20:56:15 +01:00
8dbdfa2094 Update dbl_list codegen 2025-04-19 20:54:04 +01:00
add2ba541d Merge branch 'codegen' 2025-04-19 13:52:27 +01:00
63ed2633ea Update code generation to create one file for dbl_list 2025-04-19 13:33:09 +01:00
Abdelrahman Said
3c32b247c0 Upgrade codegen 2025-04-17 09:03:30 +01:00
Abdelrahman Said
31373eba03 Update dbl_list functionality 2025-04-16 00:42:20 +01:00
Abdelrahman Said
778a4da092 Add utility to create list node from item 2025-04-16 00:27:01 +01:00
Abdelrahman Said
6fb078a868 Remove codegen and implement dbl_list as generic container 2025-04-16 00:07:11 +01:00
139 changed files with 15488 additions and 1074 deletions

2
.clangd Normal file
View File

@@ -0,0 +1,2 @@
CompileFlags:
Add: -ferror-limit=0

3
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.cache .cache
.vscode .vscode
.venv
test test
test.* test.*
*.dSYM *.dSYM
@@ -8,6 +9,6 @@ test.*
*.obj *.obj
compile_commands.json compile_commands.json
libwapp-build libwapp-build
libwapp.so dist
*.vs *.vs
__pycache__ __pycache__

149
Makefile
View File

@@ -1,22 +1,42 @@
CC = clang .PHONY: help full prng testing uuid core primitives all clean builddir build-test run-test codegen install build-lib ccodegen
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) # External variables
CFLAGS += -g -fsanitize=address,undefined CC = clang
else ifeq ($(BUILD_TYPE),release) CXX = clang++
CFLAGS += -O3 AR = ar
BUILD_TYPE = Debug
BUILD_DIR = libwapp-build/$(PLATFORM)-$(BUILD_TYPE)
INSTALL_PREFIX = dist
# Internal variables
override CFLAGS = -Wall -Wextra -Werror -pedantic -Isrc
override LIBFLAGS = -fPIC
override CSTD := -std=gnu11
override CXXSTD := -std=gnu++11
override KERNEL := $(shell uname -s)
override MACHINE := $(shell uname -m)
override PLATFORM := $(KERNEL)_$(MACHINE)
override TEST_INCLUDE := -Isrc $(shell find tests -type d | xargs -I{} echo -n "-I{} ")
override TEST_SRC := $(shell find tests -type f -name "*.c" | xargs -I{} echo -n "{} ")
override TEST_C_SRC := src/wapp.c $(TEST_SRC)
override TEST_CXX_SRC := $(shell find tests -type f -name "*.cc" | xargs -I{} echo -n "{} ")
override LIB_NAME := wapp
override OBJ_OUT := $(BUILD_DIR)/$(LIB_NAME).o
override LIB_OUT := $(BUILD_DIR)/lib$(LIB_NAME).a
override TEST_C_OUT := $(BUILD_DIR)/wapptest
override TEST_CXX_OUT := $(BUILD_DIR)/wapptestcc
override INCLUDE_INSTALL := $(INSTALL_PREFIX)/include/$(LIB_NAME)
override LIB_INSTALL := $(INSTALL_PREFIX)/lib
override HEADER_INSTALL_CMD := scripts/header_install.sh
ifeq ($(BUILD_TYPE),Debug)
override CFLAGS += -g -fsanitize=address,undefined -DWAPP_DEBUG_ASSERT
else ifeq ($(BUILD_TYPE),RelWithDebInfo)
override CFLAGS += -g -O2 -fsanitize=address,undefined -DWAPP_DEBUG_ASSERT
else ifeq ($(BUILD_TYPE),Release)
override CFLAGS += -O3
else else
$(error Invalid BUILD type '$(BUILD_TYPE)'. Use 'debug' or 'release') $(error Invalid BUILD type '$(BUILD_TYPE)'. Use 'Debug', 'RelWithDebInfo' or 'Release')
endif endif
ifeq ($(CC),gcc) ifeq ($(CC),gcc)
@@ -24,9 +44,51 @@ ifeq ($(CC),gcc)
export ASAN_OPTIONS=verify_asan_link_order=0 export ASAN_OPTIONS=verify_asan_link_order=0
endif endif
.PHONY: all clean builddir codegen build-test run-test build-lib full prng testing uuid core all: clean builddir codegen run-c-test full run-cc-test
all: clean builddir codegen run-test full help:
@echo "Available build variables:"
@echo " CC C compiler to use (Default: clang)."
@echo " CXX C++ compiler to use (Default: clang++)."
@echo " AR Archiving utility to use for building static libraries (Default: ar)."
@echo " BUILD_TYPE Build type. Choose from \`Debug\`, \`RelWithDebInfo\` or \`Release\` (Default: Debug)."
@echo " BUILD_DIR Directory where build files will be written."
@echo " INSTALL_PREFIX Prefix where library and include files will be installed."
@echo
@echo "Available targets:"
@echo " make Build, install and test the full wapp library."
@echo " make full Build and install the full wapp library."
@echo " make core Build and install only the \`core\` component of the wapp library with all its dependencies."
@echo " make prng Build and install only the \`prng\` component of the wapp library with all its dependencies."
@echo " make uuid Build and install only the \`uuid\` component of the wapp library with all its dependencies."
@echo " make testing Build and install only the \`testing\` component of the wapp library with all its dependencies."
@echo " make primitives Build and install only the \`primitives\` component of the wapp library with all its dependencies."
@echo " make clean Clean build directory."
@echo " make help Print this help message and exit."
full: LIB_SRC = src/wapp.c
full: INCLUDES = common core primitives prng testing uuid
full: install
prng: LIB_SRC = src/prng/wapp_prng.c
prng: INCLUDES = common prng
prng: install
testing: LIB_SRC = src/testing/wapp_testing.c
testing: INCLUDES = common core testing
testing: install
uuid: LIB_SRC = src/uuid/wapp_uuid.c
uuid: INCLUDES = common primitives prng
uuid: install
core: LIB_SRC = src/core/wapp_core.c
core: INCLUDES = common core primitives
core: install
primitives: LIB_SRC = src/primitives/wapp_primitives.c
primitives: INCLUDES = common primitives
primitives: install
clean: clean:
@rm -rf $(BUILD_DIR) @rm -rf $(BUILD_DIR)
@@ -34,30 +96,35 @@ clean:
builddir: builddir:
@mkdir -p $(BUILD_DIR) @mkdir -p $(BUILD_DIR)
build-c-test:
$(CC) $(CSTD) $(CFLAGS) $(TEST_INCLUDE) $(TEST_C_SRC) -o $(TEST_C_OUT)
run-c-test: build-c-test
@echo -e "\n\033[34;1mRUNNING C TESTS\033[0m"
@$(TEST_C_OUT)
@rm $(TEST_C_OUT)
build-cc-test:
$(CXX) $(CXXSTD) $(CFLAGS) $(TEST_INCLUDE) $(TEST_CXX_SRC) $(LIB_OUT) -o $(TEST_CXX_OUT)
run-cc-test: build-cc-test
@echo -e "\n\033[34;1mRUNNING C++ TESTS\033[0m"
@export LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(BUILD_DIR) && $(TEST_CXX_OUT)
@rm $(TEST_CXX_OUT)
codegen: codegen:
python3 -m codegen python3 -m codegen
build-test: install: build-lib
$(CC) $(CFLAGS) $(TEST_INCLUDE) $(TEST_SRC) -o $(TEST_OUT) @mkdir -p $(LIB_INSTALL)
@cp -v $(LIB_OUT) $(LIB_INSTALL)
@mkdir -p $(INCLUDE_INSTALL)
@bash $(HEADER_INSTALL_CMD) $(LIB_SRC) $(INCLUDE_INSTALL) $(INCLUDES)
run-test: build-test build-lib: builddir
@$(TEST_OUT) $(CC) -c $(CSTD) $(CFLAGS) $(LIBFLAGS) $(LIB_SRC) -o $(OBJ_OUT)
@rm $(TEST_OUT) $(AR) r $(LIB_OUT) $(OBJ_OUT)
@rm $(OBJ_OUT)
build-lib: ccodegen:
$(CC) $(CFLAGS) $(LIBFLAGS) $(LIB_SRC) -o $(LIB_OUT) $(CC) $(CSTD) $(CFLAGS) $(LIBFLAGS) -Isrc/core src/core/wapp_core.c ccodegen/*.c -o ccgen
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

View File

@@ -1,3 +1,3 @@
# Wizard Apprentice Standard Library # Wizard Apprentice Standard Library
A collection of useful C/C++ utilities for my projects A collection of useful C utilities for my projects

57
build
View File

@@ -1,13 +1,45 @@
#!/bin/bash #!/bin/bash
BUILD_TYPE="debug" # Colors
RED="\033[0;31m"
BOLD="\033[1m"
NC="\033[0m" # No Color
BUILD_TYPE="Debug"
ACCEPTED_BUILD_TYPES=("Debug" "RelWithDebInfo" "Release")
KERNEL="$(uname -s)"
ARGS="" ARGS=""
join_array_elements() {
local IFS=","
echo "$*"
}
contains() {
local item="$1"; shift
local e
for e; do
[[ "$e" == "$item" ]] && return 0
done
return 1
}
print_usage() {
echo -e "Usage: build [-b build_type] ..."
echo -e " Options:"
echo -e " -b, --build-type Choose from $(join_array_elements ${ACCEPTED_BUILD_TYPES[*]}) (Default: Debug)."
echo -e " -h, --help Print this message and exit"
}
while [[ $# > 0 ]];do while [[ $# > 0 ]];do
case $1 in case $1 in
--release) -b|--build-type)
BUILD_TYPE="release" BUILD_TYPE="$2"
shift shift 2
;;
-h|--help)
print_usage
exit 0
;; ;;
*|-*|--*) *|-*|--*)
rest=("$@") rest=("$@")
@@ -17,4 +49,21 @@ while [[ $# > 0 ]];do
esac esac
done done
if ! contains ${BUILD_TYPE} "${ACCEPTED_BUILD_TYPES[@]}"; then
echo -e "${RED}${BOLD}Unknown build type: ${BUILD_TYPE}${NC}\n"
print_usage
exit 1
fi
if [[ $KERNEL == "Darwin" ]]; then
if [[ ! -d .venv ]]; then
python3 -m venv .venv
fi
source .venv/bin/activate
pip install scan-build
intercept-build make CC=intercept-cc CXX=intercept-c++ BUILD_TYPE=$BUILD_TYPE $ARGS
deactivate
else
bear -- make BUILD_TYPE=$BUILD_TYPE $ARGS bear -- make BUILD_TYPE=$BUILD_TYPE $ARGS
fi

View File

@@ -4,7 +4,7 @@ Param(
$Compiler = "cl.exe" $Compiler = "cl.exe"
$GeneralFlags = "/Wall /WX /wd4996" $GeneralFlags = "/Wall /WX /wd4996 /wd4464 /wd5105 /std:c11"
$LibraryFlags = "/LD" $LibraryFlags = "/LD"
$Kernel = (Get-ChildItem Env:OS).Value $Kernel = (Get-ChildItem Env:OS).Value
@@ -46,7 +46,7 @@ mkdir -p $OutDir > $null
mkdir -p $TestsDir > $null mkdir -p $TestsDir > $null
# Run code generation # Run code generation
Invoke-Expression "python3 -m codegen" Invoke-Expression "python -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

522
ccodegen/datatypes.c Normal file
View File

@@ -0,0 +1,522 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "datatypes.h"
#include "dbl_list.h"
#include "type_enums.h"
#include "wapp_core.h"
#define ERR_MSG "Not enough capacity in dst buffer"
#define CFILE_DISCLAIMER "/**\n" \
" * THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN.\n" \
" */\n\n"
void cobject_to_string(Str8 *dst, const CObject *object) {
wapp_debug_assert(dst != NULL && object != NULL, "`allocator`, `dst` and `object` should not be NULL");
switch (object->kind) {
case COBJECT_CTYPE:
ctype_to_string(dst, object->object.c_type);
break;
case COBJECT_CQUALIFIER:
cqualifier_to_string(dst, object->object.c_qualifier);
break;
case COBJECT_CPOINTERTYPE:
cpointertype_to_string(dst, object->object.c_pointertype);
break;
case COBJECT_CPOINTER:
cpointer_to_string(dst, &(object->object.c_pointer));
break;
case COBJECT_CENUMVAL:
cenumval_to_string(dst, &(object->object.c_enumval));
break;
case COBJECT_CENUM:
cenum_to_string(dst, &(object->object.c_enum));
break;
case COBJECT_CMACRO:
cmacro_to_string(dst, &(object->object.c_macro));
break;
case COBJECT_CSTRUCT:
cstruct_to_string(dst, &(object->object.c_struct));
break;
case COBJECT_CUSERTYPE:
cusertype_to_string(dst, &(object->object.c_usertype));
break;
case COBJECT_CDATATYPE:
cdatatype_to_string(dst, &(object->object.c_datatype));
break;
case COBJECT_CARG:
carg_to_string(dst, &(object->object.c_arg));
break;
case COBJECT_CFUNC:
cfunc_to_string(dst, &(object->object.c_func));
break;
case COBJECT_CINCULDE:
cinclude_to_string(dst, &(object->object.c_include));
break;
case COBJECT_CHEADER:
cheader_to_string(dst, &(object->object.c_header));
break;
case COBJECT_CSOURCE:
csource_to_string(dst, &(object->object.c_source));
break;
default:
break;
}
}
void ctype_to_string(Str8 *dst, CType ctype) {
wapp_runtime_assert(ctypes[ctype].size <= dst->capacity, ERR_MSG);
wapp_str8_copy_str8_capped(dst, &ctypes[ctype]);
}
void cqualifier_to_string(Str8 *dst, CQualifier cqualifier) {
wapp_runtime_assert(cqualifiers[cqualifier].size <= dst->capacity, ERR_MSG);
wapp_str8_copy_str8_capped(dst, &cqualifiers[cqualifier]);
}
void cpointertype_to_string(Str8 *dst, CPointerType cpointertype) {
wapp_runtime_assert(cpointertypes[cpointertype].size <= dst->capacity, ERR_MSG);
wapp_str8_copy_str8_capped(dst, &cpointertypes[cpointertype]);
}
void cpointer_to_string(Str8 *dst, const CPointer *cpointer) {
wapp_debug_assert(dst != NULL && cpointer != NULL, "`dst` and `cpointer` should not be NULL");
u64 total_size = cpointertypes[cpointer->type].size + cqualifiers[cpointer->qualifier].size;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst,
WAPP_STR8_SPEC WAPP_STR8_SPEC,
wapp_str8_varg(cpointertypes[cpointer->type]),
wapp_str8_varg(cqualifiers[cpointer->qualifier]));
}
void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval) {
wapp_debug_assert(dst != NULL && cenumval != NULL, "`dst` and `cenumval` should not be NULL");
Str8 tmp = wapp_str8_buf(CCGEN_BUF_TINY);
u64 tmp_size = 0;
if (cenumval->value != NULL) {
wapp_str8_format(&tmp, " = %d", *(cenumval->value));
tmp_size = tmp.size;
}
u64 total_size = cenumval->name.size + tmp_size;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst,
WAPP_STR8_SPEC WAPP_STR8_SPEC,
wapp_str8_varg(cenumval->name),
wapp_str8_varg(tmp));
}
void cenum_to_string(Str8 *dst, const CEnum *cenum) {
wapp_debug_assert(dst != NULL && cenum != NULL, "`dst` and `cenum` should not be NULL");
Str8 header = wapp_str8_buf(CCGEN_BUF_LARGE);
Str8 values = wapp_str8_buf(CCGEN_BUF_MAX);
Str8 footer = wapp_str8_buf(CCGEN_BUF_LARGE);
Str8 tmp = wapp_str8_buf(CCGEN_BUF_LARGE);
if (cenum->add_typedef) {
wapp_str8_copy_cstr_capped(&header, "typedef enum {\n");
wapp_str8_format(&footer, "} " WAPP_STR8_SPEC ";\n", wapp_str8_varg(cenum->name));
} else {
wapp_str8_format(&header, "enum " WAPP_STR8_SPEC " {\n", wapp_str8_varg(cenum->name));
wapp_str8_copy_cstr_capped(&footer, "};\n");
}
for (u64 i = 0; i < cenum->values.node_count; ++i) {
cenumval_to_string(&tmp, wapp_cenumval_list_get(&(cenum->values), i)->item);
// Add 4 for extra characters
wapp_runtime_assert(tmp.size + 4 <= values.capacity - values.size, ERR_MSG);
wapp_str8_concat_capped(&values, &wapp_str8_lit_ro(" "));
wapp_str8_concat_capped(&values, &tmp);
wapp_str8_concat_capped(&values, &wapp_str8_lit_ro(",\n"));
}
u64 total_size = header.size + values.size + footer.size;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst,
WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC,
wapp_str8_varg(header),
wapp_str8_varg(values),
wapp_str8_varg(footer));
}
void cmacro_to_string(Str8 *dst, const CMacro *cmacro) {
wapp_debug_assert(dst != NULL && cmacro != NULL, "`dst` and `cmacro` should not be NULL");
Str8 def = wapp_str8_lit("#define ");
u64 total_size = def.size + cmacro->name.size + cmacro->value.size + 1; // Add 1 for newline
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst,
WAPP_STR8_SPEC WAPP_STR8_SPEC " " WAPP_STR8_SPEC "\n",
wapp_str8_varg(def),
wapp_str8_varg(cmacro->name),
wapp_str8_varg(cmacro->value));
}
void cstruct_to_string(Str8 *dst, const CStruct *cstruct) {
wapp_debug_assert(dst != NULL && cstruct != NULL, "`dst` and `cstruct` should not be NULL");
Str8 declaration = wapp_str8_buf(CCGEN_BUF_LARGE);
Str8 definition = wapp_str8_buf(CCGEN_BUF_MAX);
declare_cstruct(&declaration, cstruct);
define_cstruct(&definition, cstruct);
u64 total_size = declaration.size + definition.size;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst, WAPP_STR8_SPEC WAPP_STR8_SPEC,
wapp_str8_varg(declaration), wapp_str8_varg(definition));
}
void declare_cstruct(Str8 *dst, const CStruct *cstruct) {
wapp_debug_assert(dst != NULL && cstruct != NULL, "`dst` and `cstruct` should not be NULL");
Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX);
wapp_str8_format(&tmp,
"typedef struct " WAPP_STR8_SPEC " " WAPP_STR8_SPEC ";\n",
wapp_str8_varg(cstruct->name),
wapp_str8_varg(cstruct->typedef_name.size > 0 ? cstruct->typedef_name : cstruct->name));
wapp_runtime_assert(tmp.size <= dst->capacity, ERR_MSG);
wapp_str8_copy_str8_capped(dst, &tmp);
}
void define_cstruct(Str8 *dst, const CStruct *cstruct) {
wapp_debug_assert(dst != NULL && cstruct != NULL, "`dst` and `cstruct` should not be NULL");
Str8 definition = wapp_str8_buf(CCGEN_BUF_LARGE);
Str8 args = wapp_str8_buf(CCGEN_BUF_MAX);
Str8 footer = wapp_str8_lit_ro("};\n");
Str8 tmp = wapp_str8_buf(CCGEN_BUF_MEDIUM);
wapp_str8_format(&definition, "struct " WAPP_STR8_SPEC " {\n", wapp_str8_varg(cstruct->name));
for (u64 i = 0; i < cstruct->args.node_count; ++i) {
carg_to_string(&tmp, wapp_carg_list_get(&(cstruct->args), i)->item);
// Add 4 for extra characters
wapp_runtime_assert(tmp.size + 4 <= args.capacity - args.size, ERR_MSG);
wapp_str8_concat_capped(&args, &wapp_str8_lit_ro(" "));
wapp_str8_concat_capped(&args, &tmp);
wapp_str8_concat_capped(&args, &wapp_str8_lit_ro(";\n"));
}
u64 total_size = definition.size + args.size + footer.size;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst,
WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC,
wapp_str8_varg(definition),
wapp_str8_varg(args),
wapp_str8_varg(footer));
}
void cusertype_to_string(Str8 *dst, const CUserType *cusertype) {
wapp_debug_assert(dst != NULL && cusertype != NULL, "`dst` and `cusertype` should not be NULL");
switch (cusertype->kind) {
case CUSERTYPE_CENUM:
cenum_to_string(dst, &(cusertype->type.c_enum));
break;
case CUSERTYPE_CSTRUCT:
cstruct_to_string(dst, &(cusertype->type.c_struct));
break;
default:
break;
}
}
void cdatatype_to_string(Str8 *dst, const CDataType *cdatatype) {
wapp_debug_assert(dst != NULL && cdatatype != NULL, "`dst` and `cdatatype` should not be NULL");
switch (cdatatype->kind) {
case CDATATYPE_CTYPE:
ctype_to_string(dst, cdatatype->type.c_type);
break;
case CDATATYPE_CUSERTYPE:
cusertype_to_string(dst, &(cdatatype->type.c_usertype));
break;
case CDATATYPE_STR:
wapp_runtime_assert(cdatatype->type.str.size <= dst->capacity, ERR_MSG);
wapp_str8_copy_str8_capped(dst, &(cdatatype->type.str));
break;
default:
break;
}
}
void carg_to_string(Str8 *dst, const CArg *carg) {
wapp_debug_assert(dst != NULL && carg != NULL, "`dst` and `carg` should not be NULL");
Str8 qualifier = wapp_str8_buf(CCGEN_BUF_MEDIUM);
Str8 type = wapp_str8_buf(CCGEN_BUF_LARGE);
Str8 pointer = wapp_str8_buf(CCGEN_BUF_MEDIUM);
Str8 array = wapp_str8_buf(CCGEN_BUF_MEDIUM);
cqualifier_to_string(&qualifier, carg->qualifier);
cdatatype_to_string(&type, &(carg->type));
wapp_str8_concat_capped(&type, &wapp_str8_lit_ro(" "));
cpointer_to_string(&pointer, &(carg->pointer));
if (carg->is_array) { wapp_str8_copy_cstr_capped(&array, "[]"); }
u64 total_size = qualifier.size + type.size + pointer.size + array.size + carg->name.size;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst, WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC,
wapp_str8_varg(qualifier), wapp_str8_varg(type), wapp_str8_varg(pointer),
wapp_str8_varg(carg->name), wapp_str8_varg(array));
}
void cfunc_to_string(Str8 *dst, const CFunc *cfunc) {
wapp_debug_assert(dst != NULL && cfunc != NULL, "`dst` and `cfunc` should not be NULL");
Str8 qualifiers = wapp_str8_buf(CCGEN_BUF_LARGE);
Str8 args = wapp_str8_buf(CCGEN_BUF_LARGE);
Str8 ret_type = wapp_str8_buf(CCGEN_BUF_SMALL);
Str8 pointer = wapp_str8_buf(CCGEN_BUF_SMALL);
Str8 tmp = wapp_str8_buf(CCGEN_BUF_MEDIUM);
CQualifier *qf = NULL;
CArg *arg = NULL;
for (u64 i = 0; i < cfunc->qualifiers.node_count; ++i) {
qf = wapp_cqualifier_list_get(&(cfunc->qualifiers), i)->item;
if (*qf == CQUALIFIER_NONE) { continue; }
cqualifier_to_string(&tmp, *qf);
wapp_runtime_assert(tmp.size + 1 <= qualifiers.capacity - qualifiers.size, ERR_MSG);
if (qualifiers.size > 0) { wapp_str8_concat_capped(&qualifiers, &wapp_str8_lit_ro(" ")); }
wapp_str8_concat_capped(&qualifiers, &tmp);
}
for (u64 i = 0; i < cfunc->args.node_count; ++i) {
arg = wapp_carg_list_get(&(cfunc->args), i)->item;
carg_to_string(&tmp, arg);
wapp_runtime_assert(tmp.size + 2 <= args.capacity - args.size, ERR_MSG);
wapp_str8_concat_capped(&args, &tmp);
if (i + 1 < cfunc->args.node_count) { wapp_str8_concat_capped(&args, &wapp_str8_lit_ro(", ")); }
}
cdatatype_to_string(&ret_type, &(cfunc->ret_type));
cpointer_to_string(&pointer, &(cfunc->pointer));
u64 total_size = cfunc->name.size + qualifiers.size + args.size + ret_type.size + pointer.size + 4;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst,
WAPP_STR8_SPEC WAPP_STR8_SPEC " " WAPP_STR8_SPEC WAPP_STR8_SPEC "(" WAPP_STR8_SPEC ")",
wapp_str8_varg(qualifiers),
wapp_str8_varg(ret_type),
wapp_str8_varg(pointer),
wapp_str8_varg(cfunc->name),
wapp_str8_varg(args));
}
void declare_cfunc(Str8 *dst, const CFunc *cfunc) {
wapp_debug_assert(dst != NULL && cfunc != NULL, "`dst` and `cfunc` should not be NULL");
Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX);
cfunc_to_string(&tmp, cfunc);
wapp_runtime_assert(tmp.size + 2 <= dst->capacity, ERR_MSG);
wapp_str8_format(dst, WAPP_STR8_SPEC ";\n", wapp_str8_varg(tmp));
}
void define_cfunc(Str8 *dst, const CFunc *cfunc) {
wapp_debug_assert(dst != NULL && cfunc != NULL, "`dst` and `cfunc` should not be NULL");
Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX);
cfunc_to_string(&tmp, cfunc);
wapp_runtime_assert(tmp.size + cfunc->body.size + 8 <= dst->capacity, ERR_MSG);
wapp_str8_format(dst, WAPP_STR8_SPEC " {\n" WAPP_STR8_SPEC "\n}\n\n",
wapp_str8_varg(tmp), wapp_str8_varg(cfunc->body));
}
void cinclude_to_string(Str8 *dst, const CInclude *cinclude) {
wapp_debug_assert(dst != NULL && cinclude != NULL, "`dst` and `cinclude` should not be NULL");
Str8 header_str = wapp_str8_buf(CCGEN_BUF_LARGE);
if (!cheaderinclude_to_string(&header_str, &(cinclude->header))) { return; }
Str8 inc = wapp_str8_lit("#include ");
Str8 open_symbol = wapp_str8_buf(CCGEN_BUF_MIN);
Str8 close_symbol = wapp_str8_buf(CCGEN_BUF_MIN);
if (cinclude->is_local) {
wapp_str8_concat_capped(&open_symbol, &wapp_str8_lit_ro("\""));
wapp_str8_concat_capped(&close_symbol, &wapp_str8_lit_ro("\""));
if (cinclude->same_dir) { wapp_str8_concat_capped(&open_symbol, &wapp_str8_lit_ro("./")); }
} else {
wapp_str8_concat_capped(&open_symbol, &wapp_str8_lit_ro("<"));
wapp_str8_concat_capped(&close_symbol, &wapp_str8_lit_ro(">"));
}
u64 total_size = header_str.size + inc.size + open_symbol.size + close_symbol.size;
wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst,
WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC "\n",
wapp_str8_varg(inc),
wapp_str8_varg(open_symbol),
wapp_str8_varg(header_str),
wapp_str8_varg(close_symbol));
}
void cheader_to_string(Str8 *dst, const CHeader *cheader) {
wapp_debug_assert(dst != NULL && cheader != NULL, "`dst` and `cheader` should not be NULL");
Allocator arena = wapp_mem_arena_allocator_init(MB(64));
Str8 *output = wapp_str8_alloc_buf(&arena, KB(32));
wapp_runtime_assert(output != NULL, "Failed to allocate buffer");
Str8 header_guard_name = wapp_str8_buf(CCGEN_BUF_SMALL);
Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX);
// ADD HEADER GUARD AND START C LINKAGE
wapp_str8_to_upper(&header_guard_name, &(cheader->name));
wapp_str8_concat_capped(&header_guard_name, &wapp_str8_lit_ro("_H"));
wapp_str8_format(&tmp, "#ifndef " WAPP_STR8_SPEC "\n#define " WAPP_STR8_SPEC "\n\n"
"#ifdef WAPP_PLATFORM_CPP\nBEGIN_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n",
wapp_str8_varg(header_guard_name), wapp_str8_varg(header_guard_name));
wapp_str8_alloc_concat(&arena, output, &tmp);
for (u64 i = 0; i < cheader->includes.node_count; ++i) {
cinclude_to_string(&tmp, wapp_cinclude_list_get(&(cheader->includes), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
if (cheader->includes.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); }
for (u64 i = 0; i < cheader->macros.node_count; ++i) {
cmacro_to_string(&tmp, wapp_cmacro_list_get(&(cheader->macros), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
if (cheader->macros.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); }
if (cheader->cpp_macros.node_count > 0) {
wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("#ifdef WAPP_PLATFORM_CPP\n"));
for (u64 i = 0; i < cheader->cpp_macros.node_count; ++i) {
cmacro_to_string(&tmp, wapp_cmacro_list_get(&(cheader->cpp_macros), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("#else\n"));
for (u64 i = 0; i < cheader->c_macros.node_count; ++i) {
cmacro_to_string(&tmp, wapp_cmacro_list_get(&(cheader->c_macros), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("#endif // !WAPP_PLATFORM_CPP\n\n"));
}
for (u64 i = 0; i < cheader->decl_types.node_count; ++i) {
declare_cstruct(&tmp, wapp_cstruct_list_get(&(cheader->decl_types), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
if (cheader->decl_types.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); }
for (u64 i = 0; i < cheader->types.node_count; ++i) {
cusertype_to_string(&tmp, wapp_cusertype_list_get(&(cheader->types), i)->item);
wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("\n"));
wapp_str8_alloc_concat(&arena, output, &tmp);
}
for (u64 i = 0; i < cheader->funcs.node_count; ++i) {
declare_cfunc(&tmp, wapp_cfunc_list_get(&(cheader->funcs), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
// END C LINKAGE AND CLOSE HEADER GUARD
wapp_str8_format(&tmp, "\n#ifdef WAPP_PLATFORM_CPP\nEND_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n"
"#endif // !" WAPP_STR8_SPEC "\n", wapp_str8_varg(header_guard_name));
wapp_str8_alloc_concat(&arena, output, &tmp);
wapp_runtime_assert(output->size <= dst->capacity, ERR_MSG);
wapp_str8_copy_str8_capped(dst, output);
wapp_mem_arena_allocator_destroy(&arena);
}
void csource_to_string(Str8 *dst, const CSource *csource) {
wapp_debug_assert(dst != NULL && csource != NULL, "`dst` and `csource` should not be NULL");
Allocator arena = wapp_mem_arena_allocator_init(MB(64));
Str8 *output = wapp_str8_alloc_buf(&arena, KB(32));
Str8 *internal_funcs_def = wapp_str8_alloc_buf(&arena, KB(16));
wapp_runtime_assert(output != NULL && internal_funcs_def != NULL, "Failed to allocate buffer");
Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX);
for (u64 i = 0; i < csource->includes.node_count; ++i) {
cinclude_to_string(&tmp, wapp_cinclude_list_get(&(csource->includes), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
if (csource->includes.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); }
for (u64 i = 0; i < csource->macros.node_count; ++i) {
cmacro_to_string(&tmp, wapp_cmacro_list_get(&(csource->macros), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
if (csource->macros.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); }
for (u64 i = 0; i < csource->decl_types.node_count; ++i) {
declare_cstruct(&tmp, wapp_cstruct_list_get(&(csource->decl_types), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
if (csource->decl_types.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); }
for (u64 i = 0; i < csource->types.node_count; ++i) {
cusertype_to_string(&tmp, wapp_cusertype_list_get(&(csource->types), i)->item);
wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("\n"));
wapp_str8_alloc_concat(&arena, output, &tmp);
}
Str8RO _wapp_intern = wapp_str8_lit_ro("wapp_intern ");
for (u64 i = 0; i < csource->internal_funcs.node_count; ++i) {
declare_cfunc(&tmp, wapp_cfunc_list_get(&(csource->internal_funcs), i)->item);
wapp_str8_alloc_concat(&arena, output, &_internal);
wapp_str8_alloc_concat(&arena, output, &tmp);
define_cfunc(&tmp, wapp_cfunc_list_get(&(csource->internal_funcs), i)->item);
wapp_str8_alloc_concat(&arena, internal_funcs_def, &_internal);
wapp_str8_alloc_concat(&arena, internal_funcs_def, &tmp);
}
if (csource->internal_funcs.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); }
for (u64 i = 0; i < csource->funcs.node_count; ++i) {
define_cfunc(&tmp, wapp_cfunc_list_get(&(csource->funcs), i)->item);
wapp_str8_alloc_concat(&arena, output, &tmp);
}
wapp_runtime_assert(output->size + internal_funcs_def->size <= dst->capacity, ERR_MSG);
wapp_str8_copy_str8_capped(dst, output);
wapp_str8_concat_capped(dst, internal_funcs_def);
wapp_mem_arena_allocator_destroy(&arena);
}
b32 cheaderinclude_to_string(Str8 *dst, const CHeaderInclude *cheaderinclude) {
wapp_debug_assert(dst != NULL && cheaderinclude != NULL, "`dst` and `cheaderinclude` should not be NULL");
switch (cheaderinclude->kind) {
case C_HEADER_INCLUDE_STR:
wapp_runtime_assert(cheaderinclude->header.name.size <= dst->capacity, ERR_MSG);
wapp_str8_format(dst, WAPP_STR8_SPEC, wapp_str8_varg(cheaderinclude->header.name));
return true;
case C_HEADER_INCLUDE_HEADER:
// Take extension into account
wapp_runtime_assert(cheaderinclude->header.header.name.size + 2 <= dst->capacity, ERR_MSG);
wapp_str8_format(
dst,
WAPP_STR8_SPEC ".%s",
wapp_str8_varg(cheaderinclude->header.header.name),
cheaderinclude->header.header.extension == CFILE_EXT_H ? "h" : "c"
);
return true;
default:
return false;
}
return false;
}

280
ccodegen/datatypes.h Normal file
View File

@@ -0,0 +1,280 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef DATATYPES_H
#define DATATYPES_H
#include "wapp_core.h"
#include "dbl_list.h"
#include "type_enums.h"
#ifndef CCGEN_BUF_MIN
#define CCGEN_BUF_MIN 16
#endif // !CCGEN_BUF_MIN
#ifndef CCGEN_BUF_TINY
#define CCGEN_BUF_TINY 32
#endif // !CCGEN_BUF_TINY
#ifndef CCGEN_BUF_SMALL
#define CCGEN_BUF_SMALL 512
#endif // !CCGEN_BUF_SMALL
#ifndef CCGEN_BUF_MEDIUM
#define CCGEN_BUF_MEDIUM 1024
#endif // !CCGEN_BUF_MEDIUM
#ifndef CCGEN_BUF_LARGE
#define CCGEN_BUF_LARGE 4096
#endif // !CCGEN_BUF_LARGE
#ifndef CCGEN_BUF_MAX
#define CCGEN_BUF_MAX 8192
#endif // !CCGEN_BUF_MAX
#define CENUM(NAME, VALUES, TYPEDEF) ((CEnum){ .name = (NAME), .values = (VALUES), .add_typedef = (TYPEDEF) })
#define CSTRUCT(NAME, ARGS, TYPEDEF_NAME_PTR) ((CStruct){ .name = (NAME), .args = (ARGS), .typedef_name = (TYPEDEF_NAME_PTR) })
#define CUSERTYPE_ENUM(ENUM) ((CUserType){ .kind = CUSERTYPE_CENUM, .type.c_enum = ENUM })
#define CUSERTYPE_STRUCT(STRUCT) ((CUserType){ .kind = CUSERTYPE_CSTRUCT, .type.c_struct = STRUCT })
#define CDATATYPE_CTYPE(VALUE) ((CDataType){ .kind = CDATATYPE_CTYPE, .type.c_type = (VALUE) })
#define CDATATYPE_USERTYPE(USERTYPE) ((CDataType){ .kind = CDATATYPE_CUSERTYPE, .type.c_usertype = (USERTYPE) })
#define CDATATYPE_STR(STR) ((CDataType){ .kind = CDATATYPE_STR, .type.str = (STR) })
#define CHEADERINCLUDE_STR(NAME) ((CHeaderInclude){ .kind = C_HEADER_INCLUDE_STR, .header.name = (NAME) })
#define CHEADERINCLUDE_CHEADER(CHEADER) ((CHeaderInclude){ .kind = C_HEADER_INCLUDE_HEADER, .header.header = (CHEADER) })
#define COBJECT_TYPE(VALUE) \
((CObject){ .kind = COBJECT_CTYPE, .object.c_type = (VALUE) })
#define COBJECT_QUALIFIER(VALUE) \
((CObject){ .kind = COBJECT_CQUALIFIER, .object.c_qualifier = (VALUE) })
#define COBJECT_POINTERTYPE(VALUE) \
((CObject){ .kind = COBJECT_CPOINTERTYPE, .object.c_pointertype = (VALUE) })
#define COBJECT_POINTER(CPOINTER) \
((CObject){ .kind = COBJECT_CPOINTER, .object.c_pointer = (CPOINTER) })
#define COBJECT_ENUMVAL(CENUMVAL) \
((CObject){ .kind = COBJECT_CENUMVAL, .object.c_enumval = (CENUMVAL) })
#define COBJECT_ENUM(ENUM) \
((CObject){ .kind = COBJECT_CENUM, .object.c_enum = (ENUM) })
#define COBJECT_MACRO(CMACRO) \
((CObject){ .kind = COBJECT_CMACRO, .object.c_macro = (CMACRO) })
#define COBJECT_STRUCT(STRUCT) \
((CObject){ .kind = COBJECT_CSTRUCT, .object.c_struct = STRUCT })
#define COBJECT_USERTYPE(USERTYPE) \
((CObject){ .kind = COBJECT_CUSERTYPE, .object.c_usertype = (USERTYPE) })
#define COBJECT_DATATYPE(DATATYPE) \
((CObject){ .kind = COBJECT_CDATATYPE, .object.c_datatype = (DATATYPE) })
#define COBJECT_ARG(CARG) \
((CObject){ .kind = COBJECT_CARG, .object.c_arg = (CARG) })
#define COBJECT_FUNC(CFUNC) \
((CObject){ .kind = COBJECT_CFUNC, .object.c_func = (CFUNC) })
#define COBJECT_INCULDE(CINCLUDE) \
((CObject){ .kind = COBJECT_CINCULDE, .object.c_include = (CINCLUDE) })
#define COBJECT_HEADER(CHEADER) \
((CObject){ .kind = COBJECT_CHEADER, .object.c_header = (CHEADER) })
#define COBJECT_SOURCE(CSOURCE) \
((CObject){ .kind = COBJECT_CSOURCE, .object.c_source = (CSOURCE) })
typedef enum {
CUSERTYPE_CENUM,
CUSERTYPE_CSTRUCT,
COUNT_CUSERTYPEKIND,
} CUserTypeKind;
typedef enum {
CDATATYPE_CTYPE,
CDATATYPE_CUSERTYPE,
CDATATYPE_STR,
COUNT_CDATATYPEKIND,
} CDataTypeKind;
typedef enum {
CFILE_EXT_H,
CFILE_EXT_C,
COUNT_CFILE_EXT,
} CFileExtension;
typedef enum {
C_HEADER_INCLUDE_STR,
C_HEADER_INCLUDE_HEADER,
COUNT_CHEADERINCLUDEKIND,
} CHeaderIncludeKind;
typedef enum {
COBJECT_CTYPE,
COBJECT_CQUALIFIER,
COBJECT_CPOINTERTYPE,
COBJECT_CPOINTER,
COBJECT_CENUMVAL,
COBJECT_CENUM,
COBJECT_CMACRO,
COBJECT_CSTRUCT,
COBJECT_CUSERTYPE,
COBJECT_CDATATYPE,
COBJECT_CARG,
COBJECT_CFUNC,
COBJECT_CINCULDE,
COBJECT_CHEADER,
COBJECT_CSOURCE,
COUNT_COBJECTKIND,
} CObjectKind;
typedef struct cpointer CPointer;
typedef struct cenumval CEnumVal;
typedef struct cenum CEnum;
typedef struct cmacro CMacro;
typedef struct cstruct CStruct;
typedef struct cusertype CUserType;
typedef struct cdatatype CDataType;
typedef struct carg CArg;
typedef struct cfunc CFunc;
typedef struct cheader_include CHeaderInclude;
typedef struct cinclude CInclude;
typedef struct cheader CHeader;
typedef struct csource CSource;
typedef struct cobject CObject;
struct cpointer {
CPointerType type;
CQualifier qualifier;
};
struct cenumval {
Str8 name;
i32 *value;
};
struct cenum {
Str8 name;
CEnumValList values;
b32 add_typedef;
};
struct cmacro {
Str8 name;
Str8 value;
};
struct cstruct {
Str8 name;
CArgList args;
Str8 typedef_name;
};
struct cusertype {
CUserTypeKind kind;
union {
CEnum c_enum;
CStruct c_struct;
} type;
};
struct cdatatype {
CDataTypeKind kind;
union {
CType c_type;
CUserType c_usertype;
Str8 str;
} type;
};
struct carg {
Str8 name;
CDataType type;
CPointer pointer;
CQualifier qualifier;
b32 is_array;
};
struct cfunc {
Str8 name;
CDataType ret_type;
CArgList args;
Str8 body;
CPointer pointer;
CQualifierList qualifiers;
};
#define CFILE_ARGS \
Str8 name; \
CFileExtension extension; \
CIncludeList includes; \
CUserTypeList types; \
CFuncList funcs; \
CStructList decl_types; \
CMacroList macros; \
CMacroList c_macros; \
CMacroList cpp_macros \
struct cheader {
CFILE_ARGS;
};
struct csource {
CFILE_ARGS;
CFuncList internal_funcs;
};
struct cheader_include {
CHeaderIncludeKind kind;
union {
Str8 name;
CHeader header;
} header;
};
struct cinclude {
CHeaderInclude header;
b32 is_local;
b32 same_dir;
};
struct cobject {
CObjectKind kind;
union {
CType c_type;
CQualifier c_qualifier;
CPointerType c_pointertype;
CPointer c_pointer;
CEnumVal c_enumval;
CEnum c_enum;
CMacro c_macro;
CStruct c_struct;
CUserType c_usertype;
CDataType c_datatype;
CArg c_arg;
CFunc c_func;
CInclude c_include;
CHeader c_header;
CSource c_source;
} object;
};
void cobject_to_string(Str8 *dst, const CObject *object);
void ctype_to_string(Str8 *dst, CType ctype);
void cqualifier_to_string(Str8 *dst, CQualifier cqualifier);
void cpointertype_to_string(Str8 *dst, CPointerType cpointertype);
void cpointer_to_string(Str8 *dst, const CPointer *cpointer);
void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval);
void cenum_to_string(Str8 *dst, const CEnum *cenum);
void cmacro_to_string(Str8 *dst, const CMacro *cmacro);
void cstruct_to_string(Str8 *dst, const CStruct *cstruct);
void declare_cstruct(Str8 *dst, const CStruct *cstruct);
void define_cstruct(Str8 *dst, const CStruct *cstruct);
void cusertype_to_string(Str8 *dst, const CUserType *cusertype);
void cdatatype_to_string(Str8 *dst, const CDataType *cdatatype);
void carg_to_string(Str8 *dst, const CArg *carg);
void cfunc_to_string(Str8 *dst, const CFunc *cfunc);
void declare_cfunc(Str8 *dst, const CFunc *cfunc);
void define_cfunc(Str8 *dst, const CFunc *cfunc);
void cinclude_to_string(Str8 *dst, const CInclude *cinclude);
void cheader_to_string(Str8 *dst, const CHeader *cheader);
void csource_to_string(Str8 *dst, const CSource *csource);
b32 cheaderinclude_to_string(Str8 *dst, const CHeaderInclude *cheaderinclude);
#endif // !DATATYPES_H

1526
ccodegen/dbl_list.c Normal file

File diff suppressed because it is too large Load Diff

222
ccodegen/dbl_list.h Normal file
View File

@@ -0,0 +1,222 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef CCGEN_DBL_LIST_H
#define CCGEN_DBL_LIST_H
#include "wapp_core.h"
#include "type_enums.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP
#define wapp_cenumval_list_node(ITEM_PTR) CEnumValNode{ITEM_PTR, nullptr, nullptr}
#define wapp_carg_list_node(ITEM_PTR) CArgNode{ITEM_PTR, nullptr, nullptr}
#define wapp_cqualifier_list_node(ITEM_PTR) CQualifierNode{ITEM_PTR, nullptr, nullptr}
#define wapp_cinclude_list_node(ITEM_PTR) CIncludeNode{ITEM_PTR, nullptr, nullptr}
#define wapp_cusertype_list_node(ITEM_PTR) CUserTypeNode{ITEM_PTR, nullptr, nullptr}
#define wapp_cfunc_list_node(ITEM_PTR) CFuncNode{ITEM_PTR, nullptr, nullptr}
#define wapp_cstruct_list_node(ITEM_PTR) CStructNode{ITEM_PTR, nullptr, nullptr}
#define wapp_cmacro_list_node(ITEM_PTR) CMacroNode{ITEM_PTR, nullptr, nullptr}
#else
#define wapp_cenumval_list_node(ITEM_PTR) ((CEnumValNode){.item = ITEM_PTR})
#define wapp_carg_list_node(ITEM_PTR) ((CArgNode){.item = ITEM_PTR})
#define wapp_cqualifier_list_node(ITEM_PTR) ((CQualifierNode){.item = ITEM_PTR})
#define wapp_cinclude_list_node(ITEM_PTR) ((CIncludeNode){.item = ITEM_PTR})
#define wapp_cusertype_list_node(ITEM_PTR) ((CUserTypeNode){.item = ITEM_PTR})
#define wapp_cfunc_list_node(ITEM_PTR) ((CFuncNode){.item = ITEM_PTR})
#define wapp_cstruct_list_node(ITEM_PTR) ((CStructNode){.item = ITEM_PTR})
#define wapp_cmacro_list_node(ITEM_PTR) ((CMacroNode){.item = ITEM_PTR})
#endif // !WAPP_PLATFORM_CPP
typedef struct cenumval CEnumVal;
typedef struct carg CArg;
typedef struct cinclude CInclude;
typedef struct cusertype CUserType;
typedef struct cfunc CFunc;
typedef struct cstruct CStruct;
typedef struct cmacro CMacro;
typedef struct CEnumValNode CEnumValNode;
struct CEnumValNode {
CEnumVal *item;
CEnumValNode *prev;
CEnumValNode *next;
};
typedef struct CEnumValList CEnumValList;
struct CEnumValList {
CEnumValNode *first;
CEnumValNode *last;
u64 node_count;
};
typedef struct CArgNode CArgNode;
struct CArgNode {
CArg *item;
CArgNode *prev;
CArgNode *next;
};
typedef struct CArgList CArgList;
struct CArgList {
CArgNode *first;
CArgNode *last;
u64 node_count;
};
typedef struct CQualifierNode CQualifierNode;
struct CQualifierNode {
CQualifier *item;
CQualifierNode *prev;
CQualifierNode *next;
};
typedef struct CQualifierList CQualifierList;
struct CQualifierList {
CQualifierNode *first;
CQualifierNode *last;
u64 node_count;
};
typedef struct CIncludeNode CIncludeNode;
struct CIncludeNode {
CInclude *item;
CIncludeNode *prev;
CIncludeNode *next;
};
typedef struct CIncludeList CIncludeList;
struct CIncludeList {
CIncludeNode *first;
CIncludeNode *last;
u64 node_count;
};
typedef struct CUserTypeNode CUserTypeNode;
struct CUserTypeNode {
CUserType *item;
CUserTypeNode *prev;
CUserTypeNode *next;
};
typedef struct CUserTypeList CUserTypeList;
struct CUserTypeList {
CUserTypeNode *first;
CUserTypeNode *last;
u64 node_count;
};
typedef struct CFuncNode CFuncNode;
struct CFuncNode {
CFunc *item;
CFuncNode *prev;
CFuncNode *next;
};
typedef struct CFuncList CFuncList;
struct CFuncList {
CFuncNode *first;
CFuncNode *last;
u64 node_count;
};
typedef struct CStructNode CStructNode;
struct CStructNode {
CStruct *item;
CStructNode *prev;
CStructNode *next;
};
typedef struct CStructList CStructList;
struct CStructList {
CStructNode *first;
CStructNode *last;
u64 node_count;
};
typedef struct CMacroNode CMacroNode;
struct CMacroNode {
CMacro *item;
CMacroNode *prev;
CMacroNode *next;
};
typedef struct CMacroList CMacroList;
struct CMacroList {
CMacroNode *first;
CMacroNode *last;
u64 node_count;
};
CEnumValNode *wapp_cenumval_list_get(const CEnumValList *list, u64 index);
void wapp_cenumval_list_push_front(CEnumValList *list, CEnumValNode *node);
void wapp_cenumval_list_push_back(CEnumValList *list, CEnumValNode *node);
void wapp_cenumval_list_insert(CEnumValList *list, CEnumValNode *node, u64 index);
CEnumValNode *wapp_cenumval_list_pop_front(CEnumValList *list);
CEnumValNode *wapp_cenumval_list_pop_back(CEnumValList *list);
CEnumValNode *wapp_cenumval_list_remove(CEnumValList *list, u64 index);
void wapp_cenumval_list_empty(CEnumValList *list);
CArgNode *wapp_carg_list_get(const CArgList *list, u64 index);
void wapp_carg_list_push_front(CArgList *list, CArgNode *node);
void wapp_carg_list_push_back(CArgList *list, CArgNode *node);
void wapp_carg_list_insert(CArgList *list, CArgNode *node, u64 index);
CArgNode *wapp_carg_list_pop_front(CArgList *list);
CArgNode *wapp_carg_list_pop_back(CArgList *list);
CArgNode *wapp_carg_list_remove(CArgList *list, u64 index);
void wapp_carg_list_empty(CArgList *list);
CQualifierNode *wapp_cqualifier_list_get(const CQualifierList *list, u64 index);
void wapp_cqualifier_list_push_front(CQualifierList *list, CQualifierNode *node);
void wapp_cqualifier_list_push_back(CQualifierList *list, CQualifierNode *node);
void wapp_cqualifier_list_insert(CQualifierList *list, CQualifierNode *node, u64 index);
CQualifierNode *wapp_cqualifier_list_pop_front(CQualifierList *list);
CQualifierNode *wapp_cqualifier_list_pop_back(CQualifierList *list);
CQualifierNode *wapp_cqualifier_list_remove(CQualifierList *list, u64 index);
void wapp_cqualifier_list_empty(CQualifierList *list);
CIncludeNode *wapp_cinclude_list_get(const CIncludeList *list, u64 index);
void wapp_cinclude_list_push_front(CIncludeList *list, CIncludeNode *node);
void wapp_cinclude_list_push_back(CIncludeList *list, CIncludeNode *node);
void wapp_cinclude_list_insert(CIncludeList *list, CIncludeNode *node, u64 index);
CIncludeNode *wapp_cinclude_list_pop_front(CIncludeList *list);
CIncludeNode *wapp_cinclude_list_pop_back(CIncludeList *list);
CIncludeNode *wapp_cinclude_list_remove(CIncludeList *list, u64 index);
void wapp_cinclude_list_empty(CIncludeList *list);
CUserTypeNode *wapp_cusertype_list_get(const CUserTypeList *list, u64 index);
void wapp_cusertype_list_push_front(CUserTypeList *list, CUserTypeNode *node);
void wapp_cusertype_list_push_back(CUserTypeList *list, CUserTypeNode *node);
void wapp_cusertype_list_insert(CUserTypeList *list, CUserTypeNode *node, u64 index);
CUserTypeNode *wapp_cusertype_list_pop_front(CUserTypeList *list);
CUserTypeNode *wapp_cusertype_list_pop_back(CUserTypeList *list);
CUserTypeNode *wapp_cusertype_list_remove(CUserTypeList *list, u64 index);
void wapp_cusertype_list_empty(CUserTypeList *list);
CFuncNode *wapp_cfunc_list_get(const CFuncList *list, u64 index);
void wapp_cfunc_list_push_front(CFuncList *list, CFuncNode *node);
void wapp_cfunc_list_push_back(CFuncList *list, CFuncNode *node);
void wapp_cfunc_list_insert(CFuncList *list, CFuncNode *node, u64 index);
CFuncNode *wapp_cfunc_list_pop_front(CFuncList *list);
CFuncNode *wapp_cfunc_list_pop_back(CFuncList *list);
CFuncNode *wapp_cfunc_list_remove(CFuncList *list, u64 index);
void wapp_cfunc_list_empty(CFuncList *list);
CStructNode *wapp_cstruct_list_get(const CStructList *list, u64 index);
void wapp_cstruct_list_push_front(CStructList *list, CStructNode *node);
void wapp_cstruct_list_push_back(CStructList *list, CStructNode *node);
void wapp_cstruct_list_insert(CStructList *list, CStructNode *node, u64 index);
CStructNode *wapp_cstruct_list_pop_front(CStructList *list);
CStructNode *wapp_cstruct_list_pop_back(CStructList *list);
CStructNode *wapp_cstruct_list_remove(CStructList *list, u64 index);
void wapp_cstruct_list_empty(CStructList *list);
CMacroNode *wapp_cmacro_list_get(const CMacroList *list, u64 index);
void wapp_cmacro_list_push_front(CMacroList *list, CMacroNode *node);
void wapp_cmacro_list_push_back(CMacroList *list, CMacroNode *node);
void wapp_cmacro_list_insert(CMacroList *list, CMacroNode *node, u64 index);
CMacroNode *wapp_cmacro_list_pop_front(CMacroList *list);
CMacroNode *wapp_cmacro_list_pop_back(CMacroList *list);
CMacroNode *wapp_cmacro_list_remove(CMacroList *list, u64 index);
void wapp_cmacro_list_empty(CMacroList *list);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !DBL_LIST_H

10
ccodegen/main.c Normal file
View File

@@ -0,0 +1,10 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "datatypes.h"
#include "type_enums.h"
#include "wapp_core.h"
#include <stdio.h>
int main(void) {
return 0;
}

84
ccodegen/type_enums.h Normal file
View File

@@ -0,0 +1,84 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TYPE_ENUMS_H
#define TYPE_ENUMS_H
#include "wapp_core.h"
typedef enum {
CTYPE_VOID,
CTYPE_B32,
CTYPE_CHAR,
CTYPE_C8,
CTYPE_C16,
CTYPE_C32,
CTYPE_I8,
CTYPE_I16,
CTYPE_I32,
CTYPE_I64,
CTYPE_U8,
CTYPE_U16,
CTYPE_U32,
CTYPE_U64,
CTYPE_F32,
CTYPE_F64,
CTYPE_F128,
CTYPE_IPTR,
CTYPE_UPTR,
COUNT_CTYPE,
} CType;
wapp_intern Str8RO ctypes[COUNT_CTYPE] = {
[CTYPE_VOID] = wapp_str8_lit_ro("void"),
[CTYPE_B32] = wapp_str8_lit_ro("b32"),
[CTYPE_CHAR] = wapp_str8_lit_ro("char"),
[CTYPE_C8] = wapp_str8_lit_ro("c8"),
[CTYPE_C16] = wapp_str8_lit_ro("c16"),
[CTYPE_C32] = wapp_str8_lit_ro("c32"),
[CTYPE_I8] = wapp_str8_lit_ro("i8"),
[CTYPE_I16] = wapp_str8_lit_ro("i16"),
[CTYPE_I32] = wapp_str8_lit_ro("i32"),
[CTYPE_I64] = wapp_str8_lit_ro("i64"),
[CTYPE_U8] = wapp_str8_lit_ro("u8"),
[CTYPE_U16] = wapp_str8_lit_ro("u16"),
[CTYPE_U32] = wapp_str8_lit_ro("u32"),
[CTYPE_U64] = wapp_str8_lit_ro("u64"),
[CTYPE_F32] = wapp_str8_lit_ro("f32"),
[CTYPE_F64] = wapp_str8_lit_ro("f64"),
[CTYPE_F128] = wapp_str8_lit_ro("f128"),
[CTYPE_IPTR] = wapp_str8_lit_ro("iptr"),
[CTYPE_UPTR] = wapp_str8_lit_ro("uptr"),
};
typedef enum {
CQUALIFIER_NONE,
CQUALIFIER_CONST,
CQUALIFIER_EXTERNAL,
CQUALIFIER_INTERNAL,
CQUALIFIER_PERSISTENT,
COUNT_CQUALIFIER,
} CQualifier;
wapp_intern Str8RO cqualifiers[COUNT_CQUALIFIER] = {
[CQUALIFIER_NONE] = wapp_str8_lit_ro(""),
[CQUALIFIER_CONST] = wapp_str8_lit_ro("const "),
[CQUALIFIER_EXTERNAL] = wapp_str8_lit_ro("wapp_extern "),
[CQUALIFIER_INTERNAL] = wapp_str8_lit_ro("wapp_intern "),
[CQUALIFIER_PERSISTENT] = wapp_str8_lit_ro("wapp_persist "),
};
typedef enum {
CPOINTERTYPE_NONE,
CPOINTERTYPE_SINGLE,
CPOINTERTYPE_DOUBLE,
COUNT_CPOINTERTYPE,
} CPointerType;
wapp_intern Str8RO cpointertypes[COUNT_CPOINTERTYPE] = {
[CPOINTERTYPE_NONE] = wapp_str8_lit_ro(""),
[CPOINTERTYPE_SINGLE] = wapp_str8_lit_ro("*"),
[CPOINTERTYPE_DOUBLE] = wapp_str8_lit_ro("**"),
};
#endif // !TYPE_ENUMS_H

View File

View File

@@ -1,17 +1,60 @@
import json
from typing import Dict
from pathlib import Path from pathlib import Path
from codegen.datatypes import CDataType from codegen.datatypes import CDataType, CStruct
from codegen.dbl_list.gen_dbl_list import DblListData, gen_dbl_list from codegen.constants import WAPP_REPO_ROOT, DBL_LIST_DATA, ARRAY_DATA
from codegen.dbl_list.make_dbl_list import DblListData, make_dbl_list
from codegen.array.make_array import ArrayData, make_array
def main(): def main(types_file: Path | None):
datatypes: dict[CDataType, DblListData] = { dbl_list_datatypes: Dict[CDataType, DblListData] = {}
"int": DblListData( array_datatypes: Dict[CDataType, ArrayData] = {}
out_dir=Path("/Users/abdelrahman/dev/personal/wizapp-stdlib"),
), if types_file is not None:
with types_file.open("r") as infile:
datatypes = json.load(infile)
dbl_list_data = datatypes.get(DBL_LIST_DATA)
array_data = datatypes.get(ARRAY_DATA)
if dbl_list_data is not None and isinstance(dbl_list_data, dict):
dbl_list_datatypes = {k: DblListData.from_dict(v) for k, v in dbl_list_data.items()}
if array_data is not None and isinstance(array_data, dict):
array_datatypes = {k: ArrayData.from_dict(v) for k, v in array_data.items()}
make_dbl_list(dbl_list_datatypes)
make_array(array_datatypes)
# Save example types file
custom_struct = CStruct(name="custom_type", cargs=[], typedef_name="CustomType")
example = {
DBL_LIST_DATA: {
"CustomType": DblListData(
node_typename="CustomTypeNode",
list_typename="CustomTypeList",
hdr_decl_types=[custom_struct],
).to_dict()
},
ARRAY_DATA: {
"CustomType": ArrayData(
array_typename="CustomTypeArray",
hdr_decl_types=[custom_struct],
).to_dict()
},
} }
gen_dbl_list(datatypes) example_file = WAPP_REPO_ROOT / "codegen_custom_data_example.json"
with example_file.open("w") as outfile:
json.dump(example, outfile, indent=2)
if __name__ == "__main__": if __name__ == "__main__":
main() from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("-f", "--types-file", type=Path, help="JSON file containing custom types for codegen")
args = parser.parse_args()
main(args.types_file)

435
codegen/array/make_array.py Normal file
View File

@@ -0,0 +1,435 @@
from pathlib import Path
from dataclasses import dataclass, field
from typing import List, Dict, Any, Type
from codegen.constants import WAPP_SRC_ROOT
from codegen.utils import load_func_body_from_file, convert_to_relative
from codegen.datatypes import (
CDataType,
CMacro,
CStruct,
CFunc,
CHeader,
CSource,
CArg,
CType,
CPointer,
CPointerType,
CQualifier,
CInclude,
SerialisableDataclass,
get_datatype_string,
)
@dataclass
class ArrayData(SerialisableDataclass):
array_typename: str
hdr_decl_types: List[CStruct] = field(default_factory=list)
src_decl_types: List[CStruct] = field(default_factory=list)
@classmethod
def from_dict(cls: Type["ArrayData"], d: Dict[str, Any]) -> "ArrayData":
data = ArrayData(**d)
data.hdr_decl_types = [CStruct.from_dict(v) for v in data.hdr_decl_types if isinstance(v, dict)]
data.src_decl_types = [CStruct.from_dict(v) for v in data.src_decl_types if isinstance(v, dict)]
return data
def make_array(user_datatypes: Dict[CDataType, ArrayData] = {}):
def __format_func_body(
filename: Path,
type_string: str,
type_string_upper: str,
type_string_lower: str,
array_typename: str
):
return load_func_body_from_file(filename).format(
T=type_string,
ArrayType=array_typename,
Tupper=type_string_upper,
Tlower=type_string_lower,
)
out_dir = WAPP_SRC_ROOT / "primitives" / "array"
out_dir.mkdir(parents=True, exist_ok=True)
common_includes: List[CInclude] = [
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "primitives" / "mem_allocator" / "mem_allocator.h", out_dir)).replace("\\", "/"),
local=True,
),
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "misc" / "misc_utils.h", out_dir)).replace("\\", "/"),
local=True,
),
]
common_decl_types: List[CStruct] = []
datatypes: dict[CDataType, ArrayData] = {
CType.VOID: ArrayData(array_typename="GenericArray"),
"void *": ArrayData(array_typename="VoidPArray"),
"Str8": ArrayData(
array_typename="Str8Array",
hdr_decl_types=[
CStruct(name="str8", cargs=[], typedef_name="Str8"),
],
),
}
for _type in CType:
if _type == CType.VOID:
continue
type_title = _type.value.title()
datatypes[_type] = ArrayData(
array_typename=f"{type_title}Array",
)
datatypes.update(user_datatypes)
snippets_dir = Path(__file__).parent / "snippets"
header = CHeader(
name="array",
decl_types=[*common_decl_types],
includes=[],
types=[],
funcs=[]
)
source = CSource(
name=header.name,
decl_types=[*common_decl_types],
includes=[
CInclude(header, local=True, same_dir=True),
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "assert" / "assert.h", out_dir)).replace("\\", "/"),
local=True
),
CInclude(header="stddef.h"),
],
internal_funcs=[],
funcs=header.funcs
)
if len(common_includes) > 0:
header.includes.extend(common_includes)
source.includes.extend(common_includes)
generic_funcs = []
for _type, array_data in datatypes.items():
type_string = get_datatype_string(_type)
clean_type_string = type_string.replace(" ", "").replace("*", "_ptr")
type_string_upper = clean_type_string.upper()
type_string_lower = clean_type_string.lower()
array = CStruct(
name=array_data.array_typename,
cargs=[
CArg(name="items", _type=type_string, pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="count", _type=CType.U64),
CArg(name="capacity", _type=CType.U64),
CArg(name="item_size", _type=CType.U64),
],
)
if isinstance(_type, CType) and _type == CType.VOID:
alloc_capacity_func = CFunc(
name=f"_array_alloc_capacity",
ret_type=array,
args=[
CArg(name="allocator", _type="Allocator", pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="capacity", _type=CType.U64),
CArg(name="item_size", _type=CType.U64),
],
body=__format_func_body(
filename=snippets_dir / "alloc_capacity",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
pointer=CPointer(CPointerType.SINGLE),
)
generic_funcs.append(alloc_capacity_func)
else:
stack_array_cmacro = CMacro(
name=f"wapp_{type_string_lower}_array(...)",
value=__format_func_body(
filename=snippets_dir / "stack_array",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
stack_array_cppmacro = CMacro(
name=f"wapp_{type_string_lower}_array(...)",
value=__format_func_body(
filename=snippets_dir / "stack_array_cpp",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
stack_capacity_array_cmacro = CMacro(
name=f"wapp_{type_string_lower}_array_with_capacity(CAPACITY)",
value=__format_func_body(
filename=snippets_dir / "stack_capacity_array",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
stack_capacity_array_cppmacro = CMacro(
name=f"wapp_{type_string_lower}_array_with_capacity(CAPACITY)",
value=__format_func_body(
filename=snippets_dir / "stack_capacity_array_cpp",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
alloc_capacity_array_macro = CMacro(
name=f"wapp_{type_string_lower}_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY)",
value=__format_func_body(
filename=snippets_dir / "alloc_capacity_macro",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
array_pop_cmacro = CMacro(
name=f"wapp_{type_string_lower}_array_pop(ARRAY_PTR)",
value=__format_func_body(
filename=snippets_dir / "array_pop_macro",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
array_pop_cppmacro = CMacro(
name=f"wapp_{type_string_lower}_array_pop(ARRAY_PTR)",
value=__format_func_body(
filename=snippets_dir / "array_pop_macro_cpp",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
get_func = CFunc(
name=f"wapp_{type_string_lower}_array_get",
ret_type=type_string,
args=[
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="index", _type=CType.U64),
],
body=__format_func_body(
filename=snippets_dir / "array_get",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
pointer=CPointer(CPointerType.SINGLE),
)
set_func = CFunc(
name=f"wapp_{type_string_lower}_array_set",
ret_type=CType.VOID,
args=[
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="index", _type=CType.U64),
CArg(name="item", _type=type_string, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "array_set",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
append_capped_func = CFunc(
name=f"wapp_{type_string_lower}_array_append_capped",
ret_type=CType.VOID,
args=[
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="item", _type=type_string, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "append_capped",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
extend_capped_func = CFunc(
name=f"wapp_{type_string_lower}_array_extend_capped",
ret_type=CType.VOID,
args=[
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="other", _type=array, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
],
body=__format_func_body(
filename=snippets_dir / "extend_capped",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
clear_func = CFunc(
name=f"wapp_{type_string_lower}_array_clear",
ret_type=CType.VOID,
args=[
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "clear",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
copy_capped_func = CFunc(
name=f"wapp_{type_string_lower}_array_copy_capped",
ret_type=CType.VOID,
args=[
CArg(name="src", _type=array, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="dst", _type=array, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "copy_capped",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
)
append_alloc_func = CFunc(
name=f"wapp_{type_string_lower}_array_append_alloc",
ret_type=array,
args=[
CArg(name="allocator", _type="Allocator", pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="item", _type=type_string, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "append_alloc",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
pointer=CPointer(CPointerType.SINGLE),
)
extend_alloc_func = CFunc(
name=f"wapp_{type_string_lower}_array_extend_alloc",
ret_type=array,
args=[
CArg(name="allocator", _type="Allocator", pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="other", _type=array, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
],
body=__format_func_body(
filename=snippets_dir / "extend_alloc",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
pointer=CPointer(CPointerType.SINGLE),
)
copy_alloc_func = CFunc(
name=f"wapp_{type_string_lower}_array_copy_alloc",
ret_type=array,
args=[
CArg(name="allocator", _type="Allocator", pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="src", _type=array, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="dst", _type=array, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "copy_alloc",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
pointer=CPointer(CPointerType.SINGLE),
)
pop_func = CFunc(
name=f"_{type_string_lower}_array_pop",
ret_type=type_string,
args=[
CArg(name="array", _type=array, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "array_pop",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
array_typename=array_data.array_typename,
),
pointer=CPointer(CPointerType.SINGLE),
)
header.macros.extend([
alloc_capacity_array_macro,
])
header.c_macros.extend([
stack_array_cmacro,
stack_capacity_array_cmacro,
array_pop_cmacro,
])
header.cpp_macros.extend([
stack_array_cppmacro,
stack_capacity_array_cppmacro,
array_pop_cppmacro,
])
header.funcs.extend([
get_func,
set_func,
append_capped_func,
extend_capped_func,
clear_func,
copy_capped_func,
append_alloc_func,
extend_alloc_func,
copy_alloc_func,
pop_func,
])
header.decl_types.extend(array_data.hdr_decl_types)
header.types.extend([array])
source.decl_types.extend(array_data.src_decl_types)
source.funcs = header.funcs
header.funcs.extend(generic_funcs)
header.save(out_dir)
source.save(out_dir)

View File

@@ -0,0 +1,15 @@
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
u64 allocation_size = sizeof({ArrayType}) + item_size * capacity;
{ArrayType} *array = wapp_mem_allocator_alloc(allocator, allocation_size);
if (!array) {{
goto RETURN_GENERIC_ARRAY_ALLOC;
}}
array->items = ({T} *)((u8 *)array + sizeof({ArrayType}));
array->count = 0;
array->capacity = capacity;
array->item_size = item_size;
RETURN_GENERIC_ARRAY_ALLOC:
return array;

View File

@@ -0,0 +1 @@
(({ArrayType} *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof({T})))

View File

@@ -0,0 +1,18 @@
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
{ArrayType} *output = array;
if (array->count >= array->capacity) {{
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
output = ({ArrayType} *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
if (!output) {{
output = array;
goto RETURN_{Tupper}_ARRAY_APPEND_ALLOC;
}}
wapp_{Tlower}_array_copy_capped(array, output);
}}
wapp_{Tlower}_array_append_capped(output, item);
RETURN_{Tupper}_ARRAY_APPEND_ALLOC:
return output;

View File

@@ -0,0 +1,5 @@
wapp_debug_assert(array != NULL, "`array` should not be NULL");
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
u64 index = (array->count)++;
wapp_{Tlower}_array_set(array, index, item);

View File

@@ -0,0 +1,5 @@
wapp_debug_assert(array != NULL, "`array` should not be NULL");
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
return ({T} *)ptr;

View File

@@ -0,0 +1,4 @@
u64 index = array->count - 1;
{T} *out = wapp_{Tlower}_array_get(array, index);
--(array->count);
return out;

View File

@@ -0,0 +1,4 @@
(ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_{Tlower}_array_pop(ARRAY_PTR) : \
({T}){{0}} \
)

View File

@@ -0,0 +1,4 @@
(ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_{Tlower}_array_pop(ARRAY_PTR) : \
{T}{{}} \
)

View File

@@ -0,0 +1,3 @@
{T} *ptr = wapp_{Tlower}_array_get(array, index);
memcpy((void *)ptr, (void *)item, array->item_size);

View File

@@ -0,0 +1,2 @@
wapp_debug_assert(array != NULL, "`array` should not be NULL");
array->count = 0;

View File

@@ -0,0 +1,18 @@
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
{ArrayType} *output = dst;
if (src->count >= dst->capacity) {{
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
output = ({ArrayType} *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
if (!output) {{
output = dst;
goto RETURN_{Tupper}_ARRAY_COPY_ALLOC;
}}
}}
wapp_{Tlower}_array_clear(output);
wapp_{Tlower}_array_copy_capped(src, output);
RETURN_{Tupper}_ARRAY_COPY_ALLOC:
return output;

View File

@@ -0,0 +1,22 @@
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
wapp_{Tlower}_array_clear(dst);
{T} *item;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
u64 item_index = 0;
b32 running = true;
while (running) {{
item = wapp_{Tlower}_array_get(src, item_index);
++item_index;
running = item_index < to_copy;
if (!item) {{
continue;
}}
wapp_{Tlower}_array_append_capped(dst, item);
}}

View File

@@ -0,0 +1,19 @@
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
{ArrayType} *output = array;
u64 remaining_capacity = array->capacity - array->count;
if (other->count >= remaining_capacity) {{
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
output = ({ArrayType} *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
if (!output) {{
output = array;
goto RETURN_{Tupper}_ARRAY_EXTEND_ALLOC;
}}
wapp_{Tlower}_array_copy_capped(array, output);
}}
wapp_{Tlower}_array_extend_capped(output, other);
RETURN_{Tupper}_ARRAY_EXTEND_ALLOC:
return output;

View File

@@ -0,0 +1,23 @@
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
u64 remaining_capacity = array->capacity - array->count;
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
{T} *item;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 items_to_add = other->count;
u64 item_index = 0;
b32 running = true;
while (running) {{
item = wapp_{Tlower}_array_get(other, item_index);
++item_index;
running = item_index < items_to_add;
if (!item) {{
continue;
}}
wapp_{Tlower}_array_append_capped(array, item);
}}

View File

@@ -0,0 +1,6 @@
(({ArrayType}){{ \
.items = ({T}[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count({T}, __VA_ARGS__) * 2)]){{__VA_ARGS__}}, \
.count = wapp_misc_utils_va_args_count({T}, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count({T}, __VA_ARGS__) * 2), \
.item_size = sizeof({T}) \
}})

View File

@@ -0,0 +1,9 @@
([&]() {{ \
wapp_persist {T} buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count({T}, __VA_ARGS__) * 2)] = {{__VA_ARGS__}}; \
return {ArrayType}{{ \
buf, \
wapp_misc_utils_va_args_count({T}, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count({T}, __VA_ARGS__) * 2), \
sizeof({T}) \
}}; \
}}())

View File

@@ -0,0 +1 @@
(({ArrayType}){{.items = ({T}[CAPACITY]){{0}}, .count = 0, .capacity = CAPACITY, .item_size = sizeof({T})}})

View File

@@ -0,0 +1,4 @@
([&]() {{ \
wapp_persist {T} buf[CAPACITY] = {{}}; \
return {ArrayType}{{buf, 0, CAPACITY, sizeof({T})}}; \
}}())

View File

@@ -1,5 +1,10 @@
from pathlib import Path from pathlib import Path
# Paths
PACKAGE_DIR = Path(__file__).parent.resolve()
WAPP_REPO_ROOT = PACKAGE_DIR.parent
WAPP_SRC_ROOT = WAPP_REPO_ROOT / "src"
PACKAGE_DIR = Path(__file__).parent # Dictionary Keys
WAPP_SRC_ROOT = PACKAGE_DIR.parent / "src" DBL_LIST_DATA = "dbl_list_data"
ARRAY_DATA = "array_data"

View File

@@ -1,12 +1,73 @@
from enum import Enum from enum import Enum
from pathlib import Path from pathlib import Path
from typing import Optional, Union from typing import Optional, Union, List, Dict, Type, Any, TypeVar, cast
from dataclasses import dataclass, field from dataclasses import dataclass, asdict, field, fields
from codegen.constants import WAPP_SRC_ROOT
from codegen.utils import convert_to_relative
E = TypeVar("E", bound="Enum")
S = TypeVar("S", bound="SerialisableDataclass")
F = TypeVar("F", bound="CFile")
@dataclass
class SerialisableDataclass:
def to_dict(self) -> Dict[str, Any]:
d = asdict(self)
for f in fields(self):
member = getattr(self, f.name)
if isinstance(member, list):
d[f.name] = [self.__serialise_member(i) for i in member]
else:
d[f.name] = self.__serialise_member(member)
return d
def __serialise_member(self, member: Any) -> Any:
if isinstance(member, Enum):
return member.value
elif isinstance(member, SerialisableDataclass):
return member.to_dict()
return member
@staticmethod
def to_enum_value(value: Any, _type: Type[E]) -> "E":
if isinstance(value, _type):
return value
return _type(value)
@staticmethod
def to_c_usertype(value: dict[str, Any]) -> "CUserType":
try:
output = CStruct.from_dict(value)
except TypeError:
output = CEnum.from_dict(value)
return output
@staticmethod
def to_cdatatype(value: Any) -> "CDataType":
if isinstance(value, dict):
output = SerialisableDataclass.to_c_usertype(value)
else:
try:
output = CType(value)
except ValueError:
output = value
return output
@classmethod
def from_dict(cls: Type[S], d: Dict[str, Any]) -> "S":
return cls(**d)
class CType(Enum): class CType(Enum):
VOID = "void" VOID = "void"
BOOL = "bool" BOOL = "b32"
CHAR = "char" CHAR = "char"
C8 = "c8" C8 = "c8"
C16 = "c16" C16 = "c16"
@@ -32,9 +93,9 @@ class CType(Enum):
class CQualifier(Enum): class CQualifier(Enum):
NONE = "" NONE = ""
CONST = "const " CONST = "const "
EXTERNAL = "external " EXTERNAL = "wapp_extern "
INTERNAL = "internal " INTERNAL = "wapp_intern "
PERSISTENT = "persistent " PERSISTENT = "wapp_persist "
def __str__(self) -> str: def __str__(self) -> str:
return self.value return self.value
@@ -50,16 +111,23 @@ class CPointerType(Enum):
@dataclass @dataclass
class CPointer: class CPointer(SerialisableDataclass):
_type: CPointerType = CPointerType.NONE _type: CPointerType = CPointerType.NONE
qualifier: CQualifier = CQualifier.NONE qualifier: CQualifier = CQualifier.NONE
def __str__(self) -> str: def __str__(self) -> str:
return str(self._type) + str(self.qualifier) return str(self._type) + str(self.qualifier)
@classmethod
def from_dict(cls: Type["CPointer"], d: Dict[str, Any]) -> "CPointer":
ptr = CPointer(**d)
ptr._type = CPointer.to_enum_value(ptr._type, CPointerType)
ptr.qualifier = CPointer.to_enum_value(ptr.qualifier, CQualifier)
return ptr
@dataclass @dataclass
class CEnumVal: class CEnumVal(SerialisableDataclass):
name: str name: str
value: Optional[int] = None value: Optional[int] = None
@@ -68,9 +136,9 @@ class CEnumVal:
@dataclass @dataclass
class CEnum: class CEnum(SerialisableDataclass):
name: str name: str
values: list[CEnumVal] values: List[CEnumVal]
typedef: bool = False typedef: bool = False
def __str__(self) -> str: def __str__(self) -> str:
@@ -87,12 +155,27 @@ class CEnum:
return header + values + footer return header + values + footer
@classmethod
def from_dict(cls: Type["CEnum"], d: Dict[str, Any]) -> "CEnum":
e = CEnum(**d)
e.values = [CEnumVal.from_dict(v) for v in e.values if isinstance(v, dict)]
return e
@dataclass @dataclass
class CStruct: class CMacro(SerialisableDataclass):
name: str name: str
cargs: list["CArg"] value: str
typedef_name: str | None = None
def __str__(self) -> str:
return f"#define {self.name} {self.value}\n"
@dataclass
class CStruct(SerialisableDataclass):
name: str
cargs: List["CArg"]
typedef_name: Optional[str] = None
def __str__(self) -> str: def __str__(self) -> str:
return self.declare() + self.define() return self.declare() + self.define()
@@ -110,13 +193,19 @@ class CStruct:
return definition + args + footer; return definition + args + footer;
@classmethod
def from_dict(cls: Type["CStruct"], d: Dict[str, Any]) -> "CStruct":
s = CStruct(**d)
s.cargs = [CArg.from_dict(v) for v in s.cargs if isinstance(v, dict)]
return s
CUserType = Union[CStruct, CEnum] CUserType = Union[CStruct, CEnum]
CDataType = Union[CType, CUserType, str] CDataType = Union[CType, CUserType, str]
@dataclass @dataclass
class CArg: class CArg(SerialisableDataclass):
name: str name: str
_type: CDataType _type: CDataType
array: bool = False array: bool = False
@@ -131,15 +220,27 @@ class CArg:
return qualifier + _type + pointer + self.name + array return qualifier + _type + pointer + self.name + array
@classmethod
def from_dict(cls: Type["CArg"], d: Dict[str, Any]) -> "CArg":
arg = CArg(**d)
arg._type = CArg.to_cdatatype(arg._type)
if isinstance(arg.pointer, dict):
arg.pointer = CPointer.from_dict(arg.pointer)
arg.qualifier = CArg.to_enum_value(arg.qualifier, CQualifier)
return arg
@dataclass @dataclass
class CFunc: class CFunc(SerialisableDataclass):
name: str name: str
ret_type: CDataType ret_type: CDataType
args: list[CArg] args: List[CArg]
body: str body: str
pointer: CPointer = field(default_factory=CPointer) pointer: CPointer = field(default_factory=CPointer)
qualifiers: list[CQualifier] = field(default_factory=list) qualifiers: List[CQualifier] = field(default_factory=list)
def __str__(self) -> str: def __str__(self) -> str:
qualifiers = "" qualifiers = ""
@@ -164,9 +265,21 @@ class CFunc:
def define(self) -> str: def define(self) -> str:
return f"{str(self)} {{\n{self.body}\n}}\n\n" return f"{str(self)} {{\n{self.body}\n}}\n\n"
@classmethod
def from_dict(cls: Type["CFunc"], d: Dict[str, Any]) -> "CFunc":
f = CFunc(**d)
f.ret_type = CFunc.to_cdatatype(f.ret_type)
f.args = [CArg.from_dict(v) for v in f.args if isinstance(v, dict)]
f.qualifiers = [CFunc.to_enum_value(v, CQualifier) for v in f.qualifiers]
if isinstance(f.pointer, dict):
f.pointer = CPointer.from_dict(f.pointer)
return f
@dataclass @dataclass
class CInclude: class CInclude(SerialisableDataclass):
header: Union[str, "CHeader"] header: Union[str, "CHeader"]
local: bool = False local: bool = False
same_dir: bool = False same_dir: bool = False
@@ -189,14 +302,41 @@ class CInclude:
return f"#include {open_symbol}{name}{close_symbol}\n" return f"#include {open_symbol}{name}{close_symbol}\n"
@classmethod
def from_dict(cls: Type["CInclude"], d: Dict[str, Any]) -> "CInclude":
inc = CInclude(**d)
if isinstance(inc.header, dict):
inc.header = CHeader.from_dict(inc.header)
return inc
@dataclass @dataclass
class CFile: class CFile(SerialisableDataclass):
name: str name: str
extension: str extension: str
decl_types: list[CStruct] = field(default_factory=list) includes: List[CInclude] = field(default_factory=list)
types: List[CUserType] = field(default_factory=list)
funcs: List[CFunc] = field(default_factory=list)
decl_types: List[CStruct] = field(default_factory=list)
macros: List[CMacro] = field(default_factory=list)
c_macros: List[CMacro] = field(default_factory=list)
cpp_macros: List[CMacro] = field(default_factory=list)
def save(self, output_dir: Path): def save(self, output_dir: Path):
self.includes.extend(
[
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "aliases" / "aliases.h", output_dir)).replace("\\", "/"),
local=True,
),
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "platform" / "platform.h", output_dir)).replace("\\", "/"),
local=True,
)
]
)
output_file = output_dir / f"{self.name}.{self.extension}" output_file = output_dir / f"{self.name}.{self.extension}"
with open(output_file, "w+") as outfile: with open(output_file, "w+") as outfile:
outfile.write(str(self)) outfile.write(str(self))
@@ -204,18 +344,31 @@ class CFile:
def __str__(self) -> str: def __str__(self) -> str:
return """\ return """\
/** /**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN * THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN.
*/ */
""" """
@classmethod
def from_dict(cls: Type["CFile"], d: Dict[str, Any]) -> "CFile":
f = CFile(**d)
f.deserialise_c_file_data()
return f
def deserialise_c_file_data(self) -> None:
self.includes = [CInclude.from_dict(v) for v in self.includes if isinstance(v, dict)]
self.types = [CFile.to_c_usertype(v) for v in self.types if isinstance(v, dict)]
self.funcs = [CFunc.from_dict(v) for v in self.funcs if isinstance(v, dict)]
self.decl_types = [CStruct.from_dict(v) for v in self.decl_types if isinstance(v, dict)]
self.macros = [CMacro.from_dict(v) for v in self.macros if isinstance(v, dict)]
self.c_macros = [CMacro.from_dict(v) for v in self.c_macros if isinstance(v, dict)]
self.cpp_macros = [CMacro.from_dict(v) for v in self.cpp_macros if isinstance(v, dict)]
@dataclass @dataclass
class CHeader(CFile): class CHeader(CFile):
extension: str = "h" extension: str = "h"
includes: list[CInclude] = field(default_factory=list)
types: list[CUserType] = field(default_factory=list)
funcs: list[CFunc] = field(default_factory=list)
def __str__(self) -> str: def __str__(self) -> str:
name_upper = self.name.upper() name_upper = self.name.upper()
@@ -223,11 +376,26 @@ class CHeader(CFile):
header_guard_open = f"#ifndef {header_guard_name}\n#define {header_guard_name}\n\n" header_guard_open = f"#ifndef {header_guard_name}\n#define {header_guard_name}\n\n"
header_guard_close = f"#endif // !{header_guard_name}\n" header_guard_close = f"#endif // !{header_guard_name}\n"
c_linkage_open = "#ifdef __cplusplus\nBEGIN_C_LINKAGE\n#endif // !__cplusplus\n\n" c_linkage_open = "#ifdef WAPP_PLATFORM_CPP\nBEGIN_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n"
c_linkage_close = "\n#ifdef __cplusplus\nEND_C_LINKAGE\n#endif // !__cplusplus\n\n" c_linkage_close = "\n#ifdef WAPP_PLATFORM_CPP\nEND_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n"
includes = _get_includes_string(self.includes) includes = _get_includes_string(self.includes)
macros = ""
for macro in self.macros:
macros += str(macro)
if len(macros) > 0:
macros += "\n"
if len(self.cpp_macros) > 0:
macros += "#ifdef WAPP_PLATFORM_CPP\n"
for macro in self.cpp_macros:
macros += str(macro)
macros += "#else\n"
for macro in self.c_macros:
macros += str(macro)
macros += "#endif // !WAPP_PLATFORM_CPP\n\n"
forward_declarations = "" forward_declarations = ""
for _type in self.decl_types: for _type in self.decl_types:
forward_declarations += _type.declare() forward_declarations += _type.declare()
@@ -247,6 +415,7 @@ class CHeader(CFile):
header_guard_open + header_guard_open +
includes + includes +
c_linkage_open + c_linkage_open +
macros +
forward_declarations + forward_declarations +
types + types +
funcs + funcs +
@@ -254,18 +423,25 @@ class CHeader(CFile):
header_guard_close header_guard_close
) )
@classmethod
def from_dict(cls: Type["CHeader"], d: Dict[str, Any]) -> "CHeader":
return cast("CHeader", super().from_dict(d))
@dataclass @dataclass
class CSource(CFile): class CSource(CFile):
extension: str = "c" extension: str = "c"
includes: list[CInclude] = field(default_factory=list) internal_funcs: List[CFunc] = field(default_factory=list)
types: list[CUserType] = field(default_factory=list)
internal_funcs: list[CFunc] = field(default_factory=list)
funcs: list[CFunc] = field(default_factory=list)
def __str__(self) -> str: def __str__(self) -> str:
includes = _get_includes_string(self.includes) includes = _get_includes_string(self.includes)
macros = ""
for macro in self.macros:
macros += str(macro)
if len(macros) > 0:
macros += "\n"
forward_declarations = "" forward_declarations = ""
for _type in self.decl_types: for _type in self.decl_types:
forward_declarations += _type.declare() forward_declarations += _type.declare()
@@ -292,6 +468,7 @@ class CSource(CFile):
return ( return (
super().__str__() + super().__str__() +
includes + includes +
macros +
forward_declarations + forward_declarations +
types + types +
internal_funcs_decl + internal_funcs_decl +
@@ -299,6 +476,13 @@ class CSource(CFile):
internal_funcs_def internal_funcs_def
) )
@classmethod
def from_dict(cls: Type["CSource"], d: Dict[str, Any]) -> "CSource":
s = CSource(**d)
s.deserialise_c_file_data()
s.internal_funcs = [CFunc.from_dict(v) for v in s.funcs if isinstance(v, dict)]
return s
def get_datatype_string(_type: CDataType) -> str: def get_datatype_string(_type: CDataType) -> str:
if isinstance(_type, CType): if isinstance(_type, CType):
@@ -309,7 +493,7 @@ def get_datatype_string(_type: CDataType) -> str:
return _type return _type
def _get_includes_string(includes: list[CInclude]) -> str: def _get_includes_string(includes: List[CInclude]) -> str:
output = "" output = ""
for include in sorted(includes, key=lambda inc: inc.local, reverse=True): for include in sorted(includes, key=lambda inc: inc.local, reverse=True):
output += str(include) output += str(include)

View File

@@ -1,208 +0,0 @@
from pathlib import Path
from dataclasses import dataclass, field
from codegen.constants import WAPP_SRC_ROOT
from codegen.utils import load_func_body_from_file
from codegen.datatypes import (
CDataType,
CStruct,
CFunc,
CHeader,
CSource,
CArg,
CType,
CPointer,
CPointerType,
CQualifier,
CInclude,
get_datatype_string,
)
@dataclass
class DblListData:
out_dir: Path
hdr_includes: list[CInclude] = field(default_factory=list)
src_includes: list[CInclude] = field(default_factory=list)
hdr_decl_types: list[CStruct] = field(default_factory=list)
src_decl_types: list[CStruct] = field(default_factory=list)
def gen_dbl_list(user_datatypes: dict[CDataType, DblListData] = {}):
def __format_func_body(filename: Path, type_string: str):
return load_func_body_from_file(filename).format(
T=type_string,
Tupper=type_string.upper(),
Tlower=type_string.lower(),
)
common_includes: list[CInclude] = [
CInclude(header="../../../common/aliases/aliases.h", local=True),
]
common_decl_types: list[CStruct] = []
datatypes: dict[CDataType, DblListData] = {
"Str8": DblListData(
src_includes=[
CInclude(header="./str8.h", local=True),
],
hdr_decl_types=[
CStruct(name="str8", cargs=[], typedef_name="Str8"),
],
out_dir=WAPP_SRC_ROOT / "core/strings/str8/",
),
}
datatypes.update(user_datatypes)
snippets_dir = Path(__file__).parent / "snippets"
for _type, dbl_list_data in datatypes.items():
type_string = get_datatype_string(_type)
node = CStruct(
name=f"{type_string}Node",
cargs=[
CArg(name="item", _type=type_string, pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="prev", _type=f"{type_string}Node", pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="next", _type=f"{type_string}Node", pointer=CPointer(_type=CPointerType.SINGLE)),
],
)
dl_list = CStruct(
name=f"{type_string}List",
cargs=[
CArg(name="first", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="last", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="node_count", _type=CType.U64),
],
)
get_func = CFunc(
name=f"wapp_{type_string.lower()}_list_get",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="index", _type=CType.U64),
],
body=__format_func_body(snippets_dir / "list_get", type_string),
pointer=CPointer(CPointerType.SINGLE),
)
push_front_func = CFunc(
name=f"wapp_{type_string.lower()}_list_push_front",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(snippets_dir / "list_push_front", type_string),
)
push_back_func = CFunc(
name=f"wapp_{type_string.lower()}_list_push_back",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(snippets_dir / "list_push_back", type_string),
)
insert_func = CFunc(
name=f"wapp_{type_string.lower()}_list_insert",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="index", _type=CType.U64),
],
body=__format_func_body(snippets_dir / "list_insert", type_string),
)
pop_front_func = CFunc(
name=f"wapp_{type_string.lower()}_list_pop_front",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(snippets_dir / "list_pop_front", type_string),
pointer=CPointer(CPointerType.SINGLE),
)
pop_back_func = CFunc(
name=f"wapp_{type_string.lower()}_list_pop_back",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(snippets_dir / "list_pop_back", type_string),
pointer=CPointer(CPointerType.SINGLE),
)
remove_func = CFunc(
name=f"wapp_{type_string.lower()}_list_remove",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="index", _type=CType.U64),
],
body=__format_func_body(snippets_dir / "list_remove", type_string),
pointer=CPointer(CPointerType.SINGLE),
)
empty_func = CFunc(
name=f"wapp_{type_string.lower()}_list_empty",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(snippets_dir / "list_empty", type_string),
)
node_to_list_func = CFunc(
name=f"{type_string.lower()}_node_to_list",
ret_type=dl_list,
args=[
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(snippets_dir / "node_to_list", type_string),
qualifiers=[CQualifier.INTERNAL],
)
header = CHeader(
name=f"{type_string.lower()}_list",
decl_types=common_decl_types + dbl_list_data.hdr_decl_types,
includes=[],
types=[node, dl_list],
funcs=[
get_func,
push_front_func,
push_back_func,
insert_func,
pop_front_func,
pop_back_func,
remove_func,
empty_func,
]
)
source = CSource(
name=header.name,
decl_types=common_decl_types + dbl_list_data.src_decl_types,
includes=[CInclude(header, local=True, same_dir=True), CInclude(header="stddef.h")],
internal_funcs=[node_to_list_func],
funcs=header.funcs
)
if len(common_includes) > 0:
header.includes.extend(common_includes)
source.includes.extend(common_includes)
if len(dbl_list_data.hdr_includes) > 0:
header.includes.extend(dbl_list_data.hdr_includes)
if len(dbl_list_data.src_includes) > 0:
source.includes.extend(dbl_list_data.src_includes)
header.save(dbl_list_data.out_dir)
source.save(dbl_list_data.out_dir)

View File

@@ -0,0 +1,339 @@
from pathlib import Path
from dataclasses import dataclass, field
from typing import List, Dict, Any, Type
from codegen.constants import WAPP_SRC_ROOT
from codegen.utils import load_func_body_from_file, convert_to_relative
from codegen.datatypes import (
CDataType,
CMacro,
CStruct,
CFunc,
CHeader,
CSource,
CArg,
CType,
CPointer,
CPointerType,
CQualifier,
CInclude,
SerialisableDataclass,
get_datatype_string,
)
@dataclass
class DblListData(SerialisableDataclass):
node_typename: str
list_typename: str
hdr_decl_types: List[CStruct] = field(default_factory=list)
src_decl_types: List[CStruct] = field(default_factory=list)
@classmethod
def from_dict(cls: Type["DblListData"], d: Dict[str, Any]) -> "DblListData":
data = DblListData(**d)
data.hdr_decl_types = [CStruct.from_dict(v) for v in data.hdr_decl_types if isinstance(v, dict)]
data.src_decl_types = [CStruct.from_dict(v) for v in data.src_decl_types if isinstance(v, dict)]
return data
def make_dbl_list(user_datatypes: Dict[CDataType, DblListData] = {}):
def __format_func_body(
filename: Path,
type_string: str,
type_string_upper: str,
type_string_lower: str,
node_typename: str,
list_typename: str
):
return load_func_body_from_file(filename).format(
T=type_string,
NodeType=node_typename,
ListType=list_typename,
Tupper=type_string_upper,
Tlower=type_string_lower,
)
out_dir = WAPP_SRC_ROOT / "primitives" / "dbl_list"
out_dir.mkdir(parents=True, exist_ok=True)
common_decl_types: List[CStruct] = []
datatypes: dict[CDataType, DblListData] = {
CType.VOID: DblListData(node_typename="GenericNode", list_typename="GenericList"),
"void *": DblListData(node_typename="VoidPNode", list_typename="VoidPList"),
"Str8": DblListData(
node_typename="Str8Node",
list_typename="Str8List",
hdr_decl_types=[
CStruct(name="str8", cargs=[], typedef_name="Str8"),
],
),
}
for _type in CType:
if _type == CType.VOID:
continue
type_title = _type.value.title()
datatypes[_type] = DblListData(
node_typename=f"{type_title}Node",
list_typename=f"{type_title}List",
)
datatypes.update(user_datatypes)
snippets_dir = Path(__file__).parent / "snippets"
header = CHeader(
name="dbl_list",
decl_types=[*common_decl_types],
includes=[],
types=[],
funcs=[]
)
source = CSource(
name=header.name,
decl_types=[*common_decl_types],
includes=[
CInclude(header, local=True, same_dir=True),
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "assert" / "assert.h", out_dir)).replace("\\", "/"),
local=True
),
CInclude(header="stddef.h"),
],
internal_funcs=[],
funcs=header.funcs
)
for _type, dbl_list_data in datatypes.items():
type_string = get_datatype_string(_type)
clean_type_string = type_string.replace(" ", "").replace("*", "_ptr")
type_string_upper = clean_type_string.upper()
type_string_lower = clean_type_string.lower()
node = CStruct(
name=dbl_list_data.node_typename,
cargs=[
CArg(name="item", _type=type_string, pointer=CPointer(_type=CPointerType.SINGLE)),
],
)
node.cargs.extend([
CArg(name="prev", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="next", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)),
])
dl_list = CStruct(
name=dbl_list_data.list_typename,
cargs=[
CArg(name="first", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="last", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)),
CArg(name="node_count", _type=CType.U64),
],
)
header.types.extend([node, dl_list])
header.decl_types.extend(dbl_list_data.hdr_decl_types)
source.decl_types.extend(dbl_list_data.src_decl_types)
if isinstance(_type, CType) and _type == CType.VOID:
# Don't define any functions for the generic node and list
continue
node_cmacro = CMacro(
name=f"wapp_{type_string_lower}_list_node(ITEM_PTR)",
value=__format_func_body(
filename=snippets_dir / "list_node",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
)
node_cppmacro = CMacro(
name=f"wapp_{type_string_lower}_list_node(ITEM_PTR)",
value=__format_func_body(
filename=snippets_dir / "list_node_cpp",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
)
get_func = CFunc(
name=f"wapp_{type_string_lower}_list_get",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST),
CArg(name="index", _type=CType.U64),
],
body=__format_func_body(
filename=snippets_dir / "list_get",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
pointer=CPointer(CPointerType.SINGLE),
)
push_front_func = CFunc(
name=f"wapp_{type_string_lower}_list_push_front",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "list_push_front",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
)
push_back_func = CFunc(
name=f"wapp_{type_string_lower}_list_push_back",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "list_push_back",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
)
insert_func = CFunc(
name=f"wapp_{type_string_lower}_list_insert",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="index", _type=CType.U64),
],
body=__format_func_body(
filename=snippets_dir / "list_insert",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
)
pop_front_func = CFunc(
name=f"wapp_{type_string_lower}_list_pop_front",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "list_pop_front",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
pointer=CPointer(CPointerType.SINGLE),
)
pop_back_func = CFunc(
name=f"wapp_{type_string_lower}_list_pop_back",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "list_pop_back",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
pointer=CPointer(CPointerType.SINGLE),
)
remove_func = CFunc(
name=f"wapp_{type_string_lower}_list_remove",
ret_type=node,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
CArg(name="index", _type=CType.U64),
],
body=__format_func_body(
filename=snippets_dir / "list_remove",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
pointer=CPointer(CPointerType.SINGLE),
)
empty_func = CFunc(
name=f"wapp_{type_string_lower}_list_empty",
ret_type=CType.VOID,
args=[
CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "list_empty",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
)
node_to_list_func = CFunc(
name=f"{type_string_lower}_node_to_list",
ret_type=dl_list,
args=[
CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)),
],
body=__format_func_body(
filename=snippets_dir / "node_to_list",
type_string=type_string,
type_string_upper=type_string_upper,
type_string_lower=type_string_lower,
node_typename=dbl_list_data.node_typename,
list_typename=dbl_list_data.list_typename
),
qualifiers=[CQualifier.INTERNAL],
)
header.c_macros.append(node_cmacro)
header.cpp_macros.append(node_cppmacro)
header.funcs.extend([
get_func,
push_front_func,
push_back_func,
insert_func,
pop_front_func,
pop_back_func,
remove_func,
empty_func,
])
source.internal_funcs.append(node_to_list_func)
source.funcs = header.funcs
header.save(out_dir)
source.save(out_dir)

View File

@@ -1,6 +1,4 @@
if (!list) {{ wapp_debug_assert(list != NULL, "`list` should not be NULL");
return;
}}
u64 count = list->node_count; u64 count = list->node_count;
for (u64 i = 0; i < count; ++i) {{ for (u64 i = 0; i < count; ++i) {{

View File

@@ -1,9 +1,7 @@
if (index >= list->node_count) {{ wapp_runtime_assert(index < list->node_count, "`index` is out of bounds");
return NULL;
}}
{T}Node *output = NULL; {NodeType} *output = NULL;
{T}Node *current = list->first; {NodeType} *current = list->first;
for (u64 i = 1; i <= index; ++i) {{ for (u64 i = 1; i <= index; ++i) {{
current = current->next; current = current->next;
}} }}

View File

@@ -1,6 +1,4 @@
if (!list || !node || !(node->item)) {{ wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL");
return;
}}
if (index == 0) {{ if (index == 0) {{
wapp_{Tlower}_list_push_front(list, node); wapp_{Tlower}_list_push_front(list, node);
@@ -10,16 +8,16 @@
return; return;
}} }}
{T}Node *dst_node = wapp_{Tlower}_list_get(list, index); {NodeType} *dst_node = wapp_{Tlower}_list_get(list, index);
if (!dst_node) {{ if (!dst_node) {{
return; return;
}} }}
{T}List node_list = {Tlower}_node_to_list(node); {ListType} node_list = {Tlower}_node_to_list(node);
list->node_count += node_list.node_count; list->node_count += node_list.node_count;
{T}Node *prev = dst_node->prev; {NodeType} *prev = dst_node->prev;
dst_node->prev = node_list.last; dst_node->prev = node_list.last;
prev->next = node_list.first; prev->next = node_list.first;

View File

@@ -0,0 +1 @@
(({NodeType}){{.item = ITEM_PTR}})

View File

@@ -0,0 +1 @@
{NodeType}{{ITEM_PTR, nullptr, nullptr}}

View File

@@ -1,13 +1,15 @@
{T}Node *output = NULL; wapp_debug_assert(list != NULL, "`list` should not be NULL");
if (!list || list->node_count == 0) {{ {NodeType} *output = NULL;
if (list->node_count == 0) {{
goto RETURN_{Tupper}_LIST_POP_BACK; goto RETURN_{Tupper}_LIST_POP_BACK;
}} }}
output = list->last; output = list->last;
if (list->node_count == 1) {{ if (list->node_count == 1) {{
*list = ({T}List){{0}}; *list = ({ListType}){{0}};
goto RETURN_{Tupper}_LIST_POP_BACK; goto RETURN_{Tupper}_LIST_POP_BACK;
}} }}

View File

@@ -1,13 +1,15 @@
{T}Node *output = NULL; wapp_debug_assert(list != NULL, "`list` should not be NULL");
if (!list || list->node_count == 0) {{ {NodeType} *output = NULL;
if (list->node_count == 0) {{
goto RETURN_{Tupper}_LIST_POP_FRONT; goto RETURN_{Tupper}_LIST_POP_FRONT;
}} }}
output = list->first; output = list->first;
if (list->node_count == 1) {{ if (list->node_count == 1) {{
*list = ({T}List){{0}}; *list = ({ListType}){{0}};
goto RETURN_{Tupper}_LIST_POP_FRONT; goto RETURN_{Tupper}_LIST_POP_FRONT;
}} }}

View File

@@ -1,8 +1,6 @@
if (!list || !node || !(node->item)) {{ wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL");
return;
}}
{T}List node_list = {Tlower}_node_to_list(node); {ListType} node_list = {Tlower}_node_to_list(node);
if (list->node_count == 0) {{ if (list->node_count == 0) {{
*list = node_list; *list = node_list;
@@ -11,7 +9,7 @@
list->node_count += node_list.node_count; list->node_count += node_list.node_count;
{T}Node *last = list->last; {NodeType} *last = list->last;
if (last) {{ if (last) {{
last->next = node_list.first; last->next = node_list.first;
}} }}

View File

@@ -1,8 +1,6 @@
if (!list || !node || !(node->item)) {{ wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL");
return;
}}
{T}List node_list = {Tlower}_node_to_list(node); {ListType} node_list = {Tlower}_node_to_list(node);
if (list->node_count == 0) {{ if (list->node_count == 0) {{
*list = node_list; *list = node_list;
@@ -11,7 +9,7 @@
list->node_count += node_list.node_count; list->node_count += node_list.node_count;
{T}Node *first = list->first; {NodeType} *first = list->first;
if (first) {{ if (first) {{
first->prev = node_list.last; first->prev = node_list.last;
}} }}

View File

@@ -1,7 +1,6 @@
{T}Node *output = NULL; wapp_debug_assert(list != NULL, "`list` should not be NULL");
if (!list) {{
goto RETURN_{Tupper}_LIST_REMOVE; {NodeType} *output = NULL;
}}
if (index == 0) {{ if (index == 0) {{
output = wapp_{Tlower}_list_pop_front(list); output = wapp_{Tlower}_list_pop_front(list);

View File

@@ -1,4 +1,4 @@
{T}List output = {{.first = node, .last = node, .node_count = 1}}; {ListType} output = {{.first = node, .last = node, .node_count = 1}};
while (output.first->prev != NULL) {{ while (output.first->prev != NULL) {{
output.first = output.first->prev; output.first = output.first->prev;

View File

@@ -1,6 +1,18 @@
import os
import sys
from pathlib import Path from pathlib import Path
def load_func_body_from_file(filename: Path) -> str: def load_func_body_from_file(filename: Path) -> str:
with open(filename, "r") as infile: with open(filename, "r") as infile:
return infile.read().strip() return infile.read().rstrip()
def convert_to_relative(path: Path, target: Path) -> Path:
major = sys.version_info.major
minor = sys.version_info.minor
if major >= 3 and minor >= 12:
return path.relative_to(target, walk_up=True)
else:
return Path(os.path.relpath(str(path), start=str(target)))

View File

@@ -0,0 +1,29 @@
{
"dbl_list_data": {
"CustomType": {
"node_typename": "CustomTypeNode",
"list_typename": "CustomTypeList",
"hdr_decl_types": [
{
"name": "custom_type",
"cargs": [],
"typedef_name": "CustomType"
}
],
"src_decl_types": []
}
},
"array_data": {
"CustomType": {
"array_typename": "CustomTypeArray",
"hdr_decl_types": [
{
"name": "custom_type",
"cargs": [],
"typedef_name": "CustomType"
}
],
"src_decl_types": []
}
}
}

21
scripts/header_install.sh Normal file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
SCRIPT_DIR="$(dirname $0)"
LIB_SRC="$1"
INSTALL_PREFIX="$2"
shift 2
INCLUDES="$@"
mkdir -p "$INSTALL_PREFIX"
BASE_INCLUDE_DIR="$(dirname "$LIB_SRC")"
find $BASE_INCLUDE_DIR -maxdepth 1 -type f -name "*.h" -exec cp -v {} "$INSTALL_PREFIX" \;
cd "$SCRIPT_DIR/../src"
for INCLUDE in $INCLUDES; do
for f in $(find "$INCLUDE" -type f -name "*.h"); do
DST="$INSTALL_PREFIX/$(dirname $f)"
mkdir -p "$DST"
cp -v "$f" "$DST"
done
done

View File

@@ -1,17 +1,47 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef ALIASES_H #ifndef ALIASES_H
#define ALIASES_H #define ALIASES_H
#include "../platform/platform.h"
#include <stdint.h> #include <stdint.h>
#if WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C11_VERSION && !defined(WAPP_PLATFORM_APPLE)
#include <uchar.h>
#if WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C23_VERSION
#define c8 char8_t
#else
#define c8 uint8_t
#endif // !WAPP_PLATFORM_C23_VERSION
#define c16 char16_t
#define c32 char32_t
#else
#define c8 uint8_t #define c8 uint8_t
#define c16 uint16_t #define c16 uint16_t
#define c32 uint32_t #define c32 uint32_t
#endif // !WAPP_PLATFORM_C11_VERSION
#define u8 uint8_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 b32 uint32_t
#ifndef WAPP_PLATFORM_CPP
#ifndef false
#define false (b32)0
#endif // !false
#ifndef true
#define true (b32)1
#endif // !true
#endif // !WAPP_PLATFORM_CPP
#define i8 int8_t #define i8 int8_t
#define i16 int16_t #define i16 int16_t
#define i32 int32_t #define i32 int32_t
@@ -24,14 +54,14 @@
#define uptr uintptr_t #define uptr uintptr_t
#define iptr intptr_t #define iptr intptr_t
#define external extern #define wapp_extern extern
#define internal static #define wapp_intern static
#define persistent static #define wapp_persist static
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
#define class_mem static #define wapp_class_mem static
#define BEGIN_C_LINKAGE extern "C" { #define BEGIN_C_LINKAGE extern "C" {
#define END_C_LINKAGE } #define END_C_LINKAGE }
#endif // __cplusplus #endif // WAPP_PLATFORM_CPP
#endif // !ALIASES_H #endif // !ALIASES_H

View File

@@ -0,0 +1,41 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_ASSERT_H
#define WAPP_ASSERT_H
#include "../aliases/aliases.h"
#include "../platform/platform.h"
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define wapp_static_assert(EXPR, MSG) extern char ASSERTION_FAILED[EXPR ? 1 : -1]
#define wapp_runtime_assert(EXPR, MSG) __wapp_runtime_assert(EXPR, MSG)
#ifdef WAPP_DEBUG_ASSERT
#define wapp_debug_assert(EXPR, MSG) wapp_runtime_assert(EXPR, MSG)
#else
#define wapp_debug_assert(EXPR, MSG)
#endif
#define __wapp_runtime_assert(EXPR, MSG) do { \
if (!(EXPR)) { \
fprintf( \
stderr, \
"%s:%d (In function `%s`): Assertion failed (%" PRIu32 ")\nDiagnostic: %s\n\n", \
__FILE__, __LINE__, __func__, \
EXPR, MSG \
); \
abort(); \
} \
} while(false)
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !WAPP_ASSERT_H

View File

@@ -1,8 +1,14 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MISC_UTILS_H #ifndef MISC_UTILS_H
#define MISC_UTILS_H #define MISC_UTILS_H
#include "../aliases/aliases.h" #include "../aliases/aliases.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define KB(SIZE) (SIZE * 1024ull) #define KB(SIZE) (SIZE * 1024ull)
#define MB(SIZE) (KB(SIZE) * 1024) #define MB(SIZE) (KB(SIZE) * 1024)
#define GB(SIZE) (MB(SIZE) * 1024) #define GB(SIZE) (MB(SIZE) * 1024)
@@ -10,4 +16,41 @@
#define wapp_misc_utils_padding_size(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))] #define wapp_misc_utils_padding_size(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))]
#define U64_RSHIFT_OR_1(X) (((u64)X) | (((u64)X) >> 1))
#define U64_RSHIFT_OR_2(X) (((u64)X) | (((u64)X) >> 2))
#define U64_RSHIFT_OR_4(X) (((u64)X) | (((u64)X) >> 4))
#define U64_RSHIFT_OR_8(X) (((u64)X) | (((u64)X) >> 8))
#define U64_RSHIFT_OR_16(X) (((u64)X) | (((u64)X) >> 16))
#define U64_RSHIFT_OR_32(X) (((u64)X) | (((u64)X) >> 32))
#define wapp_misc_utils_u64_round_up_pow2(X) ( \
( \
U64_RSHIFT_OR_32( \
U64_RSHIFT_OR_16( \
U64_RSHIFT_OR_8( \
U64_RSHIFT_OR_4( \
U64_RSHIFT_OR_2( \
U64_RSHIFT_OR_1(X - 1) \
) \
) \
) \
) \
) \
) + 1 \
)
#ifdef WAPP_PLATFORM_CPP
#define wapp_misc_utils_va_args_count(T, ...) va_args_count<T>(__VA_ARGS__)
#else
#define wapp_misc_utils_va_args_count(T, ...) (sizeof((T[]){__VA_ARGS__})/sizeof(T))
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
template <typename T, typename... Args>
constexpr u64 va_args_count(Args&&...) {
return sizeof...(Args);
}
#endif // !WAPP_PLATFORM_CPP
#endif // !MISC_UTILS_H #endif // !MISC_UTILS_H

View File

@@ -1,3 +1,5 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef PLATFORM_H #ifndef PLATFORM_H
#define PLATFORM_H #define PLATFORM_H
@@ -58,4 +60,55 @@
#error "Unrecognised platform" #error "Unrecognised platform"
#endif #endif
#ifdef __cplusplus
#define WAPP_PLATFORM_CPP
#define WAPP_PLATFORM_CPP_VERSION __cplusplus
#define WAPP_PLATFORM_CPP98_VERSION 199711L
#define WAPP_PLATFORM_CPP11_VERSION 201103L
#define WAPP_PLATFORM_CPP14_VERSION 201402L
#define WAPP_PLATFORM_CPP17_VERSION 201703L
#define WAPP_PLATFORM_CPP20_VERSION 202002L
#define WAPP_PLATFORM_CPP23_VERSION 202302L
#if WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP98_VERSION
#define WAPP_PLATFORM_CPP98
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP11_VERSION
#define WAPP_PLATFORM_CPP11
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP14_VERSION
#define WAPP_PLATFORM_CPP14
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP17_VERSION
#define WAPP_PLATFORM_CPP17
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP20_VERSION
#define WAPP_PLATFORM_CPP20
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP23_VERSION
#define WAPP_PLATFORM_CPP23
#else
#error "Unrecognised C++ version"
#endif
#else
#define WAPP_PLATFORM_C
#if defined(__STDC_VERSION__)
#define WAPP_PLATFORM_C_VERSION __STDC_VERSION__
#define WAPP_PLATFORM_C99_VERSION 199901L
#define WAPP_PLATFORM_C11_VERSION 201112L
#define WAPP_PLATFORM_C17_VERSION 201710L
#define WAPP_PLATFORM_C23_VERSION 202311L
#if WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C99_VERSION
#define WAPP_PLATFORM_C99
#elif WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C11_VERSION
#define WAPP_PLATFORM_C11
#elif WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C17_VERSION
#define WAPP_PLATFORM_C17
#elif WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C23_VERSION
#define WAPP_PLATFORM_C23
#else
#error "Unrecognised C version"
#endif
#else
#define WAPP_PLATFORM_C89
#endif
#endif // !__cplusplus
#endif // !PLATFORM_H #endif // !PLATFORM_H

View File

@@ -1,7 +1,10 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_COMMON_H #ifndef WAPP_COMMON_H
#define WAPP_COMMON_H #define WAPP_COMMON_H
#include "aliases/aliases.h" #include "aliases/aliases.h"
#include "assert/assert.h"
#include "misc/misc_utils.h" #include "misc/misc_utils.h"
#include "platform/platform.h" #include "platform/platform.h"

103
src/core/file/file.c Normal file
View File

@@ -0,0 +1,103 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "file.h"
#include "../os/cpath/cpath.h"
#include "../../common/assert/assert.h"
#include "../../common/aliases/aliases.h"
#include "../../primitives/array/array.h"
#include "../../primitives/strings/str8/str8.h"
#include <stdio.h>
File *wapp_file_open(Str8RO *filepath, FileAccessMode mode) {
wapp_persist const char *modes[FILE_ACCESS_MODE_COUNT] = {
[WAPP_FA_MODE_R] = "r",
[WAPP_FA_MODE_W] = "w",
[WAPP_FA_MODE_A] = "a",
[WAPP_FA_MODE_R_EX] = "r+",
[WAPP_FA_MODE_W_EX] = "w+",
[WAPP_FA_MODE_A_EX] = "a+",
[WAPP_FA_MODE_RB] = "rb",
[WAPP_FA_MODE_WB] = "wb",
[WAPP_FA_MODE_AB] = "ab",
[WAPP_FA_MODE_RB_EX] = "rb+",
[WAPP_FA_MODE_WB_EX] = "wb+",
[WAPP_FA_MODE_AB_EX] = "ab+",
[WAPP_FA_MODE_WX] = "wx",
[WAPP_FA_MODE_WX_EX] = "wx+",
[WAPP_FA_MODE_WBX] = "wbx",
[WAPP_FA_MODE_WBX_EX] = "wbx+",
};
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return fopen((const char *)tmp, modes[mode]);
}
u64 wapp_file_get_current_position(File *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return (u64)ftell(file);
}
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fseek(file, offset, origin);
}
u64 wapp_file_get_length(File *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
u64 current = wapp_file_get_current_position(file);
wapp_file_seek(file, 0, WAPP_SEEK_END);
u64 output = ftell(file);
// Restore position
wapp_file_seek(file, current, WAPP_SEEK_START);
return output;
}
u64 wapp_file_read(GenericArray *dst, File *file, u64 item_count) {
wapp_debug_assert(dst != NULL && dst->items != NULL && file != NULL,
"`dst`, `dst->items` and `file` should not be NULL.");
u64 file_length = wapp_file_get_length(file);
u64 dst_byte_capacity = dst->item_size * dst->capacity;
u64 req_byte_count = item_count * dst->item_size;
u64 copy_byte_count = 0;
if (req_byte_count <= file_length && req_byte_count <= dst_byte_capacity) {
copy_byte_count = req_byte_count;
} else {
copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity;
}
dst->count = fread(dst->items, sizeof(u8), copy_byte_count, file) / dst->item_size;
return dst->count;
}
u64 wapp_file_write(const GenericArray *src, File *file, u64 item_count) {
wapp_debug_assert(src != NULL && src->items != NULL && file != NULL,
"`src`, `src->items` and `file` should not be NULL.");
u64 src_byte_count = src->count * src->item_size;
u64 req_byte_count = item_count * src->item_size;
u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count;
return fwrite(src->items, sizeof(u8), to_copy, file);
}
i32 wapp_file_flush(File *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fflush(file);
}
i32 wapp_file_close(File *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fclose(file);
}

72
src/core/file/file.h Normal file
View File

@@ -0,0 +1,72 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef FILE_H
#define FILE_H
#include "../../common/aliases/aliases.h"
#include "../../primitives/array/array.h"
#include "../../primitives/strings/str8/str8.h"
#include <stdio.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP
#define wapp_file_item_to_array(ITEM) (GenericArray{&(ITEM), 1, 1, sizeof(ITEM)})
#define wapp_file_array_to_item(TYPE, ARRAY) (sizeof(TYPE) == (ARRAY).item_size && (ARRAY).count == 1 ? \
*((TYPE *)((ARRAY).items)) : \
TYPE{})
#else
#define wapp_file_item_to_array(ITEM) ((GenericArray){.items = &(ITEM), \
.count = 1, \
.capacity = 1, \
.item_size = sizeof(ITEM)})
#define wapp_file_array_to_item(TYPE, ARRAY) (sizeof(TYPE) == (ARRAY).item_size && (ARRAY).count == 1 ? \
*((TYPE *)((ARRAY).items)) : \
(TYPE){0})
#endif // !WAPP_PLATFORM_CPP
typedef FILE File;
typedef enum {
WAPP_FA_MODE_R, // Equivalent to r
WAPP_FA_MODE_W, // Equivalent to w
WAPP_FA_MODE_A, // Equivalent to a
WAPP_FA_MODE_R_EX, // Equivalent to r+
WAPP_FA_MODE_W_EX, // Equivalent to w+
WAPP_FA_MODE_A_EX, // Equivalent to a+
WAPP_FA_MODE_RB, // Equivalent to rb
WAPP_FA_MODE_WB, // Equivalent to wb
WAPP_FA_MODE_AB, // Equivalent to ab
WAPP_FA_MODE_RB_EX, // Equivalent to rb+
WAPP_FA_MODE_WB_EX, // Equivalent to wb+
WAPP_FA_MODE_AB_EX, // Equivalent to ab+
WAPP_FA_MODE_WX, // Equivalent to wx
WAPP_FA_MODE_WX_EX, // Equivalent to wx+
WAPP_FA_MODE_WBX, // Equivalent to wbx
WAPP_FA_MODE_WBX_EX, // Equivalent to wbx+
FILE_ACCESS_MODE_COUNT,
} FileAccessMode;
typedef enum {
WAPP_SEEK_START = SEEK_SET,
WAPP_SEEK_CURRENT = SEEK_CUR,
WAPP_SEEK_END = SEEK_END,
} FileSeekOrigin;
File *wapp_file_open(Str8RO *filename, FileAccessMode mode);
u64 wapp_file_get_current_position(File *file);
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin);
u64 wapp_file_get_length(File *file);
u64 wapp_file_read(GenericArray *dst, File *file, u64 item_count);
u64 wapp_file_write(const GenericArray *src, File *file, u64 item_count);
i32 wapp_file_flush(File *file);
i32 wapp_file_close(File *file);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !FILE_H

View File

@@ -1,8 +1,11 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_arena.h" #include "mem_arena.h"
#include "../utils/mem_utils.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h" #include "../../../common/misc/misc_utils.h"
#include "../../os/mem/mem_os.h" #include "../../os/mem/mem_os.h"
#include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -18,14 +21,14 @@ struct arena {
u8 *buf; u8 *buf;
u8 *offset; u8 *offset;
u64 capacity; u64 capacity;
bool committed; b32 committed;
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(bool)); wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(b32));
#endif // ifdef WAPP_PLATFORM_WINDOWS #endif // ifdef WAPP_PLATFORM_WINDOWS
}; };
bool wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, bool zero_buffer) { b32 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b32 zero_buffer) {
if (!arena || *arena || base_capacity == 0) { if (!arena || *arena || base_capacity == 0) {
return false; return false;
} }
@@ -36,7 +39,11 @@ bool wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags
return false; return false;
} }
u64 arena_capacity = base_capacity >= ARENA_MINIMUM_CAPACITY ? base_capacity : ARENA_MINIMUM_CAPACITY; u64 arena_capacity = wapp_misc_utils_u64_round_up_pow2(
base_capacity >= ARENA_MINIMUM_CAPACITY ?
base_capacity :
ARENA_MINIMUM_CAPACITY
);
arena_ptr->buf = (u8 *)wapp_mem_util_alloc(NULL, arena_capacity, WAPP_MEM_ACCESS_READ_WRITE, flags, arena_ptr->buf = (u8 *)wapp_mem_util_alloc(NULL, arena_capacity, WAPP_MEM_ACCESS_READ_WRITE, flags,
zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED); zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED);
@@ -58,9 +65,7 @@ void *wapp_mem_arena_alloc(Arena *arena, u64 size) {
} }
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) { void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
if (!arena) { wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
return NULL;
}
u8 *alloc_start = arena->offset; u8 *alloc_start = arena->offset;
@@ -119,18 +124,14 @@ void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64
} }
void wapp_mem_arena_clear(Arena *arena) { void wapp_mem_arena_clear(Arena *arena) {
if (!arena) { wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
return;
}
memset(arena->buf, 0, arena->offset - arena->buf); memset(arena->buf, 0, arena->offset - arena->buf);
arena->offset = arena->buf; arena->offset = arena->buf;
} }
void wapp_mem_arena_destroy(Arena **arena) { void wapp_mem_arena_destroy(Arena **arena) {
if (!arena) { wapp_debug_assert(arena != NULL && (*arena) != NULL, "`arena` double pointer is not valid");
return;
}
Arena *arena_ptr = *arena; Arena *arena_ptr = *arena;
if (arena_ptr->buf) { if (arena_ptr->buf) {

View File

@@ -1,13 +1,15 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_ARENA_H #ifndef MEM_ARENA_H
#define MEM_ARENA_H #define MEM_ARENA_H
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include "../../os/mem/mem_os.h" #include "../../os/mem/mem_os.h"
#include <stdbool.h>
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
typedef struct arena Arena; typedef struct arena Arena;
@@ -25,7 +27,7 @@ typedef struct arena Arena;
* control over how the Arena is initialised. Wrapper macros are provided for * control over how the Arena is initialised. Wrapper macros are provided for
* easier use. * easier use.
*/ */
bool wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, bool zero_buffer); b32 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b32 zero_buffer);
void *wapp_mem_arena_alloc(Arena *arena, u64 size); void *wapp_mem_arena_alloc(Arena *arena, u64 size);
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment); void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size); void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size);
@@ -33,8 +35,8 @@ void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64
void wapp_mem_arena_clear(Arena *arena); void wapp_mem_arena_clear(Arena *arena);
void wapp_mem_arena_destroy(Arena **arena); void wapp_mem_arena_destroy(Arena **arena);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_ARENA_H #endif // !MEM_ARENA_H

View File

@@ -1,18 +1,20 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_arena_allocator.h" #include "mem_arena_allocator.h"
#include "mem_arena.h" #include "mem_arena.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../os/mem/mem_os.h" #include "../../os/mem/mem_os.h"
internal inline void *mem_arena_alloc(u64 size, void *alloc_obj); wapp_intern inline void *mem_arena_alloc(u64 size, void *alloc_obj);
internal inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj); wapp_intern inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj);
internal inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); wapp_intern inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
internal inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, wapp_intern inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj); void *alloc_obj);
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, b32 zero_buffer) {
Allocator allocator = {0}; Allocator allocator = {0};
bool initialised = wapp_mem_arena_init_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer); b32 initialised = wapp_mem_arena_init_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer);
if (!initialised) { if (!initialised) {
return allocator; return allocator;
} }
@@ -35,22 +37,22 @@ void wapp_mem_arena_allocator_destroy(Allocator *allocator) {
} }
internal inline void *mem_arena_alloc(u64 size, void *alloc_obj) { wapp_intern inline void *mem_arena_alloc(u64 size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_alloc(arena, size); return wapp_mem_arena_alloc(arena, size);
} }
internal inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj) { wapp_intern inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_alloc_aligned(arena, size, alignment); return wapp_mem_arena_alloc_aligned(arena, size, alignment);
} }
internal inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj) { wapp_intern inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_realloc(arena, ptr, old_size, new_size); return wapp_mem_arena_realloc(arena, ptr, old_size, new_size);
} }
internal inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, wapp_intern inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj) { void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment); return wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment);

View File

@@ -1,14 +1,16 @@
// vim:fileencoding=utf-8:foldmethod=marker
#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 "../../../common/aliases/aliases.h"
#include "../allocator/mem_allocator.h" #include "../../../common/platform/platform.h"
#include "../../../primitives/mem_allocator/mem_allocator.h"
#include "../../os/mem/mem_os.h" #include "../../os/mem/mem_os.h"
#include <stdbool.h>
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#define wapp_mem_arena_allocator_init(base_capacity) \ #define wapp_mem_arena_allocator_init(base_capacity) \
(wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, false)) (wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
@@ -30,12 +32,12 @@ BEGIN_C_LINKAGE
* The `wapp_mem_arena_allocator_init_custom` provides the most control over how * The `wapp_mem_arena_allocator_init_custom` provides the most control over how
* the Arena is initialised. Wrapper macros are provided for easier use. * the Arena is initialised. Wrapper macros are provided for easier use.
*/ */
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, b32 zero_buffer);
void wapp_mem_arena_allocator_clear(Allocator *allocator); void wapp_mem_arena_allocator_clear(Allocator *allocator);
void wapp_mem_arena_allocator_destroy(Allocator *allocator); void wapp_mem_arena_allocator_destroy(Allocator *allocator);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_ARENA_ALLOCATOR_H #endif // !MEM_ARENA_ALLOCATOR_H

View File

@@ -1,17 +1,15 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_utils.h" #include "mem_utils.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include <stdbool.h> #include "../../../common/assert/assert.h"
#include <stddef.h> #include <stddef.h>
#include <assert.h>
internal bool is_power_of_two(u64 num) { return (num & (num - 1)) == 0; } wapp_intern b32 is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) { void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
if (!ptr) { wapp_debug_assert(ptr != NULL, "`ptr` should not be NULL");
return NULL; wapp_runtime_assert(is_power_of_two(alignment), "`alignment` value is not a power of two");
}
assert(is_power_of_two(alignment));
uptr p = (uptr)ptr; uptr p = (uptr)ptr;
uptr align = (uptr)alignment; uptr align = (uptr)alignment;

View File

@@ -1,16 +1,19 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_UTILS_H #ifndef MEM_UTILS_H
#define MEM_UTILS_H #define MEM_UTILS_H
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
void *wapp_mem_util_align_forward(void *ptr, u64 alignment); void *wapp_mem_util_align_forward(void *ptr, u64 alignment);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_UTILS_H #endif // !MEM_UTILS_H

View File

@@ -1,11 +1,13 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "cpath.h" #include "cpath.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/misc/misc_utils.h" #include "../../../common/misc/misc_utils.h"
#include "../../mem/allocator/mem_allocator.h"
#include "../../mem/arena/mem_arena_allocator.h" #include "../../mem/arena/mem_arena_allocator.h"
#include "../../strings/str8/str8.h" #include "../../../primitives/dbl_list/dbl_list.h"
#include "../../../primitives/mem_allocator/mem_allocator.h"
#include "../../../primitives/strings/str8/str8.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -19,7 +21,7 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
} }
Str8 separator = wapp_str8_buf(4); Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP); wapp_str8_push_back(&separator, WAPP_PATH_SEP);
u64 required_capacity = parts->node_count * separator.size + wapp_str8_list_total_size(parts); u64 required_capacity = parts->node_count * separator.size + wapp_str8_list_total_size(parts);
if (dst->capacity < required_capacity) { if (dst->capacity < required_capacity) {
@@ -34,7 +36,7 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
const Str8Node *node = first_node; const Str8Node *node = first_node;
u64 node_index = 1; u64 node_index = 1;
bool running = true; b32 running = node_index < parts->node_count;
while (running && node->next) { while (running && node->next) {
node = node->next; node = node->next;
if (node->item->size == 0) { if (node->item->size == 0) {
@@ -44,7 +46,7 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
if (dst->size > 0) { if (dst->size > 0) {
char dst_last = wapp_str8_get(dst, dst->size - 1); char dst_last = wapp_str8_get(dst, dst->size - 1);
char node_start = wapp_str8_get(node->item, 0); char node_start = wapp_str8_get(node->item, 0);
bool add_path_sep = dst_last != PATH_SEP && node_start != PATH_SEP; b32 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP;
if (add_path_sep) { if (add_path_sep) {
wapp_str8_concat_capped(dst, &separator); wapp_str8_concat_capped(dst, &separator);
@@ -66,9 +68,9 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
goto RETURN_DIRUP; goto RETURN_DIRUP;
} }
bool absolute = wapp_str8_get(path, 0) == PATH_SEP; b32 absolute = wapp_str8_get(path, 0) == WAPP_PATH_SEP;
Str8 separator = wapp_str8_buf(4); Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP); wapp_str8_push_back(&separator, WAPP_PATH_SEP);
if (path->size == 0) { if (path->size == 0) {
output = wapp_str8_alloc_buf(allocator, 16); output = wapp_str8_alloc_buf(allocator, 16);
@@ -76,7 +78,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
goto RETURN_DIRUP; goto RETURN_DIRUP;
} }
wapp_str8_push_back(output, absolute ? PATH_SEP : '.'); wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
goto RETURN_DIRUP; goto RETURN_DIRUP;
} }
@@ -101,7 +103,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
goto LIST_CLEANUP_DIRUP; goto LIST_CLEANUP_DIRUP;
} }
wapp_str8_push_back(output, absolute ? PATH_SEP : '.'); wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
} else { } else {
for (u64 i = 0; i < levels; ++i) { for (u64 i = 0; i < levels; ++i) {
wapp_str8_list_pop_back(parts); wapp_str8_list_pop_back(parts);
@@ -115,7 +117,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
output = wapp_str8_alloc_buf(allocator, alloc_size); output = wapp_str8_alloc_buf(allocator, alloc_size);
if (output) { if (output) {
if (absolute) { if (absolute) {
wapp_str8_push_back(output, PATH_SEP); wapp_str8_push_back(output, WAPP_PATH_SEP);
} }
Str8 *joined = wapp_str8_join(&tmp_arena, parts, &separator); Str8 *joined = wapp_str8_join(&tmp_arena, parts, &separator);

View File

@@ -1,19 +1,25 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef CPATH_H #ifndef CPATH_H
#define CPATH_H #define CPATH_H
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h" #include "../../../common/platform/platform.h"
#include "../../mem/allocator/mem_allocator.h" #include "../../../primitives/mem_allocator/mem_allocator.h"
#include "../../strings/str8/str8.h" #include "../../../primitives/strings/str8/str8.h"
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_POSIX #ifdef WAPP_PLATFORM_POSIX
#define PATH_SEP '/' #include <limits.h>
#define WAPP_PATH_SEP '/'
#define WAPP_PATH_MAX PATH_MAX
#elif defined(WAPP_PLATFORM_WINDOWS) #elif defined(WAPP_PLATFORM_WINDOWS)
#define PATH_SEP '\\' #include <windows.h>
#define WAPP_PATH_SEP '\\'
#define WAPP_PATH_MAX MAX_PATH
#else #else
#error "Unrecognised platform" #error "Unrecognised platform"
#endif #endif
@@ -31,8 +37,8 @@ enum {
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts); u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts);
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels); Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !CPATH_H #endif // !CPATH_H

View File

@@ -1,9 +1,10 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_os.h" #include "mem_os.h"
#include "mem_os_ops.h" #include "mem_os_ops.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h" #include "../../../common/platform/platform.h"
#include <assert.h> #include <assert.h>
#include <stdbool.h>
#include <string.h> #include <string.h>
#if defined(WAPP_PLATFORM_WINDOWS) #if defined(WAPP_PLATFORM_WINDOWS)

View File

@@ -1,15 +1,17 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_H #ifndef MEM_OS_H
#define MEM_OS_H #define MEM_OS_H
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h" #include "../../../common/platform/platform.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
#include "mem_os_ops.h" #include "mem_os_ops.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#if defined(WAPP_PLATFORM_WINDOWS) #if defined(WAPP_PLATFORM_WINDOWS)
#include "win/mem_os_win.h" #include "win/mem_os_win.h"
#elif defined(WAPP_PLATFORM_POSIX) #elif defined(WAPP_PLATFORM_POSIX)
@@ -18,15 +20,14 @@ BEGIN_C_LINKAGE
#error "Unrecognised platform" #error "Unrecognised platform"
#endif #endif
void *wapp_mem_util_align_forward(void *ptr, u64 alignment);
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type); void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
void wapp_mem_util_free(void *ptr, u64 size); void wapp_mem_util_free(void *ptr, u64 size);
external void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type); wapp_extern void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
external void mem_util_free(void *ptr, u64 size); wapp_extern void mem_util_free(void *ptr, u64 size);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_H #endif // !MEM_OS_H

View File

@@ -1,9 +1,13 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_OPS_H #ifndef MEM_OS_OPS_H
#define MEM_OS_OPS_H #define MEM_OS_OPS_H
#ifdef __cplusplus #include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
typedef enum mem_access { typedef enum mem_access {
WAPP_MEM_ACCESS_NONE, WAPP_MEM_ACCESS_NONE,
@@ -19,8 +23,8 @@ typedef enum mem_init_type {
WAPP_MEM_INIT_INITIALISED, WAPP_MEM_INIT_INITIALISED,
} MemInitType; } MemInitType;
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_OPS_H #endif // !MEM_OS_OPS_H

View File

@@ -1,3 +1,5 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../common/aliases/aliases.h" #include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h" #include "../../../../common/platform/platform.h"
@@ -7,7 +9,7 @@
#include "../mem_os_ops.h" #include "../mem_os_ops.h"
#include <sys/mman.h> #include <sys/mman.h>
internal const i32 access_types[] = { wapp_intern const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PROT_NONE, [WAPP_MEM_ACCESS_NONE] = PROT_NONE,
[WAPP_MEM_ACCESS_READ_ONLY] = PROT_READ, [WAPP_MEM_ACCESS_READ_ONLY] = PROT_READ,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PROT_EXEC, [WAPP_MEM_ACCESS_EXEC_ONLY] = PROT_EXEC,

View File

@@ -1,11 +1,13 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_POSIX_H #ifndef MEM_OS_POSIX_H
#define MEM_OS_POSIX_H #define MEM_OS_POSIX_H
#include "../../../../common/platform/platform.h" #include "../../../../common/platform/platform.h"
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !__cplusplus #endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_POSIX #ifdef WAPP_PLATFORM_POSIX
@@ -26,8 +28,8 @@ typedef enum mem_alloc_flags {
#endif // !WAPP_PLATFORM_POSIX #endif // !WAPP_PLATFORM_POSIX
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // !__cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_POSIX_H #endif // !MEM_OS_POSIX_H

View File

@@ -1,3 +1,5 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../common/aliases/aliases.h" #include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h" #include "../../../../common/platform/platform.h"
@@ -10,7 +12,7 @@
#include <Windows.h> #include <Windows.h>
#include <memoryapi.h> #include <memoryapi.h>
internal const i32 access_types[] = { wapp_intern const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PAGE_NOACCESS, [WAPP_MEM_ACCESS_NONE] = PAGE_NOACCESS,
[WAPP_MEM_ACCESS_READ_ONLY] = PAGE_READONLY, [WAPP_MEM_ACCESS_READ_ONLY] = PAGE_READONLY,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PAGE_EXECUTE, [WAPP_MEM_ACCESS_EXEC_ONLY] = PAGE_EXECUTE,

View File

@@ -1,11 +1,13 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_WIN_H #ifndef MEM_OS_WIN_H
#define MEM_OS_WIN_H #define MEM_OS_WIN_H
#include "../../../../common/platform/platform.h" #include "../../../../common/platform/platform.h"
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !__cplusplus #endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
@@ -20,8 +22,8 @@ typedef enum mem_alloc_flags {
#endif // !WAPP_PLATFORM_WINDOWS #endif // !WAPP_PLATFORM_WINDOWS
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // !__cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_WIN_H #endif // !MEM_OS_WIN_H

View File

@@ -1,13 +1,15 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "commander.h" #include "commander.h"
#include "commander_output.h" #include "commander_output.h"
#include "../utils/shell_utils.h" #include "../utils/shell_utils.h"
#include "../../../mem/allocator/mem_allocator.h"
#include "../../../mem/arena/mem_arena_allocator.h" #include "../../../mem/arena/mem_arena_allocator.h"
#include "../../../strings/str8/str8.h"
#include "../../../../common/aliases/aliases.h" #include "../../../../common/aliases/aliases.h"
#include "../../../../common/misc/misc_utils.h" #include "../../../../common/misc/misc_utils.h"
#include "../../../../primitives/dbl_list/dbl_list.h"
#include "../../../../primitives/mem_allocator/mem_allocator.h"
#include "../../../../primitives/strings/str8/str8.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -15,8 +17,8 @@
#define CMD_BUF_LEN 8192 #define CMD_BUF_LEN 8192
#define OUT_BUF_LEN 4096 #define OUT_BUF_LEN 4096
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf); wapp_intern 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); wapp_intern 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 Str8List *cmd) { CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd) {
if (!cmd) { if (!cmd) {
@@ -41,7 +43,7 @@ CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_bu
return output; return output;
} }
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) { wapp_intern inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) {
char cmd_buf[CMD_BUF_LEN] = {0}; char cmd_buf[CMD_BUF_LEN] = {0};
wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN); wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN);
@@ -81,7 +83,7 @@ EXECUTE_COMMAND_CLOSE:
return output; return output;
} }
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) { wapp_intern inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) {
Str8 out = wapp_str8_buf(OUT_BUF_LEN); Str8 out = wapp_str8_buf(OUT_BUF_LEN);
out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp); out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp);

View File

@@ -1,25 +1,27 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef COMMANDER_H #ifndef COMMANDER_H
#define COMMANDER_H #define COMMANDER_H
#include "commander_output.h" #include "commander_output.h"
#include "../../../../common/aliases/aliases.h" #include "../../../../common/aliases/aliases.h"
#include "../../../strings/str8/str8.h" #include "../../../../common/platform/platform.h"
#include <stdbool.h> #include "../../../../primitives/strings/str8/str8.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#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})
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd); CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd);
external CMDError get_output_status(FILE *fp, i32 *status_out); wapp_extern CMDError get_output_status(FILE *fp, i32 *status_out);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !COMMANDER_H #endif // !COMMANDER_H

View File

@@ -1,13 +1,14 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef COMMANDER_OUTPUT_H #ifndef COMMANDER_OUTPUT_H
#define COMMANDER_OUTPUT_H #define COMMANDER_OUTPUT_H
#include "../../../../common/aliases/aliases.h" #include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h" #include "../../../../common/platform/platform.h"
#include <stdbool.h>
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
typedef enum { typedef enum {
SHELL_OUTPUT_DISCARD, SHELL_OUTPUT_DISCARD,
@@ -28,16 +29,16 @@ typedef struct commander_result CMDResult;
struct commander_result { struct commander_result {
i32 exit_code; i32 exit_code;
CMDError error; CMDError error;
bool exited; b32 exited;
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#include "misc_utils.h" #include "../../../../common/misc/misc_utils.h"
wapp_misc_utils_padding_size(sizeof(bool) + sizeof(i32) + sizeof(CMDError)); wapp_misc_utils_padding_size(sizeof(b32) + sizeof(i32) + sizeof(CMDError));
#endif // !WAPP_PLATFORM_WINDOWS #endif // !WAPP_PLATFORM_WINDOWS
}; };
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !COMMANDER_OUTPUT_H #endif // !COMMANDER_OUTPUT_H

View File

@@ -1,3 +1,5 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h" #include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h" #include "../../../../../common/platform/platform.h"

View File

@@ -1,3 +1,5 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h" #include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h" #include "../../../../../common/platform/platform.h"

View File

@@ -1,13 +1,15 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h" #include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h" #include "../../../../../common/platform/platform.h"
#include "../../../../strings/str8/str8.h" #include "../../../../../primitives/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_POSIX #ifdef WAPP_PLATFORM_POSIX
#include "../terminal_colours.h" #include "../terminal_colours.h"
#include <stdio.h> #include <stdio.h>
internal Str8RO colours[COUNT_TERM_COLOUR] = { wapp_intern Str8RO colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[30m"), [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_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_GREEN] = wapp_str8_lit_ro_initialiser_list("\033[32m"),

View File

@@ -1,6 +1,8 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "termcolour.h" #include "termcolour.h"
#include "terminal_colours.h" #include "terminal_colours.h"
#include "../../../strings/str8/str8.h" #include "../../../../primitives/strings/str8/str8.h"
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour) { void wapp_shell_termcolour_print_text(Str8RO *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) {

View File

@@ -1,21 +1,24 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TERM_COLOUR_H #ifndef TERM_COLOUR_H
#define TERM_COLOUR_H #define TERM_COLOUR_H
#include "terminal_colours.h" #include "terminal_colours.h"
#include "../../../../common/aliases/aliases.h" #include "../../../../common/aliases/aliases.h"
#include "../../../strings/str8/str8.h" #include "../../../../common/platform/platform.h"
#include "../../../../primitives/strings/str8/str8.h"
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour); void wapp_shell_termcolour_print_text(Str8RO *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); wapp_extern void print_coloured_text(Str8RO *text, TerminalColour colour);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !TERM_COLOUR_H #endif // !TERM_COLOUR_H

View File

@@ -1,9 +1,14 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TERMINAL_COLOURS_H #ifndef TERMINAL_COLOURS_H
#define TERMINAL_COLOURS_H #define TERMINAL_COLOURS_H
#ifdef __cplusplus #include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
typedef enum { typedef enum {
WAPP_TERM_COLOUR_FG_BLACK, WAPP_TERM_COLOUR_FG_BLACK,
@@ -27,8 +32,8 @@ typedef enum {
COUNT_TERM_COLOUR, COUNT_TERM_COLOUR,
} TerminalColour; } TerminalColour;
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !TERMINAL_COLOURS_H #endif // !TERMINAL_COLOURS_H

View File

@@ -1,6 +1,8 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h" #include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h" #include "../../../../../common/platform/platform.h"
#include "../../../../strings/str8/str8.h" #include "../../../../../primitives/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
@@ -20,9 +22,9 @@ struct termcolour_data {
wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD)); wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD));
}; };
internal void init_data(TermcolourData *data); wapp_intern void init_data(TermcolourData *data);
internal WORD colours[COUNT_TERM_COLOUR] = { wapp_intern WORD colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = 0, [WAPP_TERM_COLOUR_FG_BLACK] = 0,
[WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED, [WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED,
[WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN, [WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN,
@@ -42,7 +44,7 @@ internal WORD colours[COUNT_TERM_COLOUR] = {
}; };
void print_coloured_text(Str8RO *text, TerminalColour colour) { void print_coloured_text(Str8RO *text, TerminalColour colour) {
persistent TermcolourData data = {0}; wapp_persist TermcolourData data = {0};
if (data.handle == 0) { if (data.handle == 0) {
init_data(&data); init_data(&data);
} }
@@ -57,7 +59,7 @@ void print_coloured_text(Str8RO *text, TerminalColour colour) {
printf(WAPP_STR8_SPEC, wapp_str8_varg((*text))); printf(WAPP_STR8_SPEC, wapp_str8_varg((*text)));
} }
internal void init_data(TermcolourData *data) { wapp_intern void init_data(TermcolourData *data) {
// create handle // create handle
data->handle = GetStdHandle(STD_OUTPUT_HANDLE); data->handle = GetStdHandle(STD_OUTPUT_HANDLE);

View File

@@ -1,9 +1,16 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef SHELL_UTILS_H #ifndef SHELL_UTILS_H
#define SHELL_UTILS_H #define SHELL_UTILS_H
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h" #include "../../../../common/platform/platform.h"
#include <stdio.h> #include <stdio.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#define wapp_shell_utils_popen _popen #define wapp_shell_utils_popen _popen
#define wapp_shell_utils_pclose _pclose #define wapp_shell_utils_pclose _pclose
@@ -12,4 +19,8 @@
#define wapp_shell_utils_pclose pclose #define wapp_shell_utils_pclose pclose
#endif /* ifdef WAPP_PLATFORM_WINDOWS */ #endif /* ifdef WAPP_PLATFORM_WINDOWS */
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !SHELL_UTILS_H #endif // !SHELL_UTILS_H

View File

@@ -1,207 +0,0 @@
/**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN
*/
#include "./str8_list.h"
#include "../../../common/aliases/aliases.h"
#include "./str8.h"
#include <stddef.h>
internal Str8List str8_node_to_list(Str8Node *node);
Str8Node *wapp_str8_list_get(const Str8List *list, u64 index) {
if (index >= list->node_count) {
return NULL;
}
Str8Node *output = NULL;
Str8Node *current = list->first;
for (u64 i = 1; i <= index; ++i) {
current = current->next;
}
output = current;
return output;
}
void wapp_str8_list_push_front(Str8List *list, Str8Node *node) {
if (!list || !node || !(node->item)) {
return;
}
Str8List node_list = str8_node_to_list(node);
if (list->node_count == 0) {
*list = node_list;
return;
}
list->node_count += node_list.node_count;
Str8Node *first = list->first;
if (first) {
first->prev = node_list.last;
}
list->first = node_list.first;
node_list.last->next = first;
}
void wapp_str8_list_push_back(Str8List *list, Str8Node *node) {
if (!list || !node || !(node->item)) {
return;
}
Str8List node_list = str8_node_to_list(node);
if (list->node_count == 0) {
*list = node_list;
return;
}
list->node_count += node_list.node_count;
Str8Node *last = list->last;
if (last) {
last->next = node_list.first;
}
list->last = node_list.last;
node_list.first->prev = last;
}
void wapp_str8_list_insert(Str8List *list, Str8Node *node, u64 index) {
if (!list || !node || !(node->item)) {
return;
}
if (index == 0) {
wapp_str8_list_push_front(list, node);
return;
} else if (index == list->node_count) {
wapp_str8_list_push_back(list, node);
return;
}
Str8Node *dst_node = wapp_str8_list_get(list, index);
if (!dst_node) {
return;
}
Str8List node_list = str8_node_to_list(node);
list->node_count += node_list.node_count;
Str8Node *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;
}
Str8Node *wapp_str8_list_pop_front(Str8List *list) {
Str8Node *output = NULL;
if (!list || list->node_count == 0) {
goto RETURN_STR8_LIST_POP_FRONT;
}
output = list->first;
if (list->node_count == 1) {
*list = (Str8List){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;
}
Str8Node *wapp_str8_list_pop_back(Str8List *list) {
Str8Node *output = NULL;
if (!list || list->node_count == 0) {
goto RETURN_STR8_LIST_POP_BACK;
}
output = list->last;
if (list->node_count == 1) {
*list = (Str8List){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;
}
Str8Node *wapp_str8_list_remove(Str8List *list, u64 index) {
Str8Node *output = NULL;
if (!list) {
goto RETURN_STR8_LIST_REMOVE;
}
if (index == 0) {
output = wapp_str8_list_pop_front(list);
goto RETURN_STR8_LIST_REMOVE;
} else if (index == list->node_count) {
output = wapp_str8_list_pop_back(list);
goto RETURN_STR8_LIST_REMOVE;
}
output = wapp_str8_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 wapp_str8_list_empty(Str8List *list) {
if (!list) {
return;
}
u64 count = list->node_count;
for (u64 i = 0; i < count; ++i) {
wapp_str8_list_pop_back(list);
}
}
internal Str8List str8_node_to_list(Str8Node *node) {
Str8List 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,43 +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"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // !__cplusplus
typedef struct str8 Str8;
typedef struct Str8Node Str8Node;
struct Str8Node {
Str8 *item;
Str8Node *prev;
Str8Node *next;
};
typedef struct Str8List Str8List;
struct Str8List {
Str8Node *first;
Str8Node *last;
u64 node_count;
};
Str8Node *wapp_str8_list_get(const Str8List *list, u64 index);
void wapp_str8_list_push_front(Str8List *list, Str8Node *node);
void wapp_str8_list_push_back(Str8List *list, Str8Node *node);
void wapp_str8_list_insert(Str8List *list, Str8Node *node, u64 index);
Str8Node *wapp_str8_list_pop_front(Str8List *list);
Str8Node *wapp_str8_list_pop_back(Str8List *list);
Str8Node *wapp_str8_list_remove(Str8List *list, u64 index);
void wapp_str8_list_empty(Str8List *list);
#ifdef __cplusplus
END_C_LINKAGE
#endif // !__cplusplus
#endif // !STR8_LIST_H

View File

@@ -1,9 +1,10 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_CORE_C #ifndef WAPP_CORE_C
#define WAPP_CORE_C #define WAPP_CORE_C
#include "wapp_core.h" #include "wapp_core.h"
#include "strings/str8/str8.c" #include "file/file.c"
#include "strings/str8/str8_list.c"
#include "os/shell/termcolour/posix/termcolour_posix.c" #include "os/shell/termcolour/posix/termcolour_posix.c"
#include "os/shell/termcolour/win/termcolour_win.c" #include "os/shell/termcolour/win/termcolour_win.c"
#include "os/shell/termcolour/termcolour.c" #include "os/shell/termcolour/termcolour.c"
@@ -15,8 +16,8 @@
#include "os/mem/win/mem_os_win.c" #include "os/mem/win/mem_os_win.c"
#include "os/mem/mem_os.c" #include "os/mem/mem_os.c"
#include "mem/utils/mem_utils.c" #include "mem/utils/mem_utils.c"
#include "mem/allocator/mem_allocator.c"
#include "mem/arena/mem_arena.c" #include "mem/arena/mem_arena.c"
#include "mem/arena/mem_arena_allocator.c" #include "mem/arena/mem_arena_allocator.c"
#include "../primitives/wapp_primitives.c"
#endif // !WAPP_CORE_C #endif // !WAPP_CORE_C

View File

@@ -1,8 +1,9 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_CORE_H #ifndef WAPP_CORE_H
#define WAPP_CORE_H #define WAPP_CORE_H
#include "strings/str8/str8.h" #include "file/file.h"
#include "strings/str8/str8_list.h"
#include "os/shell/termcolour/termcolour.h" #include "os/shell/termcolour/termcolour.h"
#include "os/shell/termcolour/terminal_colours.h" #include "os/shell/termcolour/terminal_colours.h"
#include "os/shell/commander/commander.h" #include "os/shell/commander/commander.h"
@@ -14,9 +15,9 @@
#include "os/mem/mem_os_ops.h" #include "os/mem/mem_os_ops.h"
#include "os/mem/mem_os.h" #include "os/mem/mem_os.h"
#include "mem/utils/mem_utils.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_allocator.h"
#include "mem/arena/mem_arena.h" #include "mem/arena/mem_arena.h"
#include "../common/wapp_common.h" #include "../common/wapp_common.h"
#include "../primitives/wapp_primitives.h"
#endif // !WAPP_CORE_H #endif // !WAPP_CORE_H

3010
src/primitives/array/array.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,978 @@
/**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN.
*/
#ifndef ARRAY_H
#define ARRAY_H
#include "../mem_allocator/mem_allocator.h"
#include "../../common/misc/misc_utils.h"
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define wapp_void_ptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((VoidPArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(void *)))
#define wapp_str8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((Str8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(Str8)))
#define wapp_b32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((B32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(b32)))
#define wapp_char_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((CharArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(char)))
#define wapp_c8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c8)))
#define wapp_c16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c16)))
#define wapp_c32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c32)))
#define wapp_i8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i8)))
#define wapp_i16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i16)))
#define wapp_i32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i32)))
#define wapp_i64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i64)))
#define wapp_u8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u8)))
#define wapp_u16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u16)))
#define wapp_u32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u32)))
#define wapp_u64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u64)))
#define wapp_f32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f32)))
#define wapp_f64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f64)))
#define wapp_f128_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F128Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f128)))
#define wapp_iptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((IptrArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(iptr)))
#define wapp_uptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((UptrArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(uptr)))
#ifdef WAPP_PLATFORM_CPP
#define wapp_void_ptr_array(...) ([&]() { \
wapp_persist void * buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return VoidPArray{ \
buf, \
wapp_misc_utils_va_args_count(void *, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2), \
sizeof(void *) \
}; \
}())
#define wapp_void_ptr_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist void * buf[CAPACITY] = {}; \
return VoidPArray{buf, 0, CAPACITY, sizeof(void *)}; \
}())
#define wapp_void_ptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_void_ptr_array_pop(ARRAY_PTR) : \
void *{} \
)
#define wapp_str8_array(...) ([&]() { \
wapp_persist Str8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return Str8Array{ \
buf, \
wapp_misc_utils_va_args_count(Str8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2), \
sizeof(Str8) \
}; \
}())
#define wapp_str8_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist Str8 buf[CAPACITY] = {}; \
return Str8Array{buf, 0, CAPACITY, sizeof(Str8)}; \
}())
#define wapp_str8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_str8_array_pop(ARRAY_PTR) : \
Str8{} \
)
#define wapp_b32_array(...) ([&]() { \
wapp_persist b32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return B32Array{ \
buf, \
wapp_misc_utils_va_args_count(b32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2), \
sizeof(b32) \
}; \
}())
#define wapp_b32_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist b32 buf[CAPACITY] = {}; \
return B32Array{buf, 0, CAPACITY, sizeof(b32)}; \
}())
#define wapp_b32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_b32_array_pop(ARRAY_PTR) : \
b32{} \
)
#define wapp_char_array(...) ([&]() { \
wapp_persist char buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return CharArray{ \
buf, \
wapp_misc_utils_va_args_count(char, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2), \
sizeof(char) \
}; \
}())
#define wapp_char_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist char buf[CAPACITY] = {}; \
return CharArray{buf, 0, CAPACITY, sizeof(char)}; \
}())
#define wapp_char_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_char_array_pop(ARRAY_PTR) : \
char{} \
)
#define wapp_c8_array(...) ([&]() { \
wapp_persist c8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return C8Array{ \
buf, \
wapp_misc_utils_va_args_count(c8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2), \
sizeof(c8) \
}; \
}())
#define wapp_c8_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist c8 buf[CAPACITY] = {}; \
return C8Array{buf, 0, CAPACITY, sizeof(c8)}; \
}())
#define wapp_c8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c8_array_pop(ARRAY_PTR) : \
c8{} \
)
#define wapp_c16_array(...) ([&]() { \
wapp_persist c16 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return C16Array{ \
buf, \
wapp_misc_utils_va_args_count(c16, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2), \
sizeof(c16) \
}; \
}())
#define wapp_c16_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist c16 buf[CAPACITY] = {}; \
return C16Array{buf, 0, CAPACITY, sizeof(c16)}; \
}())
#define wapp_c16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c16_array_pop(ARRAY_PTR) : \
c16{} \
)
#define wapp_c32_array(...) ([&]() { \
wapp_persist c32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return C32Array{ \
buf, \
wapp_misc_utils_va_args_count(c32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2), \
sizeof(c32) \
}; \
}())
#define wapp_c32_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist c32 buf[CAPACITY] = {}; \
return C32Array{buf, 0, CAPACITY, sizeof(c32)}; \
}())
#define wapp_c32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c32_array_pop(ARRAY_PTR) : \
c32{} \
)
#define wapp_i8_array(...) ([&]() { \
wapp_persist i8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I8Array{ \
buf, \
wapp_misc_utils_va_args_count(i8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2), \
sizeof(i8) \
}; \
}())
#define wapp_i8_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist i8 buf[CAPACITY] = {}; \
return I8Array{buf, 0, CAPACITY, sizeof(i8)}; \
}())
#define wapp_i8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i8_array_pop(ARRAY_PTR) : \
i8{} \
)
#define wapp_i16_array(...) ([&]() { \
wapp_persist i16 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I16Array{ \
buf, \
wapp_misc_utils_va_args_count(i16, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2), \
sizeof(i16) \
}; \
}())
#define wapp_i16_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist i16 buf[CAPACITY] = {}; \
return I16Array{buf, 0, CAPACITY, sizeof(i16)}; \
}())
#define wapp_i16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i16_array_pop(ARRAY_PTR) : \
i16{} \
)
#define wapp_i32_array(...) ([&]() { \
wapp_persist i32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I32Array{ \
buf, \
wapp_misc_utils_va_args_count(i32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2), \
sizeof(i32) \
}; \
}())
#define wapp_i32_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist i32 buf[CAPACITY] = {}; \
return I32Array{buf, 0, CAPACITY, sizeof(i32)}; \
}())
#define wapp_i32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i32_array_pop(ARRAY_PTR) : \
i32{} \
)
#define wapp_i64_array(...) ([&]() { \
wapp_persist i64 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I64Array{ \
buf, \
wapp_misc_utils_va_args_count(i64, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2), \
sizeof(i64) \
}; \
}())
#define wapp_i64_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist i64 buf[CAPACITY] = {}; \
return I64Array{buf, 0, CAPACITY, sizeof(i64)}; \
}())
#define wapp_i64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i64_array_pop(ARRAY_PTR) : \
i64{} \
)
#define wapp_u8_array(...) ([&]() { \
wapp_persist u8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U8Array{ \
buf, \
wapp_misc_utils_va_args_count(u8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2), \
sizeof(u8) \
}; \
}())
#define wapp_u8_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist u8 buf[CAPACITY] = {}; \
return U8Array{buf, 0, CAPACITY, sizeof(u8)}; \
}())
#define wapp_u8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u8_array_pop(ARRAY_PTR) : \
u8{} \
)
#define wapp_u16_array(...) ([&]() { \
wapp_persist u16 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U16Array{ \
buf, \
wapp_misc_utils_va_args_count(u16, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2), \
sizeof(u16) \
}; \
}())
#define wapp_u16_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist u16 buf[CAPACITY] = {}; \
return U16Array{buf, 0, CAPACITY, sizeof(u16)}; \
}())
#define wapp_u16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u16_array_pop(ARRAY_PTR) : \
u16{} \
)
#define wapp_u32_array(...) ([&]() { \
wapp_persist u32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U32Array{ \
buf, \
wapp_misc_utils_va_args_count(u32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2), \
sizeof(u32) \
}; \
}())
#define wapp_u32_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist u32 buf[CAPACITY] = {}; \
return U32Array{buf, 0, CAPACITY, sizeof(u32)}; \
}())
#define wapp_u32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u32_array_pop(ARRAY_PTR) : \
u32{} \
)
#define wapp_u64_array(...) ([&]() { \
wapp_persist u64 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U64Array{ \
buf, \
wapp_misc_utils_va_args_count(u64, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2), \
sizeof(u64) \
}; \
}())
#define wapp_u64_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist u64 buf[CAPACITY] = {}; \
return U64Array{buf, 0, CAPACITY, sizeof(u64)}; \
}())
#define wapp_u64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u64_array_pop(ARRAY_PTR) : \
u64{} \
)
#define wapp_f32_array(...) ([&]() { \
wapp_persist f32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return F32Array{ \
buf, \
wapp_misc_utils_va_args_count(f32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2), \
sizeof(f32) \
}; \
}())
#define wapp_f32_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist f32 buf[CAPACITY] = {}; \
return F32Array{buf, 0, CAPACITY, sizeof(f32)}; \
}())
#define wapp_f32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f32_array_pop(ARRAY_PTR) : \
f32{} \
)
#define wapp_f64_array(...) ([&]() { \
wapp_persist f64 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return F64Array{ \
buf, \
wapp_misc_utils_va_args_count(f64, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2), \
sizeof(f64) \
}; \
}())
#define wapp_f64_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist f64 buf[CAPACITY] = {}; \
return F64Array{buf, 0, CAPACITY, sizeof(f64)}; \
}())
#define wapp_f64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f64_array_pop(ARRAY_PTR) : \
f64{} \
)
#define wapp_f128_array(...) ([&]() { \
wapp_persist f128 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return F128Array{ \
buf, \
wapp_misc_utils_va_args_count(f128, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2), \
sizeof(f128) \
}; \
}())
#define wapp_f128_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist f128 buf[CAPACITY] = {}; \
return F128Array{buf, 0, CAPACITY, sizeof(f128)}; \
}())
#define wapp_f128_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f128_array_pop(ARRAY_PTR) : \
f128{} \
)
#define wapp_iptr_array(...) ([&]() { \
wapp_persist iptr buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return IptrArray{ \
buf, \
wapp_misc_utils_va_args_count(iptr, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2), \
sizeof(iptr) \
}; \
}())
#define wapp_iptr_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist iptr buf[CAPACITY] = {}; \
return IptrArray{buf, 0, CAPACITY, sizeof(iptr)}; \
}())
#define wapp_iptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_iptr_array_pop(ARRAY_PTR) : \
iptr{} \
)
#define wapp_uptr_array(...) ([&]() { \
wapp_persist uptr buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return UptrArray{ \
buf, \
wapp_misc_utils_va_args_count(uptr, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2), \
sizeof(uptr) \
}; \
}())
#define wapp_uptr_array_with_capacity(CAPACITY) ([&]() { \
wapp_persist uptr buf[CAPACITY] = {}; \
return UptrArray{buf, 0, CAPACITY, sizeof(uptr)}; \
}())
#define wapp_uptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_uptr_array_pop(ARRAY_PTR) : \
uptr{} \
)
#else
#define wapp_void_ptr_array(...) ((VoidPArray){ \
.items = (void *[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(void *, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2), \
.item_size = sizeof(void *) \
})
#define wapp_void_ptr_array_with_capacity(CAPACITY) ((VoidPArray){.items = (void *[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(void *)})
#define wapp_void_ptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_void_ptr_array_pop(ARRAY_PTR) : \
(void *){0} \
)
#define wapp_str8_array(...) ((Str8Array){ \
.items = (Str8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(Str8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2), \
.item_size = sizeof(Str8) \
})
#define wapp_str8_array_with_capacity(CAPACITY) ((Str8Array){.items = (Str8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(Str8)})
#define wapp_str8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_str8_array_pop(ARRAY_PTR) : \
(Str8){0} \
)
#define wapp_b32_array(...) ((B32Array){ \
.items = (b32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(b32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2), \
.item_size = sizeof(b32) \
})
#define wapp_b32_array_with_capacity(CAPACITY) ((B32Array){.items = (b32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(b32)})
#define wapp_b32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_b32_array_pop(ARRAY_PTR) : \
(b32){0} \
)
#define wapp_char_array(...) ((CharArray){ \
.items = (char[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(char, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2), \
.item_size = sizeof(char) \
})
#define wapp_char_array_with_capacity(CAPACITY) ((CharArray){.items = (char[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(char)})
#define wapp_char_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_char_array_pop(ARRAY_PTR) : \
(char){0} \
)
#define wapp_c8_array(...) ((C8Array){ \
.items = (c8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(c8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2), \
.item_size = sizeof(c8) \
})
#define wapp_c8_array_with_capacity(CAPACITY) ((C8Array){.items = (c8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c8)})
#define wapp_c8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c8_array_pop(ARRAY_PTR) : \
(c8){0} \
)
#define wapp_c16_array(...) ((C16Array){ \
.items = (c16[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(c16, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2), \
.item_size = sizeof(c16) \
})
#define wapp_c16_array_with_capacity(CAPACITY) ((C16Array){.items = (c16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c16)})
#define wapp_c16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c16_array_pop(ARRAY_PTR) : \
(c16){0} \
)
#define wapp_c32_array(...) ((C32Array){ \
.items = (c32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(c32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2), \
.item_size = sizeof(c32) \
})
#define wapp_c32_array_with_capacity(CAPACITY) ((C32Array){.items = (c32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c32)})
#define wapp_c32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c32_array_pop(ARRAY_PTR) : \
(c32){0} \
)
#define wapp_i8_array(...) ((I8Array){ \
.items = (i8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2), \
.item_size = sizeof(i8) \
})
#define wapp_i8_array_with_capacity(CAPACITY) ((I8Array){.items = (i8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i8)})
#define wapp_i8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i8_array_pop(ARRAY_PTR) : \
(i8){0} \
)
#define wapp_i16_array(...) ((I16Array){ \
.items = (i16[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i16, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2), \
.item_size = sizeof(i16) \
})
#define wapp_i16_array_with_capacity(CAPACITY) ((I16Array){.items = (i16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i16)})
#define wapp_i16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i16_array_pop(ARRAY_PTR) : \
(i16){0} \
)
#define wapp_i32_array(...) ((I32Array){ \
.items = (i32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2), \
.item_size = sizeof(i32) \
})
#define wapp_i32_array_with_capacity(CAPACITY) ((I32Array){.items = (i32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i32)})
#define wapp_i32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i32_array_pop(ARRAY_PTR) : \
(i32){0} \
)
#define wapp_i64_array(...) ((I64Array){ \
.items = (i64[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i64, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2), \
.item_size = sizeof(i64) \
})
#define wapp_i64_array_with_capacity(CAPACITY) ((I64Array){.items = (i64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i64)})
#define wapp_i64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i64_array_pop(ARRAY_PTR) : \
(i64){0} \
)
#define wapp_u8_array(...) ((U8Array){ \
.items = (u8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2), \
.item_size = sizeof(u8) \
})
#define wapp_u8_array_with_capacity(CAPACITY) ((U8Array){.items = (u8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u8)})
#define wapp_u8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u8_array_pop(ARRAY_PTR) : \
(u8){0} \
)
#define wapp_u16_array(...) ((U16Array){ \
.items = (u16[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u16, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2), \
.item_size = sizeof(u16) \
})
#define wapp_u16_array_with_capacity(CAPACITY) ((U16Array){.items = (u16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u16)})
#define wapp_u16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u16_array_pop(ARRAY_PTR) : \
(u16){0} \
)
#define wapp_u32_array(...) ((U32Array){ \
.items = (u32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2), \
.item_size = sizeof(u32) \
})
#define wapp_u32_array_with_capacity(CAPACITY) ((U32Array){.items = (u32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u32)})
#define wapp_u32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u32_array_pop(ARRAY_PTR) : \
(u32){0} \
)
#define wapp_u64_array(...) ((U64Array){ \
.items = (u64[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u64, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2), \
.item_size = sizeof(u64) \
})
#define wapp_u64_array_with_capacity(CAPACITY) ((U64Array){.items = (u64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u64)})
#define wapp_u64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u64_array_pop(ARRAY_PTR) : \
(u64){0} \
)
#define wapp_f32_array(...) ((F32Array){ \
.items = (f32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(f32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2), \
.item_size = sizeof(f32) \
})
#define wapp_f32_array_with_capacity(CAPACITY) ((F32Array){.items = (f32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f32)})
#define wapp_f32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f32_array_pop(ARRAY_PTR) : \
(f32){0} \
)
#define wapp_f64_array(...) ((F64Array){ \
.items = (f64[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(f64, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2), \
.item_size = sizeof(f64) \
})
#define wapp_f64_array_with_capacity(CAPACITY) ((F64Array){.items = (f64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f64)})
#define wapp_f64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f64_array_pop(ARRAY_PTR) : \
(f64){0} \
)
#define wapp_f128_array(...) ((F128Array){ \
.items = (f128[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(f128, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2), \
.item_size = sizeof(f128) \
})
#define wapp_f128_array_with_capacity(CAPACITY) ((F128Array){.items = (f128[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f128)})
#define wapp_f128_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f128_array_pop(ARRAY_PTR) : \
(f128){0} \
)
#define wapp_iptr_array(...) ((IptrArray){ \
.items = (iptr[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(iptr, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2), \
.item_size = sizeof(iptr) \
})
#define wapp_iptr_array_with_capacity(CAPACITY) ((IptrArray){.items = (iptr[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(iptr)})
#define wapp_iptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_iptr_array_pop(ARRAY_PTR) : \
(iptr){0} \
)
#define wapp_uptr_array(...) ((UptrArray){ \
.items = (uptr[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(uptr, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2), \
.item_size = sizeof(uptr) \
})
#define wapp_uptr_array_with_capacity(CAPACITY) ((UptrArray){.items = (uptr[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(uptr)})
#define wapp_uptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_uptr_array_pop(ARRAY_PTR) : \
(uptr){0} \
)
#endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8;
typedef struct GenericArray GenericArray;
struct GenericArray {
void *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct VoidPArray VoidPArray;
struct VoidPArray {
void * *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct Str8Array Str8Array;
struct Str8Array {
Str8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct B32Array B32Array;
struct B32Array {
b32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct CharArray CharArray;
struct CharArray {
char *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct C8Array C8Array;
struct C8Array {
c8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct C16Array C16Array;
struct C16Array {
c16 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct C32Array C32Array;
struct C32Array {
c32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I8Array I8Array;
struct I8Array {
i8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I16Array I16Array;
struct I16Array {
i16 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I32Array I32Array;
struct I32Array {
i32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I64Array I64Array;
struct I64Array {
i64 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U8Array U8Array;
struct U8Array {
u8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U16Array U16Array;
struct U16Array {
u16 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U32Array U32Array;
struct U32Array {
u32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U64Array U64Array;
struct U64Array {
u64 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct F32Array F32Array;
struct F32Array {
f32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct F64Array F64Array;
struct F64Array {
f64 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct F128Array F128Array;
struct F128Array {
f128 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct IptrArray IptrArray;
struct IptrArray {
iptr *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct UptrArray UptrArray;
struct UptrArray {
uptr *items;
u64 count;
u64 capacity;
u64 item_size;
};
void * *wapp_void_ptr_array_get(const VoidPArray *array, u64 index);
void wapp_void_ptr_array_set(VoidPArray *array, u64 index, void * *item);
void wapp_void_ptr_array_append_capped(VoidPArray *array, void * *item);
void wapp_void_ptr_array_extend_capped(VoidPArray *array, const VoidPArray *other);
void wapp_void_ptr_array_clear(VoidPArray *array);
void wapp_void_ptr_array_copy_capped(const VoidPArray *src, VoidPArray *dst);
VoidPArray *wapp_void_ptr_array_append_alloc(const Allocator *allocator, VoidPArray *array, void * *item);
VoidPArray *wapp_void_ptr_array_extend_alloc(const Allocator *allocator, VoidPArray *array, const VoidPArray *other);
VoidPArray *wapp_void_ptr_array_copy_alloc(const Allocator *allocator, const VoidPArray *src, VoidPArray *dst);
void * *_void_ptr_array_pop(VoidPArray *array);
Str8 *wapp_str8_array_get(const Str8Array *array, u64 index);
void wapp_str8_array_set(Str8Array *array, u64 index, Str8 *item);
void wapp_str8_array_append_capped(Str8Array *array, Str8 *item);
void wapp_str8_array_extend_capped(Str8Array *array, const Str8Array *other);
void wapp_str8_array_clear(Str8Array *array);
void wapp_str8_array_copy_capped(const Str8Array *src, Str8Array *dst);
Str8Array *wapp_str8_array_append_alloc(const Allocator *allocator, Str8Array *array, Str8 *item);
Str8Array *wapp_str8_array_extend_alloc(const Allocator *allocator, Str8Array *array, const Str8Array *other);
Str8Array *wapp_str8_array_copy_alloc(const Allocator *allocator, const Str8Array *src, Str8Array *dst);
Str8 *_str8_array_pop(Str8Array *array);
b32 *wapp_b32_array_get(const B32Array *array, u64 index);
void wapp_b32_array_set(B32Array *array, u64 index, b32 *item);
void wapp_b32_array_append_capped(B32Array *array, b32 *item);
void wapp_b32_array_extend_capped(B32Array *array, const B32Array *other);
void wapp_b32_array_clear(B32Array *array);
void wapp_b32_array_copy_capped(const B32Array *src, B32Array *dst);
B32Array *wapp_b32_array_append_alloc(const Allocator *allocator, B32Array *array, b32 *item);
B32Array *wapp_b32_array_extend_alloc(const Allocator *allocator, B32Array *array, const B32Array *other);
B32Array *wapp_b32_array_copy_alloc(const Allocator *allocator, const B32Array *src, B32Array *dst);
b32 *_b32_array_pop(B32Array *array);
char *wapp_char_array_get(const CharArray *array, u64 index);
void wapp_char_array_set(CharArray *array, u64 index, char *item);
void wapp_char_array_append_capped(CharArray *array, char *item);
void wapp_char_array_extend_capped(CharArray *array, const CharArray *other);
void wapp_char_array_clear(CharArray *array);
void wapp_char_array_copy_capped(const CharArray *src, CharArray *dst);
CharArray *wapp_char_array_append_alloc(const Allocator *allocator, CharArray *array, char *item);
CharArray *wapp_char_array_extend_alloc(const Allocator *allocator, CharArray *array, const CharArray *other);
CharArray *wapp_char_array_copy_alloc(const Allocator *allocator, const CharArray *src, CharArray *dst);
char *_char_array_pop(CharArray *array);
c8 *wapp_c8_array_get(const C8Array *array, u64 index);
void wapp_c8_array_set(C8Array *array, u64 index, c8 *item);
void wapp_c8_array_append_capped(C8Array *array, c8 *item);
void wapp_c8_array_extend_capped(C8Array *array, const C8Array *other);
void wapp_c8_array_clear(C8Array *array);
void wapp_c8_array_copy_capped(const C8Array *src, C8Array *dst);
C8Array *wapp_c8_array_append_alloc(const Allocator *allocator, C8Array *array, c8 *item);
C8Array *wapp_c8_array_extend_alloc(const Allocator *allocator, C8Array *array, const C8Array *other);
C8Array *wapp_c8_array_copy_alloc(const Allocator *allocator, const C8Array *src, C8Array *dst);
c8 *_c8_array_pop(C8Array *array);
c16 *wapp_c16_array_get(const C16Array *array, u64 index);
void wapp_c16_array_set(C16Array *array, u64 index, c16 *item);
void wapp_c16_array_append_capped(C16Array *array, c16 *item);
void wapp_c16_array_extend_capped(C16Array *array, const C16Array *other);
void wapp_c16_array_clear(C16Array *array);
void wapp_c16_array_copy_capped(const C16Array *src, C16Array *dst);
C16Array *wapp_c16_array_append_alloc(const Allocator *allocator, C16Array *array, c16 *item);
C16Array *wapp_c16_array_extend_alloc(const Allocator *allocator, C16Array *array, const C16Array *other);
C16Array *wapp_c16_array_copy_alloc(const Allocator *allocator, const C16Array *src, C16Array *dst);
c16 *_c16_array_pop(C16Array *array);
c32 *wapp_c32_array_get(const C32Array *array, u64 index);
void wapp_c32_array_set(C32Array *array, u64 index, c32 *item);
void wapp_c32_array_append_capped(C32Array *array, c32 *item);
void wapp_c32_array_extend_capped(C32Array *array, const C32Array *other);
void wapp_c32_array_clear(C32Array *array);
void wapp_c32_array_copy_capped(const C32Array *src, C32Array *dst);
C32Array *wapp_c32_array_append_alloc(const Allocator *allocator, C32Array *array, c32 *item);
C32Array *wapp_c32_array_extend_alloc(const Allocator *allocator, C32Array *array, const C32Array *other);
C32Array *wapp_c32_array_copy_alloc(const Allocator *allocator, const C32Array *src, C32Array *dst);
c32 *_c32_array_pop(C32Array *array);
i8 *wapp_i8_array_get(const I8Array *array, u64 index);
void wapp_i8_array_set(I8Array *array, u64 index, i8 *item);
void wapp_i8_array_append_capped(I8Array *array, i8 *item);
void wapp_i8_array_extend_capped(I8Array *array, const I8Array *other);
void wapp_i8_array_clear(I8Array *array);
void wapp_i8_array_copy_capped(const I8Array *src, I8Array *dst);
I8Array *wapp_i8_array_append_alloc(const Allocator *allocator, I8Array *array, i8 *item);
I8Array *wapp_i8_array_extend_alloc(const Allocator *allocator, I8Array *array, const I8Array *other);
I8Array *wapp_i8_array_copy_alloc(const Allocator *allocator, const I8Array *src, I8Array *dst);
i8 *_i8_array_pop(I8Array *array);
i16 *wapp_i16_array_get(const I16Array *array, u64 index);
void wapp_i16_array_set(I16Array *array, u64 index, i16 *item);
void wapp_i16_array_append_capped(I16Array *array, i16 *item);
void wapp_i16_array_extend_capped(I16Array *array, const I16Array *other);
void wapp_i16_array_clear(I16Array *array);
void wapp_i16_array_copy_capped(const I16Array *src, I16Array *dst);
I16Array *wapp_i16_array_append_alloc(const Allocator *allocator, I16Array *array, i16 *item);
I16Array *wapp_i16_array_extend_alloc(const Allocator *allocator, I16Array *array, const I16Array *other);
I16Array *wapp_i16_array_copy_alloc(const Allocator *allocator, const I16Array *src, I16Array *dst);
i16 *_i16_array_pop(I16Array *array);
i32 *wapp_i32_array_get(const I32Array *array, u64 index);
void wapp_i32_array_set(I32Array *array, u64 index, i32 *item);
void wapp_i32_array_append_capped(I32Array *array, i32 *item);
void wapp_i32_array_extend_capped(I32Array *array, const I32Array *other);
void wapp_i32_array_clear(I32Array *array);
void wapp_i32_array_copy_capped(const I32Array *src, I32Array *dst);
I32Array *wapp_i32_array_append_alloc(const Allocator *allocator, I32Array *array, i32 *item);
I32Array *wapp_i32_array_extend_alloc(const Allocator *allocator, I32Array *array, const I32Array *other);
I32Array *wapp_i32_array_copy_alloc(const Allocator *allocator, const I32Array *src, I32Array *dst);
i32 *_i32_array_pop(I32Array *array);
i64 *wapp_i64_array_get(const I64Array *array, u64 index);
void wapp_i64_array_set(I64Array *array, u64 index, i64 *item);
void wapp_i64_array_append_capped(I64Array *array, i64 *item);
void wapp_i64_array_extend_capped(I64Array *array, const I64Array *other);
void wapp_i64_array_clear(I64Array *array);
void wapp_i64_array_copy_capped(const I64Array *src, I64Array *dst);
I64Array *wapp_i64_array_append_alloc(const Allocator *allocator, I64Array *array, i64 *item);
I64Array *wapp_i64_array_extend_alloc(const Allocator *allocator, I64Array *array, const I64Array *other);
I64Array *wapp_i64_array_copy_alloc(const Allocator *allocator, const I64Array *src, I64Array *dst);
i64 *_i64_array_pop(I64Array *array);
u8 *wapp_u8_array_get(const U8Array *array, u64 index);
void wapp_u8_array_set(U8Array *array, u64 index, u8 *item);
void wapp_u8_array_append_capped(U8Array *array, u8 *item);
void wapp_u8_array_extend_capped(U8Array *array, const U8Array *other);
void wapp_u8_array_clear(U8Array *array);
void wapp_u8_array_copy_capped(const U8Array *src, U8Array *dst);
U8Array *wapp_u8_array_append_alloc(const Allocator *allocator, U8Array *array, u8 *item);
U8Array *wapp_u8_array_extend_alloc(const Allocator *allocator, U8Array *array, const U8Array *other);
U8Array *wapp_u8_array_copy_alloc(const Allocator *allocator, const U8Array *src, U8Array *dst);
u8 *_u8_array_pop(U8Array *array);
u16 *wapp_u16_array_get(const U16Array *array, u64 index);
void wapp_u16_array_set(U16Array *array, u64 index, u16 *item);
void wapp_u16_array_append_capped(U16Array *array, u16 *item);
void wapp_u16_array_extend_capped(U16Array *array, const U16Array *other);
void wapp_u16_array_clear(U16Array *array);
void wapp_u16_array_copy_capped(const U16Array *src, U16Array *dst);
U16Array *wapp_u16_array_append_alloc(const Allocator *allocator, U16Array *array, u16 *item);
U16Array *wapp_u16_array_extend_alloc(const Allocator *allocator, U16Array *array, const U16Array *other);
U16Array *wapp_u16_array_copy_alloc(const Allocator *allocator, const U16Array *src, U16Array *dst);
u16 *_u16_array_pop(U16Array *array);
u32 *wapp_u32_array_get(const U32Array *array, u64 index);
void wapp_u32_array_set(U32Array *array, u64 index, u32 *item);
void wapp_u32_array_append_capped(U32Array *array, u32 *item);
void wapp_u32_array_extend_capped(U32Array *array, const U32Array *other);
void wapp_u32_array_clear(U32Array *array);
void wapp_u32_array_copy_capped(const U32Array *src, U32Array *dst);
U32Array *wapp_u32_array_append_alloc(const Allocator *allocator, U32Array *array, u32 *item);
U32Array *wapp_u32_array_extend_alloc(const Allocator *allocator, U32Array *array, const U32Array *other);
U32Array *wapp_u32_array_copy_alloc(const Allocator *allocator, const U32Array *src, U32Array *dst);
u32 *_u32_array_pop(U32Array *array);
u64 *wapp_u64_array_get(const U64Array *array, u64 index);
void wapp_u64_array_set(U64Array *array, u64 index, u64 *item);
void wapp_u64_array_append_capped(U64Array *array, u64 *item);
void wapp_u64_array_extend_capped(U64Array *array, const U64Array *other);
void wapp_u64_array_clear(U64Array *array);
void wapp_u64_array_copy_capped(const U64Array *src, U64Array *dst);
U64Array *wapp_u64_array_append_alloc(const Allocator *allocator, U64Array *array, u64 *item);
U64Array *wapp_u64_array_extend_alloc(const Allocator *allocator, U64Array *array, const U64Array *other);
U64Array *wapp_u64_array_copy_alloc(const Allocator *allocator, const U64Array *src, U64Array *dst);
u64 *_u64_array_pop(U64Array *array);
f32 *wapp_f32_array_get(const F32Array *array, u64 index);
void wapp_f32_array_set(F32Array *array, u64 index, f32 *item);
void wapp_f32_array_append_capped(F32Array *array, f32 *item);
void wapp_f32_array_extend_capped(F32Array *array, const F32Array *other);
void wapp_f32_array_clear(F32Array *array);
void wapp_f32_array_copy_capped(const F32Array *src, F32Array *dst);
F32Array *wapp_f32_array_append_alloc(const Allocator *allocator, F32Array *array, f32 *item);
F32Array *wapp_f32_array_extend_alloc(const Allocator *allocator, F32Array *array, const F32Array *other);
F32Array *wapp_f32_array_copy_alloc(const Allocator *allocator, const F32Array *src, F32Array *dst);
f32 *_f32_array_pop(F32Array *array);
f64 *wapp_f64_array_get(const F64Array *array, u64 index);
void wapp_f64_array_set(F64Array *array, u64 index, f64 *item);
void wapp_f64_array_append_capped(F64Array *array, f64 *item);
void wapp_f64_array_extend_capped(F64Array *array, const F64Array *other);
void wapp_f64_array_clear(F64Array *array);
void wapp_f64_array_copy_capped(const F64Array *src, F64Array *dst);
F64Array *wapp_f64_array_append_alloc(const Allocator *allocator, F64Array *array, f64 *item);
F64Array *wapp_f64_array_extend_alloc(const Allocator *allocator, F64Array *array, const F64Array *other);
F64Array *wapp_f64_array_copy_alloc(const Allocator *allocator, const F64Array *src, F64Array *dst);
f64 *_f64_array_pop(F64Array *array);
f128 *wapp_f128_array_get(const F128Array *array, u64 index);
void wapp_f128_array_set(F128Array *array, u64 index, f128 *item);
void wapp_f128_array_append_capped(F128Array *array, f128 *item);
void wapp_f128_array_extend_capped(F128Array *array, const F128Array *other);
void wapp_f128_array_clear(F128Array *array);
void wapp_f128_array_copy_capped(const F128Array *src, F128Array *dst);
F128Array *wapp_f128_array_append_alloc(const Allocator *allocator, F128Array *array, f128 *item);
F128Array *wapp_f128_array_extend_alloc(const Allocator *allocator, F128Array *array, const F128Array *other);
F128Array *wapp_f128_array_copy_alloc(const Allocator *allocator, const F128Array *src, F128Array *dst);
f128 *_f128_array_pop(F128Array *array);
iptr *wapp_iptr_array_get(const IptrArray *array, u64 index);
void wapp_iptr_array_set(IptrArray *array, u64 index, iptr *item);
void wapp_iptr_array_append_capped(IptrArray *array, iptr *item);
void wapp_iptr_array_extend_capped(IptrArray *array, const IptrArray *other);
void wapp_iptr_array_clear(IptrArray *array);
void wapp_iptr_array_copy_capped(const IptrArray *src, IptrArray *dst);
IptrArray *wapp_iptr_array_append_alloc(const Allocator *allocator, IptrArray *array, iptr *item);
IptrArray *wapp_iptr_array_extend_alloc(const Allocator *allocator, IptrArray *array, const IptrArray *other);
IptrArray *wapp_iptr_array_copy_alloc(const Allocator *allocator, const IptrArray *src, IptrArray *dst);
iptr *_iptr_array_pop(IptrArray *array);
uptr *wapp_uptr_array_get(const UptrArray *array, u64 index);
void wapp_uptr_array_set(UptrArray *array, u64 index, uptr *item);
void wapp_uptr_array_append_capped(UptrArray *array, uptr *item);
void wapp_uptr_array_extend_capped(UptrArray *array, const UptrArray *other);
void wapp_uptr_array_clear(UptrArray *array);
void wapp_uptr_array_copy_capped(const UptrArray *src, UptrArray *dst);
UptrArray *wapp_uptr_array_append_alloc(const Allocator *allocator, UptrArray *array, uptr *item);
UptrArray *wapp_uptr_array_extend_alloc(const Allocator *allocator, UptrArray *array, const UptrArray *other);
UptrArray *wapp_uptr_array_copy_alloc(const Allocator *allocator, const UptrArray *src, UptrArray *dst);
uptr *_uptr_array_pop(UptrArray *array);
GenericArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !ARRAY_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,520 @@
/**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN.
*/
#ifndef DBL_LIST_H
#define DBL_LIST_H
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP
#define wapp_void_ptr_list_node(ITEM_PTR) VoidPNode{ITEM_PTR, nullptr, nullptr}
#define wapp_str8_list_node(ITEM_PTR) Str8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_b32_list_node(ITEM_PTR) B32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_char_list_node(ITEM_PTR) CharNode{ITEM_PTR, nullptr, nullptr}
#define wapp_c8_list_node(ITEM_PTR) C8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_c16_list_node(ITEM_PTR) C16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_c32_list_node(ITEM_PTR) C32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i8_list_node(ITEM_PTR) I8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i16_list_node(ITEM_PTR) I16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i32_list_node(ITEM_PTR) I32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i64_list_node(ITEM_PTR) I64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u8_list_node(ITEM_PTR) U8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u16_list_node(ITEM_PTR) U16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u32_list_node(ITEM_PTR) U32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u64_list_node(ITEM_PTR) U64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f32_list_node(ITEM_PTR) F32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f64_list_node(ITEM_PTR) F64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f128_list_node(ITEM_PTR) F128Node{ITEM_PTR, nullptr, nullptr}
#define wapp_iptr_list_node(ITEM_PTR) IptrNode{ITEM_PTR, nullptr, nullptr}
#define wapp_uptr_list_node(ITEM_PTR) UptrNode{ITEM_PTR, nullptr, nullptr}
#else
#define wapp_void_ptr_list_node(ITEM_PTR) ((VoidPNode){.item = ITEM_PTR})
#define wapp_str8_list_node(ITEM_PTR) ((Str8Node){.item = ITEM_PTR})
#define wapp_b32_list_node(ITEM_PTR) ((B32Node){.item = ITEM_PTR})
#define wapp_char_list_node(ITEM_PTR) ((CharNode){.item = ITEM_PTR})
#define wapp_c8_list_node(ITEM_PTR) ((C8Node){.item = ITEM_PTR})
#define wapp_c16_list_node(ITEM_PTR) ((C16Node){.item = ITEM_PTR})
#define wapp_c32_list_node(ITEM_PTR) ((C32Node){.item = ITEM_PTR})
#define wapp_i8_list_node(ITEM_PTR) ((I8Node){.item = ITEM_PTR})
#define wapp_i16_list_node(ITEM_PTR) ((I16Node){.item = ITEM_PTR})
#define wapp_i32_list_node(ITEM_PTR) ((I32Node){.item = ITEM_PTR})
#define wapp_i64_list_node(ITEM_PTR) ((I64Node){.item = ITEM_PTR})
#define wapp_u8_list_node(ITEM_PTR) ((U8Node){.item = ITEM_PTR})
#define wapp_u16_list_node(ITEM_PTR) ((U16Node){.item = ITEM_PTR})
#define wapp_u32_list_node(ITEM_PTR) ((U32Node){.item = ITEM_PTR})
#define wapp_u64_list_node(ITEM_PTR) ((U64Node){.item = ITEM_PTR})
#define wapp_f32_list_node(ITEM_PTR) ((F32Node){.item = ITEM_PTR})
#define wapp_f64_list_node(ITEM_PTR) ((F64Node){.item = ITEM_PTR})
#define wapp_f128_list_node(ITEM_PTR) ((F128Node){.item = ITEM_PTR})
#define wapp_iptr_list_node(ITEM_PTR) ((IptrNode){.item = ITEM_PTR})
#define wapp_uptr_list_node(ITEM_PTR) ((UptrNode){.item = ITEM_PTR})
#endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8;
typedef struct GenericNode GenericNode;
struct GenericNode {
void *item;
GenericNode *prev;
GenericNode *next;
};
typedef struct GenericList GenericList;
struct GenericList {
GenericNode *first;
GenericNode *last;
u64 node_count;
};
typedef struct VoidPNode VoidPNode;
struct VoidPNode {
void * *item;
VoidPNode *prev;
VoidPNode *next;
};
typedef struct VoidPList VoidPList;
struct VoidPList {
VoidPNode *first;
VoidPNode *last;
u64 node_count;
};
typedef struct Str8Node Str8Node;
struct Str8Node {
Str8 *item;
Str8Node *prev;
Str8Node *next;
};
typedef struct Str8List Str8List;
struct Str8List {
Str8Node *first;
Str8Node *last;
u64 node_count;
};
typedef struct B32Node B32Node;
struct B32Node {
b32 *item;
B32Node *prev;
B32Node *next;
};
typedef struct B32List B32List;
struct B32List {
B32Node *first;
B32Node *last;
u64 node_count;
};
typedef struct CharNode CharNode;
struct CharNode {
char *item;
CharNode *prev;
CharNode *next;
};
typedef struct CharList CharList;
struct CharList {
CharNode *first;
CharNode *last;
u64 node_count;
};
typedef struct C8Node C8Node;
struct C8Node {
c8 *item;
C8Node *prev;
C8Node *next;
};
typedef struct C8List C8List;
struct C8List {
C8Node *first;
C8Node *last;
u64 node_count;
};
typedef struct C16Node C16Node;
struct C16Node {
c16 *item;
C16Node *prev;
C16Node *next;
};
typedef struct C16List C16List;
struct C16List {
C16Node *first;
C16Node *last;
u64 node_count;
};
typedef struct C32Node C32Node;
struct C32Node {
c32 *item;
C32Node *prev;
C32Node *next;
};
typedef struct C32List C32List;
struct C32List {
C32Node *first;
C32Node *last;
u64 node_count;
};
typedef struct I8Node I8Node;
struct I8Node {
i8 *item;
I8Node *prev;
I8Node *next;
};
typedef struct I8List I8List;
struct I8List {
I8Node *first;
I8Node *last;
u64 node_count;
};
typedef struct I16Node I16Node;
struct I16Node {
i16 *item;
I16Node *prev;
I16Node *next;
};
typedef struct I16List I16List;
struct I16List {
I16Node *first;
I16Node *last;
u64 node_count;
};
typedef struct I32Node I32Node;
struct I32Node {
i32 *item;
I32Node *prev;
I32Node *next;
};
typedef struct I32List I32List;
struct I32List {
I32Node *first;
I32Node *last;
u64 node_count;
};
typedef struct I64Node I64Node;
struct I64Node {
i64 *item;
I64Node *prev;
I64Node *next;
};
typedef struct I64List I64List;
struct I64List {
I64Node *first;
I64Node *last;
u64 node_count;
};
typedef struct U8Node U8Node;
struct U8Node {
u8 *item;
U8Node *prev;
U8Node *next;
};
typedef struct U8List U8List;
struct U8List {
U8Node *first;
U8Node *last;
u64 node_count;
};
typedef struct U16Node U16Node;
struct U16Node {
u16 *item;
U16Node *prev;
U16Node *next;
};
typedef struct U16List U16List;
struct U16List {
U16Node *first;
U16Node *last;
u64 node_count;
};
typedef struct U32Node U32Node;
struct U32Node {
u32 *item;
U32Node *prev;
U32Node *next;
};
typedef struct U32List U32List;
struct U32List {
U32Node *first;
U32Node *last;
u64 node_count;
};
typedef struct U64Node U64Node;
struct U64Node {
u64 *item;
U64Node *prev;
U64Node *next;
};
typedef struct U64List U64List;
struct U64List {
U64Node *first;
U64Node *last;
u64 node_count;
};
typedef struct F32Node F32Node;
struct F32Node {
f32 *item;
F32Node *prev;
F32Node *next;
};
typedef struct F32List F32List;
struct F32List {
F32Node *first;
F32Node *last;
u64 node_count;
};
typedef struct F64Node F64Node;
struct F64Node {
f64 *item;
F64Node *prev;
F64Node *next;
};
typedef struct F64List F64List;
struct F64List {
F64Node *first;
F64Node *last;
u64 node_count;
};
typedef struct F128Node F128Node;
struct F128Node {
f128 *item;
F128Node *prev;
F128Node *next;
};
typedef struct F128List F128List;
struct F128List {
F128Node *first;
F128Node *last;
u64 node_count;
};
typedef struct IptrNode IptrNode;
struct IptrNode {
iptr *item;
IptrNode *prev;
IptrNode *next;
};
typedef struct IptrList IptrList;
struct IptrList {
IptrNode *first;
IptrNode *last;
u64 node_count;
};
typedef struct UptrNode UptrNode;
struct UptrNode {
uptr *item;
UptrNode *prev;
UptrNode *next;
};
typedef struct UptrList UptrList;
struct UptrList {
UptrNode *first;
UptrNode *last;
u64 node_count;
};
VoidPNode *wapp_void_ptr_list_get(const VoidPList *list, u64 index);
void wapp_void_ptr_list_push_front(VoidPList *list, VoidPNode *node);
void wapp_void_ptr_list_push_back(VoidPList *list, VoidPNode *node);
void wapp_void_ptr_list_insert(VoidPList *list, VoidPNode *node, u64 index);
VoidPNode *wapp_void_ptr_list_pop_front(VoidPList *list);
VoidPNode *wapp_void_ptr_list_pop_back(VoidPList *list);
VoidPNode *wapp_void_ptr_list_remove(VoidPList *list, u64 index);
void wapp_void_ptr_list_empty(VoidPList *list);
Str8Node *wapp_str8_list_get(const Str8List *list, u64 index);
void wapp_str8_list_push_front(Str8List *list, Str8Node *node);
void wapp_str8_list_push_back(Str8List *list, Str8Node *node);
void wapp_str8_list_insert(Str8List *list, Str8Node *node, u64 index);
Str8Node *wapp_str8_list_pop_front(Str8List *list);
Str8Node *wapp_str8_list_pop_back(Str8List *list);
Str8Node *wapp_str8_list_remove(Str8List *list, u64 index);
void wapp_str8_list_empty(Str8List *list);
B32Node *wapp_b32_list_get(const B32List *list, u64 index);
void wapp_b32_list_push_front(B32List *list, B32Node *node);
void wapp_b32_list_push_back(B32List *list, B32Node *node);
void wapp_b32_list_insert(B32List *list, B32Node *node, u64 index);
B32Node *wapp_b32_list_pop_front(B32List *list);
B32Node *wapp_b32_list_pop_back(B32List *list);
B32Node *wapp_b32_list_remove(B32List *list, u64 index);
void wapp_b32_list_empty(B32List *list);
CharNode *wapp_char_list_get(const CharList *list, u64 index);
void wapp_char_list_push_front(CharList *list, CharNode *node);
void wapp_char_list_push_back(CharList *list, CharNode *node);
void wapp_char_list_insert(CharList *list, CharNode *node, u64 index);
CharNode *wapp_char_list_pop_front(CharList *list);
CharNode *wapp_char_list_pop_back(CharList *list);
CharNode *wapp_char_list_remove(CharList *list, u64 index);
void wapp_char_list_empty(CharList *list);
C8Node *wapp_c8_list_get(const C8List *list, u64 index);
void wapp_c8_list_push_front(C8List *list, C8Node *node);
void wapp_c8_list_push_back(C8List *list, C8Node *node);
void wapp_c8_list_insert(C8List *list, C8Node *node, u64 index);
C8Node *wapp_c8_list_pop_front(C8List *list);
C8Node *wapp_c8_list_pop_back(C8List *list);
C8Node *wapp_c8_list_remove(C8List *list, u64 index);
void wapp_c8_list_empty(C8List *list);
C16Node *wapp_c16_list_get(const C16List *list, u64 index);
void wapp_c16_list_push_front(C16List *list, C16Node *node);
void wapp_c16_list_push_back(C16List *list, C16Node *node);
void wapp_c16_list_insert(C16List *list, C16Node *node, u64 index);
C16Node *wapp_c16_list_pop_front(C16List *list);
C16Node *wapp_c16_list_pop_back(C16List *list);
C16Node *wapp_c16_list_remove(C16List *list, u64 index);
void wapp_c16_list_empty(C16List *list);
C32Node *wapp_c32_list_get(const C32List *list, u64 index);
void wapp_c32_list_push_front(C32List *list, C32Node *node);
void wapp_c32_list_push_back(C32List *list, C32Node *node);
void wapp_c32_list_insert(C32List *list, C32Node *node, u64 index);
C32Node *wapp_c32_list_pop_front(C32List *list);
C32Node *wapp_c32_list_pop_back(C32List *list);
C32Node *wapp_c32_list_remove(C32List *list, u64 index);
void wapp_c32_list_empty(C32List *list);
I8Node *wapp_i8_list_get(const I8List *list, u64 index);
void wapp_i8_list_push_front(I8List *list, I8Node *node);
void wapp_i8_list_push_back(I8List *list, I8Node *node);
void wapp_i8_list_insert(I8List *list, I8Node *node, u64 index);
I8Node *wapp_i8_list_pop_front(I8List *list);
I8Node *wapp_i8_list_pop_back(I8List *list);
I8Node *wapp_i8_list_remove(I8List *list, u64 index);
void wapp_i8_list_empty(I8List *list);
I16Node *wapp_i16_list_get(const I16List *list, u64 index);
void wapp_i16_list_push_front(I16List *list, I16Node *node);
void wapp_i16_list_push_back(I16List *list, I16Node *node);
void wapp_i16_list_insert(I16List *list, I16Node *node, u64 index);
I16Node *wapp_i16_list_pop_front(I16List *list);
I16Node *wapp_i16_list_pop_back(I16List *list);
I16Node *wapp_i16_list_remove(I16List *list, u64 index);
void wapp_i16_list_empty(I16List *list);
I32Node *wapp_i32_list_get(const I32List *list, u64 index);
void wapp_i32_list_push_front(I32List *list, I32Node *node);
void wapp_i32_list_push_back(I32List *list, I32Node *node);
void wapp_i32_list_insert(I32List *list, I32Node *node, u64 index);
I32Node *wapp_i32_list_pop_front(I32List *list);
I32Node *wapp_i32_list_pop_back(I32List *list);
I32Node *wapp_i32_list_remove(I32List *list, u64 index);
void wapp_i32_list_empty(I32List *list);
I64Node *wapp_i64_list_get(const I64List *list, u64 index);
void wapp_i64_list_push_front(I64List *list, I64Node *node);
void wapp_i64_list_push_back(I64List *list, I64Node *node);
void wapp_i64_list_insert(I64List *list, I64Node *node, u64 index);
I64Node *wapp_i64_list_pop_front(I64List *list);
I64Node *wapp_i64_list_pop_back(I64List *list);
I64Node *wapp_i64_list_remove(I64List *list, u64 index);
void wapp_i64_list_empty(I64List *list);
U8Node *wapp_u8_list_get(const U8List *list, u64 index);
void wapp_u8_list_push_front(U8List *list, U8Node *node);
void wapp_u8_list_push_back(U8List *list, U8Node *node);
void wapp_u8_list_insert(U8List *list, U8Node *node, u64 index);
U8Node *wapp_u8_list_pop_front(U8List *list);
U8Node *wapp_u8_list_pop_back(U8List *list);
U8Node *wapp_u8_list_remove(U8List *list, u64 index);
void wapp_u8_list_empty(U8List *list);
U16Node *wapp_u16_list_get(const U16List *list, u64 index);
void wapp_u16_list_push_front(U16List *list, U16Node *node);
void wapp_u16_list_push_back(U16List *list, U16Node *node);
void wapp_u16_list_insert(U16List *list, U16Node *node, u64 index);
U16Node *wapp_u16_list_pop_front(U16List *list);
U16Node *wapp_u16_list_pop_back(U16List *list);
U16Node *wapp_u16_list_remove(U16List *list, u64 index);
void wapp_u16_list_empty(U16List *list);
U32Node *wapp_u32_list_get(const U32List *list, u64 index);
void wapp_u32_list_push_front(U32List *list, U32Node *node);
void wapp_u32_list_push_back(U32List *list, U32Node *node);
void wapp_u32_list_insert(U32List *list, U32Node *node, u64 index);
U32Node *wapp_u32_list_pop_front(U32List *list);
U32Node *wapp_u32_list_pop_back(U32List *list);
U32Node *wapp_u32_list_remove(U32List *list, u64 index);
void wapp_u32_list_empty(U32List *list);
U64Node *wapp_u64_list_get(const U64List *list, u64 index);
void wapp_u64_list_push_front(U64List *list, U64Node *node);
void wapp_u64_list_push_back(U64List *list, U64Node *node);
void wapp_u64_list_insert(U64List *list, U64Node *node, u64 index);
U64Node *wapp_u64_list_pop_front(U64List *list);
U64Node *wapp_u64_list_pop_back(U64List *list);
U64Node *wapp_u64_list_remove(U64List *list, u64 index);
void wapp_u64_list_empty(U64List *list);
F32Node *wapp_f32_list_get(const F32List *list, u64 index);
void wapp_f32_list_push_front(F32List *list, F32Node *node);
void wapp_f32_list_push_back(F32List *list, F32Node *node);
void wapp_f32_list_insert(F32List *list, F32Node *node, u64 index);
F32Node *wapp_f32_list_pop_front(F32List *list);
F32Node *wapp_f32_list_pop_back(F32List *list);
F32Node *wapp_f32_list_remove(F32List *list, u64 index);
void wapp_f32_list_empty(F32List *list);
F64Node *wapp_f64_list_get(const F64List *list, u64 index);
void wapp_f64_list_push_front(F64List *list, F64Node *node);
void wapp_f64_list_push_back(F64List *list, F64Node *node);
void wapp_f64_list_insert(F64List *list, F64Node *node, u64 index);
F64Node *wapp_f64_list_pop_front(F64List *list);
F64Node *wapp_f64_list_pop_back(F64List *list);
F64Node *wapp_f64_list_remove(F64List *list, u64 index);
void wapp_f64_list_empty(F64List *list);
F128Node *wapp_f128_list_get(const F128List *list, u64 index);
void wapp_f128_list_push_front(F128List *list, F128Node *node);
void wapp_f128_list_push_back(F128List *list, F128Node *node);
void wapp_f128_list_insert(F128List *list, F128Node *node, u64 index);
F128Node *wapp_f128_list_pop_front(F128List *list);
F128Node *wapp_f128_list_pop_back(F128List *list);
F128Node *wapp_f128_list_remove(F128List *list, u64 index);
void wapp_f128_list_empty(F128List *list);
IptrNode *wapp_iptr_list_get(const IptrList *list, u64 index);
void wapp_iptr_list_push_front(IptrList *list, IptrNode *node);
void wapp_iptr_list_push_back(IptrList *list, IptrNode *node);
void wapp_iptr_list_insert(IptrList *list, IptrNode *node, u64 index);
IptrNode *wapp_iptr_list_pop_front(IptrList *list);
IptrNode *wapp_iptr_list_pop_back(IptrList *list);
IptrNode *wapp_iptr_list_remove(IptrList *list, u64 index);
void wapp_iptr_list_empty(IptrList *list);
UptrNode *wapp_uptr_list_get(const UptrList *list, u64 index);
void wapp_uptr_list_push_front(UptrList *list, UptrNode *node);
void wapp_uptr_list_push_back(UptrList *list, UptrNode *node);
void wapp_uptr_list_insert(UptrList *list, UptrNode *node, u64 index);
UptrNode *wapp_uptr_list_pop_front(UptrList *list);
UptrNode *wapp_uptr_list_pop_back(UptrList *list);
UptrNode *wapp_uptr_list_remove(UptrList *list, u64 index);
void wapp_uptr_list_empty(UptrList *list);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !DBL_LIST_H

View File

@@ -1,37 +1,28 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_allocator.h" #include "mem_allocator.h"
#include "../../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../common/assert/assert.h"
#include <stdlib.h> #include <stdlib.h>
void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size) { void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size) {
if (!allocator || !(allocator->alloc)) { wapp_debug_assert(allocator != NULL && (allocator->alloc) != NULL, "`allocator` and `allocator->alloc` should not be NULL");
return NULL;
}
return allocator->alloc(size, allocator->obj); return allocator->alloc(size, allocator->obj);
} }
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) {
if (!allocator || !(allocator->alloc_aligned)) { wapp_debug_assert(allocator != NULL && (allocator->alloc_aligned) != NULL, "`allocator` and `allocator->alloc_aligned` should not be NULL");
return NULL;
}
return allocator->alloc_aligned(size, alignment, allocator->obj); return allocator->alloc_aligned(size, alignment, allocator->obj);
} }
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) {
if (!allocator || !(allocator->realloc)) { wapp_debug_assert(allocator != NULL && (allocator->realloc) != NULL, "`allocator` and `allocator->realloc` should not be NULL");
return NULL;
}
return allocator->realloc(ptr, old_size, new_size, allocator->obj); return allocator->realloc(ptr, old_size, new_size, allocator->obj);
} }
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) {
if (!allocator || !(allocator->realloc_aligned)) { wapp_debug_assert(allocator != NULL && (allocator->realloc_aligned) != NULL, "`allocator` and `allocator->realloc_aligned` should not be NULL");
return NULL;
}
return allocator->realloc_aligned(ptr, old_size, new_size, alignment, allocator->obj); return allocator->realloc_aligned(ptr, old_size, new_size, alignment, allocator->obj);
} }

View File

@@ -1,12 +1,15 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_ALLOCATOR_H #ifndef MEM_ALLOCATOR_H
#define MEM_ALLOCATOR_H #define MEM_ALLOCATOR_H
#include "../../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#include <string.h> #include <string.h>
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
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);
@@ -14,7 +17,6 @@ typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *allo
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, u64 size, void *alloc_obj);
typedef struct allocator Allocator; typedef struct allocator Allocator;
struct allocator { struct allocator {
void *obj; void *obj;
@@ -25,8 +27,14 @@ struct allocator {
MemFreeFunc *free; MemFreeFunc *free;
}; };
#ifdef WAPP_PLATFORM_CPP
#define wapp_mem_allocator_invalid(ALLOCATOR) ([&]() { \
Allocator alloc{}; \
return memcmp(ALLOCATOR, &alloc, sizeof(Allocator)) == 0; \
}())
#else
#define wapp_mem_allocator_invalid(ALLOCATOR) (memcmp(ALLOCATOR, &((Allocator){0}), sizeof(Allocator)) == 0) #define wapp_mem_allocator_invalid(ALLOCATOR) (memcmp(ALLOCATOR, &((Allocator){0}), sizeof(Allocator)) == 0)
#endif // !WAPP_PLATFORM_CPP
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);
@@ -35,8 +43,8 @@ void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr,
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, u64 size);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // __cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !MEM_ALLOCATOR_H #endif // !MEM_ALLOCATOR_H

View File

@@ -1,22 +1,21 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "str8.h" #include "str8.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../mem/allocator/mem_allocator.h" #include "../../../common/assert/assert.h"
#include "../../mem_allocator/mem_allocator.h"
#include <ctype.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#define STR8_BUF_ALLOC_SIZE(CAPACITY) (sizeof(Str8) + sizeof(c8) * CAPACITY) #define STR8_BUF_ALLOC_SIZE(CAPACITY) (sizeof(Str8) + sizeof(c8) * CAPACITY)
Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity) { Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity) {
Str8 *str = NULL; wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
if (!allocator) { Str8 *str = wapp_mem_allocator_alloc(allocator, STR8_BUF_ALLOC_SIZE(capacity));
goto RETURN_STR8;
}
str = wapp_mem_allocator_alloc(allocator, STR8_BUF_ALLOC_SIZE(capacity));
if (!str) { if (!str) {
goto RETURN_STR8; goto RETURN_STR8;
} }
@@ -29,15 +28,20 @@ RETURN_STR8:
return str; return str;
} }
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str) { Str8 *wapp_str8_alloc_and_fill_buf(const Allocator *allocator, u64 capacity) {
Str8 *output = NULL; Str8 *out = wapp_str8_alloc_buf(allocator, capacity);
if (out) {
if (!allocator || !str) { memset(out->buf, 0, capacity);
goto RETURN_ALLOC_CSTR; out->size = capacity;
}
return out;
} }
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str) {
wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL");
u64 length = strlen(str); u64 length = strlen(str);
output = wapp_str8_alloc_buf(allocator, length * 2); Str8 *output = wapp_str8_alloc_buf(allocator, length * 2);
if (!output) { if (!output) {
goto RETURN_ALLOC_CSTR; goto RETURN_ALLOC_CSTR;
} }
@@ -50,13 +54,9 @@ RETURN_ALLOC_CSTR:
} }
Str8 *wapp_str8_alloc_str8(const Allocator *allocator, Str8RO *str) { Str8 *wapp_str8_alloc_str8(const Allocator *allocator, Str8RO *str) {
Str8 *output = NULL; wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL");
if (!allocator || !str) { Str8 *output = wapp_str8_alloc_buf(allocator, str->capacity);
goto RETURN_ALLOC_STR8;
}
output = wapp_str8_alloc_buf(allocator, str->capacity);
if (!output) { if (!output) {
goto RETURN_ALLOC_STR8; goto RETURN_ALLOC_STR8;
} }
@@ -69,10 +69,9 @@ RETURN_ALLOC_STR8:
} }
Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end) { Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end) {
wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL");
Str8 *output = NULL; Str8 *output = NULL;
if (!allocator || !str) {
goto RETURN_ALLOC_SUBSTR;
}
if (start >= str->size || start >= end) { if (start >= str->size || start >= end) {
goto RETURN_ALLOC_SUBSTR; goto RETURN_ALLOC_SUBSTR;
@@ -95,10 +94,7 @@ RETURN_ALLOC_SUBSTR:
} }
void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str) { void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str) {
if (!allocator || !str || !(*str)) { wapp_debug_assert(allocator != NULL && str != NULL && (*str) != NULL, "Either `allocator` is NULL or `str` is an invalid double pointer");
return;
}
wapp_mem_allocator_free(allocator, (void **)str, STR8_BUF_ALLOC_SIZE((*str)->capacity)); wapp_mem_allocator_free(allocator, (void **)str, STR8_BUF_ALLOC_SIZE((*str)->capacity));
} }
@@ -127,7 +123,7 @@ void wapp_str8_push_back(Str8 *str, c8 c) {
wapp_str8_set(str, index, c); wapp_str8_set(str, index, c);
} }
bool wapp_str8_equal(Str8RO *s1, Str8RO *s2) { b32 wapp_str8_equal(Str8RO *s1, Str8RO *s2) {
if (s1->size != s2->size) { if (s1->size != s2->size) {
return false; return false;
} }
@@ -135,7 +131,7 @@ bool wapp_str8_equal(Str8RO *s1, Str8RO *s2) {
return wapp_str8_equal_to_count(s1, s2, s1->size); return wapp_str8_equal_to_count(s1, s2, s1->size);
} }
bool wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) { b32 wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) {
if (!s1 || !s2) { if (!s1 || !s2) {
return false; return false;
} }
@@ -161,15 +157,13 @@ Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end) {
} }
Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src) { Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src) {
if (!allocator || !dst || !src) { wapp_debug_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
return NULL;
}
Str8 *output = NULL; Str8 *output = NULL;
u64 remaining = dst->capacity - dst->size; u64 remaining = dst->capacity - dst->size;
if (src->size <= remaining) { if (src->size <= remaining) {
output = dst; output = dst;
goto COPY_STRING_STR8_CONCAT; goto SOURCE_STRING_STR8_CONCAT;
} }
u64 capacity = dst->capacity + src->size; u64 capacity = dst->capacity + src->size;
@@ -181,7 +175,7 @@ Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src)
wapp_str8_concat_capped(output, dst); wapp_str8_concat_capped(output, dst);
COPY_STRING_STR8_CONCAT: SOURCE_STRING_STR8_CONCAT:
wapp_str8_concat_capped(output, src); wapp_str8_concat_capped(output, src);
RETURN_STR8_CONCAT: RETURN_STR8_CONCAT:
@@ -189,9 +183,7 @@ RETURN_STR8_CONCAT:
} }
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) { void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) {
if (!dst || !src) { wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
return;
}
u64 remaining = dst->capacity - dst->size; u64 remaining = dst->capacity - dst->size;
u64 to_copy = remaining < src->size ? remaining : src->size; u64 to_copy = remaining < src->size ? remaining : src->size;
@@ -201,9 +193,7 @@ void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) {
} }
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *src) { void wapp_str8_copy_cstr_capped(Str8 *dst, const char *src) {
if (!dst || !src) { wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
return;
}
u64 length = strlen(src); u64 length = strlen(src);
u64 to_copy = length <= dst->capacity ? length : dst->capacity; u64 to_copy = length <= dst->capacity ? length : dst->capacity;
@@ -214,9 +204,7 @@ 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_str8_capped(Str8 *dst, Str8RO *src) {
if (!dst || !src) { wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
return;
}
u64 to_copy = src->size <= dst->capacity ? src->size : dst->capacity; u64 to_copy = src->size <= dst->capacity ? src->size : dst->capacity;
@@ -226,9 +214,7 @@ 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_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity) {
if (!dst || !src) { wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
return;
}
u64 to_copy = src->size < dst_capacity ? src->size : dst_capacity - 1; u64 to_copy = src->size < dst_capacity ? src->size : dst_capacity - 1;
@@ -237,9 +223,7 @@ void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity) {
} }
void wapp_str8_format(Str8 *dst, const char *format, ...) { void wapp_str8_format(Str8 *dst, const char *format, ...) {
if (!dst || !format) { wapp_debug_assert(dst != NULL && format != NULL, "`dst` and `format` should not be NULL");
return;
}
va_list args1; va_list args1;
va_list args2; va_list args2;
@@ -256,6 +240,36 @@ void wapp_str8_format(Str8 *dst, const char *format, ...) {
va_end(args2); va_end(args2);
} }
void wapp_str8_to_lower(Str8 *dst, Str8RO *src) {
wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL");
wapp_debug_assert(dst->capacity >= src->capacity, "`dst` does not have enough capacity");
dst->size = src->size;
for (u64 i = 0; i < src->size; ++i) {
wapp_str8_set(dst, i, tolower(wapp_str8_get(src, i)));
}
}
void wapp_str8_to_upper(Str8 *dst, Str8RO *src) {
wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL");
wapp_debug_assert(dst->capacity >= src->capacity, "`dst` does not have enough capacity");
dst->size = src->size;
for (u64 i = 0; i < src->size; ++i) {
wapp_str8_set(dst, i, toupper(wapp_str8_get(src, i)));
}
}
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src) {
u64 size = src->count * src->item_size;
wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL");
wapp_debug_assert(dst->capacity >= size, "`dst` does not have enough capacity");
dst->size = size;
memcpy(dst->buf, src->items, size);
}
i64 wapp_str8_find(Str8RO *str, Str8RO substr) { i64 wapp_str8_find(Str8RO *str, Str8RO substr) {
if (!str || substr.size > str->size) { if (!str || substr.size > str->size) {
return -1; return -1;
@@ -264,7 +278,7 @@ i64 wapp_str8_find(Str8RO *str, Str8RO substr) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
u64 char_index = 0; u64 char_index = 0;
bool running = true; b32 running = char_index < str->size;
while (running) { while (running) {
const c8 *sub = str->buf + char_index; const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) { if (memcmp(sub, substr.buf, substr.size) == 0) {
@@ -286,7 +300,7 @@ i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
i64 char_index = str->size - substr.size; i64 char_index = str->size - substr.size;
bool running = true; b32 running = char_index >= 0;
while (running) { while (running) {
const c8 *sub = str->buf + char_index; const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) { if (memcmp(sub, substr.buf, substr.size) == 0) {
@@ -301,9 +315,7 @@ i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
} }
Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) { Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
if (!allocator || !str || !delimiter) { wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
return NULL;
}
Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List)); Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List));
@@ -331,7 +343,7 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
before_str = wapp_str8_alloc_substr(allocator, str, start, start + end); before_str = wapp_str8_alloc_substr(allocator, str, start, start + end);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node) { if (node && before_str) {
node->item = before_str; node->item = before_str;
wapp_str8_list_push_back(output, node); wapp_str8_list_push_back(output, node);
} }
@@ -346,7 +358,7 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
// Ensure the last part of the string after the delimiter is added to the list // 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); rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node) { if (node && rest) {
node->item = rest; node->item = rest;
wapp_str8_list_push_back(output, node); wapp_str8_list_push_back(output, node);
} }
@@ -356,16 +368,14 @@ RETURN_STR8_SPLIT:
} }
Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) { Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
if (!allocator || !str || !delimiter) { wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
return NULL;
}
Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List)); Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List));
if (delimiter->size > str->size) { if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str); Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node) { if (node && full) {
node->item = full; node->item = full;
wapp_str8_list_push_back(output, node); wapp_str8_list_push_back(output, node);
} }
@@ -398,7 +408,7 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size); rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node) { if (node && rest) {
node->item = rest; node->item = rest;
wapp_str8_list_push_front(output, node); wapp_str8_list_push_front(output, node);
} }
@@ -408,9 +418,7 @@ RETURN_STR8_SPLIT:
} }
Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *delimiter) { Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *delimiter) {
if (!allocator || !list || !delimiter) { wapp_debug_assert(allocator != NULL && list != NULL && delimiter != NULL, "`allocator`, `list` and `delimiter` should not be NULL");
return NULL;
}
u64 capacity = wapp_str8_list_total_size(list) + (delimiter->size * (list->node_count - 1)); u64 capacity = wapp_str8_list_total_size(list) + (delimiter->size * (list->node_count - 1));
Str8 *output = wapp_str8_alloc_buf(allocator, capacity * 2); Str8 *output = wapp_str8_alloc_buf(allocator, capacity * 2);
@@ -419,11 +427,19 @@ Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *d
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
Str8Node *node; Str8Node *node;
u64 node_index = 0; u64 node_index = 0;
bool running = true; b32 running = node_index < list->node_count;
while (running) { while (running) {
node = wapp_str8_list_get(list, node_index); node = wapp_str8_list_get(list, node_index);
if (!node) {
break;
}
wapp_str8_concat_capped(output, node->item); wapp_str8_concat_capped(output, node->item);
if (node_index + 1 < list->node_count) {
// NOTE (Abdelrahman): Comparison extracted to variable to silence
// MSVC Spectre mitigation warnings
b32 not_last = node_index + 1 < list->node_count;
if (not_last) {
wapp_str8_concat_capped(output, delimiter); wapp_str8_concat_capped(output, delimiter);
} }
@@ -439,10 +455,21 @@ u64 wapp_str8_list_total_size(const Str8List *list) {
return 0; return 0;
} }
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
Str8Node* node;
u64 node_index = 0;
u64 output = 0; u64 output = 0;
for (u64 i = 0; i < list->node_count; ++i) { b32 running = node_index < list->node_count;
Str8Node *node = wapp_str8_list_get(list, i); while (running) {
node = wapp_str8_list_get(list, node_index);
if (!node) {
break;
}
output += node->item->size; output += node->item->size;
++node_index;
running = node_index < list->node_count;
} }
return output; return output;

View File

@@ -1,15 +1,19 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef STR8_H #ifndef STR8_H
#define STR8_H #define STR8_H
#include "./str8_list.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../mem/allocator/mem_allocator.h" #include "../../../common/assert/assert.h"
#include "../../../common/platform/platform.h"
#include "../../../primitives/array/array.h"
#include "../../../primitives/dbl_list/dbl_list.h"
#include "../../mem_allocator/mem_allocator.h"
#include <string.h> #include <string.h>
#include <stdbool.h>
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !__cplusplus #endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8; typedef struct str8 Str8;
struct str8 { struct str8 {
@@ -29,6 +33,25 @@ typedef const Str8 Str8RO;
/** /**
* Str8 stack buffers * Str8 stack buffers
*/ */
#ifdef WAPP_PLATFORM_CPP
// Uses a lambda to achieve the same behaviour achieved by the C macro
#define wapp_str8_buf(CAPACITY) ([&](){ \
wapp_persist c8 buf[CAPACITY] = {}; \
memset(buf, 0, CAPACITY); \
return Str8{CAPACITY, 0, buf}; \
}())
// Uses a lambda to achieve the same behaviour achieved by the C macro
#define wapp_str8_lit(STRING) ([&]() { \
wapp_persist c8 buf[sizeof(STRING) * 2] = {}; \
memcpy(buf, STRING, sizeof(STRING)); \
return Str8{(sizeof(STRING) - 1) * 2, sizeof(STRING) - 1, buf}; \
}())
#define wapp_str8_lit_ro(STRING) Str8RO{sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING}
#define wapp_str8_lit_ro_initialiser_list(STRING) {sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING}
#else
#define wapp_str8_buf(CAPACITY) ((Str8){.capacity = CAPACITY, .size = 0, .buf = (c8[CAPACITY]){0}}) #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 // Utilises the fact that memcpy returns pointer to dest buffer and that getting
@@ -45,11 +68,13 @@ typedef const Str8 Str8RO;
#define wapp_str8_lit_ro_initialiser_list(STRING) {.capacity = sizeof(STRING) - 1, \ #define wapp_str8_lit_ro_initialiser_list(STRING) {.capacity = sizeof(STRING) - 1, \
.size = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \
.buf = (c8 *)STRING} .buf = (c8 *)STRING}
#endif // !WAPP_PLATFORM_CPP
/** /**
* Str8 allocated buffers * Str8 allocated buffers
*/ */
Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity); Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity);
Str8 *wapp_str8_alloc_and_fill_buf(const Allocator *allocator, u64 capacity);
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str); 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_str8(const Allocator *allocator, Str8RO *str);
Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end); Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end);
@@ -64,14 +89,17 @@ void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str);
c8 wapp_str8_get(Str8RO *str, u64 index); c8 wapp_str8_get(Str8RO *str, u64 index);
void wapp_str8_set(Str8 *str, u64 index, c8 c); void wapp_str8_set(Str8 *str, u64 index, c8 c);
void wapp_str8_push_back(Str8 *str, c8 c); void wapp_str8_push_back(Str8 *str, c8 c);
bool wapp_str8_equal(Str8RO *s1, Str8RO *s2); b32 wapp_str8_equal(Str8RO *s1, Str8RO *s2);
bool wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count); b32 wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count);
Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end); Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end);
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src); void wapp_str8_concat_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *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_str8_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity); void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity);
void wapp_str8_format(Str8 *dst, const char *format, ...); void wapp_str8_format(Str8 *dst, const char *format, ...);
void wapp_str8_to_lower(Str8 *dst, Str8RO *src);
void wapp_str8_to_upper(Str8 *dst, Str8RO *src);
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src);
/** /**
* Str8 find functions * Str8 find functions
@@ -91,12 +119,23 @@ Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8R
/** /**
* Str8 list utilities * Str8 list utilities
*/ */
#define wapp_str8_node_from_cstr(STRING) ((Str8Node){.item = &wapp_str8_lit(STRING)}) #ifdef WAPP_PLATFORM_CPP
#define wapp_str8_node_from_str8(STRING) ((Str8Node){.item = &(STRING)}) #define wapp_str8_node_from_cstr(STRING) wapp_str8_list_node([&]() { \
wapp_persist Str8 str = wapp_str8_lit(STRING); \
return &str; \
}())
#define wapp_str8_node_from_str8(STRING) wapp_str8_list_node([&]() { \
wapp_persist Str8 str = STRING; \
return &str; \
}())
#else
#define wapp_str8_node_from_cstr(STRING) wapp_str8_list_node(&wapp_str8_lit(STRING))
#define wapp_str8_node_from_str8(STRING) wapp_str8_list_node(&(STRING))
#endif // !WAPP_PLATFORM_CPP
u64 wapp_str8_list_total_size(const Str8List *list); u64 wapp_str8_list_total_size(const Str8List *list);
#ifdef __cplusplus #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#endif // !__cplusplus #endif // !WAPP_PLATFORM_CPP
#endif // !STR8_H #endif // !STR8_H

View File

@@ -0,0 +1,12 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_PRIMITIVES_C
#define WAPP_PRIMITIVES_C
#include "wapp_primitives.h"
#include "array/array.c"
#include "dbl_list/dbl_list.c"
#include "mem_allocator/mem_allocator.c"
#include "strings/str8/str8.c"
#endif // !WAPP_PRIMITIVES_C

View File

@@ -0,0 +1,12 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_PRIMITIVES_H
#define WAPP_PRIMITIVES_H
#include "dbl_list/dbl_list.h"
#include "array/array.h"
#include "mem_allocator/mem_allocator.h"
#include "strings/str8/str8.h"
#include "../common/wapp_common.h"
#endif // !WAPP_PRIMITIVES_H

View File

@@ -1,3 +1,5 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_PRNG_C #ifndef WAPP_PRNG_C
#define WAPP_PRNG_C #define WAPP_PRNG_C

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