Update doc formatting
+105
-164
@@ -2,19 +2,17 @@
|
||||
|
||||
The `base` package provides core data structures and memory abstractions: dynamic arrays, doubly-linked lists, queues, strings, and a pluggable allocator interface.
|
||||
|
||||
```c
|
||||
#include "wapp_base.h"
|
||||
```
|
||||
|
||||
**Dependencies:** common
|
||||
|
||||
---
|
||||
|
||||
## Allocator Interface
|
||||
|
||||
A pluggable allocator interface that abstracts memory allocation strategies.
|
||||
|
||||
```c
|
||||
#include "wapp_base.h"
|
||||
```
|
||||
|
||||
### Allocator Struct
|
||||
A pluggable allocator that abstracts memory allocation strategies. See os package for the arena-backed implementation.
|
||||
|
||||
```c
|
||||
typedef struct Allocator Allocator;
|
||||
@@ -33,22 +31,16 @@ struct Allocator {
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_mem_allocator_alloc(allocator, size)` | Allocates memory |
|
||||
| `wapp_mem_allocator_alloc_aligned(allocator, size, alignment)` | Allocated aligned memory |
|
||||
| `wapp_mem_allocator_alloc_aligned(allocator, size, alignment)` | Allocates aligned memory |
|
||||
| `wapp_mem_allocator_realloc(allocator, ptr, old_size, new_size)` | Reallocates memory |
|
||||
| `wapp_mem_allocator_realloc_aligned(allocator, ptr, old_size, new_size, alignment)` | Reallocates aligned memory |
|
||||
| `wapp_mem_allocator_free(allocator, ptr, size)` | Frees memory |
|
||||
| `wapp_mem_allocator_invalid(allocator)` | Checks if an allocator is zero-initialised (invalid) |
|
||||
|
||||
The `Allocator` struct holds function pointers and a context object. This allows different allocation strategies (malloc, arena, custom) to share the same interface.
|
||||
| `wapp_mem_allocator_invalid(allocator)` | Checks whether an allocator is zero-initialised |
|
||||
|
||||
---
|
||||
|
||||
## Memory Utilities
|
||||
|
||||
```c
|
||||
#include "wapp_base.h"
|
||||
```
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_mem_util_align_forward(ptr, alignment)` | Aligns a pointer forward to the given alignment |
|
||||
@@ -57,82 +49,69 @@ The `Allocator` struct holds function pointers and a context object. This allows
|
||||
|
||||
## Array
|
||||
|
||||
A type-generic dynamic array with stack-allocated and allocator-backed variants.
|
||||
|
||||
```c
|
||||
#include "wapp_base.h"
|
||||
```
|
||||
A type-generic dynamic array with both stack-allocated and allocator-backed variants.
|
||||
|
||||
### Typedefs
|
||||
|
||||
Convenience typedefs for common element types:
|
||||
|
||||
`VoidPtrArray`, `C8Array`, `C16Array`, `C32Array`, `U8Array`, `U16Array`, `U32Array`, `U64Array`, `B8Array`, `I8Array`, `I16Array`, `I32Array`, `I64Array`, `F32Array`, `F64Array`, `F128Array`, `UptrArray`, `IptrArray`, `Str8Array`
|
||||
`GenericArray`, `VoidPtrArray`, `C8Array`, `C16Array`, `C32Array`, `U8Array`, `U16Array`, `U32Array`, `U64Array`, `B8Array`, `I8Array`, `I16Array`, `I32Array`, `I64Array`, `F32Array`, `F64Array`, `F128Array`, `UptrArray`, `IptrArray`, `Str8Array`
|
||||
|
||||
### Creation
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_array(TYPE, ...)` | Creates a stack-allocated array with initial elements. Capacity rounds up to the next power of 2, with a minimum of 2x the element count. |
|
||||
| `wapp_array_with_capacity(TYPE, CAPACITY, FLAGS)` | Creates a stack-allocated array with a specific capacity. `FLAGS` is a bitmask of `ArrayInitFlags`. |
|
||||
| `wapp_array_alloc_capacity(TYPE, ALLOCATOR, CAPACITY, FLAGS)` | Creates an allocator-backed array with a specific capacity |
|
||||
| `wapp_array(type, ...)` | Stack-allocated array with initial elements. Capacity rounds up to the next power of 2. |
|
||||
| `wapp_array_with_capacity(type, capacity, flags)` | Stack-allocated array with a specific capacity. Use `ARRAY_INIT_NONE` or `ARRAY_INIT_FILLED`. |
|
||||
| `wapp_array_alloc_capacity(type, allocator, capacity, flags)` | Allocator-backed array with a specific capacity |
|
||||
|
||||
### Element Operations
|
||||
### Element Access & Mutation
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_array_count(ARRAY)` | Returns the current element count |
|
||||
| `wapp_array_capacity(ARRAY)` | Returns the total capacity |
|
||||
| `wapp_array_item_size(ARRAY)` | Returns the size of a single element |
|
||||
| `wapp_array_set_count(ARRAY, COUNT)` | Sets the element count |
|
||||
| `wapp_array_get(TYPE, ARRAY, INDEX)` | Returns a pointer to the element at `INDEX` |
|
||||
| `wapp_array_set(TYPE, ARRAY, INDEX, VALUE_PTR)` | Sets the element at `INDEX` from `VALUE_PTR` |
|
||||
| `wapp_array_pop(TYPE, ARRAY)` | Pops and returns the last element by value. Returns `0`/`{}` if empty. |
|
||||
| `wapp_array_count(array)` | Current element count |
|
||||
| `wapp_array_capacity(array)` | Total capacity |
|
||||
| `wapp_array_item_size(array)` | Size of a single element |
|
||||
| `wapp_array_set_count(array, count)` | Sets the element count |
|
||||
| `wapp_array_get(type, array, index)` | Returns pointer to element at `index` |
|
||||
| `wapp_array_set(type, array, index, value_ptr)` | Sets element at `index` from `value_ptr` |
|
||||
| `wapp_array_pop(type, array)` | Pops and returns the last element by value (or `0`) |
|
||||
|
||||
### Mutation (Capped - no allocation)
|
||||
### Capped Operations (no allocation)
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_array_append_capped(TYPE, ARRAY, VALUE_PTR)` | Appends an element within current capacity. Does not grow. |
|
||||
| `wapp_array_extend_capped(TYPE, DST, SRC)` | Extends `DST` with elements from `SRC` within capacity. |
|
||||
| `wapp_array_copy_capped(TYPE, DST, SRC)` | Copies `SRC` elements into `DST` within capacity. |
|
||||
| `wapp_array_clear(TYPE, ARRAY)` | Resets the element count to 0 |
|
||||
| `wapp_array_append_capped(type, array, value_ptr)` | Appends within current capacity |
|
||||
| `wapp_array_extend_capped(type, dst, src)` | Extends `dst` with elements from `src` |
|
||||
| `wapp_array_copy_capped(type, dst, src)` | Copies `src` into `dst` |
|
||||
| `wapp_array_clear(type, array)` | Resets count to zero |
|
||||
|
||||
### Mutation (Allocator-backed - may reallocate)
|
||||
### Allocator-backed Operations (may grow)
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_array_append_alloc(TYPE, ALLOCATOR, ARRAY, VALUE_PTR, FLAGS)` | Appends, growing via allocator if needed |
|
||||
| `wapp_array_extend_alloc(TYPE, ALLOCATOR, DST, SRC, FLAGS)` | Extends, growing via allocator if needed |
|
||||
| `wapp_array_copy_alloc(TYPE, ALLOCATOR, DST, SRC, FLAGS)` | Copies, growing via allocator if needed |
|
||||
| `wapp_array_append_alloc(type, allocator, array, value_ptr, flags)` | Appends, growing via allocator |
|
||||
| `wapp_array_extend_alloc(type, allocator, dst, src, flags)` | Extends, growing via allocator |
|
||||
| `wapp_array_copy_alloc(type, allocator, dst, src, flags)` | Copies, growing via allocator |
|
||||
|
||||
### Other
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_array_calc_alloc_size(TYPE, CAPACITY)` | Calculates the allocation size needed for a given capacity |
|
||||
| `wapp_array_from_preallcated_buffer(TYPE, BUFFER, BUFFER_SIZE)` | Creates an array from a pre-allocated buffer |
|
||||
|
||||
### Initialization Flags
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `ARRAY_INIT_NONE` | No initialization (elements contain garbage) |
|
||||
| `ARRAY_INIT_FILLED` | Zero-fill all elements on creation |
|
||||
| `wapp_array_calc_alloc_size(type, capacity)` | Allocation size needed for a given capacity |
|
||||
| `wapp_array_from_preallcated_buffer(type, buffer, buffer_size)` | Creates an array from a pre-allocated buffer |
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
// Stack-allocated array with initial values
|
||||
// Stack-allocated array
|
||||
I32Array arr = wapp_array(i32, 10, 20, 30);
|
||||
wapp_array_count(&arr); // 3
|
||||
wapp_array_capacity(&arr); // 8 (next power of 2)
|
||||
wapp_array_count(arr); // 3
|
||||
wapp_array_capacity(arr); // 8
|
||||
|
||||
// Append (capped)
|
||||
i32 val = 40;
|
||||
wapp_array_append_capped(i32, &arr, &val);
|
||||
wapp_array_append_capped(i32, arr, &val);
|
||||
|
||||
// Heap-allocated array with automatic growth via arena
|
||||
// Allocator-backed with automatic growth
|
||||
Allocator arena = wapp_mem_arena_allocator_init(KiB(16));
|
||||
I32Array dyn = wapp_array_alloc_capacity(i32, &arena, 4, ARRAY_INIT_NONE);
|
||||
wapp_array_append_alloc(i32, &arena, &dyn, &val, ARRAY_INIT_NONE);
|
||||
@@ -142,73 +121,52 @@ wapp_array_append_alloc(i32, &arena, &dyn, &val, ARRAY_INIT_NONE);
|
||||
|
||||
## Doubly-Linked List
|
||||
|
||||
A type-generic doubly-linked list with both stack-allocated (persistent) and allocator-backed nodes.
|
||||
|
||||
```c
|
||||
#include "wapp_base.h"
|
||||
```
|
||||
A type-generic doubly-linked list with node-level operations.
|
||||
|
||||
### Typedefs
|
||||
|
||||
Convenience typedefs for common element types, both for lists and nodes:
|
||||
|
||||
`VoidPtrList`, `C8List`, `C16List`, `C32List`, `U8List`, `U16List`, `U32List`, `U64List`, `B8List`, `I8List`, `I16List`, `I32List`, `I64List`, `F32List`, `F64List`, `F128List`, `UptrList`, `IptrList`, `Str8List`
|
||||
`GenericList`, `GenericNode`, `VoidPtrList`, `U8List`, `U16List`, `U32List`, `U64List`, `B8List`, `I8List`, `I16List`, `I32List`, `I64List`, `F32List`, `F64List`, `F128List`, `UptrList`, `IptrList`, `Str8List` (and corresponding `*Node` types).
|
||||
|
||||
### Creation
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_dbl_list(TYPE)` | Creates an empty stack-allocated doubly-linked list |
|
||||
| `wapp_dbl_list_alloc(TYPE, ALLOCATOR)` | Allocates a list using the given allocator |
|
||||
| `wapp_dbl_list(type)` | Creates an empty stack-allocated list |
|
||||
| `wapp_dbl_list_alloc(type, allocator)` | Allocates a list via allocator |
|
||||
|
||||
### Element Access
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_dbl_list_get(TYPE, LIST, INDEX)` | Returns a pointer to the element at `INDEX` (walks from nearest end) |
|
||||
| `wapp_dbl_list_get_node(TYPE, LIST, INDEX)` | Returns the `GenericNode*` at `INDEX` |
|
||||
| `wapp_dbl_list_get_node_item(TYPE, NODE)` | Returns a pointer to the item in a node |
|
||||
| `wapp_dbl_list_get(type, list, index)` | Returns pointer to element at `index` |
|
||||
| `wapp_dbl_list_get_node(type, list, index)` | Returns the `GenericNode*` at `index` |
|
||||
| `wapp_dbl_list_get_node_item(type, node)` | Returns pointer to the item in a node |
|
||||
|
||||
### Mutation (Stack-allocated persistent nodes)
|
||||
### Mutation
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_dbl_list_push_front(TYPE, LIST, ITEM_PTR)` | Inserts at the front |
|
||||
| `wapp_dbl_list_push_back(TYPE, LIST, ITEM_PTR)` | Appends at the back |
|
||||
| `wapp_dbl_list_insert(TYPE, LIST, ITEM_PTR, INDEX)` | Inserts at `INDEX` |
|
||||
| `wapp_dbl_list_pop_front(TYPE, LIST)` | Removes and returns the front element (or `NULL`) |
|
||||
| `wapp_dbl_list_pop_back(TYPE, LIST)` | Removes and returns the back element (or `NULL`) |
|
||||
| `wapp_dbl_list_remove(TYPE, LIST, INDEX)` | Removes and returns the element at `INDEX` (or `NULL`) |
|
||||
| `wapp_dbl_list_empty(TYPE, LIST)` | Removes all elements from the list |
|
||||
| `wapp_dbl_list_push_front(type, list, item_ptr)` | Inserts at the front |
|
||||
| `wapp_dbl_list_push_back(type, list, item_ptr)` | Appends at the back |
|
||||
| `wapp_dbl_list_insert(type, list, item_ptr, index)` | Inserts at `index` |
|
||||
| `wapp_dbl_list_pop_front(type, list)` | Removes and returns the front element |
|
||||
| `wapp_dbl_list_pop_back(type, list)` | Removes and returns the back element |
|
||||
| `wapp_dbl_list_remove(type, list, index)` | Removes and returns element at `index` |
|
||||
| `wapp_dbl_list_empty(type, list)` | Removes all elements |
|
||||
|
||||
### Mutation (Allocator-backed nodes)
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_dbl_list_push_front_alloc(TYPE, ALLOCATOR, LIST, ITEM_PTR)` | Inserts at front with allocated node |
|
||||
| `wapp_dbl_list_push_back_alloc(TYPE, ALLOCATOR, LIST, ITEM_PTR)` | Appends at back with allocated node |
|
||||
| `wapp_dbl_list_insert_alloc(TYPE, ALLOCATOR, LIST, ITEM_PTR, INDEX)` | Inserts at `INDEX` with allocated node |
|
||||
|
||||
### Node-Level Operations
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_dbl_list_pop_front_node(TYPE, LIST)` | Removes and returns the front `GenericNode*` (or `NULL`) |
|
||||
| `wapp_dbl_list_pop_back_node(TYPE, LIST)` | Removes and returns the back `GenericNode*` (or `NULL`) |
|
||||
| `wapp_dbl_list_remove_node(TYPE, LIST, INDEX)` | Removes and returns the `GenericNode*` at `INDEX` (or `NULL`) |
|
||||
Allocation-backed variants (`_push_front_alloc`, `_push_back_alloc`, `_insert_alloc`) accept an `allocator` parameter for node allocation. Node-level variants (`_pop_front_node`, `_pop_back_node`, `_remove_node`) return the `GenericNode*` directly.
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
Str8List list = wapp_dbl_list(Str8);
|
||||
|
||||
Str8 s1 = wapp_str8_lit("hello");
|
||||
Str8 s2 = wapp_str8_lit("world");
|
||||
|
||||
wapp_dbl_list_push_back(Str8, &list, &s1);
|
||||
wapp_dbl_list_push_back(Str8, &list, &s2);
|
||||
|
||||
Str8 *item = wapp_dbl_list_get(Str8, &list, 0); // pointer to s1
|
||||
Str8 *item = wapp_dbl_list_get(Str8, &list, 0);
|
||||
```
|
||||
|
||||
---
|
||||
@@ -217,51 +175,41 @@ Str8 *item = wapp_dbl_list_get(Str8, &list, 0); // pointer to s1
|
||||
|
||||
A type-generic circular queue (FIFO) backed by a dynamic array.
|
||||
|
||||
```c
|
||||
#include "wapp_base.h"
|
||||
```
|
||||
|
||||
### Typedefs
|
||||
|
||||
Convenience typedefs: `VoidPtrQueue`, `C8Queue`, `C16Queue`, `C32Queue`, `U8Queue`, `U16Queue`, `U32Queue`, `U64Queue`, `B8Queue`, `I8Queue`, `I32Queue`, `I64Queue`, `F32Queue`, `F64Queue`, `F128Queue`, `UptrQueue`, `IptrQueue`, `Str8Queue`
|
||||
`GenericQueue`, `VoidPtrQueue`, `U8Queue`, `U16Queue`, `U32Queue`, `U64Queue`, `I8Queue`, `I16Queue`, `I32Queue`, `I64Queue`, `F32Queue`, `F64Queue`, `F128Queue`, `UptrQueue`, `IptrQueue`, `Str8Queue`
|
||||
|
||||
### Creation
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_queue(TYPE, CAPACITY)` | Creates a stack-allocated queue with the given capacity |
|
||||
| `wapp_queue_alloc(TYPE, ALLOCATOR, CAPACITY)` | Creates an allocator-backed queue |
|
||||
| `wapp_queue(type, capacity)` | Stack-allocated queue |
|
||||
| `wapp_queue_alloc(type, allocator, capacity)` | Allocator-backed queue |
|
||||
|
||||
### Operations
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_queue_push(TYPE, QUEUE, VALUE_PTR)` | Pushes an item to the back. Fails if full. |
|
||||
| `wapp_queue_push_alloc(TYPE, ALLOCATOR, QUEUE, VALUE_PTR)` | Pushes, growing the backing array via allocator if full |
|
||||
| `wapp_queue_pop(TYPE, QUEUE)` | Pops and returns a pointer to the front item |
|
||||
| `wapp_queue_capacity(QUEUE)` | Returns the current capacity |
|
||||
| `wapp_queue_item_size(QUEUE)` | Returns the size of a single element |
|
||||
| `wapp_queue_push(type, queue, value_ptr)` | Pushes to the back (fails if full) |
|
||||
| `wapp_queue_push_alloc(type, allocator, queue, value_ptr)` | Pushes, growing via allocator |
|
||||
| `wapp_queue_pop(type, queue)` | Pops and returns pointer to the front item |
|
||||
| `wapp_queue_capacity(queue)` | Current capacity |
|
||||
| `wapp_queue_item_size(queue)` | Size of a single element |
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
I32Queue queue = wapp_queue(i32, 8);
|
||||
|
||||
i32 val = 42;
|
||||
wapp_queue_push(i32, &queue, &val);
|
||||
|
||||
i32 *result = wapp_queue_pop(i32, &queue); // pointer to 42
|
||||
i32 *result = wapp_queue_pop(i32, &queue);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Str8
|
||||
|
||||
A length-tracked, mutable string type.
|
||||
|
||||
```c
|
||||
#include "wapp_base.h"
|
||||
```
|
||||
A length-tracked mutable string type.
|
||||
|
||||
### Type
|
||||
|
||||
@@ -278,97 +226,90 @@ typedef const Str8 Str8RO; // read-only view
|
||||
|
||||
### Printf Helpers
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `WAPP_STR8_SPEC` | Format specifier (`"%.*s"`) for printf |
|
||||
| `wapp_str8_varg(STRING)` | Expands to `(int)(STRING).size, (STRING).buf` for use with `WAPP_STR8_SPEC` |
|
||||
|
||||
```c
|
||||
#define WAPP_STR8_SPEC "%.*s"
|
||||
#define wapp_str8_varg(s) (int)((s).size), (s).buf
|
||||
|
||||
printf("Value: " WAPP_STR8_SPEC "\n", wapp_str8_varg(my_str));
|
||||
```
|
||||
|
||||
### Creation - Stack
|
||||
### Creation (Stack)
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_str8_buf(CAPACITY)` | Creates an empty string buffer (zeroed) |
|
||||
| `wapp_str8_lit(STRING)` | Creates a mutable copy of a string literal (capacity = 2x length) |
|
||||
| `wapp_str8_lit_ro(STRING)` | Creates a read-only view of a string literal |
|
||||
| `wapp_str8_lit_ro_initialiser_list(STRING)` | For use in static initialisers when compound literals aren't supported |
|
||||
| `wapp_str8_buf(capacity)` | Zeroed empty buffer |
|
||||
| `wapp_str8_lit(string)` | Mutable copy (capacity = 2x length) |
|
||||
| `wapp_str8_lit_ro(string)` | Read-only view of a string literal |
|
||||
| `wapp_str8_lit_ro_initialiser_list(string)` | For use in static initialisers |
|
||||
|
||||
### Creation - Allocator
|
||||
### Creation (Allocator)
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_str8_alloc_buf(allocator, capacity)` | Allocates an empty string buffer via allocator |
|
||||
| `wapp_str8_alloc_and_fill_buf(allocator, capacity)` | Allocates and zero-fills |
|
||||
| `wapp_str8_alloc_cstr(allocator, cstr)` | Copies a C string into an allocated Str8 |
|
||||
| `wapp_str8_alloc_str8(allocator, str)` | Copies a Str8 into an allocated Str8 |
|
||||
| `wapp_str8_alloc_substr(allocator, str, start, end)` | Copies a substring range |
|
||||
| `wapp_str8_alloc_concat(allocator, dst, src)` | Concatenates and returns a new allocated Str8 |
|
||||
| `wapp_str8_dealloc_buf(allocator, str)` | Frees an allocated Str8 |
|
||||
| `wapp_str8_alloc_buf(allocator, capacity)` | Empty buffer via allocator |
|
||||
| `wapp_str8_alloc_and_fill_buf(allocator, capacity)` | Zero-filled buffer |
|
||||
| `wapp_str8_alloc_cstr(allocator, cstr)` | Copy a C string |
|
||||
| `wapp_str8_alloc_str8(allocator, str)` | Copy a Str8 |
|
||||
| `wapp_str8_alloc_substr(allocator, str, start, end)` | Copy a substring |
|
||||
| `wapp_str8_alloc_concat(allocator, dst, src)` | Concatenate into new allocation |
|
||||
| `wapp_str8_dealloc_buf(allocator, str)` | Free an allocated Str8 |
|
||||
|
||||
### Element Access & Mutation
|
||||
### Access & Mutation
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_str8_get(str, index)` | Gets character at `index`. Returns `'\0'` if out of bounds. |
|
||||
| `wapp_str8_set(str, index, c)` | Sets character at `index` |
|
||||
| `wapp_str8_push_back(str, c)` | Appends a single character |
|
||||
| `wapp_str8_get(str, index)` | Character at `index` (or `'\0'` if out of bounds) |
|
||||
| `wapp_str8_set(str, index, c)` | Set character at `index` |
|
||||
| `wapp_str8_push_back(str, c)` | Append a single character |
|
||||
|
||||
### Comparison & Search
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_str8_equal(s1, s2)` | Full string equality |
|
||||
| `wapp_str8_equal_to_count(s1, s2, count)` | Equality limited to the first `count` characters |
|
||||
| `wapp_str8_find(str, substr)` | Forward search. Returns index or `-1`. |
|
||||
| `wapp_str8_rfind(str, substr)` | Reverse search. Returns index or `-1`. |
|
||||
| `wapp_str8_equal(s1, s2)` | Full equality |
|
||||
| `wapp_str8_equal_to_count(s1, s2, n)` | Equality limited to first `n` characters |
|
||||
| `wapp_str8_find(str, substr)` | Forward search (returns index or `-1`) |
|
||||
| `wapp_str8_rfind(str, substr)` | Reverse search (returns index or `-1`) |
|
||||
|
||||
### Content Manipulation
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_str8_slice(str, start, end)` | Returns a read-only substring view |
|
||||
| `wapp_str8_concat_capped(dst, src)` | Concatenates within `dst` capacity |
|
||||
| `wapp_str8_copy_cstr_capped(dst, cstr)` | Copies a C string into a Str8 |
|
||||
| `wapp_str8_copy_str8_capped(dst, src)` | Copies a Str8 into another Str8 |
|
||||
| `wapp_str8_copy_to_cstr(dst, src, dst_capacity)` | Copies Str8 content to a C string buffer |
|
||||
| `wapp_str8_format(dst, format, ...)` | printf-style formatting into a Str8 |
|
||||
| `wapp_str8_to_lower(dst, src)` | Converts to lowercase |
|
||||
| `wapp_str8_to_upper(dst, src)` | Converts to uppercase |
|
||||
| `wapp_str8_from_bytes(dst, src)` | Converts a `U8Array` of bytes into a Str8 |
|
||||
| `wapp_str8_slice(str, start, end)` | Read-only substring view |
|
||||
| `wapp_str8_concat_capped(dst, src)` | Concatenate within capacity |
|
||||
| `wapp_str8_copy_cstr_capped(dst, cstr)` | Copy C string into Str8 |
|
||||
| `wapp_str8_copy_str8_capped(dst, src)` | Copy Str8 into Str8 |
|
||||
| `wapp_str8_copy_to_cstr(dst, src, dst_capacity)` | Copy to C string buffer |
|
||||
| `wapp_str8_format(dst, format, ...)` | printf-style formatting |
|
||||
| `wapp_str8_to_lower(dst, src)` | Convert to lowercase |
|
||||
| `wapp_str8_to_upper(dst, src)` | Convert to uppercase |
|
||||
| `wapp_str8_from_bytes(dst, src)` | Convert `U8Array` bytes to Str8 |
|
||||
|
||||
### Split and Join
|
||||
### Split & Join
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_str8_split(allocator, str, delimiter)` | Splits forward into a `Str8List` (all parts) |
|
||||
| `wapp_str8_split_with_max(allocator, str, delimiter, max_splits)` | Splits forward with a maximum number of splits |
|
||||
| `wapp_str8_rsplit(allocator, str, delimiter)` | Splits in reverse |
|
||||
| `wapp_str8_rsplit_with_max(allocator, str, delimiter, max_splits)` | Splits in reverse with a maximum |
|
||||
| `wapp_str8_join(allocator, list, delimiter)` | Joins a `Str8List` with a delimiter |
|
||||
| `wapp_str8_split(allocator, str, delimiter)` | Split into `Str8List` |
|
||||
| `wapp_str8_split_with_max(allocator, str, delimiter, max_splits)` | Split with maximum parts |
|
||||
| `wapp_str8_rsplit(allocator, str, delimiter)` | Reverse split |
|
||||
| `wapp_str8_rsplit_with_max(allocator, str, delimiter, max_splits)` | Reverse split with maximum |
|
||||
| `wapp_str8_join(allocator, list, delimiter)` | Join a `Str8List` with delimiter |
|
||||
| `wapp_str8_list_total_size(list)` | Sum of all string sizes in a list |
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
Str8 s = wapp_str8_lit("Hello, World!");
|
||||
printf(WAPP_STR8_SPEC "\n", wapp_str8_varg(s)); // prints "Hello, World!"
|
||||
|
||||
Str8 buf = wapp_str8_buf(256);
|
||||
wapp_str8_copy_cstr_capped(&buf, "Hello");
|
||||
wapp_str8_push_back(&buf, '!');
|
||||
printf(WAPP_STR8_SPEC "\n", wapp_str8_varg(s));
|
||||
|
||||
// Formatting
|
||||
Str8 buf = wapp_str8_buf(256);
|
||||
wapp_str8_format(&buf, "Value: %d", 42);
|
||||
|
||||
// Split
|
||||
// Split and join
|
||||
Allocator arena = wapp_mem_arena_allocator_init(KiB(16));
|
||||
Str8 data = wapp_str8_lit("a,b,c");
|
||||
Str8 delim = wapp_str8_lit_ro(",");
|
||||
Str8List *parts = wapp_str8_split(&arena, &data, &delim);
|
||||
|
||||
// Join
|
||||
Str8 *joined = wapp_str8_join(&arena, parts, &delim);
|
||||
```
|
||||
|
||||
+100
-94
@@ -1,106 +1,109 @@
|
||||
# common
|
||||
|
||||
The `common` package provides foundational type definitions, platform detection, assertion macros, and miscellaneous utilities used by all other packages.
|
||||
|
||||
**Dependencies:** None
|
||||
|
||||
---
|
||||
|
||||
## Aliases
|
||||
|
||||
Convenient typedefs for primitive types and qualifiers.
|
||||
The `common` package provides foundational type definitions, platform detection, assertion macros, and miscellaneous utilities used across the entire library.
|
||||
|
||||
```c
|
||||
#include "wapp_common.h"
|
||||
```
|
||||
|
||||
### Integer Types
|
||||
**Dependencies:** None
|
||||
|
||||
| Type | Underlying |
|
||||
|------|-----------|
|
||||
| `u8`, `u16`, `u32`, `u64` | `uint8_t`, `uint16_t`, `uint32_t`, `uint64_t` |
|
||||
| `i8`, `i16`, `i32`, `i64` | `int8_t`, `int16_t`, `int32_t`, `int64_t` |
|
||||
| `b8` | `uint8_t` (boolean) |
|
||||
| `uptr`, `iptr` | `uintptr_t`, `intptr_t` |
|
||||
---
|
||||
|
||||
### Character Types
|
||||
## Type Aliases
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `c8` | UTF-8 code unit (`uint8_t` or `char8_t`) |
|
||||
| `c16` | UTF-16 code unit (`uint16_t` or `char16_t`) |
|
||||
| `c32` | UTF-32 code unit (`uint32_t` or `char32_t`) |
|
||||
Convenient typedefs for primitive types.
|
||||
|
||||
### Floating-Point Types
|
||||
```c
|
||||
// Integer types
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef int8_t i8;
|
||||
typedef int16_t i16;
|
||||
typedef int32_t i32;
|
||||
typedef int64_t i64;
|
||||
typedef uint8_t b8; // boolean
|
||||
typedef uintptr_t uptr;
|
||||
typedef intptr_t iptr;
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `f32` | 32-bit float |
|
||||
| `f64` | 64-bit double |
|
||||
| `f128` | 80+ bit long double |
|
||||
// Character types
|
||||
typedef uint8_t c8; // UTF-8 code unit
|
||||
typedef uint16_t c16; // UTF-16 code unit
|
||||
typedef uint32_t c32; // UTF-32 code unit
|
||||
|
||||
// Floating-point types
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
typedef long double f128;
|
||||
```
|
||||
|
||||
Where available, `c8`/`c16`/`c32` map to `char8_t`/`char16_t`/`char32_t`.
|
||||
|
||||
### Boolean Macros (C only)
|
||||
|
||||
In C, `true` and `false` are defined as `(b8)1` and `(b8)0` respectively when unavailable.
|
||||
In C, `true` and `false` are defined as `(b8)1` and `(b8)0` when not already available.
|
||||
|
||||
### Qualifier Macros
|
||||
|
||||
| Macro | Expands To | Description |
|
||||
|-------|-----------|-------------|
|
||||
| `wapp_extern` | `extern` | External linkage |
|
||||
| `wapp_intern` | `static` | Internal linkage |
|
||||
| `wapp_persist` | `static` | Persistent storage duration |
|
||||
| `wapp_class_mem` | `static` | Class-level static (C++ only) |
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_extern` | External linkage (`extern`) |
|
||||
| `wapp_intern` | Internal linkage (`static`) |
|
||||
| `wapp_persist` | Persistent storage (`static`) |
|
||||
| `wapp_class_mem` | Class-level static (C++ only) |
|
||||
|
||||
### C/C++ Interop
|
||||
|
||||
```c
|
||||
BEGIN_C_LINKAGE // extern "C" { (C++ only)
|
||||
END_C_LINKAGE // } (C++ only)
|
||||
BEGIN_C_LINKAGE // extern "C" { (C++ only)
|
||||
END_C_LINKAGE // } (C++ only)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Platform Detection
|
||||
|
||||
The library auto-detects the target platform and defines the appropriate macros.
|
||||
The library auto-detects the target platform and language version at compile time.
|
||||
|
||||
### Platform Macros
|
||||
```c
|
||||
#include "wapp_common.h"
|
||||
```
|
||||
|
||||
**OS Family:**
|
||||
- `WAPP_PLATFORM_POSIX` - Any POSIX-compliant system
|
||||
- `WAPP_PLATFORM_WINDOWS` - Any Windows system (including Cygwin)
|
||||
- `WAPP_PLATFORM_UNIX` - Traditional Unix systems
|
||||
### Operating Systems
|
||||
|
||||
**Specific Platforms:**
|
||||
- `WAPP_PLATFORM_LINUX` - Linux
|
||||
- `WAPP_PLATFORM_MACOS` - macOS
|
||||
- `WAPP_PLATFORM_IOS` - iOS
|
||||
- `WAPP_PLATFORM_ANDROID` - Android
|
||||
- `WAPP_PLATFORM_FREE_BSD` - FreeBSD
|
||||
- `WAPP_PLATFORM_NET_BSD` - NetBSD
|
||||
- `WAPP_PLATFORM_OPEN_BSD` - OpenBSD
|
||||
- `WAPP_PLATFORM_DRAGON_FLY` - DragonFly BSD
|
||||
- `WAPP_PLATFORM_GNU` - GNU/Hurd
|
||||
- `WAPP_PLATFORM_CYGWIN` - Cygwin
|
||||
- `WAPP_PLATFORM_WINDOWS64` - 64-bit Windows
|
||||
- `WAPP_PLATFORM_WINDOWS32` - 32-bit Windows
|
||||
- `WAPP_PLATFORM_APPLE` - Any Apple platform
|
||||
| Macro | Targets |
|
||||
|-------|---------|
|
||||
| `WAPP_PLATFORM_POSIX` | All POSIX-compliant systems |
|
||||
| `WAPP_PLATFORM_LINUX` | Linux |
|
||||
| `WAPP_PLATFORM_MACOS` | macOS |
|
||||
| `WAPP_PLATFORM_IOS` | iOS |
|
||||
| `WAPP_PLATFORM_ANDROID` | Android |
|
||||
| `WAPP_PLATFORM_FREE_BSD` | FreeBSD |
|
||||
| `WAPP_PLATFORM_NET_BSD` | NetBSD |
|
||||
| `WAPP_PLATFORM_OPEN_BSD` | OpenBSD |
|
||||
| `WAPP_PLATFORM_DRAGON_FLY` | DragonFly BSD |
|
||||
| `WAPP_PLATFORM_GNU` | GNU/Hurd |
|
||||
| `WAPP_PLATFORM_CYGWIN` | Cygwin |
|
||||
| `WAPP_PLATFORM_WINDOWS` | All Windows (32-bit, 64-bit, Cygwin) |
|
||||
| `WAPP_PLATFORM_APPLE` | All Apple platforms |
|
||||
|
||||
### Language Version Macros
|
||||
### Language Version
|
||||
|
||||
**C Language:**
|
||||
- `WAPP_PLATFORM_C` - Defined when compiling as C
|
||||
- `WAPP_PLATFORM_C89`, `WAPP_PLATFORM_C99`, `WAPP_PLATFORM_C11`, `WAPP_PLATFORM_C17`, `WAPP_PLATFORM_C23`
|
||||
|
||||
**C++ Language:**
|
||||
- `WAPP_PLATFORM_CPP` - Defined when compiling as C++
|
||||
- `WAPP_PLATFORM_CPP98`, `WAPP_PLATFORM_CPP11`, `WAPP_PLATFORM_CPP14`, `WAPP_PLATFORM_CPP17`, `WAPP_PLATFORM_CPP20`, `WAPP_PLATFORM_CPP23`
|
||||
| Macro | Defined When |
|
||||
|-------|-------------|
|
||||
| `WAPP_PLATFORM_C` | Compiling as C |
|
||||
| `WAPP_PLATFORM_C99`, `WAPP_PLATFORM_C11`, `WAPP_PLATFORM_C17`, `WAPP_PLATFORM_C23` | Specific C standard versions |
|
||||
| `WAPP_PLATFORM_CPP` | Compiling as C++ |
|
||||
| `WAPP_PLATFORM_CPP11`, `WAPP_PLATFORM_CPP14`, `WAPP_PLATFORM_CPP17`, `WAPP_PLATFORM_CPP20`, `WAPP_PLATFORM_CPP23` | Specific C++ standard versions |
|
||||
|
||||
---
|
||||
|
||||
## Assertions
|
||||
|
||||
Runtime and compile-time assertion macros with configurable behaviour.
|
||||
|
||||
```c
|
||||
#include "wapp_common.h"
|
||||
```
|
||||
@@ -109,11 +112,16 @@ The library auto-detects the target platform and defines the appropriate macros.
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_static_assert(EXPR, MSG)` | Compile-time assertion using `extern char` trick |
|
||||
| `wapp_runtime_assert(EXPR, MSG)` | Runtime assertion (disabled by `WAPP_NO_RUNTIME_ASSERT`) |
|
||||
| `wapp_debug_assert(EXPR, MSG)` | Runtime assertion, only active when `WAPP_DEBUG_ASSERT` is defined |
|
||||
| `wapp_static_assert(expr, msg)` | Compile-time assertion via `extern char` trick |
|
||||
| `wapp_runtime_assert(expr, msg)` | Runtime check; aborts with file/line/function info on failure |
|
||||
| `wapp_debug_assert(expr, msg)` | Like `wapp_runtime_assert`, but only active when `WAPP_DEBUG_ASSERT` is defined |
|
||||
|
||||
On failure, assertions print the file, line, function, expression value, and diagnostic message to `stderr`, then call `abort()`.
|
||||
On failure, the diagnostic includes the file name, line number, function name, expression value, and message:
|
||||
|
||||
```
|
||||
src/foo.c:42 (In function `load_config`): Assertion failed (1)
|
||||
Diagnostic: config should not be NULL
|
||||
```
|
||||
|
||||
### Build Configuration
|
||||
|
||||
@@ -121,7 +129,7 @@ On failure, assertions print the file, line, function, expression value, and dia
|
||||
// Enable debug assertions during development
|
||||
#define WAPP_DEBUG_ASSERT
|
||||
|
||||
// Disable all runtime assertions for release
|
||||
// Disable all runtime assertions for release builds
|
||||
#define WAPP_NO_RUNTIME_ASSERT
|
||||
```
|
||||
|
||||
@@ -129,6 +137,8 @@ On failure, assertions print the file, line, function, expression value, and dia
|
||||
|
||||
## Misc Utilities
|
||||
|
||||
Helper macros for size literals, alignment, and bit operations.
|
||||
|
||||
```c
|
||||
#include "wapp_common.h"
|
||||
```
|
||||
@@ -137,32 +147,28 @@ On failure, assertions print the file, line, function, expression value, and dia
|
||||
|
||||
Binary (IEC) prefixes:
|
||||
|
||||
| Macro | Formula |
|
||||
|-------|---------|
|
||||
| `KiB(SIZE)` | `SIZE << 10` |
|
||||
| `MiB(SIZE)` | `SIZE << 20` |
|
||||
| `GiB(SIZE)` | `SIZE << 30` |
|
||||
| `TiB(SIZE)` | `SIZE << 40` |
|
||||
| `PiB(SIZE)` | `SIZE << 50` |
|
||||
| `EiB(SIZE)` | `SIZE << 60` |
|
||||
| Macro | Expands To |
|
||||
|-------|-----------|
|
||||
| `KiB(n)` | `n << 10` |
|
||||
| `MiB(n)` | `n << 20` |
|
||||
| `GiB(n)` | `n << 30` |
|
||||
| `TiB(n)` | `n << 40` |
|
||||
|
||||
Decimal (SI) prefixes:
|
||||
|
||||
| Macro | Formula |
|
||||
|-------|---------|
|
||||
| `KB(SIZE)` | `SIZE * 1000` |
|
||||
| `MB(SIZE)` | `KB(SIZE) * 1000` |
|
||||
| `GB(SIZE)` | `MB(SIZE) * 1000` |
|
||||
| `TB(SIZE)` | `GB(SIZE) * 1000` |
|
||||
| `PB(SIZE)` | `TB(SIZE) * 1000` |
|
||||
| `EB(SIZE)` | `PB(SIZE) * 1000` |
|
||||
| Macro | Expands To |
|
||||
|-------|-----------|
|
||||
| `KB(n)` | `n * 1000` |
|
||||
| `MB(n)` | `KB(n) * 1000` |
|
||||
| `GB(n)` | `MB(n) * 1000` |
|
||||
| `TB(n)` | `GB(n) * 1000` |
|
||||
|
||||
### Utility Macros
|
||||
### Other Utilities
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_misc_utils_reserve_padding(SIZE)` | Inserts padding bytes to align a struct field to pointer size |
|
||||
| `wapp_misc_utils_u64_round_up_pow2(X)` | Rounds `X` up to the nearest power of 2 |
|
||||
| `wapp_is_power_of_two(NUM)` | Checks if `NUM` is a power of 2 |
|
||||
| `wapp_pointer_offset(PTR, OFFSET)` | Adds a byte offset to a pointer |
|
||||
| `wapp_misc_utils_va_args_count(T, ...)` | Returns the number of variadic arguments of type `T` |
|
||||
| Macro / Function | Description |
|
||||
|------------------|-------------|
|
||||
| `wapp_misc_utils_reserve_padding(size)` | Inserts padding to align a struct field to pointer size |
|
||||
| `wapp_misc_utils_u64_round_up_pow2(x)` | Rounds `x` up to the nearest power of 2 |
|
||||
| `wapp_is_power_of_two(n)` | Tests whether `n` is a power of 2 |
|
||||
| `wapp_pointer_offset(ptr, offset)` | Adds a byte offset to a pointer |
|
||||
| `wapp_misc_utils_va_args_count(t, ...)` | Returns the number of variadic arguments of type `t` |
|
||||
|
||||
+68
-104
@@ -1,6 +1,10 @@
|
||||
# os
|
||||
|
||||
The `os` package provides OS-level abstractions: file I/O, memory-mapped arena allocators, shell command execution, terminal colour output, and path manipulation.
|
||||
The `os` package provides OS-level abstractions: virtual memory, arena allocators, file I/O, shell command execution, terminal colour output, and path manipulation.
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
|
||||
**Dependencies:** common, base
|
||||
|
||||
@@ -10,17 +14,13 @@ The `os` package provides OS-level abstractions: file I/O, memory-mapped arena a
|
||||
|
||||
Low-level virtual memory allocation.
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
|
||||
### Types
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `MemAccess` | Memory access permissions: `WAPP_MEM_ACCESS_NONE`, `WAPP_MEM_ACCESS_READ_ONLY`, `WAPP_MEM_ACCESS_EXEC_ONLY`, `WAPP_MEM_ACCESS_READ_WRITE`, `WAPP_MEM_ACCESS_READ_EXEC`, `WAPP_MEM_ACCESS_READ_WRITE_EXEC` |
|
||||
| `MemAllocFlags` | Allocation flags: `WAPP_MEM_ALLOC_RESERVE`, `WAPP_MEM_ALLOC_COMMIT` |
|
||||
| `MemInitType` | Initialization: `WAPP_MEM_INIT_UNINITIALISED`, `WAPP_MEM_INIT_INITIALISED` |
|
||||
| Type | Values |
|
||||
|------|--------|
|
||||
| `MemAccess` | `WAPP_MEM_ACCESS_NONE`, `WAPP_MEM_ACCESS_READ_ONLY`, `WAPP_MEM_ACCESS_EXEC_ONLY`, `WAPP_MEM_ACCESS_READ_WRITE`, `WAPP_MEM_ACCESS_READ_EXEC`, `WAPP_MEM_ACCESS_READ_WRITE_EXEC` |
|
||||
| `MemAllocFlags` | `WAPP_MEM_ALLOC_RESERVE`, `WAPP_MEM_ALLOC_COMMIT` |
|
||||
| `MemInitType` | `WAPP_MEM_INIT_UNINITIALISED`, `WAPP_MEM_INIT_INITIALISED` |
|
||||
|
||||
### Functions
|
||||
|
||||
@@ -33,37 +33,35 @@ Low-level virtual memory allocation.
|
||||
|
||||
On POSIX, `wapp_os_mem_alloc` wraps `mmap` and `wapp_os_mem_free` wraps `munmap`. On Windows they wrap `VirtualAlloc` and `VirtualFree`.
|
||||
|
||||
POSIX uses `MAP_POPULATE` (Linux/GNU) or `MAP_PREFAULT_READ` (FreeBSD) for the commit flag. Other POSIX platforms (BSD, Apple) set both flags to `0`, relying on lazy mapping.
|
||||
|
||||
On Windows, `WAPP_MEM_ALLOC_RESERVE` maps to `MEM_RESERVE` and `WAPP_MEM_ALLOC_COMMIT` maps to `MEM_COMMIT`.
|
||||
The commit flag behaviour varies by platform:
|
||||
- Linux/GNU: `WAPP_MEM_ALLOC_COMMIT` maps to `MAP_POPULATE`
|
||||
- FreeBSD: `WAPP_MEM_ALLOC_COMMIT` maps to `MAP_PREFAULT_READ`
|
||||
- Other BSD/Apple/Unix: both flags are `0` (lazy mapping)
|
||||
- Windows: `WAPP_MEM_ALLOC_RESERVE` = `MEM_RESERVE`, `WAPP_MEM_ALLOC_COMMIT` = `MEM_COMMIT`
|
||||
|
||||
---
|
||||
|
||||
## Arena Allocator
|
||||
|
||||
A bump allocator backed by OS virtual memory (or a user-provided buffer). Provides fast, sequential allocations with temporary allocation scoping (memory stacking).
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
A bump allocator backed by OS virtual memory (or a user-provided buffer). Provides fast sequential allocations with temporary scope support.
|
||||
|
||||
### Initialization
|
||||
|
||||
| Function / Macro | Description |
|
||||
|------------------|-------------|
|
||||
| `wapp_mem_arena_init_allocated(arena, base_capacity)` | Initialises an arena with reserved OS memory |
|
||||
| `wapp_mem_arena_init_allocated_commit(arena, base_capacity)` | Reserves and commits OS memory |
|
||||
| `wapp_mem_arena_init_allocated_zero(arena, base_capacity)` | Reserves and zeroes OS memory |
|
||||
| `wapp_mem_arena_init_allocated_commit_and_zero(arena, base_capacity)` | Reserves, commits, and zeroes |
|
||||
| `wapp_mem_arena_init_allocated_custom(arena, base_capacity, flags, zero)` | Full control over initialization |
|
||||
| `wapp_mem_arena_init_buffer(arena, buffer, buffer_size)` | Initialises an arena from a pre-existing buffer |
|
||||
| `wapp_mem_arena_init_allocated(arena, base_capacity)` | Arena backed by reserved OS memory |
|
||||
| `wapp_mem_arena_init_allocated_commit(arena, base_capacity)` | Reserved and committed |
|
||||
| `wapp_mem_arena_init_allocated_zero(arena, base_capacity)` | Reserved and zeroed |
|
||||
| `wapp_mem_arena_init_allocated_commit_and_zero(arena, base_capacity)` | Reserved, committed, and zeroed |
|
||||
| `wapp_mem_arena_init_allocated_custom(arena, base_capacity, flags, zero)` | Full control |
|
||||
| `wapp_mem_arena_init_buffer(arena, buffer, buffer_size)` | Arena from a pre-existing buffer |
|
||||
|
||||
### Allocation
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_mem_arena_alloc(arena, size)` | Bump-allocates memory |
|
||||
| `wapp_mem_arena_alloc_aligned(arena, size, alignment)` | Bump-allocates aligned memory |
|
||||
| `wapp_mem_arena_alloc(arena, size)` | Bump allocates memory |
|
||||
| `wapp_mem_arena_alloc_aligned(arena, size, alignment)` | Bump allocates aligned memory |
|
||||
| `wapp_mem_arena_realloc(arena, ptr, old_size, new_size)` | Reallocates within the arena |
|
||||
| `wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment)` | Reallocates aligned |
|
||||
|
||||
@@ -71,10 +69,10 @@ A bump allocator backed by OS virtual memory (or a user-provided buffer). Provid
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_mem_arena_temp_begin(arena)` | Saves the current position (start of temp scope) |
|
||||
| `wapp_mem_arena_temp_end(arena)` | Rewinds to the saved position (ends temp scope) |
|
||||
| `wapp_mem_arena_temp_begin(arena)` | Saves current position |
|
||||
| `wapp_mem_arena_temp_end(arena)` | Rewinds to saved position (ends temporary scope) |
|
||||
| `wapp_mem_arena_clear(arena)` | Zeroes all arena memory |
|
||||
| `wapp_mem_arena_destroy(arena)` | Frees the arena and sets pointer to `NULL` |
|
||||
| `wapp_mem_arena_destroy(arena)` | Frees arena and sets pointer to `NULL` |
|
||||
|
||||
### Example
|
||||
|
||||
@@ -84,7 +82,7 @@ wapp_mem_arena_init_allocated(&arena, MiB(1));
|
||||
|
||||
i32 *numbers = wapp_mem_arena_alloc(arena, 100 * sizeof(i32));
|
||||
|
||||
// Temporary scope
|
||||
// Temporary allocation scope
|
||||
wapp_mem_arena_temp_begin(arena);
|
||||
// ... temporary allocations ...
|
||||
wapp_mem_arena_temp_end(arena); // memory rewound
|
||||
@@ -94,15 +92,11 @@ wapp_mem_arena_destroy(&arena); // arena is now NULL
|
||||
|
||||
### Arena-backed Allocator
|
||||
|
||||
Wraps an `Arena` in the `Allocator` interface (from base).
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
Wraps an `Arena` in the `Allocator` interface from base.
|
||||
|
||||
| Function / Macro | Description |
|
||||
|------------------|-------------|
|
||||
| `wapp_mem_arena_allocator_init(capacity)` | Creates an `Allocator` backed by a new arena |
|
||||
| `wapp_mem_arena_allocator_init(capacity)` | `Allocator` backed by a new arena |
|
||||
| `wapp_mem_arena_allocator_init_commit(capacity)` | With committed memory |
|
||||
| `wapp_mem_arena_allocator_init_zero(capacity)` | With zeroed memory |
|
||||
| `wapp_mem_arena_allocator_init_commit_and_zero(capacity)` | With committed and zeroed memory |
|
||||
@@ -113,7 +107,7 @@ Wraps an `Arena` in the `Allocator` interface (from base).
|
||||
| `wapp_mem_arena_allocator_clear(allocator)` | Clear arena |
|
||||
| `wapp_mem_arena_allocator_destroy(allocator)` | Destroy arena |
|
||||
|
||||
**Note:** The arena allocator only supports `alloc` and `alloc_aligned`. `realloc`, `realloc_aligned`, and `free` are not implemented (individual frees are unsupported by arenas).
|
||||
> **Note:** The arena allocator only supports `alloc` and `alloc_aligned`. `realloc`, `realloc_aligned`, and `free` are not implemented (arenas do not support individual frees).
|
||||
|
||||
```c
|
||||
Allocator allocator = wapp_mem_arena_allocator_init(KiB(16));
|
||||
@@ -125,32 +119,28 @@ wapp_mem_arena_allocator_destroy(&allocator);
|
||||
|
||||
## File I/O
|
||||
|
||||
Cross-platform file operations.
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
Cross-platform file operations with array-level read/write support.
|
||||
|
||||
### Types
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `WFile` | Opaque file handle |
|
||||
| `FileAccessMode` | Access mode enum |
|
||||
| `FileSeekOrigin` | Seek origin enum |
|
||||
| `FileAccessMode` | Access mode (see below) |
|
||||
| `FileSeekOrigin` | Seek origin |
|
||||
|
||||
### File Access Modes
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `WAPP_ACCESS_READ` | Read-only (`r`) |
|
||||
| `WAPP_ACCESS_WRITE` | Write-only, truncates (`w`) |
|
||||
| `WAPP_ACCESS_APPEND` | Append (`a`) |
|
||||
| `WAPP_ACCESS_READ_EX` | Read/write (`r+`) |
|
||||
| `WAPP_ACCESS_WRITE_EX` | Read/write, truncates (`w+`) |
|
||||
| `WAPP_ACCESS_APPEND_EX` | Read/append (`a+`) |
|
||||
| `WAPP_ACCESS_WRITE_FAIL_ON_EXIST` | Write, fail if exists (`wx`) |
|
||||
| `WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX` | Read/write, fail if exists (`wx+`) |
|
||||
| Mode | stdio Equivalent | Description |
|
||||
|------|-----------------|-------------|
|
||||
| `WAPP_ACCESS_READ` | `r` | Read-only |
|
||||
| `WAPP_ACCESS_WRITE` | `w` | Write-only, truncates |
|
||||
| `WAPP_ACCESS_APPEND` | `a` | Append |
|
||||
| `WAPP_ACCESS_READ_EX` | `r+` | Read/write |
|
||||
| `WAPP_ACCESS_WRITE_EX` | `w+` | Read/write, truncates |
|
||||
| `WAPP_ACCESS_APPEND_EX` | `a+` | Read/append |
|
||||
| `WAPP_ACCESS_WRITE_FAIL_ON_EXIST` | `wx` | Write, fail if exists |
|
||||
| `WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX` | `wx+` | Read/write, fail if exists |
|
||||
|
||||
### Seek Origins
|
||||
|
||||
@@ -166,24 +156,20 @@ Cross-platform file operations.
|
||||
|----------|-------------|
|
||||
| `wapp_file_open(allocator, filepath, mode)` | Opens a file |
|
||||
| `wapp_file_close(file)` | Closes a file |
|
||||
| `wapp_file_read(buffer, file, byte_count)` | Reads raw bytes. Returns bytes read. |
|
||||
| `wapp_file_write(buffer, file, byte_count)` | Writes raw bytes. Returns bytes written or negative on error. |
|
||||
| `wapp_file_read(buf, file, byte_count)` | Reads raw bytes. Returns bytes read. |
|
||||
| `wapp_file_write(buf, file, byte_count)` | Writes raw bytes. Returns count or negative on error. |
|
||||
| `wapp_file_read_array(dst_array, file, item_count)` | Reads array elements from file |
|
||||
| `wapp_file_write_array(src_array, file, item_count)` | Writes array elements to file |
|
||||
| `wapp_file_seek(file, offset, origin)` | Seeks to a position. Returns the new position or negative on error. |
|
||||
| `wapp_file_get_current_position(file)` | Returns the current file cursor position or negative on error |
|
||||
| `wapp_file_get_length(file)` | Returns the file size in bytes |
|
||||
| `wapp_file_seek(file, offset, origin)` | Seeks to position. Returns new position or negative. |
|
||||
| `wapp_file_get_current_position(file)` | Current file cursor position |
|
||||
| `wapp_file_get_length(file)` | File size in bytes |
|
||||
| `wapp_file_flush(file)` | Flushes file buffers |
|
||||
| `wapp_file_rename(old_path, new_path)` | Renames a file |
|
||||
| `wapp_file_remove(path)` | Deletes a file |
|
||||
|
||||
### Platform Notes
|
||||
|
||||
On POSIX, `WFile` stores an `i32 fd` (file descriptor) and all operations wrap POSIX system calls (`open`, `read`, `write`, `lseek`, `ftruncate`, `close`, `rename`, `unlink`).
|
||||
|
||||
On Windows, `WFile` stores a `HANDLE` and operations wrap Win32 API calls (`CreateFile`, `ReadFile`, `WriteFile`, `SetFilePointerEx`, `GetFileSizeEx`, `FlushFileBuffers`, `CloseHandle`, `MoveFileEx`, `DeleteFile`).
|
||||
|
||||
Newline convention: `END_OF_LINE` is `"\n"` on POSIX and `"\r\n"` on Windows.
|
||||
On POSIX, `WFile` wraps an `i32 fd` and operations use POSIX system calls (`open`, `read`, `write`, `lseek`, `close`, `rename`, `unlink`). On Windows, `WFile` wraps a `HANDLE` and operations use Win32 API (`CreateFile`, `ReadFile`, `WriteFile`, `SetFilePointerEx`, `CloseHandle`, `MoveFileEx`, `DeleteFile`).
|
||||
|
||||
### Example
|
||||
|
||||
@@ -198,10 +184,9 @@ I32Array arr = wapp_array_from_preallcated_buffer(i32, data, sizeof(data));
|
||||
wapp_file_write_array(arr, f, 3);
|
||||
wapp_file_close(f);
|
||||
|
||||
// Read
|
||||
// Read back
|
||||
f = wapp_file_open(&arena, &filename, WAPP_ACCESS_READ);
|
||||
i64 len = wapp_file_get_length(f);
|
||||
// ... read into buffer ...
|
||||
wapp_file_close(f);
|
||||
wapp_file_remove(&filename);
|
||||
```
|
||||
@@ -212,10 +197,6 @@ wapp_file_remove(&filename);
|
||||
|
||||
Execute shell commands and capture or discard their output.
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
|
||||
### Types
|
||||
|
||||
```c
|
||||
@@ -245,26 +226,23 @@ typedef struct CMDResult {
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_shell_commander_execute(out_handling, out_buf, cmd)` | Executes a command. When `out_handling` is `SHELL_OUTPUT_CAPTURE`, `out_buf` must point to a `Str8` buffer. |
|
||||
| `wapp_shell_commander_execute(out_handling, out_buf, cmd)` | Executes a command. Requires a `Str8` buffer when using `SHELL_OUTPUT_CAPTURE`. |
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
// Build command
|
||||
Str8List cmd = wapp_dbl_list(Str8);
|
||||
Str8 prog = wapp_str8_lit("echo");
|
||||
Str8 arg = wapp_str8_lit("hello world");
|
||||
wapp_dbl_list_push_back(Str8, &cmd, &prog);
|
||||
wapp_dbl_list_push_back(Str8, &cmd, &arg);
|
||||
|
||||
// Execute and discard output
|
||||
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
|
||||
// result.exited == true, result.exit_code == 0
|
||||
// Discard output
|
||||
CMDResult r = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
|
||||
|
||||
// Execute and capture output
|
||||
// Capture output
|
||||
Str8 buf = wapp_str8_buf(64);
|
||||
result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
|
||||
// buf contains "hello world\n"
|
||||
r = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
|
||||
```
|
||||
|
||||
---
|
||||
@@ -273,39 +251,27 @@ result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
|
||||
|
||||
Print coloured text to the terminal.
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
|
||||
### Colour Values
|
||||
|
||||
| Colour | Description |
|
||||
|--------|-------------|
|
||||
| `WAPP_TERM_COLOUR_FG_BLACK` through `WAPP_TERM_COLOUR_FG_WHITE` | Standard foreground colours |
|
||||
| `WAPP_TERM_COLOUR_FG_BR_BLACK` through `WAPP_TERM_COLOUR_FG_BR_WHITE` | Bright foreground variants |
|
||||
| `WAPP_TERM_COLOUR_CLEAR` | Reset to default |
|
||||
Available colours: `WAPP_TERM_COLOUR_FG_BLACK`, `WAPP_TERM_COLOUR_FG_RED`, `WAPP_TERM_COLOUR_FG_GREEN`, `WAPP_TERM_COLOUR_FG_BLUE`, `WAPP_TERM_COLOUR_FG_CYAN`, `WAPP_TERM_COLOUR_FG_MAGENTA`, `WAPP_TERM_COLOUR_FG_YELLOW`, `WAPP_TERM_COLOUR_FG_WHITE`, plus bright variants (`WAPP_TERM_COLOUR_FG_BR_*`) and `WAPP_TERM_COLOUR_CLEAR`.
|
||||
|
||||
### Functions
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_shell_termcolour_print_text(text, colour)` | Prints text in the specified colour |
|
||||
| `wapp_shell_termcolour_clear_colour()` | Resets terminal colours to default |
|
||||
| `wapp_shell_termcolour_clear_colour()` | Resets to default terminal colours |
|
||||
|
||||
---
|
||||
|
||||
## CPath
|
||||
|
||||
Cross-platform path manipulation utilities.
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
Cross-platform path manipulation.
|
||||
|
||||
### Constants
|
||||
|
||||
| Constant | Value |
|
||||
|----------|-------|
|
||||
| Constant | Description |
|
||||
|----------|-------------|
|
||||
| `WAPP_PATH_SEP` | Platform path separator (`'/'` or `'\\'`) |
|
||||
| `WAPP_PATH_MAX` | Maximum path length |
|
||||
|
||||
@@ -313,16 +279,19 @@ Cross-platform path manipulation utilities.
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_cpath_join_path(dst, parts)` | Joins a `Str8List` of path components into a `Str8`. Returns an error code: `CPATH_JOIN_SUCCESS` (0), `CPATH_JOIN_INVALID_ARGS`, `CPATH_JOIN_EMPTY_PARTS`, `CPATH_JOIN_INSUFFICIENT_DST_CAPACITY`. Handles separator insertion automatically. |
|
||||
| `wapp_cpath_dirname(allocator, path)` | Returns the parent directory (equivalent to `dirup(path, 1)`) |
|
||||
| `wapp_cpath_join_path(dst, parts)` | Joins a `Str8List` of path components into a `Str8`. Returns `CPATH_JOIN_SUCCESS` (0) or an error code. Handles separator insertion automatically. |
|
||||
| `wapp_cpath_dirname(allocator, path)` | Returns the parent directory |
|
||||
| `wapp_cpath_dirup(allocator, path, count)` | Returns the directory `count` levels up |
|
||||
|
||||
### Error Codes
|
||||
|
||||
`CPATH_JOIN_SUCCESS`, `CPATH_JOIN_INVALID_ARGS`, `CPATH_JOIN_EMPTY_PARTS`, `CPATH_JOIN_INSUFFICIENT_DST_CAPACITY`
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
Allocator arena = wapp_mem_arena_allocator_init(KiB(16));
|
||||
|
||||
// Join path components
|
||||
Str8List parts = wapp_dbl_list(Str8);
|
||||
Str8 root = wapp_str8_lit("/");
|
||||
Str8 home = wapp_str8_lit("home");
|
||||
@@ -332,9 +301,8 @@ wapp_dbl_list_push_back(Str8, &parts, &home);
|
||||
wapp_dbl_list_push_back(Str8, &parts, &user);
|
||||
|
||||
Str8 out = wapp_str8_buf(256);
|
||||
wapp_cpath_join_path(&out, &parts); // out = "/home/user"
|
||||
wapp_cpath_join_path(&out, &parts); // "/home/user"
|
||||
|
||||
// Parent directory
|
||||
Str8 dir = wapp_str8_lit("/home/user/docs");
|
||||
Str8 *parent = wapp_cpath_dirname(&arena, &dir); // "/home/user"
|
||||
Str8 *grandparent = wapp_cpath_dirup(&arena, &dir, 2); // "/home"
|
||||
@@ -346,10 +314,6 @@ Str8 *grandparent = wapp_cpath_dirup(&arena, &dir, 2); // "/home"
|
||||
|
||||
Cross-platform wrappers for `popen`/`pclose`.
|
||||
|
||||
```c
|
||||
#include "wapp_os.h"
|
||||
```
|
||||
|
||||
| Macro | POSIX | Windows |
|
||||
|-------|-------|---------|
|
||||
| `wapp_shell_utils_popen` | `popen` | `_popen` |
|
||||
|
||||
+16
-14
@@ -1,6 +1,10 @@
|
||||
# prng
|
||||
|
||||
The `prng` package provides a **Xorshift256** pseudo-random number generator (PRNG). It uses a SplitMix64 seeding strategy initialised from the system clock.
|
||||
The `prng` package provides a **Xorshift256** pseudo-random number generator. It uses a SplitMix64 seeding strategy initialised from the system clock.
|
||||
|
||||
```c
|
||||
#include "wapp_prng.h"
|
||||
```
|
||||
|
||||
**Dependencies:** common
|
||||
|
||||
@@ -8,11 +12,7 @@ The `prng` package provides a **Xorshift256** pseudo-random number generator (PR
|
||||
|
||||
## Xorshift256
|
||||
|
||||
A fast, non-cryptographic PRNG with a 256-bit state.
|
||||
|
||||
```c
|
||||
#include "wapp_prng.h"
|
||||
```
|
||||
A fast, non-cryptographic PRNG with a 256-bit state. Three variants are available with different trade-offs between speed and statistical quality.
|
||||
|
||||
### State
|
||||
|
||||
@@ -30,19 +30,21 @@ struct XOR256State {
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_prng_xorshift_init_state()` | Seeds and returns a new `XOR256State`. The OS generator is seeded once globally from the system clock (CLOCK_MONOTONIC_RAW on POSIX, `timespec_get` or `time` otherwise). A SplitMix64 generator then expands this into the 4 x 64-bit state. |
|
||||
| `wapp_prng_xorshift_256(state)` | Standard xorshift256 variant. Returns a `u64`. |
|
||||
| `wapp_prng_xorshift_256ss(state)` | xorshift256 with "scrambled" output (`rol64(z * 5, 7) * 9`). Passes BigCrush. |
|
||||
| `wapp_prng_xorshift_256p(state)` | xorshift256 with "+" output (`w + x`). Passes BigCrush. |
|
||||
| `wapp_prng_xorshift_init_state()` | Seeds a new `XOR256State` from the system clock using SplitMix64 expansion |
|
||||
| `wapp_prng_xorshift_256(state)` | Standard xorshift256. Fastest variant. |
|
||||
| `wapp_prng_xorshift_256ss(state)` | Scrambled output: `rol64(z * 5, 7) * 9`. Passes BigCrush. |
|
||||
| `wapp_prng_xorshift_256p(state)` | Plus output: `w + x`. Passes BigCrush. |
|
||||
|
||||
The state is seeded once globally from the system clock (`CLOCK_MONOTONIC_RAW` on POSIX, `timespec_get` or `time` otherwise), then expanded via SplitMix64 into four 64-bit state words.
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
XOR256State state = wapp_prng_xorshift_init_state();
|
||||
|
||||
u64 r1 = wapp_prng_xorshift_256(&state);
|
||||
u64 r2 = wapp_prng_xorshift_256ss(&state);
|
||||
u64 r3 = wapp_prng_xorshift_256p(&state);
|
||||
u64 r1 = wapp_prng_xorshift_256(&state); // fast
|
||||
u64 r2 = wapp_prng_xorshift_256ss(&state); // high quality (BigCrush)
|
||||
u64 r3 = wapp_prng_xorshift_256p(&state); // high quality (BigCrush)
|
||||
```
|
||||
|
||||
The state is passed by pointer and mutated on each call. The `_ss` and `_p` variants provide better statistical quality and pass the BigCrush test suite, while the standard `_256` variant is faster but has known weaknesses.
|
||||
> The `_256ss` and `_256p` variants provide better statistical quality and pass the BigCrush test suite. The standard `_256` variant is faster but has known statistical weaknesses.
|
||||
|
||||
+16
-22
@@ -1,6 +1,10 @@
|
||||
# testing
|
||||
|
||||
The `testing` package provides a lightweight test runner that uses terminal colours for pass/fail output.
|
||||
The `testing` package provides a lightweight test runner with coloured pass/fail output. It is designed for the library's own test suite but can be used in any C/C++ project.
|
||||
|
||||
```c
|
||||
#include "wapp_testing.h"
|
||||
```
|
||||
|
||||
**Dependencies:** common, os, base
|
||||
|
||||
@@ -8,11 +12,7 @@ The `testing` package provides a lightweight test runner that uses terminal colo
|
||||
|
||||
## Tester
|
||||
|
||||
A simple test framework. Each test is a function that returns a `TestFuncResult`. Tests are registered by passing their function pointers to `wapp_tester_run_tests`.
|
||||
|
||||
```c
|
||||
#include "wapp_testing.h"
|
||||
```
|
||||
Each test is a function that returns a `TestFuncResult`. Tests are registered by passing their function pointers to `wapp_tester_run_tests`.
|
||||
|
||||
### Types
|
||||
|
||||
@@ -23,29 +23,22 @@ struct TestFuncResult {
|
||||
b8 passed;
|
||||
};
|
||||
|
||||
// Test function signature:
|
||||
typedef TestFuncResult(TestFunc)(void);
|
||||
```
|
||||
|
||||
### Test Result Helper
|
||||
### Macros
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_tester_result(PASSED)` | Creates a `TestFuncResult` with the current function's name via `__func__` |
|
||||
|
||||
### Test Runner
|
||||
|
||||
| Macro / Function | Description |
|
||||
|------------------|-------------|
|
||||
| `wapp_tester_run_tests(func1, func2, ..., funcN)` | Runs all listed test functions. Must be NULL-terminated (the varargs macro automatically appends `NULL`). |
|
||||
| `run_tests(func1, ...)` | Underlying function (varargs, NULL-terminated) |
|
||||
| `wapp_tester_result(passed)` | Creates a `TestFuncResult` using `__func__` as the test name |
|
||||
| `wapp_tester_run_tests(...)` | Runs all listed test functions (NULL-terminated automatically) |
|
||||
|
||||
### Behaviour
|
||||
|
||||
- Each test runs sequentially in declaration order.
|
||||
- Tests run sequentially in declaration order.
|
||||
- Passing tests are shown in green (`[PASSED]`), failing tests in red (`[FAILED]`).
|
||||
- Output uses terminal colours via `wapp_shell_termcolour_print_text`.
|
||||
- On the first failure, the runner calls `exit(EXIT_FAILURE)` immediately.
|
||||
- Output uses terminal colours via the os package's `wapp_shell_termcolour_print_text`.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -72,6 +65,7 @@ int main(void) {
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
[PASSED] test_addition
|
||||
[PASSED] test_subtraction
|
||||
@@ -80,8 +74,8 @@ Output:
|
||||
### Writing Tests
|
||||
|
||||
Each test function must:
|
||||
1. Have the signature `TestFuncResult test_name(void)`
|
||||
2. Return `wapp_tester_result(condition)` where `condition` is `true` for pass, `false` for fail
|
||||
3. Not take any parameters
|
||||
- Have the signature `TestFuncResult test_name(void)`
|
||||
- Return `wapp_tester_result(condition)` where `condition` is `true` for pass, `false` for fail
|
||||
- Take no parameters
|
||||
|
||||
Tests that share state (e.g. a file handle or an arena) can use `wapp_intern` (file-level `static`) variables to persist state across sequentially run tests.
|
||||
Tests that share state (e.g. a file handle or arena) can use `wapp_persist` (file-level `static`) variables to persist state across sequentially run tests.
|
||||
|
||||
+34
-26
@@ -2,67 +2,75 @@
|
||||
|
||||
The `uuid` package provides **UUID v4** generation as specified by RFC 4122. UUIDs are generated using the library's Xorshift256 PRNG and formatted as 36-character strings.
|
||||
|
||||
```c
|
||||
#include "wapp_uuid.h"
|
||||
```
|
||||
|
||||
**Dependencies:** common, base, prng
|
||||
|
||||
---
|
||||
|
||||
## UUID v4
|
||||
|
||||
```c
|
||||
#include "wapp_uuid.h"
|
||||
```
|
||||
|
||||
### Type
|
||||
|
||||
```c
|
||||
typedef struct WUUID WUUID;
|
||||
struct WUUID {
|
||||
Str8 uuid; // The UUID string representation
|
||||
Str8 uuid; // The UUID string representation
|
||||
};
|
||||
```
|
||||
|
||||
### Constants
|
||||
|
||||
| Constant | Description |
|
||||
|----------|-------------|
|
||||
| `UUID_BUF_LENGTH` | `48` - recommended buffer size for UUID strings |
|
||||
| `WAPP_UUID_SPEC` | `WAPP_STR8_SPEC` - for printf formatting |
|
||||
| `wapp_uuid_varg(wuuid)` | Expands to `wapp_str8_varg((WUUID).uuid)` for printf |
|
||||
| Constant | Value |
|
||||
|----------|-------|
|
||||
| `UUID_BUF_LENGTH` | `48` |
|
||||
| `WAPP_UUID_SPEC` | `WAPP_STR8_SPEC` |
|
||||
|
||||
### Convenience Macro
|
||||
### Printf Helpers
|
||||
|
||||
| Macro | Description |
|
||||
|-------|-------------|
|
||||
| `wapp_uuid_gen_uuid4()` | One-shot UUID v4 generation. Creates a buffer and returns a fully initialised `WUUID` in a single expression - no variables needed. |
|
||||
```c
|
||||
#define wapp_uuid_varg(wuuid) wapp_str8_varg((WUUID).uuid)
|
||||
|
||||
printf(WAPP_UUID_SPEC "\n", wapp_uuid_varg(u));
|
||||
```
|
||||
|
||||
### One-shot Generation
|
||||
|
||||
```c
|
||||
WUUID u = wapp_uuid_gen_uuid4();
|
||||
```
|
||||
|
||||
Creates a buffer and returns a fully initialised `WUUID` in a single expression.
|
||||
|
||||
### Low-Level API
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `wapp_uuid_create()` | Creates an empty `WUUID` with a zeroed buffer of `UUID_BUF_LENGTH` capacity |
|
||||
| `wapp_uuid_init_uuid4(uuid)` | Fills a `WUUID` with a randomly generated UUID v4. Returns the same pointer for chaining. |
|
||||
| Function / Macro | Description |
|
||||
|------------------|-------------|
|
||||
| `wapp_uuid_create()` | Creates an empty `WUUID` with a zeroed buffer |
|
||||
| `wapp_uuid_init_uuid4(uuid)` | Fills a `WUUID` with a randomly generated UUID v4. Returns the same pointer. |
|
||||
|
||||
### Example
|
||||
|
||||
```c
|
||||
// One-shot generation (most common usage)
|
||||
// One-shot
|
||||
WUUID uuid = wapp_uuid_gen_uuid4();
|
||||
printf(WAPP_UUID_SPEC "\n", wapp_uuid_varg(uuid));
|
||||
// Example output: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
||||
|
||||
// Two-step (low-level)
|
||||
// Two-step
|
||||
WUUID u = wapp_uuid_create();
|
||||
wapp_uuid_init_uuid4(&u);
|
||||
printf(WAPP_UUID_SPEC "\n", wapp_uuid_varg(u));
|
||||
```
|
||||
|
||||
### UUID Format
|
||||
|
||||
The generated UUID follows RFC 4122:
|
||||
Generated UUIDs follow RFC 4122:
|
||||
|
||||
```
|
||||
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
||||
```
|
||||
Where:
|
||||
|
||||
- The `4` identifies version 4 (random)
|
||||
- `y` is one of `8`, `9`, `a`, or `b` (the variant field)
|
||||
- All other digits are randomly generated via `wapp_prng_xorshift_256`
|
||||
- `y` is one of `8`, `9`, `a`, or `b` (the RFC 4122 variant field)
|
||||
- All other hex digits are generated via `wapp_prng_xorshift_256`
|
||||
|
||||
Reference in New Issue
Block a user