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>
This commit is contained in:
		
							
								
								
									
										43
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,20 +1,30 @@ | |||||||
| CC           = clang | CC           = clang | ||||||
|  | CXX          = clang++ | ||||||
|  | AR           = ar | ||||||
| BUILD_TYPE   = debug | BUILD_TYPE   = debug | ||||||
| CFLAGS       = -Wall -Wextra -Werror -pedantic -std=gnu11 -Isrc | CFLAGS       = -Wall -Wextra -Werror -pedantic -std=gnu11 -Isrc | ||||||
| LIBFLAGS     = -fPIC -shared | CXXFLAGS     = -Wall -Wextra -Werror -pedantic -std=gnu++11 -Isrc | ||||||
|  | LIBFLAGS     = -fPIC | ||||||
| KERNEL       = $(shell uname -s) | KERNEL       = $(shell uname -s) | ||||||
| MACHINE      = $(shell uname -m) | MACHINE      = $(shell uname -m) | ||||||
| PLATFORM     = $(KERNEL)_$(MACHINE) | PLATFORM     = $(KERNEL)_$(MACHINE) | ||||||
| TEST_INCLUDE = -Isrc $(shell find tests -type d | xargs -I{} echo -n "-I{} ") | 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 "{} ") | TEST_SRC     = $(shell find tests -type f -name "*.c" | xargs -I{} echo -n "{} ") | ||||||
|  | TEST_C_SRC   = src/wapp.c $(TEST_SRC) | ||||||
|  | TEST_CXX_SRC = $(shell find tests -type f -name "*.cc" | xargs -I{} echo -n "{} ") | ||||||
| BUILD_DIR    = libwapp-build/$(PLATFORM)-$(BUILD_TYPE) | BUILD_DIR    = libwapp-build/$(PLATFORM)-$(BUILD_TYPE) | ||||||
| LIB_OUT      = $(BUILD_DIR)/libwapp.so | LIB_NAME     = wapp | ||||||
| TEST_OUT     = $(BUILD_DIR)/wapptest | OBJ_OUT      = $(BUILD_DIR)/$(LIB_NAME).o | ||||||
|  | LIB_OUT      = $(BUILD_DIR)/lib$(LIB_NAME).a | ||||||
|  | TEST_C_OUT   = $(BUILD_DIR)/wapptest | ||||||
|  | TEST_CXX_OUT = $(BUILD_DIR)/wapptestcc | ||||||
|  |  | ||||||
| ifeq ($(BUILD_TYPE),debug) | ifeq ($(BUILD_TYPE),debug) | ||||||
| 	CFLAGS += -g -fsanitize=address,undefined -DWAPP_DEBUG_ASSERT | 	CFLAGS += -g -fsanitize=address,undefined -DWAPP_DEBUG_ASSERT | ||||||
|  | 	CXXFLAGS += -g -fsanitize=address,undefined -DWAPP_DEBUG_ASSERT | ||||||
| else ifeq ($(BUILD_TYPE),release) | else ifeq ($(BUILD_TYPE),release) | ||||||
| 	CFLAGS += -O3 | 	CFLAGS += -O3 | ||||||
|  | 	CXXFLAGS += -O3 | ||||||
| else | else | ||||||
| 	$(error Invalid BUILD type '$(BUILD_TYPE)'. Use 'debug' or 'release') | 	$(error Invalid BUILD type '$(BUILD_TYPE)'. Use 'debug' or 'release') | ||||||
| endif | endif | ||||||
| @@ -26,7 +36,7 @@ endif | |||||||
|  |  | ||||||
| .PHONY: all clean builddir build-test run-test codegen build-lib full prng testing uuid core primitives | .PHONY: all clean builddir build-test run-test codegen build-lib full prng testing uuid core primitives | ||||||
|  |  | ||||||
| all: clean builddir codegen run-test full | all: clean builddir codegen run-c-test full run-cc-test | ||||||
|  |  | ||||||
| clean: | clean: | ||||||
| 	@rm -rf $(BUILD_DIR) | 	@rm -rf $(BUILD_DIR) | ||||||
| @@ -34,18 +44,29 @@ clean: | |||||||
| builddir: | builddir: | ||||||
| 	@mkdir -p $(BUILD_DIR) | 	@mkdir -p $(BUILD_DIR) | ||||||
|  |  | ||||||
| build-test: | build-c-test: | ||||||
| 	$(CC) $(CFLAGS) $(TEST_INCLUDE) $(TEST_SRC) -o $(TEST_OUT) | 	$(CC) $(CFLAGS) $(TEST_INCLUDE) $(TEST_C_SRC) -o $(TEST_C_OUT) | ||||||
|  |  | ||||||
| run-test: build-test | run-c-test: build-c-test | ||||||
| 	@$(TEST_OUT) | 	@echo -e "\n\033[34;1mRUNNING C TESTS\033[0m" | ||||||
| 	@rm $(TEST_OUT) | 	@$(TEST_C_OUT) | ||||||
|  | 	@rm $(TEST_C_OUT) | ||||||
|  |  | ||||||
|  | build-cc-test: | ||||||
|  | 	$(CXX) $(CXXFLAGS) $(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-lib: | build-lib: | ||||||
| 	$(CC) $(CFLAGS) $(LIBFLAGS) $(LIB_SRC) -o $(LIB_OUT) | 	$(CC) -c $(CFLAGS) $(LIBFLAGS) $(LIB_SRC) -o $(OBJ_OUT) | ||||||
|  | 	$(AR) r $(LIB_OUT) $(OBJ_OUT) | ||||||
|  | 	@rm $(OBJ_OUT) | ||||||
|  |  | ||||||
| full: LIB_SRC = src/wapp.c | full: LIB_SRC = src/wapp.c | ||||||
| full: build-lib | full: build-lib | ||||||
|   | |||||||
| @@ -153,7 +153,7 @@ def make_array(user_datatypes: Dict[CDataType, ArrayData] = {}): | |||||||
|             ) |             ) | ||||||
|             generic_funcs.append(alloc_capacity_func) |             generic_funcs.append(alloc_capacity_func) | ||||||
|          |          | ||||||
|         stack_array_macro = CMacro( |         stack_array_cmacro = CMacro( | ||||||
|             name=f"wapp_{type_string_lower}_array(...)", |             name=f"wapp_{type_string_lower}_array(...)", | ||||||
|             value=__format_func_body( |             value=__format_func_body( | ||||||
|                 filename=snippets_dir / "stack_array", |                 filename=snippets_dir / "stack_array", | ||||||
| @@ -163,8 +163,18 @@ def make_array(user_datatypes: Dict[CDataType, ArrayData] = {}): | |||||||
|                 array_typename=array_data.array_typename, |                 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_macro = CMacro( |         stack_capacity_array_cmacro = CMacro( | ||||||
|             name=f"wapp_{type_string_lower}_array_with_capacity(CAPACITY)", |             name=f"wapp_{type_string_lower}_array_with_capacity(CAPACITY)", | ||||||
|             value=__format_func_body( |             value=__format_func_body( | ||||||
|                 filename=snippets_dir / "stack_capacity_array", |                 filename=snippets_dir / "stack_capacity_array", | ||||||
| @@ -174,6 +184,16 @@ def make_array(user_datatypes: Dict[CDataType, ArrayData] = {}): | |||||||
|                 array_typename=array_data.array_typename, |                 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( |         alloc_capacity_array_macro = CMacro( | ||||||
|             name=f"wapp_{type_string_lower}_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY)", |             name=f"wapp_{type_string_lower}_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY)", | ||||||
| @@ -186,7 +206,7 @@ def make_array(user_datatypes: Dict[CDataType, ArrayData] = {}): | |||||||
|             ), |             ), | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         array_pop_macro = CMacro( |         array_pop_cmacro = CMacro( | ||||||
|             name=f"wapp_{type_string_lower}_array_pop(ARRAY_PTR)", |             name=f"wapp_{type_string_lower}_array_pop(ARRAY_PTR)", | ||||||
|             value=__format_func_body( |             value=__format_func_body( | ||||||
|                 filename=snippets_dir / "array_pop_macro", |                 filename=snippets_dir / "array_pop_macro", | ||||||
| @@ -196,6 +216,16 @@ def make_array(user_datatypes: Dict[CDataType, ArrayData] = {}): | |||||||
|                 array_typename=array_data.array_typename, |                 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( |         get_func = CFunc( | ||||||
|             name=f"wapp_{type_string_lower}_array_get", |             name=f"wapp_{type_string_lower}_array_get", | ||||||
| @@ -366,10 +396,17 @@ def make_array(user_datatypes: Dict[CDataType, ArrayData] = {}): | |||||||
|  |  | ||||||
|         header.decl_types.extend(array_data.hdr_decl_types) |         header.decl_types.extend(array_data.hdr_decl_types) | ||||||
|         header.macros.extend([ |         header.macros.extend([ | ||||||
|             stack_array_macro, |  | ||||||
|             stack_capacity_array_macro, |  | ||||||
|             alloc_capacity_array_macro, |             alloc_capacity_array_macro, | ||||||
|             array_pop_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.types.extend([array]) |         header.types.extend([array]) | ||||||
|         header.funcs.extend([ |         header.funcs.extend([ | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								codegen/array/snippets/array_pop_macro_cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								codegen/array/snippets/array_pop_macro_cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|  |   *_{Tlower}_array_pop(ARRAY_PTR) : \ | ||||||
|  |   {T}{{}} \ | ||||||
|  | ) | ||||||
							
								
								
									
										9
									
								
								codegen/array/snippets/stack_array_cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								codegen/array/snippets/stack_array_cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | ([&]() {{ \ | ||||||
|  |   persistent {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}) \ | ||||||
|  |   }}; \ | ||||||
|  | }}()) | ||||||
							
								
								
									
										4
									
								
								codegen/array/snippets/stack_capacity_array_cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								codegen/array/snippets/stack_capacity_array_cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | ([&]() {{ \ | ||||||
|  |   persistent {T} buf[CAPACITY] = {{}}; \ | ||||||
|  |   return {ArrayType}{{buf, 0, CAPACITY, sizeof({T})}}; \ | ||||||
|  | }}()) | ||||||
| @@ -211,6 +211,8 @@ class CFile: | |||||||
|     funcs: List[CFunc] = field(default_factory=list) |     funcs: List[CFunc] = field(default_factory=list) | ||||||
|     decl_types: List[CStruct] = field(default_factory=list) |     decl_types: List[CStruct] = field(default_factory=list) | ||||||
|     macros: List[CMacro] = 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( |         self.includes.extend( | ||||||
| @@ -246,7 +248,10 @@ class CHeader(CFile): | |||||||
|         name_upper = self.name.upper() |         name_upper = self.name.upper() | ||||||
|         header_guard_name = f"{name_upper}_H" |         header_guard_name = f"{name_upper}_H" | ||||||
|         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"\n#endif // !{header_guard_name}\n" |         header_guard_close = f"#endif // !{header_guard_name}\n" | ||||||
|  |  | ||||||
|  |         c_linkage_open = "#ifdef WAPP_PLATFORM_CPP\nBEGIN_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\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) | ||||||
|  |  | ||||||
| @@ -256,6 +261,15 @@ class CHeader(CFile): | |||||||
|         if len(macros) > 0: |         if len(macros) > 0: | ||||||
|             macros += "\n" |             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() | ||||||
| @@ -274,10 +288,12 @@ class CHeader(CFile): | |||||||
|             super().__str__() + |             super().__str__() + | ||||||
|             header_guard_open + |             header_guard_open + | ||||||
|             includes + |             includes + | ||||||
|  |             c_linkage_open + | ||||||
|             macros + |             macros + | ||||||
|             forward_declarations + |             forward_declarations + | ||||||
|             types + |             types + | ||||||
|             funcs + |             funcs + | ||||||
|  |             c_linkage_close + | ||||||
|             header_guard_close |             header_guard_close | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -139,7 +139,7 @@ def make_dbl_list(user_datatypes: Dict[CDataType, DblListData] = {}): | |||||||
|             ], |             ], | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         node_macro = CMacro( |         node_cmacro = CMacro( | ||||||
|             name=f"wapp_{type_string_lower}_list_node(ITEM_PTR)", |             name=f"wapp_{type_string_lower}_list_node(ITEM_PTR)", | ||||||
|             value=__format_func_body( |             value=__format_func_body( | ||||||
|                 filename=snippets_dir / "list_node", |                 filename=snippets_dir / "list_node", | ||||||
| @@ -151,6 +151,18 @@ def make_dbl_list(user_datatypes: Dict[CDataType, DblListData] = {}): | |||||||
|             ), |             ), | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |         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( |         get_func = CFunc( | ||||||
|             name=f"wapp_{type_string_lower}_list_get", |             name=f"wapp_{type_string_lower}_list_get", | ||||||
|             ret_type=node, |             ret_type=node, | ||||||
| @@ -307,7 +319,8 @@ def make_dbl_list(user_datatypes: Dict[CDataType, DblListData] = {}): | |||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         header.decl_types.extend(dbl_list_data.hdr_decl_types) |         header.decl_types.extend(dbl_list_data.hdr_decl_types) | ||||||
|         header.macros.append(node_macro) |         header.c_macros.append(node_cmacro) | ||||||
|  |         header.cpp_macros.append(node_cppmacro) | ||||||
|         header.types.extend([node, dl_list]) |         header.types.extend([node, dl_list]) | ||||||
|         header.funcs.extend([ |         header.funcs.extend([ | ||||||
|             get_func, |             get_func, | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								codegen/dbl_list/snippets/list_node_cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								codegen/dbl_list/snippets/list_node_cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | {NodeType}{{ITEM_PTR, nullptr, nullptr}} | ||||||
| @@ -30,13 +30,17 @@ | |||||||
|  |  | ||||||
| #define b32 uint32_t | #define b32 uint32_t | ||||||
|  |  | ||||||
|  | #ifndef WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #ifndef false | #ifndef false | ||||||
| #define false (b32)0 | #define false (b32)0 | ||||||
| #endif | #endif // !false | ||||||
|  |  | ||||||
| #ifndef true | #ifndef true | ||||||
| #define true (b32)1 | #define true (b32)1 | ||||||
| #endif | #endif // !true | ||||||
|  |  | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #define i8 int8_t | #define i8 int8_t | ||||||
| #define i16 int16_t | #define i16 int16_t | ||||||
| @@ -54,4 +58,10 @@ | |||||||
| #define internal static | #define internal static | ||||||
| #define persistent static | #define persistent static | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | #define class_mem static | ||||||
|  | #define BEGIN_C_LINKAGE extern "C" { | ||||||
|  | #define END_C_LINKAGE } | ||||||
|  | #endif // WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !ALIASES_H | #endif // !ALIASES_H | ||||||
|   | |||||||
| @@ -1,10 +1,18 @@ | |||||||
| // vim:fileencoding=utf-8:foldmethod=marker | // vim:fileencoding=utf-8:foldmethod=marker | ||||||
|  |  | ||||||
|  | #ifndef WAPP_ASSERT_H | ||||||
|  | #define WAPP_ASSERT_H | ||||||
|  |  | ||||||
| #include "../aliases/aliases.h" | #include "../aliases/aliases.h" | ||||||
|  | #include "../platform/platform.h" | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <inttypes.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_static_assert(EXPR, MSG) extern char ASSERTION_FAILED[EXPR ? 1 : -1] | ||||||
| #define wapp_runtime_assert(EXPR, MSG) __wapp_runtime_assert(EXPR, MSG) | #define wapp_runtime_assert(EXPR, MSG) __wapp_runtime_assert(EXPR, MSG) | ||||||
|  |  | ||||||
| @@ -25,3 +33,9 @@ | |||||||
|     abort();                                                                          \ |     abort();                                                                          \ | ||||||
|   }                                                                                   \ |   }                                                                                   \ | ||||||
| } while(false) | } while(false) | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
|  | #endif // !WAPP_ASSERT_H | ||||||
|   | |||||||
| @@ -5,6 +5,10 @@ | |||||||
|  |  | ||||||
| #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) | ||||||
| @@ -34,6 +38,19 @@ | |||||||
|   ) + 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)) | #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 | ||||||
|   | |||||||
| @@ -61,7 +61,30 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|   #error "WAPP is a C only library" |   #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 | #else | ||||||
|   #define WAPP_PLATFORM_C |   #define WAPP_PLATFORM_C | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,10 @@ | |||||||
| #include "../../os/mem/mem_os.h" | #include "../../os/mem/mem_os.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef struct arena Arena; | typedef struct arena Arena; | ||||||
|  |  | ||||||
| #define wapp_mem_arena_init(arena_dptr, base_capacity)                         \ | #define wapp_mem_arena_init(arena_dptr, base_capacity)                         \ | ||||||
| @@ -32,4 +36,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 WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_ARENA_H | #endif // !MEM_ARENA_H | ||||||
|   | |||||||
| @@ -9,6 +9,10 @@ | |||||||
| #include "../../os/mem/mem_os.h" | #include "../../os/mem/mem_os.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #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)) | ||||||
| #define wapp_mem_arena_allocator_init_commit(base_capacity)                    \ | #define wapp_mem_arena_allocator_init_commit(base_capacity)                    \ | ||||||
| @@ -33,4 +37,8 @@ Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags | |||||||
| 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 WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_ARENA_ALLOCATOR_H | #endif // !MEM_ARENA_ALLOCATOR_H | ||||||
|   | |||||||
| @@ -6,6 +6,14 @@ | |||||||
| #include "../../../common/aliases/aliases.h" | #include "../../../common/aliases/aliases.h" | ||||||
| #include "../../../common/platform/platform.h" | #include "../../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #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 WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_UTILS_H | #endif // !MEM_UTILS_H | ||||||
|   | |||||||
| @@ -8,6 +8,10 @@ | |||||||
| #include "../../../primitives/mem_allocator/mem_allocator.h" | #include "../../../primitives/mem_allocator/mem_allocator.h" | ||||||
| #include "../../../primitives/strings/str8/str8.h" | #include "../../../primitives/strings/str8/str8.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #ifdef WAPP_PLATFORM_POSIX | #ifdef WAPP_PLATFORM_POSIX | ||||||
| #define PATH_SEP '/' | #define PATH_SEP '/' | ||||||
| #elif defined(WAPP_PLATFORM_WINDOWS) | #elif defined(WAPP_PLATFORM_WINDOWS) | ||||||
| @@ -29,4 +33,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 WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !CPATH_H | #endif // !CPATH_H | ||||||
|   | |||||||
| @@ -8,6 +8,10 @@ | |||||||
|  |  | ||||||
| #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) | ||||||
| @@ -22,4 +26,8 @@ void wapp_mem_util_free(void *ptr, u64 size); | |||||||
| external void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type); | external void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type); | ||||||
| external void mem_util_free(void *ptr, u64 size); | external void mem_util_free(void *ptr, u64 size); | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_OS_H | #endif // !MEM_OS_H | ||||||
|   | |||||||
| @@ -5,6 +5,10 @@ | |||||||
|  |  | ||||||
| #include "../../../common/platform/platform.h" | #include "../../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef enum mem_access { | typedef enum mem_access { | ||||||
|   WAPP_MEM_ACCESS_NONE, |   WAPP_MEM_ACCESS_NONE, | ||||||
|   WAPP_MEM_ACCESS_READ_ONLY, |   WAPP_MEM_ACCESS_READ_ONLY, | ||||||
| @@ -19,4 +23,8 @@ typedef enum mem_init_type { | |||||||
|   WAPP_MEM_INIT_INITIALISED, |   WAPP_MEM_INIT_INITIALISED, | ||||||
| } MemInitType; | } MemInitType; | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_OS_OPS_H | #endif // !MEM_OS_OPS_H | ||||||
|   | |||||||
| @@ -5,6 +5,10 @@ | |||||||
|  |  | ||||||
| #include "../../../../common/platform/platform.h" | #include "../../../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #ifdef WAPP_PLATFORM_POSIX | #ifdef WAPP_PLATFORM_POSIX | ||||||
|  |  | ||||||
| #include <sys/mman.h> | #include <sys/mman.h> | ||||||
| @@ -24,4 +28,8 @@ typedef enum mem_alloc_flags { | |||||||
|  |  | ||||||
| #endif // !WAPP_PLATFORM_POSIX | #endif // !WAPP_PLATFORM_POSIX | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_OS_POSIX_H | #endif // !MEM_OS_POSIX_H | ||||||
|   | |||||||
| @@ -5,6 +5,10 @@ | |||||||
|  |  | ||||||
| #include "../../../../common/platform/platform.h" | #include "../../../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #ifdef WAPP_PLATFORM_WINDOWS | #ifdef WAPP_PLATFORM_WINDOWS | ||||||
|  |  | ||||||
| #define WIN32_LEAN_AND_MEAN | #define WIN32_LEAN_AND_MEAN | ||||||
| @@ -18,4 +22,8 @@ typedef enum mem_alloc_flags { | |||||||
|  |  | ||||||
| #endif // !WAPP_PLATFORM_WINDOWS | #endif // !WAPP_PLATFORM_WINDOWS | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_OS_WIN_H | #endif // !MEM_OS_WIN_H | ||||||
|   | |||||||
| @@ -11,10 +11,18 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #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); | external CMDError get_output_status(FILE *fp, i32 *status_out); | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !COMMANDER_H | #endif // !COMMANDER_H | ||||||
|   | |||||||
| @@ -7,6 +7,10 @@ | |||||||
| #include "../../../../common/platform/platform.h" | #include "../../../../common/platform/platform.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|   SHELL_OUTPUT_DISCARD, |   SHELL_OUTPUT_DISCARD, | ||||||
|   SHELL_OUTPUT_PRINT, |   SHELL_OUTPUT_PRINT, | ||||||
| @@ -34,4 +38,8 @@ struct commander_result { | |||||||
| #endif // !WAPP_PLATFORM_WINDOWS | #endif // !WAPP_PLATFORM_WINDOWS | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !COMMANDER_OUTPUT_H | #endif // !COMMANDER_OUTPUT_H | ||||||
|   | |||||||
| @@ -8,9 +8,17 @@ | |||||||
| #include "../../../../common/platform/platform.h" | #include "../../../../common/platform/platform.h" | ||||||
| #include "../../../../primitives/strings/str8/str8.h" | #include "../../../../primitives/strings/str8/str8.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #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); | external void print_coloured_text(Str8RO *text, TerminalColour colour); | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !TERM_COLOUR_H | #endif // !TERM_COLOUR_H | ||||||
|   | |||||||
| @@ -3,8 +3,13 @@ | |||||||
| #ifndef TERMINAL_COLOURS_H | #ifndef TERMINAL_COLOURS_H | ||||||
| #define TERMINAL_COLOURS_H | #define TERMINAL_COLOURS_H | ||||||
|  |  | ||||||
|  | #include "../../../../common/aliases/aliases.h" | ||||||
| #include "../../../../common/platform/platform.h" | #include "../../../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|   WAPP_TERM_COLOUR_FG_BLACK, |   WAPP_TERM_COLOUR_FG_BLACK, | ||||||
|   WAPP_TERM_COLOUR_FG_RED, |   WAPP_TERM_COLOUR_FG_RED, | ||||||
| @@ -27,4 +32,8 @@ typedef enum { | |||||||
|   COUNT_TERM_COLOUR, |   COUNT_TERM_COLOUR, | ||||||
| } TerminalColour; | } TerminalColour; | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !TERMINAL_COLOURS_H | #endif // !TERMINAL_COLOURS_H | ||||||
|   | |||||||
| @@ -3,9 +3,14 @@ | |||||||
| #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 | ||||||
| @@ -14,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 | ||||||
|   | |||||||
| @@ -11,6 +11,373 @@ | |||||||
| #include "../../common/aliases/aliases.h" | #include "../../common/aliases/aliases.h" | ||||||
| #include "../../common/platform/platform.h" | #include "../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
|  | #define wapp_str8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((Str8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(Str8))) | ||||||
|  | #define wapp_void_ptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((VoidPArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(void *))) | ||||||
|  | #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_str8_array(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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_void_ptr_array(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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_b32_array(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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(...) ([&]() { \ | ||||||
|  |   persistent 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) ([&]() { \ | ||||||
|  |   persistent 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_str8_array(...) ((Str8Array){ \ | #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__}, \ |   .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__), \ |   .count = wapp_misc_utils_va_args_count(Str8, __VA_ARGS__), \ | ||||||
| @@ -18,7 +385,6 @@ | |||||||
|   .item_size = sizeof(Str8) \ |   .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_with_capacity(CAPACITY) ((Str8Array){.items = (Str8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(Str8)}) | ||||||
| #define wapp_str8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((Str8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(Str8))) |  | ||||||
| #define wapp_str8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_str8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_str8_array_pop(ARRAY_PTR) : \ |   *_str8_array_pop(ARRAY_PTR) : \ | ||||||
|   (Str8){0} \ |   (Str8){0} \ | ||||||
| @@ -30,7 +396,6 @@ | |||||||
|   .item_size = sizeof(void *) \ |   .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_with_capacity(CAPACITY) ((VoidPArray){.items = (void *[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(void *)}) | ||||||
| #define wapp_void_ptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((VoidPArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(void *))) |  | ||||||
| #define wapp_void_ptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_void_ptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_void_ptr_array_pop(ARRAY_PTR) : \ |   *_void_ptr_array_pop(ARRAY_PTR) : \ | ||||||
|   (void *){0} \ |   (void *){0} \ | ||||||
| @@ -42,7 +407,6 @@ | |||||||
|   .item_size = sizeof(b32) \ |   .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_with_capacity(CAPACITY) ((B32Array){.items = (b32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(b32)}) | ||||||
| #define wapp_b32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((B32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(b32))) |  | ||||||
| #define wapp_b32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_b32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_b32_array_pop(ARRAY_PTR) : \ |   *_b32_array_pop(ARRAY_PTR) : \ | ||||||
|   (b32){0} \ |   (b32){0} \ | ||||||
| @@ -54,7 +418,6 @@ | |||||||
|   .item_size = sizeof(char) \ |   .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_with_capacity(CAPACITY) ((CharArray){.items = (char[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(char)}) | ||||||
| #define wapp_char_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((CharArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(char))) |  | ||||||
| #define wapp_char_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_char_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_char_array_pop(ARRAY_PTR) : \ |   *_char_array_pop(ARRAY_PTR) : \ | ||||||
|   (char){0} \ |   (char){0} \ | ||||||
| @@ -66,7 +429,6 @@ | |||||||
|   .item_size = sizeof(c8) \ |   .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_with_capacity(CAPACITY) ((C8Array){.items = (c8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c8)}) | ||||||
| #define wapp_c8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c8))) |  | ||||||
| #define wapp_c8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_c8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_c8_array_pop(ARRAY_PTR) : \ |   *_c8_array_pop(ARRAY_PTR) : \ | ||||||
|   (c8){0} \ |   (c8){0} \ | ||||||
| @@ -78,7 +440,6 @@ | |||||||
|   .item_size = sizeof(c16) \ |   .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_with_capacity(CAPACITY) ((C16Array){.items = (c16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c16)}) | ||||||
| #define wapp_c16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c16))) |  | ||||||
| #define wapp_c16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_c16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_c16_array_pop(ARRAY_PTR) : \ |   *_c16_array_pop(ARRAY_PTR) : \ | ||||||
|   (c16){0} \ |   (c16){0} \ | ||||||
| @@ -90,7 +451,6 @@ | |||||||
|   .item_size = sizeof(c32) \ |   .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_with_capacity(CAPACITY) ((C32Array){.items = (c32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c32)}) | ||||||
| #define wapp_c32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c32))) |  | ||||||
| #define wapp_c32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_c32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_c32_array_pop(ARRAY_PTR) : \ |   *_c32_array_pop(ARRAY_PTR) : \ | ||||||
|   (c32){0} \ |   (c32){0} \ | ||||||
| @@ -102,7 +462,6 @@ | |||||||
|   .item_size = sizeof(i8) \ |   .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_with_capacity(CAPACITY) ((I8Array){.items = (i8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i8)}) | ||||||
| #define wapp_i8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i8))) |  | ||||||
| #define wapp_i8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_i8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_i8_array_pop(ARRAY_PTR) : \ |   *_i8_array_pop(ARRAY_PTR) : \ | ||||||
|   (i8){0} \ |   (i8){0} \ | ||||||
| @@ -114,7 +473,6 @@ | |||||||
|   .item_size = sizeof(i16) \ |   .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_with_capacity(CAPACITY) ((I16Array){.items = (i16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i16)}) | ||||||
| #define wapp_i16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i16))) |  | ||||||
| #define wapp_i16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_i16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_i16_array_pop(ARRAY_PTR) : \ |   *_i16_array_pop(ARRAY_PTR) : \ | ||||||
|   (i16){0} \ |   (i16){0} \ | ||||||
| @@ -126,7 +484,6 @@ | |||||||
|   .item_size = sizeof(i32) \ |   .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_with_capacity(CAPACITY) ((I32Array){.items = (i32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i32)}) | ||||||
| #define wapp_i32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i32))) |  | ||||||
| #define wapp_i32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_i32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_i32_array_pop(ARRAY_PTR) : \ |   *_i32_array_pop(ARRAY_PTR) : \ | ||||||
|   (i32){0} \ |   (i32){0} \ | ||||||
| @@ -138,7 +495,6 @@ | |||||||
|   .item_size = sizeof(i64) \ |   .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_with_capacity(CAPACITY) ((I64Array){.items = (i64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i64)}) | ||||||
| #define wapp_i64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i64))) |  | ||||||
| #define wapp_i64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_i64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_i64_array_pop(ARRAY_PTR) : \ |   *_i64_array_pop(ARRAY_PTR) : \ | ||||||
|   (i64){0} \ |   (i64){0} \ | ||||||
| @@ -150,7 +506,6 @@ | |||||||
|   .item_size = sizeof(u8) \ |   .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_with_capacity(CAPACITY) ((U8Array){.items = (u8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u8)}) | ||||||
| #define wapp_u8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u8))) |  | ||||||
| #define wapp_u8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_u8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_u8_array_pop(ARRAY_PTR) : \ |   *_u8_array_pop(ARRAY_PTR) : \ | ||||||
|   (u8){0} \ |   (u8){0} \ | ||||||
| @@ -162,7 +517,6 @@ | |||||||
|   .item_size = sizeof(u16) \ |   .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_with_capacity(CAPACITY) ((U16Array){.items = (u16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u16)}) | ||||||
| #define wapp_u16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u16))) |  | ||||||
| #define wapp_u16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_u16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_u16_array_pop(ARRAY_PTR) : \ |   *_u16_array_pop(ARRAY_PTR) : \ | ||||||
|   (u16){0} \ |   (u16){0} \ | ||||||
| @@ -174,7 +528,6 @@ | |||||||
|   .item_size = sizeof(u32) \ |   .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_with_capacity(CAPACITY) ((U32Array){.items = (u32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u32)}) | ||||||
| #define wapp_u32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u32))) |  | ||||||
| #define wapp_u32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_u32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_u32_array_pop(ARRAY_PTR) : \ |   *_u32_array_pop(ARRAY_PTR) : \ | ||||||
|   (u32){0} \ |   (u32){0} \ | ||||||
| @@ -186,7 +539,6 @@ | |||||||
|   .item_size = sizeof(u64) \ |   .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_with_capacity(CAPACITY) ((U64Array){.items = (u64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u64)}) | ||||||
| #define wapp_u64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u64))) |  | ||||||
| #define wapp_u64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_u64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_u64_array_pop(ARRAY_PTR) : \ |   *_u64_array_pop(ARRAY_PTR) : \ | ||||||
|   (u64){0} \ |   (u64){0} \ | ||||||
| @@ -198,7 +550,6 @@ | |||||||
|   .item_size = sizeof(f32) \ |   .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_with_capacity(CAPACITY) ((F32Array){.items = (f32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f32)}) | ||||||
| #define wapp_f32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f32))) |  | ||||||
| #define wapp_f32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_f32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_f32_array_pop(ARRAY_PTR) : \ |   *_f32_array_pop(ARRAY_PTR) : \ | ||||||
|   (f32){0} \ |   (f32){0} \ | ||||||
| @@ -210,7 +561,6 @@ | |||||||
|   .item_size = sizeof(f64) \ |   .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_with_capacity(CAPACITY) ((F64Array){.items = (f64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f64)}) | ||||||
| #define wapp_f64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f64))) |  | ||||||
| #define wapp_f64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_f64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_f64_array_pop(ARRAY_PTR) : \ |   *_f64_array_pop(ARRAY_PTR) : \ | ||||||
|   (f64){0} \ |   (f64){0} \ | ||||||
| @@ -222,7 +572,6 @@ | |||||||
|   .item_size = sizeof(f128) \ |   .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_with_capacity(CAPACITY) ((F128Array){.items = (f128[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f128)}) | ||||||
| #define wapp_f128_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F128Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f128))) |  | ||||||
| #define wapp_f128_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_f128_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_f128_array_pop(ARRAY_PTR) : \ |   *_f128_array_pop(ARRAY_PTR) : \ | ||||||
|   (f128){0} \ |   (f128){0} \ | ||||||
| @@ -234,7 +583,6 @@ | |||||||
|   .item_size = sizeof(iptr) \ |   .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_with_capacity(CAPACITY) ((IptrArray){.items = (iptr[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(iptr)}) | ||||||
| #define wapp_iptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((IptrArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(iptr))) |  | ||||||
| #define wapp_iptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_iptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_iptr_array_pop(ARRAY_PTR) : \ |   *_iptr_array_pop(ARRAY_PTR) : \ | ||||||
|   (iptr){0} \ |   (iptr){0} \ | ||||||
| @@ -246,11 +594,11 @@ | |||||||
|   .item_size = sizeof(uptr) \ |   .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_with_capacity(CAPACITY) ((UptrArray){.items = (uptr[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(uptr)}) | ||||||
| #define wapp_uptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((UptrArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(uptr))) |  | ||||||
| #define wapp_uptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | #define wapp_uptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ | ||||||
|   *_uptr_array_pop(ARRAY_PTR) : \ |   *_uptr_array_pop(ARRAY_PTR) : \ | ||||||
|   (uptr){0} \ |   (uptr){0} \ | ||||||
| ) | ) | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef struct str8 Str8; | typedef struct str8 Str8; | ||||||
|  |  | ||||||
| @@ -616,4 +964,8 @@ UptrArray *wapp_uptr_array_copy_alloc(const Allocator *allocator, const UptrArra | |||||||
| uptr *_uptr_array_pop(UptrArray *array); | uptr *_uptr_array_pop(UptrArray *array); | ||||||
| VoidPArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size); | VoidPArray *_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 | #endif // !ARRAY_H | ||||||
|   | |||||||
| @@ -9,6 +9,32 @@ | |||||||
| #include "../../common/aliases/aliases.h" | #include "../../common/aliases/aliases.h" | ||||||
| #include "../../common/platform/platform.h" | #include "../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | #define wapp_str8_list_node(ITEM_PTR) Str8Node{ITEM_PTR, nullptr, nullptr} | ||||||
|  | #define wapp_void_ptr_list_node(ITEM_PTR) VoidPNode{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_str8_list_node(ITEM_PTR) ((Str8Node){.item = ITEM_PTR}) | #define wapp_str8_list_node(ITEM_PTR) ((Str8Node){.item = ITEM_PTR}) | ||||||
| #define wapp_void_ptr_list_node(ITEM_PTR) ((VoidPNode){.item = ITEM_PTR}) | #define wapp_void_ptr_list_node(ITEM_PTR) ((VoidPNode){.item = ITEM_PTR}) | ||||||
| #define wapp_b32_list_node(ITEM_PTR) ((B32Node){.item = ITEM_PTR}) | #define wapp_b32_list_node(ITEM_PTR) ((B32Node){.item = ITEM_PTR}) | ||||||
| @@ -29,6 +55,7 @@ | |||||||
| #define wapp_f128_list_node(ITEM_PTR) ((F128Node){.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_iptr_list_node(ITEM_PTR) ((IptrNode){.item = ITEM_PTR}) | ||||||
| #define wapp_uptr_list_node(ITEM_PTR) ((UptrNode){.item = ITEM_PTR}) | #define wapp_uptr_list_node(ITEM_PTR) ((UptrNode){.item = ITEM_PTR}) | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef struct str8 Str8; | typedef struct str8 Str8; | ||||||
|  |  | ||||||
| @@ -473,4 +500,8 @@ UptrNode *wapp_uptr_list_pop_back(UptrList *list); | |||||||
| UptrNode *wapp_uptr_list_remove(UptrList *list, u64 index); | UptrNode *wapp_uptr_list_remove(UptrList *list, u64 index); | ||||||
| void wapp_uptr_list_empty(UptrList *list); | void wapp_uptr_list_empty(UptrList *list); | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !DBL_LIST_H | #endif // !DBL_LIST_H | ||||||
|   | |||||||
| @@ -7,6 +7,10 @@ | |||||||
| #include "../../common/platform/platform.h" | #include "../../common/platform/platform.h" | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #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); | ||||||
| typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); | typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); | ||||||
| @@ -23,7 +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); | ||||||
| @@ -32,4 +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 WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !MEM_ALLOCATOR_H | #endif // !MEM_ALLOCATOR_H | ||||||
|   | |||||||
| @@ -28,6 +28,15 @@ RETURN_STR8: | |||||||
|   return str; |   return str; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Str8 *wapp_str8_alloc_and_fill_buf(const Allocator *allocator, u64 capacity) { | ||||||
|  |   Str8 *out = wapp_str8_alloc_buf(allocator, capacity); | ||||||
|  |   if (out) { | ||||||
|  |     memset(out->buf, 0, capacity); | ||||||
|  |     out->size = capacity; | ||||||
|  |   } | ||||||
|  |   return out; | ||||||
|  | } | ||||||
|  |  | ||||||
| Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str) { | 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"); |   wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,12 +4,17 @@ | |||||||
| #define STR8_H | #define STR8_H | ||||||
|  |  | ||||||
| #include "../../../common/aliases/aliases.h" | #include "../../../common/aliases/aliases.h" | ||||||
|  | #include "../../../common/assert/assert.h" | ||||||
| #include "../../../common/platform/platform.h" | #include "../../../common/platform/platform.h" | ||||||
| #include "../../../primitives/dbl_list/dbl_list.h" | #include "../../../primitives/dbl_list/dbl_list.h" | ||||||
| #include "../../mem_allocator/mem_allocator.h" | #include "../../mem_allocator/mem_allocator.h" | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef struct str8 Str8; | typedef struct str8 Str8; | ||||||
| struct str8 { | struct str8 { | ||||||
|   u64 capacity; |   u64 capacity; | ||||||
| @@ -28,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) ([&](){ \ | ||||||
|  |   persistent 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) ([&]() {                            \ | ||||||
|  |   persistent 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 | ||||||
| @@ -44,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); | ||||||
| @@ -90,8 +116,23 @@ Str8     *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8R | |||||||
| /** | /** | ||||||
|  * Str8 list utilities |  * Str8 list utilities | ||||||
|  */ |  */ | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | #define wapp_str8_node_from_cstr(STRING) wapp_str8_list_node([&]() { \ | ||||||
|  |   persistent Str8 str = wapp_str8_lit(STRING);                      \ | ||||||
|  |   return &str;                                                      \ | ||||||
|  | }()) | ||||||
|  | #define wapp_str8_node_from_str8(STRING) wapp_str8_list_node([&]() { \ | ||||||
|  |   persistent 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_cstr(STRING) wapp_str8_list_node(&wapp_str8_lit(STRING)) | ||||||
| #define wapp_str8_node_from_str8(STRING) wapp_str8_list_node(&(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 WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !STR8_H | #endif // !STR8_H | ||||||
|   | |||||||
| @@ -6,6 +6,10 @@ | |||||||
| #include "../../common/aliases/aliases.h" | #include "../../common/aliases/aliases.h" | ||||||
| #include "../../common/platform/platform.h" | #include "../../common/platform/platform.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| typedef struct xor_256_state XOR256State; | typedef struct xor_256_state XOR256State; | ||||||
| struct xor_256_state { | struct xor_256_state { | ||||||
|   u64 x; |   u64 x; | ||||||
| @@ -19,4 +23,8 @@ u64 wapp_prng_xorshift_256(XOR256State *state); | |||||||
| u64 wapp_prng_xorshift_256ss(XOR256State *state); | u64 wapp_prng_xorshift_256ss(XOR256State *state); | ||||||
| u64 wapp_prng_xorshift_256p(XOR256State *state); | u64 wapp_prng_xorshift_256p(XOR256State *state); | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !XORSHIFT_H | #endif // !XORSHIFT_H | ||||||
|   | |||||||
| @@ -8,7 +8,16 @@ | |||||||
| #include "../../primitives/strings/str8/str8.h" | #include "../../primitives/strings/str8/str8.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | #define wapp_tester_result(PASSED) (TestFuncResult{wapp_str8_lit_ro(__func__), PASSED}) | ||||||
|  | #else | ||||||
| #define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED}) | #define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED}) | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL) | #define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL) | ||||||
|  |  | ||||||
| typedef struct test_func_result TestFuncResult; | typedef struct test_func_result TestFuncResult; | ||||||
| @@ -25,4 +34,8 @@ typedef TestFuncResult(TestFunc)(void); | |||||||
|  |  | ||||||
| void run_tests(TestFunc *func1, ...); | void run_tests(TestFunc *func1, ...); | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !TESTER_H | #endif // !TESTER_H | ||||||
|   | |||||||
| @@ -7,6 +7,10 @@ | |||||||
| #include "../common/platform/platform.h" | #include "../common/platform/platform.h" | ||||||
| #include "../primitives/strings/str8/str8.h" | #include "../primitives/strings/str8/str8.h" | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | BEGIN_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #define UUID_BUF_LENGTH 48 | #define UUID_BUF_LENGTH 48 | ||||||
| #define WAPP_UUID_SPEC WAPP_STR8_SPEC | #define WAPP_UUID_SPEC WAPP_STR8_SPEC | ||||||
| #define wapp_uuid_varg(UUID) wapp_str8_varg((UUID).uuid) | #define wapp_uuid_varg(UUID) wapp_str8_varg((UUID).uuid) | ||||||
| @@ -26,4 +30,8 @@ struct uuid { | |||||||
| // Fails when passed a NULL pointer. | // Fails when passed a NULL pointer. | ||||||
| UUID *wapp_uuid_init_uuid4(UUID *uuid); | UUID *wapp_uuid_init_uuid4(UUID *uuid); | ||||||
|  |  | ||||||
|  | #ifdef WAPP_PLATFORM_CPP | ||||||
|  | END_C_LINKAGE | ||||||
|  | #endif // !WAPP_PLATFORM_CPP | ||||||
|  |  | ||||||
| #endif // !UUID_H | #endif // !UUID_H | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								tests/allocator/test_allocator.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/allocator/test_allocator.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | #include "test_allocator.h" | ||||||
|  | #include "wapp.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_allocator(void) { | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(4096); | ||||||
|  |   bool result         = allocator.obj != nullptr && allocator.alloc != nullptr && | ||||||
|  |                         allocator.alloc_aligned != nullptr && | ||||||
|  |                         allocator.realloc != nullptr && allocator.realloc_aligned != nullptr && | ||||||
|  |                         allocator.free == nullptr; | ||||||
|  |   void *ptr           = wapp_mem_allocator_alloc(&allocator, 20); | ||||||
|  |   result              = result && (ptr != nullptr); | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
							
								
								
									
										112
									
								
								tests/arena/test_arena.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								tests/arena/test_arena.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | #include "test_arena.h" | ||||||
|  | #include "wapp.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #define ARENA_CAPACITY KB(16) | ||||||
|  |  | ||||||
|  | internal Arena *arena = nullptr; | ||||||
|  | internal i32 count    = 20; | ||||||
|  | internal i32 *array   = nullptr; | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_init(void) { | ||||||
|  |   bool result = wapp_mem_arena_init(&arena, ARENA_CAPACITY); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) { | ||||||
|  |   Arena *large_arena = nullptr; | ||||||
|  |   u64 capacity       = GB(512); | ||||||
|  |   bool result        = wapp_mem_arena_init(&large_arena, capacity); | ||||||
|  |   if (result) { | ||||||
|  |     wapp_mem_arena_destroy(&large_arena); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) { | ||||||
|  |   array       = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32)); | ||||||
|  |   bool result = array != nullptr; | ||||||
|  |  | ||||||
|  |   for (i32 i = 0; i < count; ++i) { | ||||||
|  |     array[i] = i * 10; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_alloc_fails_when_over_capacity(void) { | ||||||
|  |   u8 *bytes   = (u8 *)wapp_mem_arena_alloc(arena, ARENA_CAPACITY * 2); | ||||||
|  |   bool result = bytes == nullptr; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_realloc_bigger_size(void) { | ||||||
|  |   u64 old_count = 10; | ||||||
|  |   u64 new_count = 20; | ||||||
|  |   i32 *bytes    = (i32 *)wapp_mem_arena_alloc(arena, old_count * sizeof(i32)); | ||||||
|  |  | ||||||
|  |   for (u64 i = 0; i < old_count; ++i) { | ||||||
|  |     bytes[i] = (i32)i; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   i32 *new_bytes = (i32 *)wapp_mem_arena_realloc(arena, bytes, old_count * sizeof(i32), new_count * sizeof(i32)); | ||||||
|  |   if (!new_bytes) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (u64 i = 0; i < new_count; ++i) { | ||||||
|  |     if (i < old_count && new_bytes[i] != bytes[i]) { | ||||||
|  |       return wapp_tester_result(false); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_realloc_smaller_size(void) { | ||||||
|  |   u64 old_count = 10; | ||||||
|  |   u64 new_count = 5; | ||||||
|  |   i32 *bytes    = (i32 *)wapp_mem_arena_alloc(arena, old_count * sizeof(i32)); | ||||||
|  |  | ||||||
|  |   for (u64 i = 0; i < old_count; ++i) { | ||||||
|  |     bytes[i] = (i32)i; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   i32 *new_bytes = (i32 *)wapp_mem_arena_realloc(arena, bytes, old_count * sizeof(i32), new_count * sizeof(i32)); | ||||||
|  |   if (!new_bytes) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (u64 i = 0; i < new_count; ++i) { | ||||||
|  |     if (i < new_count && new_bytes[i] != bytes[i]) { | ||||||
|  |       return wapp_tester_result(false); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_clear(void) { | ||||||
|  |   wapp_mem_arena_clear(arena); | ||||||
|  |   bool result = true; | ||||||
|  |  | ||||||
|  |   for (i32 i = 0; i < count; ++i) { | ||||||
|  |     if (array[i] != 0) { | ||||||
|  |       result = false; | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_arena_destroy(void) { | ||||||
|  |   wapp_mem_arena_destroy(&arena); | ||||||
|  |   bool result = arena == nullptr; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
							
								
								
									
										274
									
								
								tests/array/test_i32_array.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								tests/array/test_i32_array.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | |||||||
|  | #include "test_i32_array.h" | ||||||
|  | #include "wapp.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   I32Array array = wapp_i32_array(1, 2, 3, 4, 5, 6, 7); | ||||||
|  |   result = array.count == 7 && array.capacity == 16; | ||||||
|  |  | ||||||
|  |   i32 *item; | ||||||
|  |   u64 count    = array.count; | ||||||
|  |   u64 index    = 0; | ||||||
|  |   bool running = true; | ||||||
|  |   while (running) { | ||||||
|  |       item   = wapp_i32_array_get(&array, index); | ||||||
|  |       result = result && item && (*item == (i32)(index + 1)); | ||||||
|  |  | ||||||
|  |       ++index; | ||||||
|  |       running = index < count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_with_capacity(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   I32Array array = wapp_i32_array_with_capacity(64); | ||||||
|  |   result = array.count == 0 && array.capacity == 64; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_get(void) { | ||||||
|  |   bool result = true; | ||||||
|  |  | ||||||
|  |   I32Array array = wapp_i32_array(0, 1, 2, 3, 4, 5, 6, 7, 8); | ||||||
|  |  | ||||||
|  |   i32 *item; | ||||||
|  |   u64 count    = array.count; | ||||||
|  |   u64 index    = 0; | ||||||
|  |   bool running = true; | ||||||
|  |   while (running) { | ||||||
|  |     item   = wapp_i32_array_get(&array, index); | ||||||
|  |     result = result && item && (*item == (i32)index); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_set(void) { | ||||||
|  |   bool result = true; | ||||||
|  |  | ||||||
|  |   I32Array array = wapp_i32_array(0, 1, 2, 3, 4, 5, 6, 7, 8); | ||||||
|  |  | ||||||
|  |   i32 *item; | ||||||
|  |   u64 count    = array.count; | ||||||
|  |   u64 index    = 0; | ||||||
|  |   bool running = true; | ||||||
|  |   while (running) { | ||||||
|  |     i32 num = (i32)(index * 2); | ||||||
|  |     wapp_i32_array_set(&array, index, &num); | ||||||
|  |     item   = wapp_i32_array_get(&array, index); | ||||||
|  |     result = result && item && (*item == (i32)(index * 2)); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_append_capped(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   I32Array array = wapp_i32_array_with_capacity(64); | ||||||
|  |   i32 item1 = 10; | ||||||
|  |   wapp_i32_array_append_capped(&array, &item1); | ||||||
|  |  | ||||||
|  |   result = array.count == 1; | ||||||
|  |   i32 *item = wapp_i32_array_get(&array, 0); | ||||||
|  |   result = result && item && *item == 10; | ||||||
|  |  | ||||||
|  |   array = wapp_i32_array(1); | ||||||
|  |   i32 item2 = 10; | ||||||
|  |   wapp_i32_array_append_capped(&array, &item2); | ||||||
|  |  | ||||||
|  |   result = result && array.count == 2; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_extend_capped(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   I32Array array1 = wapp_i32_array(1, 2, 3, 4); | ||||||
|  |   I32Array array2 = wapp_i32_array(10, 20); | ||||||
|  |  | ||||||
|  |   result = array1.count == 4 && array2.count == 2; | ||||||
|  |  | ||||||
|  |   wapp_i32_array_extend_capped(&array1, &array2); | ||||||
|  |  | ||||||
|  |   result = result && array1.count == 6; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_clear(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   I32Array array = wapp_i32_array(0, 1, 2, 3, 4, 5, 6, 7, 8); | ||||||
|  |   result = array.count == 9; | ||||||
|  |  | ||||||
|  |   wapp_i32_array_clear(&array); | ||||||
|  |  | ||||||
|  |   result = result && array.count == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_pop(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   I32Array array1 = wapp_i32_array(0, 1, 2, 3, 4, 5, 6, 7, 8); | ||||||
|  |   I32Array array2 = wapp_i32_array_with_capacity(32); | ||||||
|  |  | ||||||
|  |   i32 item1 = wapp_i32_array_pop(&array1); | ||||||
|  |   i32 item2 = wapp_i32_array_pop(&array2); | ||||||
|  |  | ||||||
|  |   result = item1 == 8 && item2 == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_copy_capped(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   I32Array src  = wapp_i32_array(1, 2, 3, 4, 5); | ||||||
|  |   I32Array dst1 = wapp_i32_array(1, 2, 3, 4, 5, 6); | ||||||
|  |   I32Array dst2 = wapp_i32_array(1, 2); | ||||||
|  |  | ||||||
|  |   u64 expected_count = 5; | ||||||
|  |   wapp_i32_array_copy_capped(&src, &dst1); | ||||||
|  |   result = dst1.count == expected_count; | ||||||
|  |  | ||||||
|  |   u64 index    = 0; | ||||||
|  |   bool running = true; | ||||||
|  |   while (running) { | ||||||
|  |     result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(&dst1, index)); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < expected_count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   expected_count = 4; | ||||||
|  |   wapp_i32_array_copy_capped(&src, &dst2); | ||||||
|  |   result = result && dst2.count == expected_count; | ||||||
|  |  | ||||||
|  |   index   = 0; | ||||||
|  |   running = true; | ||||||
|  |   while (running) { | ||||||
|  |     result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(&dst2, index)); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < expected_count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_alloc_capacity(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); | ||||||
|  |   u64 capacity        = 32; | ||||||
|  |   I32Array *array     = wapp_i32_array_alloc_capacity(&allocator, capacity); | ||||||
|  |  | ||||||
|  |   result = array && array->capacity == capacity; | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_append_alloc(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); | ||||||
|  |   I32Array array1     = wapp_i32_array(1, 2, 3, 4, 5, 6, 7, 8); | ||||||
|  |   I32Array array2     = wapp_i32_array(1, 2); | ||||||
|  |  | ||||||
|  |   i32 num = 10; | ||||||
|  |   I32Array *arr_ptr = wapp_i32_array_append_alloc(&allocator, &array1, &num); | ||||||
|  |   result = arr_ptr == &array1; | ||||||
|  |  | ||||||
|  |   u64 count    = 4; | ||||||
|  |   u64 index    = 0; | ||||||
|  |   bool running = true; | ||||||
|  |   while (running) { | ||||||
|  |     i32 num = (i32)index; | ||||||
|  |     arr_ptr = wapp_i32_array_append_alloc(&allocator, &array2, &num); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < count; | ||||||
|  |   } | ||||||
|  |   result = result && arr_ptr != &array2; | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_extend_alloc(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); | ||||||
|  |   I32Array array1     = wapp_i32_array(1, 2, 3, 4, 5, 6, 7, 8); | ||||||
|  |   I32Array array2     = wapp_i32_array(1, 2); | ||||||
|  |   I32Array array3     = wapp_i32_array(1, 2, 3, 4); | ||||||
|  |  | ||||||
|  |   I32Array *arr_ptr = wapp_i32_array_extend_alloc(&allocator, &array1, &array3); | ||||||
|  |   result = arr_ptr == &array1; | ||||||
|  |  | ||||||
|  |   arr_ptr = wapp_i32_array_extend_alloc(&allocator, &array2, &array3); | ||||||
|  |   result  = result && arr_ptr != &array2; | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_i32_array_copy_alloc(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); | ||||||
|  |   I32Array src        = wapp_i32_array(1, 2, 3, 4, 5); | ||||||
|  |   I32Array dst1       = wapp_i32_array(1, 2, 3, 4, 5, 6); | ||||||
|  |   I32Array dst2       = wapp_i32_array(1, 2); | ||||||
|  |   I32Array *array_ptr = nullptr; | ||||||
|  |  | ||||||
|  |   u64 expected_count = 5; | ||||||
|  |   array_ptr = wapp_i32_array_copy_alloc(&allocator, &src, &dst1); | ||||||
|  |   result = array_ptr->count == expected_count && array_ptr == &dst1; | ||||||
|  |  | ||||||
|  |   u64 index    = 0; | ||||||
|  |   bool running = true; | ||||||
|  |   while (running) { | ||||||
|  |     result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(array_ptr, index)); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < expected_count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   expected_count = 5; | ||||||
|  |   array_ptr = wapp_i32_array_copy_alloc(&allocator, &src, &dst2); | ||||||
|  |   result = result && array_ptr->count == expected_count && array_ptr != &dst2; | ||||||
|  |  | ||||||
|  |   index   = 0; | ||||||
|  |   running = true; | ||||||
|  |   while (running) { | ||||||
|  |     result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(array_ptr, index)); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < expected_count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
							
								
								
									
										205
									
								
								tests/cpath/test_cpath.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								tests/cpath/test_cpath.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,205 @@ | |||||||
|  | #include "test_cpath.h" | ||||||
|  | #include "wapp.h" | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #define MAIN_BUF_SIZE 4096 | ||||||
|  | #define TMP_BUF_SIZE  1024 | ||||||
|  |  | ||||||
|  | TestFuncResult test_cpath_join_path(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); | ||||||
|  |   Str8 out      = wapp_str8_buf(MAIN_BUF_SIZE); | ||||||
|  |   Str8 tmp      = wapp_str8_buf(TMP_BUF_SIZE); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); | ||||||
|  |   wapp_str8_format(&tmp, "%c", PATH_SEP); | ||||||
|  |  | ||||||
|  |   Str8List parts = {}; | ||||||
|  |  | ||||||
|  |   Str8Node tmp_node = wapp_str8_node_from_str8(tmp); | ||||||
|  |   wapp_str8_list_push_back(&parts, &tmp_node); | ||||||
|  |  | ||||||
|  |   Str8Node home_node = wapp_str8_node_from_cstr("home"); | ||||||
|  |   wapp_str8_list_push_back(&parts, &home_node); | ||||||
|  |  | ||||||
|  |   Str8Node user_node = wapp_str8_node_from_cstr("abdelrahman"); | ||||||
|  |   wapp_str8_list_push_back(&parts, &user_node); | ||||||
|  |  | ||||||
|  |   Str8Node docs_node = wapp_str8_node_from_cstr("Documents"); | ||||||
|  |   wapp_str8_list_push_back(&parts, &docs_node); | ||||||
|  |  | ||||||
|  |   wapp_cpath_join_path(&out, &parts); | ||||||
|  |   result = wapp_str8_equal(&out, &expected); | ||||||
|  |  | ||||||
|  |   wapp_str8_list_pop_front(&parts); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); | ||||||
|  |  | ||||||
|  |   wapp_cpath_join_path(&out, &parts); | ||||||
|  |   result = result && wapp_str8_equal(&out, &expected); | ||||||
|  |  | ||||||
|  |   Str8RO str = wapp_str8_lit_ro("home"); | ||||||
|  |   wapp_str8_concat_capped(&tmp, &str); | ||||||
|  |   wapp_str8_list_pop_front(&parts); | ||||||
|  |  | ||||||
|  |   Str8Node tmp_node_2 = wapp_str8_node_from_str8(tmp); | ||||||
|  |   wapp_str8_list_push_front(&parts, &tmp_node_2); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); | ||||||
|  |  | ||||||
|  |   wapp_cpath_join_path(&out, &parts); | ||||||
|  |   result = result && wapp_str8_equal(&out, &expected); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&tmp, "home%c", PATH_SEP); | ||||||
|  |   wapp_str8_list_pop_front(&parts); | ||||||
|  |  | ||||||
|  |   Str8Node home_node_2 = wapp_str8_node_from_cstr("home"); | ||||||
|  |   wapp_str8_list_push_front(&parts, &home_node_2); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); | ||||||
|  |  | ||||||
|  |   wapp_cpath_join_path(&out, &parts); | ||||||
|  |   result = result && wapp_str8_equal(&out, &expected); | ||||||
|  |  | ||||||
|  |   wapp_str8_list_empty(&parts); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&tmp, "%chome", PATH_SEP); | ||||||
|  |  | ||||||
|  |   Str8Node tmp_node_3 = wapp_str8_node_from_str8(tmp); | ||||||
|  |   wapp_str8_list_push_back(&parts, &tmp_node_3); | ||||||
|  |  | ||||||
|  |   Str8Node empty_node = wapp_str8_node_from_cstr(""); | ||||||
|  |   wapp_str8_list_push_back(&parts, &empty_node); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&expected, "%chome", PATH_SEP); | ||||||
|  |  | ||||||
|  |   wapp_cpath_join_path(&out, &parts); | ||||||
|  |   result = result && wapp_str8_equal(&out, &expected); | ||||||
|  |  | ||||||
|  |   wapp_str8_list_pop_front(&parts); | ||||||
|  |  | ||||||
|  |   Str8Node empty_node_2 = wapp_str8_node_from_cstr(""); | ||||||
|  |   wapp_str8_list_push_back(&parts, &empty_node_2); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&expected, "%s", ""); | ||||||
|  |  | ||||||
|  |   wapp_cpath_join_path(&out, &parts); | ||||||
|  |   result = result && wapp_str8_equal(&out, &expected); | ||||||
|  |  | ||||||
|  |   wapp_str8_list_pop_back(&parts); | ||||||
|  |  | ||||||
|  |   Str8Node home_node_3 = wapp_str8_node_from_cstr("home"); | ||||||
|  |   wapp_str8_list_push_back(&parts, &home_node_3); | ||||||
|  |  | ||||||
|  |   wapp_str8_copy_cstr_capped(&expected, "home"); | ||||||
|  |  | ||||||
|  |   wapp_cpath_join_path(&out, &parts); | ||||||
|  |   result = result && wapp_str8_equal(&out, &expected); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_cpath_dirname(void) { | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(MB(8)); | ||||||
|  |   if (wapp_mem_allocator_invalid(&arena)) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   bool result; | ||||||
|  |   Str8 *output = nullptr; | ||||||
|  |  | ||||||
|  |   Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); | ||||||
|  |   Str8 tmp      = wapp_str8_buf(TMP_BUF_SIZE); | ||||||
|  |  | ||||||
|  |   // CASE 1 | ||||||
|  |   wapp_str8_format(&tmp, "%c", PATH_SEP); | ||||||
|  |   wapp_str8_format(&expected, "%c", PATH_SEP); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirname(&arena, &tmp); | ||||||
|  |   result = output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 2 | ||||||
|  |   wapp_str8_format(&expected, "%s", "."); | ||||||
|  |  | ||||||
|  |   Str8 path = wapp_str8_lit("home"); | ||||||
|  |   output = wapp_cpath_dirname(&arena, &path); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 3 | ||||||
|  |   path = wapp_str8_lit(""); | ||||||
|  |   output = wapp_cpath_dirname(&arena, &path); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 4 | ||||||
|  |   wapp_str8_format(&tmp, "%chome%ctest", PATH_SEP, PATH_SEP); | ||||||
|  |   wapp_str8_format(&expected, "%chome", PATH_SEP); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirname(&arena, &tmp); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 5 | ||||||
|  |   wapp_str8_format(&tmp, "%chome%ctest%c", PATH_SEP, PATH_SEP, PATH_SEP); | ||||||
|  |   wapp_str8_format(&expected, "%chome", PATH_SEP); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirname(&arena, &tmp); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_cpath_dirup(void) { | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(MB(8)); | ||||||
|  |   if (wapp_mem_allocator_invalid(&arena)) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   bool result; | ||||||
|  |   Str8 *output = nullptr; | ||||||
|  |  | ||||||
|  |   Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); | ||||||
|  |   Str8 tmp      = wapp_str8_buf(TMP_BUF_SIZE); | ||||||
|  |  | ||||||
|  |   // CASE 1 | ||||||
|  |   wapp_str8_format(&tmp, "%c", PATH_SEP); | ||||||
|  |   wapp_str8_format(&expected, "%c", PATH_SEP); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirup(&arena, &tmp, 3); | ||||||
|  |   result = output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 2 | ||||||
|  |   wapp_str8_format(&tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); | ||||||
|  |   wapp_str8_format(&expected, "%c", PATH_SEP); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirup(&arena, &tmp, 3); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 3 | ||||||
|  |   wapp_str8_format(&tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); | ||||||
|  |   wapp_str8_copy_cstr_capped(&expected, "."); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirup(&arena, &tmp, 3); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 4 | ||||||
|  |   wapp_str8_format(&tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); | ||||||
|  |   wapp_str8_format(&expected, "%chome", PATH_SEP); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirup(&arena, &tmp, 2); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   // CASE 5 | ||||||
|  |   wapp_str8_format(&tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); | ||||||
|  |   wapp_str8_copy_cstr_capped(&expected, "home"); | ||||||
|  |  | ||||||
|  |   output = wapp_cpath_dirup(&arena, &tmp, 2); | ||||||
|  |   result = result && output != nullptr && wapp_str8_equal(output, &expected); | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								tests/shell_commander/test_shell_commander.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								tests/shell_commander/test_shell_commander.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | #include "test_shell_commander.h" | ||||||
|  | #include "wapp.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | TestFuncResult test_commander_cmd_success(void) { | ||||||
|  |   Str8List cmd  = {}; | ||||||
|  |   Str8Node echo = wapp_str8_node_from_cstr("echo"); | ||||||
|  |   Str8Node msg  = wapp_str8_node_from_cstr("hello world"); | ||||||
|  |   wapp_str8_list_push_back(&cmd, &echo); | ||||||
|  |   wapp_str8_list_push_back(&cmd, &msg); | ||||||
|  |  | ||||||
|  |   CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, nullptr, &cmd); | ||||||
|  |   bool succeeded   = result.exited && result.exit_code == EXIT_SUCCESS && | ||||||
|  |                      result.error == SHELL_ERR_NO_ERROR; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(succeeded); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_commander_cmd_failure(void) { | ||||||
|  |   Str8List cmd  = {}; | ||||||
|  |   Str8Node grep = wapp_str8_node_from_cstr("grep"); | ||||||
|  |   wapp_str8_list_push_back(&cmd, &grep); | ||||||
|  |  | ||||||
|  |   CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, nullptr, &cmd); | ||||||
|  |   bool failed      = result.exited && result.exit_code != EXIT_SUCCESS && | ||||||
|  |                      result.error == SHELL_ERR_NO_ERROR; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(failed); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_commander_cmd_out_buf_success(void) { | ||||||
|  |   Str8 buf          = wapp_str8_buf(64); | ||||||
|  |   Str8 expected     = wapp_str8_buf(64); | ||||||
|  |   char msg[]        = "hello world"; | ||||||
|  |   wapp_str8_copy_cstr_capped(&expected, msg); | ||||||
|  |  | ||||||
|  |   Str8List cmd  = {}; | ||||||
|  |   Str8Node echo = wapp_str8_node_from_cstr("echo"); | ||||||
|  |   Str8Node arg  = wapp_str8_node_from_cstr(msg); | ||||||
|  |   wapp_str8_list_push_back(&cmd, &echo); | ||||||
|  |   wapp_str8_list_push_back(&cmd, &arg); | ||||||
|  |  | ||||||
|  |   CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); | ||||||
|  |   bool succeeded   = result.exited && result.exit_code == EXIT_SUCCESS && | ||||||
|  |                      result.error == SHELL_ERR_NO_ERROR && wapp_str8_equal_to_count(&buf, &expected, strlen(msg)); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(succeeded); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_commander_cmd_out_buf_failure(void) { | ||||||
|  |   Str8 buf         = wapp_str8_buf(4); | ||||||
|  |   Str8 expected    = wapp_str8_buf(64); | ||||||
|  |   char msg[]       = "hello world"; | ||||||
|  |   wapp_str8_copy_cstr_capped(&expected, msg); | ||||||
|  |  | ||||||
|  |   Str8List cmd  = {}; | ||||||
|  |   Str8Node echo = wapp_str8_node_from_cstr("echo"); | ||||||
|  |   Str8Node arg  = wapp_str8_node_from_cstr(msg); | ||||||
|  |   wapp_str8_list_push_back(&cmd, &echo); | ||||||
|  |   wapp_str8_list_push_back(&cmd, &arg); | ||||||
|  |  | ||||||
|  |   CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); | ||||||
|  |   bool failed      = !result.exited && result.exit_code != EXIT_SUCCESS && | ||||||
|  |                      result.error == SHELL_ERR_OUT_BUF_FULL && !wapp_str8_equal(&buf, &expected); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(failed); | ||||||
|  | } | ||||||
							
								
								
									
										614
									
								
								tests/str8/test_str8.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										614
									
								
								tests/str8/test_str8.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,614 @@ | |||||||
|  | #include "test_str8.h" | ||||||
|  | #include "wapp.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #define ARRLEN(ARR) (sizeof(ARR) / sizeof(ARR[0])) | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_lit(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("Hello world"); | ||||||
|  |   result  = s1.capacity == 22 && s1.capacity != s1.size; | ||||||
|  |  | ||||||
|  |   Str8 s2 = wapp_str8_lit("Different strokes for different folks"); | ||||||
|  |   result  = result && s2.capacity == 74 && s2.capacity != s2.size; | ||||||
|  |  | ||||||
|  |   Str8 s3 = wapp_str8_lit("Discretion is the better part of valour"); | ||||||
|  |   result  = result && s3.capacity == 78 && s3.capacity != s3.size; | ||||||
|  |  | ||||||
|  |   Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view"); | ||||||
|  |   result  = result && s4.capacity == 76 && s4.capacity != s4.size; | ||||||
|  |  | ||||||
|  |   Str8 s5 = wapp_str8_lit("Do as I say, not as I do"); | ||||||
|  |   result  = result && s5.capacity == 48 && s5.capacity != s5.size; | ||||||
|  |  | ||||||
|  |   Str8 s6 = wapp_str8_lit("Do as you would be done by"); | ||||||
|  |   result  = result && s6.capacity == 52 && s6.capacity != s6.size; | ||||||
|  |  | ||||||
|  |   Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you"); | ||||||
|  |   result  = result && s7.capacity == 94 && s7.capacity != s7.size; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_lit_ro(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8RO s1 = wapp_str8_lit_ro("Hello world"); | ||||||
|  |   result    = s1.capacity == 11 && s1.capacity == s1.size; | ||||||
|  |  | ||||||
|  |   Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks"); | ||||||
|  |   result    = result && s2.capacity == 37 && s2.capacity == s2.size; | ||||||
|  |  | ||||||
|  |   Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour"); | ||||||
|  |   result    = result && s3.capacity == 39 && s3.capacity == s3.size; | ||||||
|  |  | ||||||
|  |   Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view"); | ||||||
|  |   result    = result && s4.capacity == 38 && s4.capacity == s4.size; | ||||||
|  |  | ||||||
|  |   Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do"); | ||||||
|  |   result    = result && s5.capacity == 24 && s5.capacity == s5.size; | ||||||
|  |  | ||||||
|  |   Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by"); | ||||||
|  |   result    = result && s6.capacity == 26 && s6.capacity == s6.size; | ||||||
|  |  | ||||||
|  |   Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you"); | ||||||
|  |   result    = result && s7.capacity == 47 && s7.capacity == s7.size; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_buf(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_buf(1024); | ||||||
|  |   result  = s1.capacity == 1024 && s1.size == 0; | ||||||
|  |  | ||||||
|  |   Str8 s2 = wapp_str8_buf(2048); | ||||||
|  |   result  = result && s2.capacity == 2048 && s2.size == 0; | ||||||
|  |  | ||||||
|  |   Str8 s3 = wapp_str8_buf(4096); | ||||||
|  |   result  = result && s3.capacity == 4096 && s3.size == 0; | ||||||
|  |  | ||||||
|  |   Str8 s4 = wapp_str8_buf(8192); | ||||||
|  |   result  = result && s4.capacity == 8192 && s4.size == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_alloc_buf(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |   if (wapp_mem_allocator_invalid(&allocator)) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   u64 capacity = 4096; | ||||||
|  |  | ||||||
|  |   Str8 *s = wapp_str8_alloc_buf(&allocator, capacity); | ||||||
|  |   if (!s) { | ||||||
|  |     result = false; | ||||||
|  |     wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |     return wapp_tester_result(result); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   result  = s->capacity == capacity; | ||||||
|  |  | ||||||
|  |   const char *cstr = "My name is Abdelrahman"; | ||||||
|  |   wapp_str8_copy_cstr_capped(s, cstr); | ||||||
|  |  | ||||||
|  |   result = result && s->capacity == capacity && s->size == strlen(cstr) && memcmp(s->buf, cstr, s->size) == 0; | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_alloc_cstr(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |   if (wapp_mem_allocator_invalid(&allocator)) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const char *str  = "Abdelrahman"; | ||||||
|  |   u64 length = strlen(str); | ||||||
|  |   Str8 *s    = wapp_str8_alloc_cstr(&allocator, str); | ||||||
|  |   if (!s) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   result = s->size == length && memcmp(s->buf, str, length) == 0; | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_alloc_str8(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |   if (wapp_mem_allocator_invalid(&allocator)) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Str8 str = wapp_str8_lit("Abdelrahman"); | ||||||
|  |   Str8 *s  = wapp_str8_alloc_str8(&allocator, &str); | ||||||
|  |   if (!s) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   result = wapp_str8_equal(s, &str); | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_alloc_substr(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |   if (wapp_mem_allocator_invalid(&allocator)) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Str8 str = wapp_str8_lit("Abdelrahman"); | ||||||
|  |   Str8 *s  = wapp_str8_alloc_substr(&allocator, &str, 3, 8); | ||||||
|  |   if (!s) { | ||||||
|  |     return wapp_tester_result(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   result = s->size == 5 && memcmp(s->buf, "elrah", s->size) == 0; | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&allocator); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_get_index_within_bounds(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8RO s1 = wapp_str8_lit_ro("Hello world"); | ||||||
|  |   result    = wapp_str8_get(&s1, 4) == 'o'; | ||||||
|  |  | ||||||
|  |   Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks"); | ||||||
|  |   result    = result && wapp_str8_get(&s2, 0) == 'D'; | ||||||
|  |  | ||||||
|  |   Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour"); | ||||||
|  |   result    = result && wapp_str8_get(&s3, 13) == ' '; | ||||||
|  |  | ||||||
|  |   Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view"); | ||||||
|  |   result    = result && wapp_str8_get(&s4, 20) == 'n'; | ||||||
|  |  | ||||||
|  |   Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do"); | ||||||
|  |   result    = result && wapp_str8_get(&s5, 11) == ','; | ||||||
|  |  | ||||||
|  |   Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by"); | ||||||
|  |   result    = result && wapp_str8_get(&s6, 25) == 'y'; | ||||||
|  |  | ||||||
|  |   Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you"); | ||||||
|  |   result    = result && wapp_str8_get(&s7, 16) == 's'; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_get_index_out_of_bounds(void) { | ||||||
|  |   Str8 s1      = wapp_str8_lit("Hello world"); | ||||||
|  |   bool result  = wapp_str8_get(&s1, 20) == '\0'; | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_set(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("Hello world"); | ||||||
|  |   wapp_str8_set(&s1, 4, 'f'); | ||||||
|  |   result  = wapp_str8_get(&s1, 4) == 'f'; | ||||||
|  |  | ||||||
|  |   Str8 s2 = wapp_str8_lit("Different strokes for different folks"); | ||||||
|  |   wapp_str8_set(&s2, 0, 'A'); | ||||||
|  |   result  = result && wapp_str8_get(&s2, 0) == 'A'; | ||||||
|  |  | ||||||
|  |   Str8 s3 = wapp_str8_lit("Discretion is the better part of valour"); | ||||||
|  |   wapp_str8_set(&s3, 13, 'u'); | ||||||
|  |   result  = result && wapp_str8_get(&s3, 13) == 'u'; | ||||||
|  |  | ||||||
|  |   Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view"); | ||||||
|  |   wapp_str8_set(&s4, 20, 'R'); | ||||||
|  |   result  = result && wapp_str8_get(&s4, 20) == 'R'; | ||||||
|  |  | ||||||
|  |   Str8 s5 = wapp_str8_lit("Do as I say, not as I do"); | ||||||
|  |   wapp_str8_set(&s5, 11, '.'); | ||||||
|  |   result  = result && wapp_str8_get(&s5, 11) == '.'; | ||||||
|  |  | ||||||
|  |   Str8 s6 = wapp_str8_lit("Do as you would be done by"); | ||||||
|  |   wapp_str8_set(&s6, 25, 'w'); | ||||||
|  |   result  = result && wapp_str8_get(&s6, 25) == 'w'; | ||||||
|  |  | ||||||
|  |   Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you"); | ||||||
|  |   wapp_str8_set(&s7, 16, 'i'); | ||||||
|  |   result  = result && wapp_str8_get(&s7, 16) == 'i'; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_push_back(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 expected = wapp_str8_lit("Abdelrahman"); | ||||||
|  |   Str8 buf      = wapp_str8_buf(64); | ||||||
|  |   wapp_str8_push_back(&buf, 'A'); | ||||||
|  |   wapp_str8_push_back(&buf, 'b'); | ||||||
|  |   wapp_str8_push_back(&buf, 'd'); | ||||||
|  |   wapp_str8_push_back(&buf, 'e'); | ||||||
|  |   wapp_str8_push_back(&buf, 'l'); | ||||||
|  |   wapp_str8_push_back(&buf, 'r'); | ||||||
|  |   wapp_str8_push_back(&buf, 'a'); | ||||||
|  |   wapp_str8_push_back(&buf, 'h'); | ||||||
|  |   wapp_str8_push_back(&buf, 'm'); | ||||||
|  |   wapp_str8_push_back(&buf, 'a'); | ||||||
|  |   wapp_str8_push_back(&buf, 'n'); | ||||||
|  |  | ||||||
|  |   result = wapp_str8_equal(&buf, &expected); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_equal(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8RO s1 = wapp_str8_lit_ro("hello"); | ||||||
|  |   Str8RO s2 = wapp_str8_lit_ro("hell"); | ||||||
|  |   Str8RO s3 = wapp_str8_lit_ro("hello"); | ||||||
|  |   Str8RO s4 = wapp_str8_lit_ro("goodbye"); | ||||||
|  |  | ||||||
|  |   result = wapp_str8_equal(&s1, &s2) == false; | ||||||
|  |   result = result && wapp_str8_equal(&s1, &s3) == true; | ||||||
|  |   result = result && wapp_str8_equal(&s1, &s4) == false; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_slice(void) { | ||||||
|  |   bool result; | ||||||
|  |   Str8 s = wapp_str8_lit("Different strokes for different folks"); | ||||||
|  |  | ||||||
|  |   Str8RO sub1 = wapp_str8_slice(&s, 3, 9); | ||||||
|  |   result = sub1.size == 6 && sub1.capacity == 6; | ||||||
|  |  | ||||||
|  |   Str8RO sub2 = wapp_str8_slice(&s, 18, 21); | ||||||
|  |   result = result && sub2.size == 3 && sub2.capacity == 3; | ||||||
|  |  | ||||||
|  |   Str8RO sub3 = wapp_str8_slice(&s, 5, 1); | ||||||
|  |   result = result && sub3.size == 0 && sub3.capacity == 0; | ||||||
|  |  | ||||||
|  |   Str8RO sub4 = wapp_str8_slice(&s, 70, 80); | ||||||
|  |   result = result && sub4.size == 0 && sub4.capacity == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_alloc_concat(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |  | ||||||
|  |   Str8 str     = wapp_str8_lit("Hello world"); | ||||||
|  |   Str8 suffix1 = wapp_str8_lit(" from me."); | ||||||
|  |   Str8 suffix2 = wapp_str8_lit(" This is my code."); | ||||||
|  |   Str8 concat1 = wapp_str8_lit("Hello world from me."); | ||||||
|  |   Str8 concat2 = wapp_str8_lit("Hello world from me. This is my code."); | ||||||
|  |  | ||||||
|  |   Str8 *output; | ||||||
|  |  | ||||||
|  |   output = wapp_str8_alloc_concat(&arena, &str, &suffix1); | ||||||
|  |   result = output->size == concat1.size && wapp_str8_equal(output, &concat1); | ||||||
|  |  | ||||||
|  |   output = wapp_str8_alloc_concat(&arena, output, &suffix2); | ||||||
|  |   result = result && output->size == concat2.size && wapp_str8_equal(output, &concat2); | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_concat_capped(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 str     = wapp_str8_lit("Hello world"); | ||||||
|  |   Str8 suffix1 = wapp_str8_lit(" from me."); | ||||||
|  |   Str8 suffix2 = wapp_str8_lit(" This is my code."); | ||||||
|  |   Str8 concat1 = wapp_str8_lit("Hello world from me."); | ||||||
|  |   Str8 concat2 = wapp_str8_lit("Hello world from me. T"); | ||||||
|  |  | ||||||
|  |   wapp_str8_concat_capped(&str, &suffix1); | ||||||
|  |   result = str.size == concat1.size && wapp_str8_equal(&str, &concat1); | ||||||
|  |  | ||||||
|  |   wapp_str8_concat_capped(&str, &suffix2); | ||||||
|  |   result = result && str.size == concat2.size && wapp_str8_equal(&str, &concat2); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_copy_cstr_capped(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 buf         = wapp_str8_buf(32); | ||||||
|  |   const char *src1 = "Hello world"; | ||||||
|  |   const char *src2 = "Hello world from the Wizard Apprentice standard library"; | ||||||
|  |   Str8RO src1_cp   = wapp_str8_lit_ro("Hello world"); | ||||||
|  |   Str8RO src2_cp   = wapp_str8_lit_ro("Hello world from the Wizard Appr"); | ||||||
|  |  | ||||||
|  |   wapp_str8_copy_cstr_capped(&buf, src1); | ||||||
|  |   result = buf.size == src1_cp.size && wapp_str8_equal(&buf, &src1_cp); | ||||||
|  |  | ||||||
|  |   wapp_str8_copy_cstr_capped(&buf, src2); | ||||||
|  |   result = result && buf.size == src2_cp.size && buf.size == buf.capacity && wapp_str8_equal(&buf, &src2_cp); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_copy_str8_capped(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 buf       = wapp_str8_buf(32); | ||||||
|  |   Str8RO src1    = wapp_str8_lit_ro("Hello world"); | ||||||
|  |   Str8RO src2    = wapp_str8_lit_ro("Hello world from the Wizard Apprentice standard library"); | ||||||
|  |   Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr"); | ||||||
|  |  | ||||||
|  |   wapp_str8_copy_str8_capped(&buf, &src1); | ||||||
|  |   result = buf.size == src1.size && wapp_str8_equal(&buf, &src1); | ||||||
|  |  | ||||||
|  |   wapp_str8_copy_str8_capped(&buf, &src2); | ||||||
|  |   result = result && buf.size < src2.size && buf.size == buf.capacity && wapp_str8_equal(&buf, &src2_cp); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_format(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 buf      = wapp_str8_buf(128); | ||||||
|  |   Str8 expected = wapp_str8_lit("My name is Abdelrahman and I am 35 years old"); | ||||||
|  |  | ||||||
|  |   wapp_str8_format(&buf, "My name is %s and I am %u years old", "Abdelrahman", 35); | ||||||
|  |  | ||||||
|  |   result = wapp_str8_equal(&buf, &expected); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_find(void) { | ||||||
|  |   bool result; | ||||||
|  |   Str8RO s = wapp_str8_lit("Do as I say, not as I do"); | ||||||
|  |  | ||||||
|  |   result = wapp_str8_find(&s, wapp_str8_lit_ro("d")) != -1; | ||||||
|  |   result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("not")) != -1); | ||||||
|  |   result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("as I say")) != -1); | ||||||
|  |  | ||||||
|  |   result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("f")) == -1); | ||||||
|  |   result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("hello")) == -1); | ||||||
|  |   result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("not sa I")) == -1); | ||||||
|  |   result = result && (wapp_str8_find(&s, wapp_str8_lit_ro("Do unto others as you would have them do to you")) == -1); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_rfind(void) { | ||||||
|  |   bool result; | ||||||
|  |   Str8RO s = wapp_str8_lit("Do as I say, not as I do"); | ||||||
|  |  | ||||||
|  |   result = wapp_str8_rfind(&s, wapp_str8_lit_ro("d")) != -1; | ||||||
|  |   result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("not")) != -1); | ||||||
|  |   result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("as I say")) != -1); | ||||||
|  |  | ||||||
|  |   result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("f")) == -1); | ||||||
|  |   result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("hello")) == -1); | ||||||
|  |   result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("not sa I")) == -1); | ||||||
|  |   result = result && (wapp_str8_rfind(&s, wapp_str8_lit_ro("Do unto others as you would have them do to you")) == -1); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_split(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |  | ||||||
|  |   Str8 str        = wapp_str8_lit("hello world from me"); | ||||||
|  |   Str8 delim1     = wapp_str8_lit(" "); | ||||||
|  |   Str8 delim2     = wapp_str8_lit("from"); | ||||||
|  |   Str8List *list1 = wapp_str8_split(&arena, &str, &delim1); | ||||||
|  |   Str8List *list2 = wapp_str8_split(&arena, &str, &delim2); | ||||||
|  |  | ||||||
|  |   Str8RO splits1[] = { | ||||||
|  |     wapp_str8_slice(&str, 0, 5), | ||||||
|  |     wapp_str8_slice(&str, 6, 11), | ||||||
|  |     wapp_str8_slice(&str, 12, 16), | ||||||
|  |     wapp_str8_slice(&str, 17, 19), | ||||||
|  |   }; | ||||||
|  |   Str8RO splits2[] = { | ||||||
|  |     wapp_str8_slice(&str, 0, 12), | ||||||
|  |     wapp_str8_slice(&str, 16, 19), | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   u64 index1    = 0; | ||||||
|  |   u64 count1    = ARRLEN(splits1); | ||||||
|  |   bool running1 = true; | ||||||
|  |  | ||||||
|  |   u64 index2    = 0; | ||||||
|  |   u64 count2    = ARRLEN(splits2); | ||||||
|  |   bool running2 = true; | ||||||
|  |  | ||||||
|  |   result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3; | ||||||
|  |   result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4; | ||||||
|  |  | ||||||
|  |   // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of | ||||||
|  |   // MSVC Spectre mitigation warnings | ||||||
|  |   while (running1) { | ||||||
|  |     Str8Node *node = wapp_str8_list_get(list1, index1); | ||||||
|  |     result = result && wapp_str8_equal(node->item, &(splits1[index1])); | ||||||
|  |  | ||||||
|  |     ++index1; | ||||||
|  |     running1 = index1 < count1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of | ||||||
|  |   // MSVC Spectre mitigation warnings | ||||||
|  |   while (running2) { | ||||||
|  |     Str8Node *node = wapp_str8_list_get(list2, index2); | ||||||
|  |     result = result && wapp_str8_equal(node->item, &(splits2[index2])); | ||||||
|  |  | ||||||
|  |     ++index2; | ||||||
|  |     running2 = index2 < count2; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_split_with_max(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |  | ||||||
|  |   Str8 str       = wapp_str8_lit("hello world from me"); | ||||||
|  |   Str8 delim     = wapp_str8_lit(" "); | ||||||
|  |   Str8List *list = wapp_str8_split_with_max(&arena, &str, &delim, 2); | ||||||
|  |  | ||||||
|  |   Str8RO splits[] = { | ||||||
|  |     wapp_str8_slice(&str, 0, 5), | ||||||
|  |     wapp_str8_slice(&str, 6, 11), | ||||||
|  |     wapp_str8_slice(&str, 12, 19), | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   u64 index    = 0; | ||||||
|  |   u64 count    = ARRLEN(splits); | ||||||
|  |   bool running = true; | ||||||
|  |  | ||||||
|  |   result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2; | ||||||
|  |  | ||||||
|  |   // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of | ||||||
|  |   // MSVC Spectre mitigation warnings | ||||||
|  |   while (running) { | ||||||
|  |     Str8Node *node = wapp_str8_list_get(list, index); | ||||||
|  |     result = result && wapp_str8_equal(node->item, &(splits[index])); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_rsplit(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |  | ||||||
|  |   Str8 str        = wapp_str8_lit("hello world from me"); | ||||||
|  |   Str8 delim1     = wapp_str8_lit(" "); | ||||||
|  |   Str8 delim2     = wapp_str8_lit("from"); | ||||||
|  |   Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1); | ||||||
|  |   Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2); | ||||||
|  |  | ||||||
|  |   Str8RO splits1[] = { | ||||||
|  |     wapp_str8_slice(&str, 0, 5), | ||||||
|  |     wapp_str8_slice(&str, 6, 11), | ||||||
|  |     wapp_str8_slice(&str, 12, 16), | ||||||
|  |     wapp_str8_slice(&str, 17, 19), | ||||||
|  |   }; | ||||||
|  |   Str8RO splits2[] = { | ||||||
|  |     wapp_str8_slice(&str, 0, 12), | ||||||
|  |     wapp_str8_slice(&str, 16, 19), | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   u64 index1    = 0; | ||||||
|  |   u64 count1    = ARRLEN(splits1); | ||||||
|  |   bool running1 = true; | ||||||
|  |  | ||||||
|  |   u64 index2    = 0; | ||||||
|  |   u64 count2    = ARRLEN(splits2); | ||||||
|  |   bool running2 = true; | ||||||
|  |  | ||||||
|  |   result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3; | ||||||
|  |   result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4; | ||||||
|  |  | ||||||
|  |   // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of | ||||||
|  |   // MSVC Spectre mitigation warnings | ||||||
|  |   while (running1) { | ||||||
|  |     Str8Node *node = wapp_str8_list_get(list1, index1); | ||||||
|  |     result = result && wapp_str8_equal(node->item, &(splits1[index1])); | ||||||
|  |  | ||||||
|  |     ++index1; | ||||||
|  |     running1 = index1 < count1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of | ||||||
|  |   // MSVC Spectre mitigation warnings | ||||||
|  |   while (running2) { | ||||||
|  |     Str8Node *node = wapp_str8_list_get(list2, index2); | ||||||
|  |     result = result && wapp_str8_equal(node->item, &(splits2[index2])); | ||||||
|  |  | ||||||
|  |     ++index2; | ||||||
|  |     running2 = index2 < count2; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_rsplit_with_max(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |  | ||||||
|  |   Str8 str       = wapp_str8_lit("hello world from me"); | ||||||
|  |   Str8 delim     = wapp_str8_lit(" "); | ||||||
|  |   Str8List *list = wapp_str8_rsplit_with_max(&arena, &str, &delim, 2); | ||||||
|  |  | ||||||
|  |   Str8RO splits[] = { | ||||||
|  |     wapp_str8_slice(&str, 0, 11), | ||||||
|  |     wapp_str8_slice(&str, 12, 16), | ||||||
|  |     wapp_str8_slice(&str, 17, 19), | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   u64 index    = 0; | ||||||
|  |   u64 count    = ARRLEN(splits); | ||||||
|  |   bool running = true; | ||||||
|  |  | ||||||
|  |   result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2; | ||||||
|  |  | ||||||
|  |   // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of | ||||||
|  |   // MSVC Spectre mitigation warnings | ||||||
|  |   while (running) { | ||||||
|  |     Str8Node *node = wapp_str8_list_get(list, index); | ||||||
|  |     result = result && wapp_str8_equal(node->item, &(splits[index])); | ||||||
|  |  | ||||||
|  |     ++index; | ||||||
|  |     running = index < count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_join(void) { | ||||||
|  |   bool result; | ||||||
|  |   Allocator arena = wapp_mem_arena_allocator_init(KB(100)); | ||||||
|  |  | ||||||
|  |   Str8 str        = wapp_str8_lit("hello world from me"); | ||||||
|  |   Str8 delim1     = wapp_str8_lit(" "); | ||||||
|  |   Str8 delim2     = wapp_str8_lit("from"); | ||||||
|  |   Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1); | ||||||
|  |   Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2); | ||||||
|  |   Str8 *join1     = wapp_str8_join(&arena, list1, &delim1); | ||||||
|  |   Str8 *join2     = wapp_str8_join(&arena, list2, &delim2); | ||||||
|  |  | ||||||
|  |   result = join1->size == str.size && wapp_str8_equal(join1, &str); | ||||||
|  |   result = result && join2->size == str.size && wapp_str8_equal(join2, &str); | ||||||
|  |  | ||||||
|  |   wapp_mem_arena_allocator_destroy(&arena); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
							
								
								
									
										271
									
								
								tests/str8/test_str8_list.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								tests/str8/test_str8_list.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,271 @@ | |||||||
|  | #include "test_str8_list.h" | ||||||
|  | #include "wapp.h" | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_get(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("1"); | ||||||
|  |   Str8 s2 = wapp_str8_lit("2"); | ||||||
|  |   Str8 s3 = wapp_str8_lit("3"); | ||||||
|  |   Str8 s4 = wapp_str8_lit("4"); | ||||||
|  |   Str8 s5 = wapp_str8_lit("5"); | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |   Str8Node n1   = { &s1, nullptr, nullptr }; | ||||||
|  |   Str8Node n2   = { &s2, nullptr, nullptr }; | ||||||
|  |   Str8Node n3   = { &s3, nullptr, nullptr }; | ||||||
|  |   Str8Node n4   = { &s4, nullptr, nullptr }; | ||||||
|  |   Str8Node n5   = { &s5, nullptr, nullptr }; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_back(&list, &n1); | ||||||
|  |   wapp_str8_list_push_back(&list, &n2); | ||||||
|  |   wapp_str8_list_push_back(&list, &n3); | ||||||
|  |   wapp_str8_list_push_back(&list, &n4); | ||||||
|  |   wapp_str8_list_push_back(&list, &n5); | ||||||
|  |  | ||||||
|  |   Str8Node *node = wapp_str8_list_get(&list, 0); | ||||||
|  |   result = node->item == &s1 && wapp_str8_equal(node->item, &s1); | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_get(&list, 1); | ||||||
|  |   result = result && node->item == &s2 && wapp_str8_equal(node->item, &s2); | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_get(&list, 2); | ||||||
|  |   result = result && node->item == &s3 && wapp_str8_equal(node->item, &s3); | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_get(&list, 3); | ||||||
|  |   result = result && node->item == &s4 && wapp_str8_equal(node->item, &s4); | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_get(&list, 4); | ||||||
|  |   result = result && node->item == &s5 && wapp_str8_equal(node->item, &s5); | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_push_front(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("1"); | ||||||
|  |   Str8 s2 = wapp_str8_lit("2"); | ||||||
|  |   Str8 s3 = wapp_str8_lit("3"); | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |   Str8Node n1   = { &s1, nullptr, nullptr }; | ||||||
|  |   Str8Node n2   = { &s2, nullptr, nullptr }; | ||||||
|  |   Str8Node n3   = { &s3, nullptr, nullptr }; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_front(&list, &n1); | ||||||
|  |   result = list.first == list.last && list.first == &n1 && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_front(&list, &n2); | ||||||
|  |   result = result && list.first == &n2 && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_front(&list, &n3); | ||||||
|  |   result = result && list.first == &n3 && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_push_back(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("1"); | ||||||
|  |   Str8 s2 = wapp_str8_lit("2"); | ||||||
|  |   Str8 s3 = wapp_str8_lit("3"); | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |   Str8Node n1   = { &s1, nullptr, nullptr }; | ||||||
|  |   Str8Node n2   = { &s2, nullptr, nullptr }; | ||||||
|  |   Str8Node n3   = { &s3, nullptr, nullptr }; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_back(&list, &n1); | ||||||
|  |   result = list.first == list.last && list.last == &n1 && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_back(&list, &n2); | ||||||
|  |   result = result && list.last == &n2 && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_back(&list, &n3); | ||||||
|  |   result = result && list.last == &n3 && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_insert(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("1"); | ||||||
|  |   Str8 s2 = wapp_str8_lit("2"); | ||||||
|  |   Str8 s3 = wapp_str8_lit("3"); | ||||||
|  |   Str8 s4 = wapp_str8_lit("4"); | ||||||
|  |   Str8 s5 = wapp_str8_lit("5"); | ||||||
|  |   Str8 s6 = wapp_str8_lit("6"); | ||||||
|  |   Str8 s7 = wapp_str8_lit("7"); | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |   Str8Node n1   = { &s1, nullptr, nullptr }; | ||||||
|  |   Str8Node n2   = { &s2, nullptr, nullptr }; | ||||||
|  |   Str8Node n3   = { &s3, nullptr, nullptr }; | ||||||
|  |   Str8Node n4   = { &s4, nullptr, nullptr }; | ||||||
|  |   Str8Node n5   = { &s5, nullptr, nullptr }; | ||||||
|  |   Str8Node n6   = { &s6, nullptr, nullptr }; | ||||||
|  |   Str8Node n7   = { &s7, nullptr, nullptr }; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_back(&list, &n1); | ||||||
|  |   wapp_str8_list_push_back(&list, &n2); | ||||||
|  |   wapp_str8_list_push_back(&list, &n3); | ||||||
|  |   wapp_str8_list_push_back(&list, &n4); | ||||||
|  |   wapp_str8_list_push_back(&list, &n5); | ||||||
|  |  | ||||||
|  |   Str8Node *node; | ||||||
|  |   wapp_str8_list_insert(&list, &n6, 2); | ||||||
|  |   node   = wapp_str8_list_get(&list, 2); | ||||||
|  |   result = node != NULL && node->item == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6; | ||||||
|  |   wapp_str8_list_insert(&list, &n7, 5); | ||||||
|  |   node   = wapp_str8_list_get(&list, 5); | ||||||
|  |   result = result && node != NULL && node->item == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_pop_front(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("1"); | ||||||
|  |   Str8 s2 = wapp_str8_lit("2"); | ||||||
|  |   Str8 s3 = wapp_str8_lit("3"); | ||||||
|  |   Str8 s4 = wapp_str8_lit("4"); | ||||||
|  |   Str8 s5 = wapp_str8_lit("5"); | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |   Str8Node n1   = { &s1, nullptr, nullptr }; | ||||||
|  |   Str8Node n2   = { &s2, nullptr, nullptr }; | ||||||
|  |   Str8Node n3   = { &s3, nullptr, nullptr }; | ||||||
|  |   Str8Node n4   = { &s4, nullptr, nullptr }; | ||||||
|  |   Str8Node n5   = { &s5, nullptr, nullptr }; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_back(&list, &n1); | ||||||
|  |   wapp_str8_list_push_back(&list, &n2); | ||||||
|  |   wapp_str8_list_push_back(&list, &n3); | ||||||
|  |   wapp_str8_list_push_back(&list, &n4); | ||||||
|  |   wapp_str8_list_push_back(&list, &n5); | ||||||
|  |  | ||||||
|  |   Str8Node *node = wapp_str8_list_pop_front(&list); | ||||||
|  |   result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_front(&list); | ||||||
|  |   result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_front(&list); | ||||||
|  |   result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_front(&list); | ||||||
|  |   result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_front(&list); | ||||||
|  |   result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_pop_back(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("1"); | ||||||
|  |   Str8 s2 = wapp_str8_lit("2"); | ||||||
|  |   Str8 s3 = wapp_str8_lit("3"); | ||||||
|  |   Str8 s4 = wapp_str8_lit("4"); | ||||||
|  |   Str8 s5 = wapp_str8_lit("5"); | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |   Str8Node n1   = { &s1, nullptr, nullptr }; | ||||||
|  |   Str8Node n2   = { &s2, nullptr, nullptr }; | ||||||
|  |   Str8Node n3   = { &s3, nullptr, nullptr }; | ||||||
|  |   Str8Node n4   = { &s4, nullptr, nullptr }; | ||||||
|  |   Str8Node n5   = { &s5, nullptr, nullptr }; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_front(&list, &n1); | ||||||
|  |   wapp_str8_list_push_front(&list, &n2); | ||||||
|  |   wapp_str8_list_push_front(&list, &n3); | ||||||
|  |   wapp_str8_list_push_front(&list, &n4); | ||||||
|  |   wapp_str8_list_push_front(&list, &n5); | ||||||
|  |  | ||||||
|  |   Str8Node *node = wapp_str8_list_pop_back(&list); | ||||||
|  |   result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_back(&list); | ||||||
|  |   result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_back(&list); | ||||||
|  |   result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_back(&list); | ||||||
|  |   result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_pop_back(&list); | ||||||
|  |   result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_remove(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8 s1 = wapp_str8_lit("1"); | ||||||
|  |   Str8 s2 = wapp_str8_lit("2"); | ||||||
|  |   Str8 s3 = wapp_str8_lit("3"); | ||||||
|  |   Str8 s4 = wapp_str8_lit("4"); | ||||||
|  |   Str8 s5 = wapp_str8_lit("5"); | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |   Str8Node n1   = { &s1, nullptr, nullptr }; | ||||||
|  |   Str8Node n2   = { &s2, nullptr, nullptr }; | ||||||
|  |   Str8Node n3   = { &s3, nullptr, nullptr }; | ||||||
|  |   Str8Node n4   = { &s4, nullptr, nullptr }; | ||||||
|  |   Str8Node n5   = { &s5, nullptr, nullptr }; | ||||||
|  |  | ||||||
|  |   wapp_str8_list_push_back(&list, &n1); | ||||||
|  |   wapp_str8_list_push_back(&list, &n2); | ||||||
|  |   wapp_str8_list_push_back(&list, &n3); | ||||||
|  |   wapp_str8_list_push_back(&list, &n4); | ||||||
|  |   wapp_str8_list_push_back(&list, &n5); | ||||||
|  |  | ||||||
|  |   Str8Node *node = wapp_str8_list_remove(&list, 0); | ||||||
|  |   result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_remove(&list, 0); | ||||||
|  |   result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_remove(&list, 0); | ||||||
|  |   result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_remove(&list, 0); | ||||||
|  |   result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; | ||||||
|  |  | ||||||
|  |   node = wapp_str8_list_remove(&list, 0); | ||||||
|  |   result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TestFuncResult test_str8_list_empty(void) { | ||||||
|  |   bool result; | ||||||
|  |  | ||||||
|  |   Str8List list = {}; | ||||||
|  |  | ||||||
|  |   Str8Node hello = wapp_str8_node_from_cstr("Hello"); | ||||||
|  |   wapp_str8_list_push_back(&list, &hello); | ||||||
|  |  | ||||||
|  |   Str8Node from = wapp_str8_node_from_cstr("from"); | ||||||
|  |   wapp_str8_list_push_back(&list, &from); | ||||||
|  |  | ||||||
|  |   Str8Node wizapp = wapp_str8_node_from_cstr("wizapp"); | ||||||
|  |   wapp_str8_list_push_back(&list, &wizapp); | ||||||
|  |  | ||||||
|  |   Str8Node stdlib = wapp_str8_node_from_cstr("stdlib"); | ||||||
|  |   wapp_str8_list_push_back(&list, &stdlib); | ||||||
|  |  | ||||||
|  |   wapp_str8_list_empty(&list); | ||||||
|  |  | ||||||
|  |   result = list.first == NULL && list.last == NULL && list.node_count == 0 && wapp_str8_list_total_size(&list) == 0; | ||||||
|  |  | ||||||
|  |   return wapp_tester_result(result); | ||||||
|  | } | ||||||
| @@ -9,7 +9,8 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  |  | ||||||
| int main(void) { | int main(void) { | ||||||
|   wapp_tester_run_tests(test_arena_allocator, |   wapp_tester_run_tests( | ||||||
|  |       test_arena_allocator, | ||||||
|       test_arena_init, |       test_arena_init, | ||||||
|       test_arena_init_succeeds_when_reserving_very_large_size, |       test_arena_init_succeeds_when_reserving_very_large_size, | ||||||
|       test_arena_alloc_succeeds_when_within_capacity, |       test_arena_alloc_succeeds_when_within_capacity, | ||||||
| @@ -69,7 +70,8 @@ int main(void) { | |||||||
|       test_commander_cmd_success, |       test_commander_cmd_success, | ||||||
|       test_commander_cmd_failure, |       test_commander_cmd_failure, | ||||||
|       test_commander_cmd_out_buf_success, |       test_commander_cmd_out_buf_success, | ||||||
|                         test_commander_cmd_out_buf_failure); |       test_commander_cmd_out_buf_failure | ||||||
|  |   ); | ||||||
|  |  | ||||||
|   return EXIT_SUCCESS; |   return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										77
									
								
								tests/wapptest.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								tests/wapptest.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | #include "test_str8.h" | ||||||
|  | #include "test_str8_list.h" | ||||||
|  | #include "test_allocator.h" | ||||||
|  | #include "test_arena.h" | ||||||
|  | #include "test_i32_array.h" | ||||||
|  | #include "test_cpath.h" | ||||||
|  | #include "test_shell_commander.h" | ||||||
|  | #include "wapp.h" | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | int main(void) { | ||||||
|  |   wapp_tester_run_tests( | ||||||
|  |       test_arena_allocator, | ||||||
|  |       test_arena_init, | ||||||
|  |       test_arena_init_succeeds_when_reserving_very_large_size, | ||||||
|  |       test_arena_alloc_succeeds_when_within_capacity, | ||||||
|  |       test_arena_alloc_fails_when_over_capacity, | ||||||
|  |       test_arena_realloc_bigger_size, | ||||||
|  |       test_arena_realloc_smaller_size, | ||||||
|  |       test_arena_clear, | ||||||
|  |       test_arena_destroy, | ||||||
|  |       test_i32_array, | ||||||
|  |       test_i32_array_with_capacity, | ||||||
|  |       test_i32_array_get, | ||||||
|  |       test_i32_array_set, | ||||||
|  |       test_i32_array_append_capped, | ||||||
|  |       test_i32_array_extend_capped, | ||||||
|  |       test_i32_array_clear, | ||||||
|  |       test_i32_array_pop, | ||||||
|  |       test_i32_array_copy_capped, | ||||||
|  |       test_i32_array_alloc_capacity, | ||||||
|  |       test_i32_array_append_alloc, | ||||||
|  |       test_i32_array_extend_alloc, | ||||||
|  |       test_i32_array_copy_alloc, | ||||||
|  |       test_str8_lit, | ||||||
|  |       test_str8_lit_ro, | ||||||
|  |       test_str8_buf, | ||||||
|  |       test_str8_alloc_buf, | ||||||
|  |       test_str8_alloc_cstr, | ||||||
|  |       test_str8_alloc_str8, | ||||||
|  |       test_str8_alloc_substr, | ||||||
|  |       test_str8_alloc_concat, | ||||||
|  |       test_str8_get_index_within_bounds, | ||||||
|  |       test_str8_get_index_out_of_bounds, | ||||||
|  |       test_str8_set, | ||||||
|  |       test_str8_equal, | ||||||
|  |       test_str8_slice, | ||||||
|  |       test_str8_concat_capped, | ||||||
|  |       test_str8_copy_cstr_capped, | ||||||
|  |       test_str8_copy_str8_capped, | ||||||
|  |       test_str8_format, | ||||||
|  |       test_str8_find, | ||||||
|  |       test_str8_rfind, | ||||||
|  |       test_str8_split, | ||||||
|  |       test_str8_split_with_max, | ||||||
|  |       test_str8_rsplit, | ||||||
|  |       test_str8_rsplit_with_max, | ||||||
|  |       test_str8_join, | ||||||
|  |       test_str8_list_get, | ||||||
|  |       test_str8_list_push_front, | ||||||
|  |       test_str8_list_push_back, | ||||||
|  |       test_str8_list_insert, | ||||||
|  |       test_str8_list_pop_front, | ||||||
|  |       test_str8_list_pop_back, | ||||||
|  |       test_str8_list_remove, | ||||||
|  |       test_str8_list_empty, | ||||||
|  |       test_cpath_join_path, | ||||||
|  |       test_cpath_dirname, | ||||||
|  |       test_cpath_dirup, | ||||||
|  |       test_commander_cmd_success, | ||||||
|  |       test_commander_cmd_failure, | ||||||
|  |       test_commander_cmd_out_buf_success, | ||||||
|  |       test_commander_cmd_out_buf_failure | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   return EXIT_SUCCESS; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user