3 Commits

Author SHA1 Message Date
7d49ad78e6 Update wapp array C API 2025-12-07 21:56:16 +00:00
cf4a8a262e Reformat 2025-12-07 21:55:15 +00:00
7cab77bb30 Remove array codegen code 2025-12-07 17:36:14 +00:00
33 changed files with 366 additions and 4634 deletions

View File

@@ -2,29 +2,22 @@ import json
from typing import Dict from typing import Dict
from pathlib import Path from pathlib import Path
from codegen.datatypes import CDataType, CStruct from codegen.datatypes import CDataType, CStruct
from codegen.constants import WAPP_REPO_ROOT, DBL_LIST_DATA, ARRAY_DATA from codegen.constants import WAPP_REPO_ROOT, DBL_LIST_DATA
from codegen.dbl_list.make_dbl_list import DblListData, make_dbl_list from codegen.dbl_list.make_dbl_list import DblListData, make_dbl_list
from codegen.array.make_array import ArrayData, make_array
def main(types_file: Path | None): def main(types_file: Path | None):
dbl_list_datatypes: Dict[CDataType, DblListData] = {} dbl_list_datatypes: Dict[CDataType, DblListData] = {}
array_datatypes: Dict[CDataType, ArrayData] = {}
if types_file is not None and types_file.is_file() and "json" in types_file.suffix.lower(): if types_file is not None and types_file.is_file() and "json" in types_file.suffix.lower():
with types_file.open("r") as infile: with types_file.open("r") as infile:
datatypes = json.load(infile) datatypes = json.load(infile)
dbl_list_data = datatypes.get(DBL_LIST_DATA) dbl_list_data = datatypes.get(DBL_LIST_DATA)
array_data = datatypes.get(ARRAY_DATA)
if dbl_list_data is not None and isinstance(dbl_list_data, dict): if dbl_list_data is not None and isinstance(dbl_list_data, dict):
dbl_list_datatypes = {k: DblListData.from_dict(v) for k, v in dbl_list_data.items()} dbl_list_datatypes = {k: DblListData.from_dict(v) for k, v in dbl_list_data.items()}
if array_data is not None and isinstance(array_data, dict):
array_datatypes = {k: ArrayData.from_dict(v) for k, v in array_data.items()}
make_dbl_list(dbl_list_datatypes) make_dbl_list(dbl_list_datatypes)
make_array(array_datatypes)
# Save example types file # Save example types file
custom_struct = CStruct(name="custom_type", cargs=[], typedef_name="CustomType") custom_struct = CStruct(name="custom_type", cargs=[], typedef_name="CustomType")
@@ -36,12 +29,6 @@ def main(types_file: Path | None):
hdr_decl_types=[custom_struct], hdr_decl_types=[custom_struct],
).to_dict() ).to_dict()
}, },
ARRAY_DATA: {
"CustomType": ArrayData(
array_typename="CustomTypeArray",
hdr_decl_types=[custom_struct],
).to_dict()
},
} }
example_file = WAPP_REPO_ROOT / "codegen_custom_data_example.json" example_file = WAPP_REPO_ROOT / "codegen_custom_data_example.json"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,4 +7,3 @@ WAPP_SRC_ROOT = WAPP_REPO_ROOT / "src"
# Dictionary Keys # Dictionary Keys
DBL_LIST_DATA = "dbl_list_data" DBL_LIST_DATA = "dbl_list_data"
ARRAY_DATA = "array_data"

View File

@@ -12,18 +12,5 @@
], ],
"src_decl_types": [] "src_decl_types": []
} }
},
"array_data": {
"CustomType": {
"array_typename": "CustomTypeArray",
"hdr_decl_types": [
{
"name": "custom_type",
"cargs": [],
"typedef_name": "CustomType"
}
],
"src_decl_types": []
}
} }
} }

View File

@@ -66,8 +66,8 @@ u64 wapp_file_read(GenericArray *dst, File *file, u64 item_count) {
"`dst`, `dst->items` and `file` should not be NULL."); "`dst`, `dst->items` and `file` should not be NULL.");
u64 file_length = wapp_file_get_length(file); u64 file_length = wapp_file_get_length(file);
u64 dst_byte_capacity = dst->item_size * dst->capacity; u64 dst_byte_capacity = dst->header.item_size * dst->header.capacity;
u64 req_byte_count = item_count * dst->item_size; u64 req_byte_count = item_count * dst->header.item_size;
u64 copy_byte_count = 0; u64 copy_byte_count = 0;
if (req_byte_count <= file_length && req_byte_count <= dst_byte_capacity) { if (req_byte_count <= file_length && req_byte_count <= dst_byte_capacity) {
@@ -76,17 +76,17 @@ u64 wapp_file_read(GenericArray *dst, File *file, u64 item_count) {
copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity; copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity;
} }
dst->count = fread(dst->items, sizeof(u8), copy_byte_count, file) / dst->item_size; dst->header.count = fread(dst->items, sizeof(u8), copy_byte_count, file) / dst->header.item_size;
return dst->count; return dst->header.count;
} }
u64 wapp_file_write(const GenericArray *src, File *file, u64 item_count) { u64 wapp_file_write(const GenericArray *src, File *file, u64 item_count) {
wapp_debug_assert(src != NULL && src->items != NULL && file != NULL, wapp_debug_assert(src != NULL && src->items != NULL && file != NULL,
"`src`, `src->items` and `file` should not be NULL."); "`src`, `src->items` and `file` should not be NULL.");
u64 src_byte_count = src->count * src->item_size; u64 src_byte_count = src->header.count * src->header.item_size;
u64 req_byte_count = item_count * src->item_size; u64 req_byte_count = item_count * src->header.item_size;
u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count; u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count;
return fwrite(src->items, sizeof(u8), to_copy, file); return fwrite(src->items, sizeof(u8), to_copy, file);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
// vim:fileencoding=utf-8:foldmethod=marker // vim:fileencoding=utf-8:foldmethod=marker
#include "str8.h" #include "str8.h"
#include "../../array/array.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../mem_allocator/mem_allocator.h" #include "../../mem_allocator/mem_allocator.h"
@@ -260,14 +261,15 @@ void wapp_str8_to_upper(Str8 *dst, Str8RO *src) {
} }
} }
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src) { void wapp_str8_from_bytes(Str8 *dst, const u8 *src_byte_array) {
u64 size = src->count * src->item_size; wapp_debug_assert(src_byte_array != NULL && dst != NULL, "`dst` and `src` should not be NULL");
u64 size = wapp_array_count(u8, src_byte_array) * wapp_array_item_size(u8, src_byte_array);
wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL");
wapp_debug_assert(dst->capacity >= size, "`dst` does not have enough capacity"); wapp_debug_assert(dst->capacity >= size, "`dst` does not have enough capacity");
dst->size = size; dst->size = size;
memcpy(dst->buf, src->items, size); memcpy(dst->buf, src_byte_array, size);
} }
i64 wapp_str8_find(Str8RO *str, Str8RO substr) { i64 wapp_str8_find(Str8RO *str, Str8RO substr) {

View File

@@ -99,7 +99,7 @@ void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity);
void wapp_str8_format(Str8 *dst, const char *format, ...); void wapp_str8_format(Str8 *dst, const char *format, ...);
void wapp_str8_to_lower(Str8 *dst, Str8RO *src); void wapp_str8_to_lower(Str8 *dst, Str8RO *src);
void wapp_str8_to_upper(Str8 *dst, Str8RO *src); void wapp_str8_to_upper(Str8 *dst, Str8RO *src);
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src); void wapp_str8_from_bytes(Str8 *dst, const u8 *src);
/** /**
* Str8 find functions * Str8 find functions

View File

@@ -4,16 +4,16 @@
TestFuncResult test_i32_array(void) { TestFuncResult test_i32_array(void) {
b8 result; b8 result;
I32Array array = wapp_i32_array(1, 2, 3, 4, 5, 6, 7); i32 *array = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7);
result = array.count == 7 && array.capacity == 16; result = wapp_array_count(i32, array) == 7 && wapp_array_capacity(i32, array) == 16;
i32 *item; i32 item;
u64 count = array.count; u64 count = wapp_array_count(i32, array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_i32_array_get(&array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)(index + 1)); result = result && item && item == (i32)(index + 1);
++index; ++index;
running = index < count; running = index < count;
@@ -25,8 +25,8 @@ TestFuncResult test_i32_array(void) {
TestFuncResult test_i32_array_with_capacity(void) { TestFuncResult test_i32_array_with_capacity(void) {
b8 result; b8 result;
I32Array array = wapp_i32_array_with_capacity(64); i32 *array = wapp_array_with_capacity(i32, 64);
result = array.count == 0 && array.capacity == 64; result = wapp_array_count(i32, array) == 0 && wapp_array_capacity(i32, array) == 64;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -34,15 +34,15 @@ TestFuncResult test_i32_array_with_capacity(void) {
TestFuncResult test_i32_array_get(void) { TestFuncResult test_i32_array_get(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_i32_array(0, 1, 2, 3, 4, 5, 6, 7, 8); i32 *array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 item;
u64 count = array.count; u64 count = wapp_array_count(i32, array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_i32_array_get(&array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)index); result = result && item == (i32)index;
++index; ++index;
running = index < count; running = index < count;
@@ -54,17 +54,17 @@ TestFuncResult test_i32_array_get(void) {
TestFuncResult test_i32_array_set(void) { TestFuncResult test_i32_array_set(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_i32_array(0, 1, 2, 3, 4, 5, 6, 7, 8); i32 *array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 item;
u64 count = array.count; u64 count = wapp_array_count(i32, array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)(index * 2); i32 num = (i32)(index * 2);
wapp_i32_array_set(&array, index, &num); wapp_array_set(i32, array, index, &num);
item = wapp_i32_array_get(&array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)(index * 2)); result = result && item == (i32)(index * 2);
++index; ++index;
running = index < count; running = index < count;
@@ -76,17 +76,17 @@ TestFuncResult test_i32_array_set(void) {
TestFuncResult test_i32_array_append_capped(void) { TestFuncResult test_i32_array_append_capped(void) {
b8 result; b8 result;
I32Array array = wapp_i32_array_with_capacity(64); i32 *array = wapp_array_with_capacity(i32, 64);
wapp_i32_array_append_capped(&array, &((i32){10})); wapp_array_append_capped(i32, array, &((i32){10}));
result = array.count == 1; result = wapp_array_count(i32, array) == 1;
i32 *item = wapp_i32_array_get(&array, 0); i32 item = wapp_array_get(i32, array, 0);
result = result && item && *item == 10; result = result && item == 10;
array = wapp_i32_array(1); array = wapp_array(i32, 1);
wapp_i32_array_append_capped(&array, &((i32){10})); wapp_array_append_capped(i32, array, &((i32){10}));
result = result && array.count == 2; result = result && wapp_array_count(i32, array) == 2;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -94,41 +94,14 @@ TestFuncResult test_i32_array_append_capped(void) {
TestFuncResult test_i32_array_extend_capped(void) { TestFuncResult test_i32_array_extend_capped(void) {
b8 result; b8 result;
I32Array array1 = wapp_i32_array(1, 2, 3, 4); i32 *array1 = wapp_array(i32, 1, 2, 3, 4);
I32Array array2 = wapp_i32_array(10, 20); i32 *array2 = wapp_array(i32, 10, 20);
result = array1.count == 4 && array2.count == 2; result = wapp_array_count(i32, array1) == 4 && wapp_array_count(i32, array2) == 2;
wapp_i32_array_extend_capped(&array1, &array2); wapp_array_extend_capped(i32, array1, array2);
result = result && array1.count == 6; result = result && wapp_array_count(i32, array1) == 6;
return wapp_tester_result(result);
}
TestFuncResult test_i32_array_clear(void) {
b8 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) {
b8 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); return wapp_tester_result(result);
} }
@@ -136,31 +109,31 @@ TestFuncResult test_i32_array_pop(void) {
TestFuncResult test_i32_array_copy_capped(void) { TestFuncResult test_i32_array_copy_capped(void) {
b8 result; b8 result;
I32Array src = wapp_i32_array(1, 2, 3, 4, 5); i32 *src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_i32_array(1, 2, 3, 4, 5, 6); i32 *dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_i32_array(1, 2); i32 *dst2 = wapp_array(i32, 1, 2);
u64 expected_count = 5; u64 expected_count = 5;
wapp_i32_array_copy_capped(&src, &dst1); wapp_array_copy_capped(i32, dst1, src);
result = dst1.count == expected_count; result = wapp_array_count(i32, dst1) == expected_count;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(&dst1, index)); result = result && wapp_array_get(i32, src, index) == wapp_array_get(i32, dst1, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 4; expected_count = 4;
wapp_i32_array_copy_capped(&src, &dst2); wapp_array_copy_capped(i32, dst2, src);
result = result && dst2.count == expected_count; result = result && wapp_array_count(i32, dst2) == expected_count;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(&dst2, index)); result = result && wapp_array_get(i32, src, index) == wapp_array_get(i32, dst2, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -174,9 +147,9 @@ TestFuncResult test_i32_array_alloc_capacity(void) {
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MB(4));
u64 capacity = 32; u64 capacity = 32;
I32Array *array = wapp_i32_array_alloc_capacity(&allocator, capacity); i32 *array = wapp_array_alloc_capacity(i32, &allocator, capacity);
result = array && array->capacity == capacity; result = array && wapp_array_capacity(i32, array) == capacity;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -187,23 +160,23 @@ TestFuncResult test_i32_array_append_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MB(4));
I32Array array1 = wapp_i32_array(1, 2, 3, 4, 5, 6, 7, 8); i32 *array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_i32_array(1, 2); i32 *array2 = wapp_array(i32, 1, 2);
I32Array *arr_ptr = wapp_i32_array_append_alloc(&allocator, &array1, &((i32){10})); i32 *arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &((i32){10}));
result = arr_ptr == &array1; result = arr_ptr == array1;
u64 count = 4; u64 count = 4;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)index; i32 num = (i32)index;
arr_ptr = wapp_i32_array_append_alloc(&allocator, &array2, &num); arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num);
++index; ++index;
running = index < count; running = index < count;
} }
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -214,15 +187,15 @@ TestFuncResult test_i32_array_extend_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MB(4));
I32Array array1 = wapp_i32_array(1, 2, 3, 4, 5, 6, 7, 8); i32 *array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_i32_array(1, 2); i32 *array2 = wapp_array(i32, 1, 2);
I32Array array3 = wapp_i32_array(1, 2, 3, 4); i32 *array3 = wapp_array(i32, 1, 2, 3, 4);
I32Array *arr_ptr = wapp_i32_array_extend_alloc(&allocator, &array1, &array3); i32 *arr_ptr = wapp_array_extend_alloc(i32, &allocator, array1, array3);
result = arr_ptr == &array1; result = arr_ptr == array1;
arr_ptr = wapp_i32_array_extend_alloc(&allocator, &array2, &array3); arr_ptr = wapp_array_extend_alloc(i32, &allocator, array2, array3);
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -233,32 +206,32 @@ TestFuncResult test_i32_array_copy_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MB(4));
I32Array src = wapp_i32_array(1, 2, 3, 4, 5); i32 *src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_i32_array(1, 2, 3, 4, 5, 6); i32 *dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_i32_array(1, 2); i32 *dst2 = wapp_array(i32, 1, 2);
I32Array *array_ptr = NULL; i32 *array_ptr = NULL;
u64 expected_count = 5; u64 expected_count = 5;
array_ptr = wapp_i32_array_copy_alloc(&allocator, &src, &dst1); array_ptr = wapp_array_copy_alloc(i32, &allocator, dst1, src);
result = array_ptr->count == expected_count && array_ptr == &dst1; result = wapp_array_count(i32, array_ptr) == expected_count && array_ptr == dst1;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(array_ptr, index)); result = result && wapp_array_get(i32, src, index) == wapp_array_get(i32, array_ptr, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 5; expected_count = 5;
array_ptr = wapp_i32_array_copy_alloc(&allocator, &src, &dst2); array_ptr = wapp_array_copy_alloc(i32, &allocator, dst2, src);
result = result && array_ptr->count == expected_count && array_ptr != &dst2; result = result && wapp_array_count(i32, array_ptr) == expected_count && array_ptr != dst2;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && (*wapp_i32_array_get(&src, index) == *wapp_i32_array_get(array_ptr, index)); result = result && wapp_array_get(i32, src, index) == wapp_array_get(i32, array_ptr, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -268,3 +241,30 @@ TestFuncResult test_i32_array_copy_alloc(void) {
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_i32_array_pop(void) {
b8 result;
i32 *array1 = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *array2 = wapp_array_with_capacity(i32, 32);
i32 item1 = wapp_array_pop(i32, array1);
i32 item2 = wapp_array_pop(i32, array2);
result = item1 == 8 && item2 == 0;
return wapp_tester_result(result);
}
TestFuncResult test_i32_array_clear(void) {
b8 result;
i32 *array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
result = wapp_array_count(i32, array) == 9;
wapp_array_clear(i32, array);
result = result && wapp_array_count(i32, array) == 0;
return wapp_tester_result(result);
}

View File

@@ -9,12 +9,12 @@ TestFuncResult test_i32_array_get(void);
TestFuncResult test_i32_array_set(void); TestFuncResult test_i32_array_set(void);
TestFuncResult test_i32_array_append_capped(void); TestFuncResult test_i32_array_append_capped(void);
TestFuncResult test_i32_array_extend_capped(void); TestFuncResult test_i32_array_extend_capped(void);
TestFuncResult test_i32_array_clear(void);
TestFuncResult test_i32_array_pop(void);
TestFuncResult test_i32_array_copy_capped(void); TestFuncResult test_i32_array_copy_capped(void);
TestFuncResult test_i32_array_alloc_capacity(void); TestFuncResult test_i32_array_alloc_capacity(void);
TestFuncResult test_i32_array_append_alloc(void); TestFuncResult test_i32_array_append_alloc(void);
TestFuncResult test_i32_array_extend_alloc(void); TestFuncResult test_i32_array_extend_alloc(void);
TestFuncResult test_i32_array_copy_alloc(void); TestFuncResult test_i32_array_copy_alloc(void);
TestFuncResult test_i32_array_pop(void);
TestFuncResult test_i32_array_clear(void);
#endif // !TEST_INT_ARRAY_H #endif // !TEST_INT_ARRAY_H

View File

@@ -6,16 +6,16 @@ TestFuncResult test_str8_array(void) {
b8 result; b8 result;
Str8 expected[] = {wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")}; Str8 expected[] = {wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")};
Str8Array array = wapp_str8_array(wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")); Str8 *array = wapp_array(Str8, wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye"));
result = array.count == 3 && array.capacity == 8; result = wapp_array_count(Str8, array) == 3 && wapp_array_capacity(Str8, array) == 8;
Str8 *item; Str8 item;
u64 count = array.count; u64 count = wapp_array_count(Str8, array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_str8_array_get(&array, index); item = wapp_array_get(Str8, array, index);
result = result && item && (wapp_str8_equal(item, &expected[index])); result = result && (wapp_str8_equal(&item, &expected[index]));
++index; ++index;
running = index < count; running = index < count;

View File

@@ -616,10 +616,10 @@ TestFuncResult test_str8_from_bytes(void) {
b8 result; b8 result;
Str8 str = wapp_str8_buf(1024); Str8 str = wapp_str8_buf(1024);
U8Array bytes = wapp_u8_array('W', 'A', 'P', 'P'); u8 *bytes = wapp_array(u8, 'W', 'A', 'P', 'P');
wapp_str8_from_bytes(&str, &bytes); wapp_str8_from_bytes(&str, bytes);
result = str.size == bytes.count * bytes.item_size; result = str.size == wapp_array_count(u8, bytes) * wapp_array_item_size(u8, bytes);
result = result && wapp_str8_equal(&str, &wapp_str8_lit_ro("WAPP")); result = result && wapp_str8_equal(&str, &wapp_str8_lit_ro("WAPP"));
return wapp_tester_result(result); return wapp_tester_result(result);

View File

@@ -27,13 +27,13 @@ int main(void) {
test_i32_array_set, test_i32_array_set,
test_i32_array_append_capped, test_i32_array_append_capped,
test_i32_array_extend_capped, test_i32_array_extend_capped,
test_i32_array_clear,
test_i32_array_pop,
test_i32_array_copy_capped, test_i32_array_copy_capped,
test_i32_array_alloc_capacity, test_i32_array_alloc_capacity,
test_i32_array_append_alloc, test_i32_array_append_alloc,
test_i32_array_extend_alloc, test_i32_array_extend_alloc,
test_i32_array_copy_alloc, test_i32_array_copy_alloc,
test_i32_array_pop,
test_i32_array_clear,
test_str8_lit, test_str8_lit,
test_str8_lit_ro, test_str8_lit_ro,
test_str8_buf, test_str8_buf,