63 Commits

Author SHA1 Message Date
6346765e32 Fix UUID for C++
All checks were successful
Release / release (push) Successful in 5s
2026-05-10 02:13:41 +01:00
Abdelrahman Said
270dbfe5ca Update README
All checks were successful
Release / release (push) Successful in 7s
2026-03-09 22:32:04 +00:00
Abdelrahman Said
7fd808fe7b Add LICENSE file
All checks were successful
Release / release (push) Successful in 11s
2026-03-09 22:17:05 +00:00
95deda1f59 v1.0.0
All checks were successful
Release / release (push) Successful in 3s
2026-03-08 23:56:50 +00:00
3f3d1e1e5d Ensure all tags are fetched when checking out the repo
All checks were successful
Release / release (push) Successful in 3s
2026-03-08 23:55:19 +00:00
877b8e9a04 Update release workflow
Some checks failed
Release / release (push) Failing after 2s
2026-03-08 23:52:05 +00:00
4ce59f537c Trigger workflow one more time
Some checks failed
Release / release (push) Failing after 3s
2026-03-08 23:44:02 +00:00
7d13bde13b Trigger workflow 2026-03-08 23:40:18 +00:00
3aa792a620 Add release workflow 2026-03-08 23:34:09 +00:00
c0b667847c Update package script 2026-03-08 23:33:59 +00:00
ce2956f072 Update package script 2026-03-08 23:14:16 +00:00
a1182016af Add VERSION 2026-03-08 21:38:47 +00:00
59423e294a Add packaging script 2026-03-08 21:38:41 +00:00
ef5c9376a9 Fix mistake when building with no runtime assert 2026-03-08 20:22:21 +00:00
eeed101228 Move large file source def to code 2026-03-08 13:10:17 +00:00
6b88d7e3fe Add TODO for updating UUID implementation 2026-02-09 00:02:21 +00:00
58dab46902 Revert "Update uuid C++ implementation"
This reverts commit 1cdb08a81a.
2026-02-08 23:57:09 +00:00
269ee5d9ab Revert "Update uuid C++ implementation"
This reverts commit 610df6869f.
2026-02-08 23:57:05 +00:00
610df6869f Update uuid C++ implementation 2026-02-08 23:53:30 +00:00
1cdb08a81a Update uuid C++ implementation 2026-02-08 23:48:02 +00:00
8d9ef89329 Fix bug with queue 2026-02-08 19:16:36 +00:00
Abdelrahman Said
3d3452f523 Update queue implementation to use ring buffer 2026-01-24 20:46:05 +00:00
Abdelrahman Said
8e41b627bc Add function to create array from preallocated buffer 2026-01-24 20:45:52 +00:00
Abdelrahman Said
7a54c28c0f Update array allocation functions 2026-01-24 12:17:15 +00:00
Abdelrahman Said
bd659e64fc Ensure array count is set correctly when allocating 2026-01-22 06:09:43 +00:00
Abdelrahman Said
21ac756fad Pass init flags to allocating array utilities 2026-01-19 06:09:36 +00:00
Abdelrahman Said
243f04c0ca Handle lseek64 not existing on macOS 2026-01-19 06:00:09 +00:00
4cc8cb3d25 Fix MSVC errors 2026-01-11 23:48:35 +00:00
a9f5b9c3c6 Add queue implementation 2026-01-11 23:46:23 +00:00
9af9cedd51 Add pointer offset utility 2026-01-11 23:46:12 +00:00
1e536cc3ba Rename array alloc size utility 2026-01-11 21:58:49 +00:00
e6f31e4f7b Update dbl list utilities 2026-01-11 21:46:00 +00:00
6cd3c6f596 Add utility to get node item 2026-01-11 21:31:55 +00:00
5a504c6791 Add extra utilities for dbl list 2026-01-11 21:26:17 +00:00
a4492cf8e8 Switch array fill to flags 2026-01-11 20:17:09 +00:00
ce76ac1e7c Add utility to calculate allocation size for array 2026-01-11 19:44:22 +00:00
cff418b9e9 Simplify dbl list API (#11)
Reviewed-on: #11
Co-authored-by: Abdelrahman <said.abdelrahman89@gmail.com>
Co-committed-by: Abdelrahman <said.abdelrahman89@gmail.com>
2026-01-11 18:22:54 +00:00
b88cb71aa8 Update array and dbl list macros 2026-01-05 03:57:50 +00:00
8efcf14462 Switch numerical aliases to typedefs 2026-01-04 23:10:58 +00:00
f383fbb43e Reformat 2026-01-04 16:04:09 +00:00
24069529c3 Add temp arena support 2026-01-04 01:21:42 +00:00
d2b4ec2052 Rename dbl list labels 2026-01-03 20:20:40 +00:00
0a761eef05 Reformat 2026-01-03 19:53:43 +00:00
821406315e Reformat 2026-01-03 19:51:26 +00:00
8adbc1f841 Reformat 2026-01-03 19:17:10 +00:00
1f3df20b7d Reformat 2026-01-03 19:13:42 +00:00
458046a5d0 Reformat 2026-01-03 18:51:30 +00:00
6d4a72aff9 Fix MSVC errors 2026-01-03 18:45:54 +00:00
326265722e Add support for initialising arena with backing buffer 2026-01-03 18:36:30 +00:00
83b879a180 Always reserve padding for structs that need it 2026-01-03 17:04:36 +00:00
b372447a46 Implement Windows file IO 2026-01-03 03:15:25 +00:00
fac9cb57eb Update windows include 2026-01-03 03:15:03 +00:00
abad2fa02a Add padding to stack array 2026-01-03 03:14:53 +00:00
576699996f Update POSIX file IO 2026-01-03 03:13:42 +00:00
c2ca99cac4 Implement POSIX file IO 2026-01-02 22:57:12 +00:00
a07f05d1a3 Use 64 bit offsets for file seeking 2026-01-02 22:56:26 +00:00
ebf16c6ba3 Move is_power_of_two to misc_utils 2026-01-02 19:19:25 +00:00
91138f9239 Reformat 2026-01-02 19:03:19 +00:00
ae8cb2e473 Add function to rename file 2026-01-02 19:02:17 +00:00
f5c2ed89a4 Add tests for file IO API 2026-01-02 18:56:19 +00:00
989a5f60c4 Update file IO API 2026-01-02 18:56:09 +00:00
659a3e457c Reformat 2026-01-02 17:17:25 +00:00
c2a156e256 Remove array structs (#10)
Reviewed-on: #10
2026-01-02 16:50:52 +00:00
62 changed files with 2578 additions and 875 deletions

View File

@@ -0,0 +1,81 @@
name: Release
on:
push:
branches:
- main # or your default branch
jobs:
release:
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # fetch full history
tags: true # fetch all tags
- name: Check/Create Tag
id: tag
run: |
VERSION=$(cat VERSION | tr -d '[:space:]') # read version and trim whitespace
echo "Version: $VERSION"
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "Tag v$VERSION already exists. Skipping release."
exit 0
fi
# Tag does not exist → create it
echo "Creating tag v$VERSION"
git tag "v$VERSION"
git push origin "v$VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Build Artifacts
if: steps.tag.outputs.version
run: |
chmod +x ./package
./package
ls -l dist/
- name: Create Release
if: steps.tag.outputs.version
id: create_release
run: |
VERSION="${{ steps.tag.outputs.version }}"
RESPONSE=$(curl -s -X POST \
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
-H "Content-Type: application/json" \
"https://git.thewizardapprentice.com/api/v1/repos/${{ gitea.repository }}/releases" \
-d '{
"tag_name": "v'"$VERSION"'",
"name": "wapp-v'"$VERSION"'",
"body": "Automated release for wapp-v'"$VERSION"'",
"draft": false,
"prerelease": false
}')
echo "$RESPONSE"
RELEASE_ID=$(echo $RESPONSE | jq -r '.id')
echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT
- name: Upload Artifacts
if: steps.tag.outputs.version
run: |
RELEASE_ID="${{ steps.create_release.outputs.release_id }}"
for FILE in dist/*; do
FILENAME=$(basename "$FILE")
echo "Uploading $FILENAME"
curl -X POST \
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$FILE" \
"https://git.thewizardapprentice.com/api/v1/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets?name=$FILENAME"
done
- name: Cleanup
if: steps.tag.outputs.version
run: rm -rf dist/*

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2026] [Abdelrahman Said]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -46,7 +46,7 @@ endif
# Disable runtime asserts
ifeq ($(RUNTIME_ASSERT), false)
override BUILD_FLAGS += WAPP_NO_RUNTIME_ASSERT
override BUILD_FLAGS += -DWAPP_NO_RUNTIME_ASSERT
endif
ifeq ($(CC),gcc)

View File

@@ -1,3 +1,5 @@
# Wizard Apprentice Standard Library
A group of utilities for C/C++ projects
**Wizard Apprentice Standard Library** (`wapp`) is a lightweight collection of reusable utilities for **C and C++** projects.
For more information about the library and how to use it, check the [wiki](https://git.thewizardapprentice.com/abdelrahman/wizapp-stdlib/wiki).

1
VERSION Normal file
View File

@@ -0,0 +1 @@
1.0.1

View File

@@ -52,9 +52,6 @@ mkdir -p $ObjDir > $null
mkdir -p $OutDir > $null
mkdir -p $TestsDir > $null
# Run code generation
Invoke-Expression "python -m codegen"
# Build and run C tests
Invoke-Expression "$Compiler $GeneralFlags $CStd $IncludeDirs $TestIncludeDirs $SrcFiles $TestCSrcFiles $TestCOutputFlags" -ErrorAction Stop
Invoke-Expression "$TestsDir/$TestCOutputBasename.exe"

11
package Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
cp -r src wapp
mkdir -p dist
ARCHIVE_NAME="wapp-v$(cat VERSION)"
tar -czvf dist/$ARCHIVE_NAME.tar.gz wapp
zip -r dist/$ARCHIVE_NAME.zip wapp
rm -rf wapp

View File

@@ -7,8 +7,7 @@
#include "../../common/aliases/aliases.h"
#include <stddef.h>
#define _offset_pointer(PTR, OFFSET) ((void *)((uptr)(PTR) + (OFFSET)))
#define _array_header(ARRAY) (ArrayHeader *)(_offset_pointer(ARRAY, -sizeof(ArrayHeader)))
#define _array_header(ARRAY) (ArrayHeader *)(wapp_pointer_offset(ARRAY, (i64)sizeof(ArrayHeader) * -1))
wapp_persist inline void _array_validate(const GenericArray array, u64 item_size);
@@ -55,7 +54,7 @@ void *_array_get(GenericArray array, u64 index, u64 item_size) {
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(index < header->count, "`index` is out of bounds");
return _offset_pointer(array, header->item_size * index);
return wapp_pointer_offset(array, header->item_size * index);
}
void _array_set(GenericArray array, u64 index, void *value, u64 item_size) {
@@ -86,7 +85,7 @@ void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_siz
u64 remaining_capacity = dst_header->capacity - dst_header->count;
u64 copy_count = src_header->count < remaining_capacity ? src_header->count : remaining_capacity;
void *dst_ptr = _offset_pointer(dst, dst_header->count * dst_header->item_size);
void *dst_ptr = wapp_pointer_offset(dst, dst_header->count * dst_header->item_size);
memcpy(dst_ptr, src, copy_count * src_header->item_size);
dst_header->count += copy_count;
}
@@ -105,7 +104,8 @@ void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size)
dst_header->count = copy_count;
}
GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value, u64 item_size) {
GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value,
ArrayInitFlags flags, u64 item_size) {
wapp_runtime_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
_array_validate(array, item_size);
@@ -114,7 +114,8 @@ GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array,
ArrayHeader *header = _array_header(array);
if (header->count >= header->capacity) {
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(header->capacity * 2);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity, header->item_size, false);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity, flags,
header->item_size);
if (!output) {
output = array;
goto RETURN_ARRAY_APPEND_ALLOC;
@@ -124,11 +125,16 @@ GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array,
_array_append_capped(output, value, item_size);
if ((flags & ARRAY_INIT_FILLED) == ARRAY_INIT_FILLED) {
_array_set_count(output, _array_capacity(output));
}
RETURN_ARRAY_APPEND_ALLOC:
return output;
}
GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src, u64 item_size) {
GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
ArrayInitFlags flags, u64 item_size) {
wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
_array_validate(dst, item_size);
_array_validate(src, item_size);
@@ -140,7 +146,8 @@ GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, c
u64 remaining_capacity = dst_header->capacity - dst_header->count;
if (src_header->count >= remaining_capacity) {
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst_header->capacity * 2);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity, dst_header->item_size, false);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity,
flags, dst_header->item_size);
if (!output) {
output = dst;
goto RETURN_ARRAY_EXTEND_ALLOC;
@@ -150,11 +157,16 @@ GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, c
_array_extend_capped(output, src, item_size);
if ((flags & ARRAY_INIT_FILLED) == ARRAY_INIT_FILLED) {
_array_set_count(output, _array_capacity(output));
}
RETURN_ARRAY_EXTEND_ALLOC:
return output;
}
GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src, u64 item_size) {
GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
ArrayInitFlags flags, u64 item_size) {
wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
_array_validate(dst, item_size);
_array_validate(src, item_size);
@@ -166,7 +178,7 @@ GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, con
if (src_header->count >= dst_header->capacity) {
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst_header->capacity * 2);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity,
src_header->item_size, false);
flags, src_header->item_size);
if (!output) {
output = dst;
goto RETURN_ARRAY_COPY_ALLOC;
@@ -175,6 +187,10 @@ GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, con
_array_copy_capped(output, src, item_size);
if ((flags & ARRAY_INIT_FILLED) == ARRAY_INIT_FILLED) {
_array_set_count(output, _array_capacity(output));
}
RETURN_ARRAY_COPY_ALLOC:
return output;
}
@@ -200,27 +216,49 @@ void _array_clear(GenericArray array, u64 item_size) {
header->count = 0;
}
GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size, b8 fill) {
u64 _array_calc_alloc_size(u64 capacity, u64 item_size) {
return sizeof(ArrayHeader) + item_size * capacity;
}
GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, ArrayInitFlags flags,
u64 item_size) {
wapp_runtime_assert(allocator != NULL, "`allocator` should not be NULL");
GenericArray output = NULL;
u64 allocation_size = sizeof(ArrayHeader) + item_size * capacity;
ArrayHeader *header = wapp_mem_allocator_alloc(allocator, allocation_size);
if (!header) {
u64 allocation_size = _array_calc_alloc_size(capacity, item_size);
void *buffer = wapp_mem_allocator_alloc(allocator, allocation_size);
if (!buffer) {
goto RETURN_ARRAY_ALLOC;
}
output = (u8 *)(header + 1);
header->magic = WAPP_ARRAY_MAGIC;
header->count = fill ? capacity : 0;
header->capacity = capacity;
header->item_size = item_size;
output = _array_from_preallocated_buffer(buffer, allocation_size, flags, item_size);
RETURN_ARRAY_ALLOC:
return output;
}
GenericArray _array_from_preallocated_buffer(void *buffer, u64 buffer_size, ArrayInitFlags flags,
u64 item_size) {
wapp_runtime_assert(buffer != NULL, "`buffer` should not be NULL");
i64 data_buffer_size = (i64)buffer_size - (i64)(sizeof(ArrayHeader));
if (data_buffer_size <= 0) {
return NULL;
}
u64 item_capacity = (u64)data_buffer_size / item_size;
ArrayHeader *header = (ArrayHeader *)buffer;
GenericArray output = (u8 *)(header + 1);
header->magic = WAPP_ARRAY_MAGIC;
header->count = flags & ARRAY_INIT_FILLED ? item_capacity : 0;
header->capacity = item_capacity;
header->item_size = item_size;
return output;
}
wapp_persist inline void _array_validate(const GenericArray array, u64 item_size) {
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");

View File

@@ -17,9 +17,6 @@ BEGIN_C_LINKAGE
#define _calc_array_count(TYPE, ...) wapp_misc_utils_va_args_count(TYPE, __VA_ARGS__)
#define _calc_array_capacity(TYPE, ...) wapp_misc_utils_u64_round_up_pow2(_calc_array_count(TYPE, __VA_ARGS__) * 2)
#define wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, FILL) \
((TYPE *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(TYPE), FILL))
typedef struct Str8 Str8;
// NOTE (Abdelrahman): Typedefs to distinguish arrays from regular pointers
@@ -44,6 +41,11 @@ typedef uptr *UptrArray;
typedef iptr *IptrArray;
typedef Str8 *Str8Array;
typedef enum {
ARRAY_INIT_NONE = 0,
ARRAY_INIT_FILLED = 1 << 1,
} ArrayInitFlags;
#ifdef WAPP_PLATFORM_CPP
#define wapp_array(TYPE, ...) ([&]() { \
u64 capacity = _calc_array_capacity(TYPE, __VA_ARGS__); \
@@ -63,13 +65,13 @@ typedef Str8 *Str8Array;
memcpy(buf, items, capacity * sizeof(TYPE)); \
return (TYPE *)buf; \
}())
#define wapp_array_with_capacity(TYPE, CAPACITY, FILL) ([&]() { \
#define wapp_array_with_capacity(TYPE, CAPACITY, FLAGS) ([&]() { \
wapp_persist u8 array[ \
sizeof(ArrayHeader) + CAPACITY * sizeof(TYPE) \
] = {0}; \
ArrayHeader *header = (ArrayHeader *)array; \
header->magic = WAPP_ARRAY_MAGIC; \
header->count = FILL ? CAPACITY : 0; \
header->count = (FLAGS & ARRAY_INIT_FILLED) ? CAPACITY : 0; \
header->capacity = CAPACITY; \
header->item_size = sizeof(TYPE); \
\
@@ -84,9 +86,12 @@ typedef Str8 *Str8Array;
return *((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))); \
}())
#else
#define _stack_array(TYPE, SIZE) struct { ArrayHeader header; TYPE items[SIZE]; }
#define _stack_array(TYPE, SIZE) struct {ArrayHeader header; \
TYPE items[SIZE]; \
wapp_misc_utils_reserve_padding(sizeof(ArrayHeader) + \
sizeof(TYPE) * SIZE);}
#define wapp_array(TYPE, ...) \
(TYPE *)( \
((TYPE *)( \
(_stack_array(TYPE, _calc_array_capacity(TYPE, __VA_ARGS__))){ \
.header = { \
.magic = WAPP_ARRAY_MAGIC, \
@@ -96,73 +101,82 @@ typedef Str8 *Str8Array;
}, \
.items = {__VA_ARGS__}, \
}.items \
)
#define wapp_array_with_capacity(TYPE, CAPACITY, FILL) \
(TYPE *)( \
))
#define wapp_array_with_capacity(TYPE, CAPACITY, FLAGS) \
((TYPE *)( \
(_stack_array(TYPE, CAPACITY)){ \
.header = { \
.magic = WAPP_ARRAY_MAGIC, \
.count = FILL ? CAPACITY : 0, \
.count = (FLAGS & ARRAY_INIT_FILLED) ? CAPACITY : 0, \
.capacity = CAPACITY, \
.item_size = sizeof(TYPE), \
}, \
.items = {0}, \
}.items \
)
))
#define wapp_array_pop(TYPE, ARRAY) \
(ARRAY != NULL && _array_count((GenericArray)ARRAY) > 0 ? \
*((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))) : \
(TYPE){0} \
(ARRAY == NULL || _array_count((GenericArray)ARRAY) == 0 ? \
(TYPE){0} : \
*((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))) \
)
#endif // !WAPP_PLATFORM_CPP
#define wapp_array_count(ARRAY) \
_array_count((GenericArray)ARRAY)
(_array_count((GenericArray)ARRAY))
#define wapp_array_capacity(ARRAY) \
_array_capacity((GenericArray)ARRAY)
(_array_capacity((GenericArray)ARRAY))
#define wapp_array_item_size(ARRAY) \
_array_item_size((GenericArray)ARRAY)
(_array_item_size((GenericArray)ARRAY))
#define wapp_array_set_count(ARRAY, COUNT) \
_array_set_count((GenericArray)ARRAY, COUNT)
(_array_set_count((GenericArray)ARRAY, COUNT))
#define wapp_array_get(TYPE, ARRAY, INDEX) \
((TYPE *)_array_get((GenericArray)ARRAY, \
INDEX, \
sizeof(TYPE)))
#define wapp_array_set(TYPE, ARRAY, INDEX, VALUE_PTR) \
_array_set((GenericArray)ARRAY, \
(_array_set((GenericArray)ARRAY, \
INDEX, \
(u8 *)VALUE_PTR, \
sizeof(TYPE))
sizeof(TYPE)))
#define wapp_array_append_capped(TYPE, ARRAY, VALUE_PTR) \
_array_append_capped((GenericArray)ARRAY, \
(_array_append_capped((GenericArray)ARRAY, \
(u8 *)VALUE_PTR, \
sizeof(TYPE))
sizeof(TYPE)))
#define wapp_array_extend_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
_array_extend_capped((GenericArray)DST_ARRAY, \
(_array_extend_capped((GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
sizeof(TYPE)))
#define wapp_array_copy_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
_array_copy_capped((GenericArray)DST_ARRAY, \
(_array_copy_capped((GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
#define wapp_array_append_alloc(TYPE, ALLOCATOR_PTR, ARRAY, VALUE_PTR) \
(TYPE *)_array_append_alloc(ALLOCATOR_PTR, \
sizeof(TYPE)))
#define wapp_array_append_alloc(TYPE, ALLOCATOR_PTR, ARRAY, VALUE_PTR, FLAGS) \
((TYPE *)_array_append_alloc(ALLOCATOR_PTR, \
(GenericArray)ARRAY, \
(u8 *)VALUE_PTR, \
sizeof(TYPE))
#define wapp_array_extend_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY) \
(TYPE *)_array_extend_alloc(ALLOCATOR_PTR, \
FLAGS, \
sizeof(TYPE)))
#define wapp_array_extend_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY, FLAGS) \
((TYPE *)_array_extend_alloc(ALLOCATOR_PTR, \
(GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
#define wapp_array_copy_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY) \
(TYPE *)_array_copy_alloc(ALLOCATOR_PTR, \
FLAGS, \
sizeof(TYPE)))
#define wapp_array_copy_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY, FLAGS) \
((TYPE *)_array_copy_alloc(ALLOCATOR_PTR, \
(GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
FLAGS, \
sizeof(TYPE)))
#define wapp_array_clear(TYPE, ARRAY) \
_array_clear((GenericArray)ARRAY, \
sizeof(TYPE))
(_array_clear((GenericArray)ARRAY, \
sizeof(TYPE)))
#define wapp_array_calc_alloc_size(TYPE, CAPACITY) _array_calc_alloc_size(CAPACITY, sizeof(TYPE))
#define wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, FLAGS) \
((TYPE *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, FLAGS, sizeof(TYPE)))
#define wapp_array_from_preallcated_buffer(TYPE, BUFFER, BUFFER_SIZE) \
((TYPE *)_array_from_preallcated_buffer(BUFFER, BUFFER_SIZE, sizeof(TYPE)))
typedef struct header ArrayHeader;
struct header {
@@ -181,12 +195,19 @@ void _array_set(GenericArray array, u64 index, void *value, u64 item_siz
void _array_append_capped(GenericArray array, void *value, u64 item_size);
void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_size);
void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size);
GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value, u64 item_size);
GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src, u64 item_size);
GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src, u64 item_size);
GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value,
ArrayInitFlags flags, u64 item_size);
GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
ArrayInitFlags flags, u64 item_size);
GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
ArrayInitFlags flags, u64 item_size);
void *_array_pop(GenericArray array, u64 item_size);
void _array_clear(GenericArray array, u64 item_size);
GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size, b8 fill);
u64 _array_calc_alloc_size(u64 capacity, u64 item_size);
GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, ArrayInitFlags flags,
u64 item_size);
GenericArray _array_from_preallocated_buffer(void *buffer, u64 buffer_size, ArrayInitFlags flags,
u64 item_size);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE

View File

@@ -25,15 +25,16 @@ DBL_LIST_ALLOC_RETURN:
return list;
}
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, u64 item_size) {
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, void *item, u64 item_size) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
GenericNode *node = wapp_mem_allocator_alloc(allocator, sizeof(GenericNode));
if (!node) { goto DBL_LIST_NODE_ALLOC_RETURN; }
memset((void *)node, 0, sizeof(GenericNode));
node->magic = WAPP_DBL_NODE_MAGIC;
node->item_size = item_size;
node->item = item;
node->header.magic = WAPP_DBL_NODE_MAGIC;
node->header.item_size = item_size;
DBL_LIST_NODE_ALLOC_RETURN:
return node;
@@ -47,7 +48,7 @@ GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size) {
GenericNode *output = NULL;
GenericNode *current = list->first;
for (u64 i = 1; i <= index; ++i) {
current = current->next;
current = current->header.next;
}
output = current;
@@ -71,11 +72,11 @@ void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size) {
GenericNode *first = list->first;
if (first) {
first->prev = node_list.last;
first->header.prev = node_list.last;
}
list->first = node_list.first;
node_list.last->next = first;
node_list.last->header.next = first;
}
void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size) {
@@ -94,11 +95,11 @@ void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size) {
GenericNode *last = list->last;
if (last) {
last->next = node_list.first;
last->header.next = node_list.first;
}
list->last = node_list.last;
node_list.first->prev = last;
node_list.first->header.prev = last;
}
void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size) {
@@ -123,13 +124,13 @@ void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_
list->node_count += node_list.node_count;
GenericNode *prev = dst_node->prev;
GenericNode *prev = dst_node->header.prev;
dst_node->prev = node_list.last;
prev->next = node_list.first;
dst_node->header.prev = node_list.last;
prev->header.next = node_list.first;
node_list.first->prev = prev;
node_list.last->next = dst_node;
node_list.first->header.prev = prev;
node_list.last->header.next = dst_node;
}
GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size) {
@@ -139,22 +140,22 @@ GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size) {
GenericNode *output = NULL;
if (list->node_count == 0) {
goto RETURN_I32_LIST_POP_FRONT;
goto RETURN_LIST_POP_FRONT;
}
output = list->first;
if (list->node_count == 1) {
*list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size};
goto RETURN_I32_LIST_POP_FRONT;
goto RETURN_LIST_POP_FRONT;
}
--(list->node_count);
list->first = output->next;
list->first = output->header.next;
output->prev = output->next = NULL;
output->header.prev = output->header.next = NULL;
RETURN_I32_LIST_POP_FRONT:
RETURN_LIST_POP_FRONT:
return output;
}
@@ -165,22 +166,22 @@ GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size) {
GenericNode *output = NULL;
if (list->node_count == 0) {
goto RETURN_I32_LIST_POP_BACK;
goto RETURN_LIST_POP_BACK;
}
output = list->last;
if (list->node_count == 1) {
*list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size};
goto RETURN_I32_LIST_POP_BACK;
goto RETURN_LIST_POP_BACK;
}
--(list->node_count);
list->last = output->prev;
list->last = output->header.prev;
output->prev = output->next = NULL;
output->header.prev = output->header.next = NULL;
RETURN_I32_LIST_POP_BACK:
RETURN_LIST_POP_BACK:
return output;
}
@@ -192,25 +193,25 @@ GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size) {
if (index == 0) {
output = _dbl_list_pop_front(list, item_size);
goto RETURN_I32_LIST_REMOVE;
goto RETURN_LIST_REMOVE;
} else if (index == list->node_count) {
output = _dbl_list_pop_back(list, item_size);
goto RETURN_I32_LIST_REMOVE;
goto RETURN_LIST_REMOVE;
}
output = _dbl_list_get(list, index, item_size);
if (!output) {
goto RETURN_I32_LIST_REMOVE;
goto RETURN_LIST_REMOVE;
}
output->prev->next = output->next;
output->next->prev = output->prev;
output->header.prev->header.next = output->header.next;
output->header.next->header.prev = output->header.prev;
--(list->node_count);
output->prev = output->next = NULL;
output->header.prev = output->header.next = NULL;
RETURN_I32_LIST_REMOVE:
RETURN_LIST_REMOVE:
return output;
}
@@ -233,13 +234,13 @@ wapp_intern GenericList _node_to_list(GenericNode *node, u64 item_size) {
.item_size = item_size,
};
while (output.first->prev != NULL) {
output.first = output.first->prev;
while (output.first->header.prev != NULL) {
output.first = output.first->header.prev;
++(output.node_count);
}
while (output.last->next != NULL) {
output.last = output.last->next;
while (output.last->header.next != NULL) {
output.last = output.last->header.next;
++(output.node_count);
}
@@ -252,7 +253,7 @@ wapp_intern inline void _dbl_list_validate(const GenericList *list, u64 item_siz
}
wapp_intern inline void _dbl_list_node_validate(const GenericList *list, const GenericNode *node, u64 item_size) {
wapp_runtime_assert(node->magic == WAPP_DBL_NODE_MAGIC, "`node` isn't a valid wapp node type");
wapp_runtime_assert(list->item_size == node->item_size, "Mismatched `list` and `node` types");
wapp_runtime_assert(node->item_size == item_size, "Invalid item provided");
wapp_runtime_assert(node->header.magic == WAPP_DBL_NODE_MAGIC, "`node` isn't a valid wapp node type");
wapp_runtime_assert(list->item_size == node->header.item_size, "Mismatched `list` and `node` types");
wapp_runtime_assert(node->header.item_size == item_size, "Invalid item provided");
}

View File

@@ -14,63 +14,160 @@ BEGIN_C_LINKAGE
#define WAPP_DBL_LIST_MAGIC (u64)0x57415f444c5354
#define WAPP_DBL_NODE_MAGIC (u64)0x57415f444e44
#define WAPP_DEF_DBL_LIST_TYPE(T, NODE_NAME, LIST_NAME) \
typedef struct NODE_NAME NODE_NAME; \
struct NODE_NAME { \
u64 magic; \
T *item; \
NODE_NAME *prev; \
NODE_NAME *next; \
u64 item_size; \
}; \
\
typedef struct { \
u64 magic; \
NODE_NAME *first; \
NODE_NAME *last; \
u64 node_count; \
u64 item_size; \
} LIST_NAME
typedef struct GenericNode GenericNode;
typedef struct {
u64 magic;
u64 item_size;
GenericNode *prev;
GenericNode *next;
} NodeHeader;
struct GenericNode {
NodeHeader header;
void *item;
};
typedef struct {
u64 magic;
u64 node_count;
u64 item_size;
GenericNode *first;
GenericNode *last;
} GenericList;
// NOTE (Abdelrahman): GenericList typedefs for readability
typedef GenericList VoidPtrList;
typedef GenericList C8List;
typedef GenericList C16List;
typedef GenericList C32List;
typedef GenericList U8List;
typedef GenericList U16List;
typedef GenericList U32List;
typedef GenericList U64List;
typedef GenericList B8List;
typedef GenericList I8List;
typedef GenericList I16List;
typedef GenericList I32List;
typedef GenericList I64List;
typedef GenericList F32List;
typedef GenericList F64List;
typedef GenericList F128List;
typedef GenericList UptrList;
typedef GenericList IptrList;
typedef GenericList Str8List;
// NOTE (Abdelrahman): GenericNode typedefs for readability
typedef GenericNode VoidPtrNode;
typedef GenericNode C8Node;
typedef GenericNode C16Node;
typedef GenericNode C32Node;
typedef GenericNode U8Node;
typedef GenericNode U16Node;
typedef GenericNode U32Node;
typedef GenericNode U64Node;
typedef GenericNode B8Node;
typedef GenericNode I8Node;
typedef GenericNode I16Node;
typedef GenericNode I32Node;
typedef GenericNode I64Node;
typedef GenericNode F32Node;
typedef GenericNode F64Node;
typedef GenericNode F128Node;
typedef GenericNode UptrNode;
typedef GenericNode IptrNode;
typedef GenericNode Str8Node;
#ifdef WAPP_PLATFORM_CPP
#define wapp_dbl_list(ELEM_TYPE, LIST_TYPE) \
LIST_TYPE{WAPP_DBL_LIST_MAGIC, nullptr, nullptr, 0, sizeof(ELEM_TYPE)}
#define wapp_dbl_list_node(ELEM_TYPE, NODE_TYPE, ELEM_PTR) \
NODE_TYPE{WAPP_DBL_NODE_MAGIC, ELEM_PTR, nullptr, nullptr, sizeof(ELEM_TYPE)}
#define wapp_dbl_list(TYPE) \
GenericList{WAPP_DBL_LIST_MAGIC, 0, sizeof(TYPE), nullptr, nullptr}
#define _dbl_list_node(TYPE, ITEM_PTR) ([&]() { \
wapp_persist GenericNode node = { \
NodeHeader{WAPP_DBL_NODE_MAGIC, sizeof(TYPE), nullptr, nullptr}, \
ITEM_PTR, \
}; \
\
return &node; \
}())
#else
#define wapp_dbl_list(ELEM_TYPE, LIST_TYPE) ( \
(LIST_TYPE){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(ELEM_TYPE)} \
#define wapp_dbl_list(TYPE) ( \
(GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(TYPE)} \
)
#define wapp_dbl_list_node(ELEM_TYPE, NODE_TYPE, ELEM_PTR) ( \
(NODE_TYPE){.magic = WAPP_DBL_NODE_MAGIC, .item = ELEM_PTR, .item_size = sizeof(ELEM_TYPE)} \
#define _dbl_list_node(TYPE, ITEM_PTR) ( \
&((GenericNode){.header = {.magic = WAPP_DBL_NODE_MAGIC, .item_size = sizeof(TYPE)}, \
.item = ITEM_PTR}) \
)
#endif // !WAPP_PLATFORM_CPP
#define wapp_dbl_list_alloc(ELEM_TYPE, LIST_TYPE, ALLOCATOR) \
(LIST_TYPE *)_dbl_list_alloc(ALLOCATOR, sizeof(ELEM_TYPE))
#define wapp_dbl_list_node_alloc(ELEM_TYPE, NODE_TYPE, ALLOCATOR) \
(NODE_TYPE *)_dbl_list_node_alloc(ALLOCATOR, sizeof(ELEM_TYPE))
#define wapp_dbl_list_get(ELEM_TYPE, NODE_TYPE, LIST_PTR, ELEM_INDEX) \
(NODE_TYPE *)_dbl_list_get((GenericList *)LIST_PTR, ELEM_INDEX, sizeof(ELEM_TYPE))
#define wapp_dbl_list_push_front(ELEM_TYPE, LIST_PTR, NODE_PTR) \
_dbl_list_push_front((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, sizeof(ELEM_TYPE))
#define wapp_dbl_list_push_back(ELEM_TYPE, LIST_PTR, NODE_PTR) \
_dbl_list_push_back((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, sizeof(ELEM_TYPE))
#define wapp_dbl_list_insert(ELEM_TYPE, LIST_PTR, NODE_PTR, ELEM_INDEX) \
_dbl_list_insert((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, ELEM_INDEX, sizeof(ELEM_TYPE))
#define wapp_dbl_list_pop_front(ELEM_TYPE, NODE_TYPE, LIST_PTR) \
(NODE_TYPE *)_dbl_list_pop_front((GenericList *)LIST_PTR, sizeof(ELEM_TYPE))
#define wapp_dbl_list_pop_back(ELEM_TYPE, NODE_TYPE, LIST_PTR) \
(NODE_TYPE *)_dbl_list_pop_back((GenericList *)LIST_PTR, sizeof(ELEM_TYPE))
#define wapp_dbl_list_remove(ELEM_TYPE, NODE_TYPE, LIST_PTR, ELEM_INDEX) \
(NODE_TYPE *)_dbl_list_remove((GenericList *)LIST_PTR, ELEM_INDEX, sizeof(ELEM_TYPE))
#define wapp_dbl_list_empty(ELEM_TYPE, LIST_PTR) \
_dbl_list_empty((GenericList *)LIST_PTR, sizeof(ELEM_TYPE))
WAPP_DEF_DBL_LIST_TYPE(void, GenericNode, GenericList);
#define wapp_dbl_list_alloc(TYPE, ALLOCATOR) \
(_dbl_list_alloc(ALLOCATOR, sizeof(TYPE)))
#define wapp_dbl_list_get(TYPE, LIST_PTR, ITEM_INDEX) \
((TYPE *)(_dbl_list_get(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item))
#define wapp_dbl_list_get_node(TYPE, LIST_PTR, ITEM_INDEX) \
(_dbl_list_get(LIST_PTR, ITEM_INDEX, sizeof(TYPE)))
#define wapp_dbl_list_get_node_item(TYPE, NODE_PTR) \
((TYPE *)( \
(NODE_PTR == NULL) ? \
NULL : \
(NODE_PTR)->item \
))
#define wapp_dbl_list_push_front(TYPE, LIST_PTR, ITEM_PTR) \
(_dbl_list_push_front(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), sizeof(TYPE)))
#define wapp_dbl_list_push_back(TYPE, LIST_PTR, ITEM_PTR) \
(_dbl_list_push_back(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), sizeof(TYPE)))
#define wapp_dbl_list_insert(TYPE, LIST_PTR, ITEM_PTR, ITEM_INDEX) \
(_dbl_list_insert(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), \
ITEM_INDEX, sizeof(TYPE)))
#define wapp_dbl_list_push_front_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \
(_dbl_list_push_front(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \
sizeof(TYPE)))
#define wapp_dbl_list_push_back_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \
(_dbl_list_push_back(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \
sizeof(TYPE)))
#define wapp_dbl_list_insert_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR, ITEM_INDEX) \
(_dbl_list_insert(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \
ITEM_INDEX, sizeof(TYPE)))
#define wapp_dbl_list_pop_front(TYPE, LIST_PTR) \
((TYPE *)( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_front(LIST_PTR, sizeof(TYPE))->item \
))
#define wapp_dbl_list_pop_back(TYPE, LIST_PTR) \
((TYPE *)( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_back(LIST_PTR, sizeof(TYPE))->item \
))
#define wapp_dbl_list_remove(TYPE, LIST_PTR, ITEM_INDEX) \
((TYPE *)( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \
NULL : \
_dbl_list_remove(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item \
))
#define wapp_dbl_list_pop_front_node(TYPE, LIST_PTR) \
( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_front(LIST_PTR, sizeof(TYPE)) \
)
#define wapp_dbl_list_pop_back_node(TYPE, LIST_PTR) \
( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_back(LIST_PTR, sizeof(TYPE)) \
)
#define wapp_dbl_list_remove_node(TYPE, LIST_PTR, ITEM_INDEX) \
( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \
NULL : \
_dbl_list_remove(LIST_PTR, ITEM_INDEX, sizeof(TYPE)) \
)
#define wapp_dbl_list_empty(TYPE, LIST_PTR) \
(_dbl_list_empty(LIST_PTR, sizeof(TYPE)))
GenericList *_dbl_list_alloc(const Allocator *allocator, u64 item_size);
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, u64 item_size);
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, void *item, u64 item_size);
GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size);
void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size);
void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size);
@@ -80,29 +177,6 @@ GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size);
GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size);
void _dbl_list_empty(GenericList *list, u64 item_size);
// Base list types
typedef struct Str8 Str8;
WAPP_DEF_DBL_LIST_TYPE(void *, VoidPtrNode, VoidPtrList);
WAPP_DEF_DBL_LIST_TYPE(c8 , C8Node , C8List);
WAPP_DEF_DBL_LIST_TYPE(c16 , C16Node , C16List);
WAPP_DEF_DBL_LIST_TYPE(c32 , C32Node , C32List);
WAPP_DEF_DBL_LIST_TYPE(u8 , U8Node , U8List);
WAPP_DEF_DBL_LIST_TYPE(u16 , U16Node , U16List);
WAPP_DEF_DBL_LIST_TYPE(u32 , U32Node , U32List);
WAPP_DEF_DBL_LIST_TYPE(u64 , U64Node , U64List);
WAPP_DEF_DBL_LIST_TYPE(b8 , B8Node , B8List);
WAPP_DEF_DBL_LIST_TYPE(i8 , I8Node , I8List);
WAPP_DEF_DBL_LIST_TYPE(i16 , I16Node , I16List);
WAPP_DEF_DBL_LIST_TYPE(i32 , I32Node , I32List);
WAPP_DEF_DBL_LIST_TYPE(i64 , I64Node , I64List);
WAPP_DEF_DBL_LIST_TYPE(f32 , F32Node , F32List);
WAPP_DEF_DBL_LIST_TYPE(f64 , F64Node , F64List);
WAPP_DEF_DBL_LIST_TYPE(f128 , F128Node , F128List);
WAPP_DEF_DBL_LIST_TYPE(uptr , UptrNode , UptrList);
WAPP_DEF_DBL_LIST_TYPE(iptr , IptrNode , IptrList);
WAPP_DEF_DBL_LIST_TYPE(Str8 , Str8Node , Str8List);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP

View File

@@ -3,13 +3,12 @@
#include "mem_utils.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include <stddef.h>
wapp_intern b8 is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
wapp_debug_assert(ptr != NULL, "`ptr` should not be NULL");
wapp_runtime_assert(is_power_of_two(alignment), "`alignment` value is not a power of two");
wapp_runtime_assert(wapp_is_power_of_two(alignment), "`alignment` value is not a power of two");
uptr p = (uptr)ptr;
uptr align = (uptr)alignment;

85
src/base/queue/queue.c Normal file
View File

@@ -0,0 +1,85 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "queue.h"
#include "../array/array.h"
#include "../../common/assert/assert.h"
#include "../../common/misc/misc_utils.h"
#include <string.h>
void _queue_push(GenericQueue *queue, void *item, u64 item_size) {
wapp_debug_assert(queue != NULL, "`queue` should not be NULL");
wapp_runtime_assert(item_size == wapp_array_item_size(queue->items), "Invalid type");
u64 capacity = wapp_array_capacity(queue->items);
if (queue->count >= capacity) { return; }
u64 index = (queue->back)++;
_array_set(queue->items, index, item, item_size);
++(queue->count);
if (queue->back >= capacity) {
queue->back = 0;
}
}
GenericQueue *_queue_push_alloc(const Allocator *allocator, GenericQueue *queue, void *item, u64 item_size) {
wapp_debug_assert(allocator != NULL && queue != NULL && item != NULL,
"`allocator`, `queue` and `item` should not be NULL");
wapp_runtime_assert(item_size == wapp_array_item_size(queue->items), "Invalid type");
GenericQueue *output = queue;
u64 capacity = wapp_array_capacity(queue->items);
if (queue->count >= capacity) {
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(capacity * 2);
u64 array_size = _array_calc_alloc_size(new_capacity, item_size);
u64 alloc_size = sizeof(GenericQueue) + array_size;
void *buffer = wapp_mem_allocator_alloc(allocator, alloc_size);
if (!buffer) {
goto RETURN_QUEUE_PUSH_ALLOC;
}
memset((void *)buffer, 0, alloc_size);
output = (GenericQueue *)buffer;
output->items = _array_from_preallocated_buffer((void *)(output + 1), array_size, ARRAY_INIT_FILLED, item_size);
// NOTE (Abdelrahman): When the queue is full, the front and back indices should
// always be the same
u64 front_count = capacity - queue->front;
u64 back_count = queue->back;
void *copy_boundary = (void *)((uptr)(queue->items) + (queue->front * item_size));
memcpy(output->items, copy_boundary, front_count * item_size);
if (back_count > 0) {
void *back_copy_dst = (void *)((uptr)(output->items) + (front_count * item_size));
memcpy(back_copy_dst, queue->items, back_count * item_size);
}
output->front = 0;
output->back = front_count + back_count;
output->count = queue->count;
}
_queue_push(output, item, item_size);
RETURN_QUEUE_PUSH_ALLOC:
return output;
}
void *_queue_pop(GenericQueue *queue, u64 item_size) {
wapp_debug_assert(queue != NULL, "`queue` should not be NULL");
wapp_runtime_assert(item_size == wapp_array_item_size(queue->items), "Invalid type");
if (queue->count == 0) { return NULL; }
u64 index = (queue->front)++;
--(queue->count);
u64 capacity = wapp_array_capacity(queue->items);
if (queue->front >= capacity) {
queue->front = 0;
}
return _array_get(queue->items, index, item_size);
}

100
src/base/queue/queue.h Normal file
View File

@@ -0,0 +1,100 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef QUEUE_H
#define QUEUE_H
#include "../array/array.h"
#include "../mem/allocator/mem_allocator.h"
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef struct {
GenericArray items;
u64 front;
u64 back;
u64 count;
} GenericQueue;
// NOTE (Abdelrahman): GenericQueue typedefs for readability
typedef GenericQueue VoidPtrQueue;
typedef GenericQueue C8Queue;
typedef GenericQueue C16Queue;
typedef GenericQueue C32Queue;
typedef GenericQueue U8Queue;
typedef GenericQueue U16Queue;
typedef GenericQueue U32Queue;
typedef GenericQueue U64Queue;
typedef GenericQueue B8Queue;
typedef GenericQueue I8Queue;
typedef GenericQueue I16Queue;
typedef GenericQueue I32Queue;
typedef GenericQueue I64Queue;
typedef GenericQueue F32Queue;
typedef GenericQueue F64Queue;
typedef GenericQueue F128Queue;
typedef GenericQueue UptrQueue;
typedef GenericQueue IptrQueue;
typedef GenericQueue Str8Queue;
#ifdef WAPP_PLATFORM_CPP
#define wapp_queue(TYPE, CAPACITY) ([&]() { \
wapp_persist GenericArray arr = wapp_array_with_capacity(TYPE, CAPACITY, ARRAY_INIT_FILLED); \
wapp_persist GenericQueue queue = { \
arr, \
0, \
0, \
0, \
}; \
\
return queue; \
}())
#define wapp_queue_alloc(TYPE, ALLOCATOR_PTR, CAPACITY) ([&]() { \
wapp_persist GenericQueue queue = { \
wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, ARRAY_INIT_FILLED), \
0, \
0, \
0, \
}; \
\
return queue; \
}())
#else
#define wapp_queue(TYPE, CAPACITY) ((GenericQueue){ \
.items = wapp_array_with_capacity(TYPE, CAPACITY, ARRAY_INIT_FILLED), \
.front = 0, \
.back = 0, \
.count = 0, \
})
#define wapp_queue_alloc(TYPE, ALLOCATOR_PTR, CAPACITY) ((GenericQueue){ \
.items = wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, ARRAY_INIT_FILLED), \
.front = 0, \
.back = 0, \
.count = 0, \
})
#endif // !WAPP_PLATFORM_CPP
#define wapp_queue_capacity(QUEUE_PTR) (wapp_array_capacity((QUEUE_PTR)->items))
#define wapp_queue_item_size(QUEUE_PTR) (wapp_array_item_size((QUEUE_PTR)->items))
#define wapp_queue_push(TYPE, QUEUE_PTR, VALUE_PTR) ( \
_queue_push(QUEUE_PTR, VALUE_PTR, sizeof(TYPE)) \
)
#define wapp_queue_push_alloc(TYPE, ALLOCATOR_PTR, QUEUE_PTR, VALUE_PTR) ( \
_queue_push_alloc(ALLOCATOR_PTR, QUEUE_PTR, VALUE_PTR, sizeof(TYPE)) \
)
#define wapp_queue_pop(TYPE, QUEUE_PTR) ( \
(TYPE *)_queue_pop(QUEUE_PTR, sizeof(TYPE)) \
)
void _queue_push(GenericQueue *queue, void *item, u64 item_size);
GenericQueue *_queue_push_alloc(const Allocator *allocator, GenericQueue *queue, void *item, u64 item_size);
void *_queue_pop(GenericQueue *queue, u64 item_size);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !QUEUE_H

View File

@@ -333,14 +333,12 @@ i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_dbl_list_alloc(Str8, Str8List, allocator);
Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
if (node) {
node->item = full;
wapp_dbl_list_push_back(Str8, output, node);
if (full) {
wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
}
goto RETURN_STR8_SPLIT;
@@ -358,10 +356,8 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
}
before_str = wapp_str8_alloc_substr(allocator, str, start, start + end);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
if (node && before_str) {
node->item = before_str;
wapp_dbl_list_push_back(Str8, output, node);
if (before_str) {
wapp_dbl_list_push_back_alloc(Str8, allocator, output, before_str);
}
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
@@ -373,10 +369,8 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
// Ensure the last part of the string after the delimiter is added to the list
rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
if (node && rest) {
node->item = rest;
wapp_dbl_list_push_back(Str8, output, node);
if (rest) {
wapp_dbl_list_push_back_alloc(Str8, allocator, output, rest);
}
RETURN_STR8_SPLIT:
@@ -386,14 +380,12 @@ RETURN_STR8_SPLIT:
Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_dbl_list_alloc(Str8, Str8List, allocator);
Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
if (node && full) {
node->item = full;
wapp_dbl_list_push_back(Str8, output, node);
if (full) {
wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
}
goto RETURN_STR8_SPLIT;
@@ -410,10 +402,8 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
}
after_str = wapp_str8_alloc_substr(allocator, rest, end + delimiter->size, str->size);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
if (node) {
node->item = after_str;
wapp_dbl_list_push_front(Str8, output, node);
if (after_str) {
wapp_dbl_list_push_front_alloc(Str8, allocator, output, after_str);
}
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
@@ -423,10 +413,8 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
}
rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
if (node && rest) {
node->item = rest;
wapp_dbl_list_push_front(Str8, output, node);
if (rest) {
wapp_dbl_list_push_front_alloc(Str8, allocator, output, rest);
}
RETURN_STR8_SPLIT:
@@ -441,16 +429,16 @@ Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *d
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
Str8Node *node;
Str8 *node;
u64 node_index = 0;
b8 running = node_index < list->node_count;
while (running) {
node = wapp_dbl_list_get(Str8, Str8Node, list, node_index);
node = wapp_dbl_list_get(Str8, list, node_index);
if (!node) {
break;
}
wapp_str8_concat_capped(output, node->item);
wapp_str8_concat_capped(output, node);
// NOTE (Abdelrahman): Comparison extracted to variable to silence
// MSVC Spectre mitigation warnings
@@ -473,17 +461,17 @@ u64 wapp_str8_list_total_size(const Str8List *list) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
Str8Node* node;
Str8 *node;
u64 node_index = 0;
u64 output = 0;
b8 running = node_index < list->node_count;
while (running) {
node = wapp_dbl_list_get(Str8, Str8Node, list, node_index);
node = wapp_dbl_list_get(Str8, list, node_index);
if (!node) {
break;
}
output += node->item->size;
output += node->size;
++node_index;
running = node_index < list->node_count;
}

View File

@@ -125,27 +125,6 @@ u64 wapp_str8_list_total_size(const Str8List *list);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#include <type_traits>
template <typename T>
constexpr bool is_lvalue(T&&) {
return std::is_lvalue_reference<T>{};
}
#define wapp_str8_node_from_cstr(STRING) wapp_dbl_list_node(Str8, Str8Node, [&]() { \
wapp_persist Str8 str = wapp_str8_lit(STRING); \
return &str; \
}())
#define wapp_str8_node_from_str8(STRING) wapp_dbl_list_node(Str8, Str8Node, [&]() { \
if (is_lvalue(STRING)) { return &STRING; } \
\
wapp_persist Str8 str = STRING; \
return &str; \
}())
#else
#define wapp_str8_node_from_cstr(STRING) wapp_dbl_list_node(Str8, Str8Node, &wapp_str8_lit(STRING))
#define wapp_str8_node_from_str8(STRING) wapp_dbl_list_node(Str8, Str8Node, &(STRING))
#endif // !WAPP_PLATFORM_CPP
#endif // !STR8_H

View File

@@ -6,6 +6,7 @@
#include "wapp_base.h"
#include "array/array.c"
#include "dbl_list/dbl_list.c"
#include "queue/queue.c"
#include "mem/allocator/mem_allocator.c"
#include "mem/utils/mem_utils.c"
#include "strings/str8/str8.c"

View File

@@ -3,8 +3,9 @@
#ifndef WAPP_BASE_H
#define WAPP_BASE_H
#include "dbl_list/dbl_list.h"
#include "array/array.h"
#include "dbl_list/dbl_list.h"
#include "queue/queue.h"
#include "mem/allocator/mem_allocator.h"
#include "mem/utils/mem_utils.h"
#include "strings/str8/str8.h"

View File

@@ -10,25 +10,25 @@
#include <uchar.h>
#if WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C23_VERSION
#define c8 char8_t
typedef char8_t c8;
#else
#define c8 uint8_t
typedef uint8_t c8;
#endif // !WAPP_PLATFORM_C23_VERSION
#define c16 char16_t
#define c32 char32_t
typedef char16_t c16;
typedef char32_t c32;
#else
#define c8 uint8_t
#define c16 uint16_t
#define c32 uint32_t
typedef uint8_t c8;
typedef uint16_t c16;
typedef uint32_t c32;
#endif // !WAPP_PLATFORM_C
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
#define b8 uint8_t
typedef uint8_t b8;
#ifndef WAPP_PLATFORM_CPP
@@ -42,17 +42,17 @@
#endif // !WAPP_PLATFORM_CPP
#define i8 int8_t
#define i16 int16_t
#define i32 int32_t
#define i64 int64_t
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
#define f32 float
#define f64 double
#define f128 long double
typedef float f32;
typedef double f64;
typedef long double f128;
#define uptr uintptr_t
#define iptr intptr_t
typedef uintptr_t uptr;
typedef intptr_t iptr;
#define wapp_extern extern
#define wapp_intern static

View File

@@ -23,7 +23,7 @@ BEGIN_C_LINKAGE
#define PB(SIZE) (TB(SIZE) * 1000llu)
#define EB(SIZE) (PB(SIZE) * 1000llu)
#define wapp_misc_utils_padding_size(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))]
#define wapp_misc_utils_reserve_padding(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))]
#define U64_RSHIFT_OR_1(X) (((u64)X) | (((u64)X) >> 1))
#define U64_RSHIFT_OR_2(X) (((u64)X) | (((u64)X) >> 2))
@@ -47,6 +47,9 @@ BEGIN_C_LINKAGE
) + 1 \
)
#define wapp_is_power_of_two(NUM) ((NUM & (NUM - 1)) == 0)
#define wapp_pointer_offset(PTR, OFFSET) ((void *)((uptr)(PTR) + (OFFSET)))
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE

View File

@@ -6,7 +6,6 @@
#include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include "../../../base/mem/utils/mem_utils.h"
#include <stdlib.h>
#include <string.h>
#ifndef DEFAULT_ALIGNMENT
@@ -17,45 +16,70 @@
#define ARENA_MINIMUM_CAPACITY KiB(16) // Allocate minimum of 4 pages
typedef enum {
ARENA_STORAGE_TYPE_ALLOCATED,
ARENA_STORAGE_TYPE_BUFFER,
} ArenaStorageType;
struct Arena {
u8 *buf;
u8 *offset;
u8 *prev_offset;
u64 capacity;
ArenaStorageType type;
b8 committed;
#ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(b8));
#endif // ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_reserve_padding(sizeof(u8 *) * 3 + sizeof(u64) + sizeof(ArenaStorageType) + sizeof(b8));
};
b8 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
b8 wapp_mem_arena_init_buffer(Arena **arena, u8 *buffer, u64 buffer_size) {
if (!arena || *arena || buffer_size < sizeof(Arena)) {
return false;
}
*arena = (Arena *)buffer;
Arena *arena_ptr = *arena;
arena_ptr->buf = (u8 *)(arena_ptr + 1);
arena_ptr->offset = arena_ptr->buf;
arena_ptr->prev_offset = NULL;
arena_ptr->capacity = buffer_size - sizeof(Arena);
arena_ptr->type = ARENA_STORAGE_TYPE_BUFFER;
arena_ptr->committed = true;
return true;
}
b8 wapp_mem_arena_init_allocated_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
if (!arena || *arena || base_capacity == 0) {
return false;
}
*arena = (Arena *)calloc(1, sizeof(Arena));
Arena *arena_ptr = *arena;
if (!arena_ptr) {
u64 size = sizeof(Arena) + (base_capacity >= ARENA_MINIMUM_CAPACITY ? base_capacity : ARENA_MINIMUM_CAPACITY);
u64 alloc_size = wapp_misc_utils_u64_round_up_pow2(size);
u8 *allocated = (u8 *)wapp_os_mem_alloc(NULL, alloc_size, WAPP_MEM_ACCESS_READ_WRITE, flags,
zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED);
if (!allocated) {
return false;
}
u64 arena_capacity = wapp_misc_utils_u64_round_up_pow2(
base_capacity >= ARENA_MINIMUM_CAPACITY ?
base_capacity :
ARENA_MINIMUM_CAPACITY
);
b8 committed = (flags & WAPP_MEM_ALLOC_COMMIT) == WAPP_MEM_ALLOC_COMMIT;
arena_ptr->buf = (u8 *)wapp_os_mem_alloc(NULL, arena_capacity, WAPP_MEM_ACCESS_READ_WRITE, flags,
zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED);
#ifdef WAPP_PLATFORM_WINDOWS
if (!committed) {
wapp_os_mem_alloc(allocated, sizeof(Arena), WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_INITIALISED);
}
#endif // ifdef WAPP_PLATFORM_WINDOWS
if (!(arena_ptr->buf)) {
if (!wapp_mem_arena_init_buffer(arena, allocated, alloc_size)) {
wapp_mem_arena_destroy(arena);
return false;
}
arena_ptr->capacity = arena_capacity;
arena_ptr->offset = arena_ptr->buf;
arena_ptr->committed = (flags & WAPP_MEM_ALLOC_COMMIT) == WAPP_MEM_ALLOC_COMMIT;
Arena *arena_ptr = *arena;
arena_ptr->type = ARENA_STORAGE_TYPE_ALLOCATED;
arena_ptr->committed = committed;
return true;
}
@@ -77,7 +101,7 @@ void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
arena->offset = output + size;
#ifdef WAPP_PLATFORM_WINDOWS
if (!(arena->committed)) {
if (arena->type == ARENA_STORAGE_TYPE_ALLOCATED && !(arena->committed)) {
wapp_os_mem_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start),
WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_UNINITIALISED);
@@ -90,6 +114,8 @@ void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
}
void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL;
@@ -107,6 +133,8 @@ void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size
}
void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL;
@@ -123,6 +151,27 @@ void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64
return new_ptr;
}
void wapp_mem_arena_temp_begin(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if (arena->prev_offset != NULL) {
return;
}
arena->prev_offset = arena->offset;
}
void wapp_mem_arena_temp_end(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if (arena->prev_offset == NULL) {
return;
}
arena->offset = arena->prev_offset;
arena->prev_offset = NULL;
}
void wapp_mem_arena_clear(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
@@ -134,13 +183,10 @@ void wapp_mem_arena_destroy(Arena **arena) {
wapp_debug_assert(arena != NULL && (*arena) != NULL, "`arena` double pointer is not valid");
Arena *arena_ptr = *arena;
if (arena_ptr->buf) {
wapp_os_mem_free(arena_ptr->buf, arena_ptr->capacity);
if (arena_ptr->type == ARENA_STORAGE_TYPE_ALLOCATED) {
wapp_os_mem_free(*arena, sizeof(Arena) + arena_ptr->capacity);
}
arena_ptr->buf = arena_ptr->offset = NULL;
arena_ptr->capacity = 0;
free(*arena);
*arena = NULL;
}

View File

@@ -13,25 +13,28 @@ BEGIN_C_LINKAGE
typedef struct Arena Arena;
#define wapp_mem_arena_init(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
#define wapp_mem_arena_init_commit(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false))
#define wapp_mem_arena_init_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, true))
#define wapp_mem_arena_init_commit_and_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, true))
#define wapp_mem_arena_init_allocated(arena_dptr, base_capacity) \
(wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
#define wapp_mem_arena_init_allocated_commit(arena_dptr, base_capacity) \
(wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false))
#define wapp_mem_arena_init_allocated_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, true))
#define wapp_mem_arena_init_allocated_commit_and_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, true))
/**
* Arena initialisation function. `wapp_mem_arena_init_custom` provides the most
* Arena initialisation function. `wapp_mem_arena_init_allocated_custom` provides the most
* control over how the Arena is initialised. Wrapper macros are provided for
* easier use.
*/
b8 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer);
b8 wapp_mem_arena_init_allocated_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer);
b8 wapp_mem_arena_init_buffer(Arena **arena, u8 *buffer, u64 buffer_size);
void *wapp_mem_arena_alloc(Arena *arena, u64 size);
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size);
void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment);
void wapp_mem_arena_temp_begin(Arena *arena);
void wapp_mem_arena_temp_end(Arena *arena);
void wapp_mem_arena_clear(Arena *arena);
void wapp_mem_arena_destroy(Arena **arena);

View File

@@ -4,38 +4,66 @@
#include "mem_arena.h"
#include "../../mem/mem_os.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
wapp_intern void initialise_arena_allocator(Allocator *allocator);
wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj);
wapp_intern void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj);
wapp_intern void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
wapp_intern void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj);
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
Allocator wapp_mem_arena_allocator_init_with_buffer(u8 *buffer, u64 buffer_size) {
Allocator allocator = {0};
b8 initialised = wapp_mem_arena_init_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer);
b8 initialised = wapp_mem_arena_init_buffer((Arena **)(&allocator.obj), buffer, buffer_size);
if (!initialised) {
return allocator;
}
allocator.alloc = mem_arena_alloc;
allocator.alloc_aligned = mem_arena_alloc_aligned;
allocator.realloc = mem_arena_realloc;
allocator.realloc_aligned = mem_arena_realloc_aligned;
initialise_arena_allocator(&allocator);
return allocator;
}
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
Allocator allocator = {0};
b8 initialised = wapp_mem_arena_init_allocated_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer);
if (!initialised) {
return allocator;
}
initialise_arena_allocator(&allocator);
return allocator;
}
void wapp_mem_arena_allocator_temp_begin(const Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_temp_begin((Arena *)(allocator->obj));
}
void wapp_mem_arena_allocator_temp_end(const Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_temp_end((Arena *)(allocator->obj));
}
void wapp_mem_arena_allocator_clear(Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_clear((Arena *)(allocator->obj));
}
void wapp_mem_arena_allocator_destroy(Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_destroy((Arena **)(&(allocator->obj)));
*allocator = (Allocator){0};
}
wapp_intern void initialise_arena_allocator(Allocator *allocator) {
allocator->alloc = mem_arena_alloc;
allocator->alloc_aligned = mem_arena_alloc_aligned;
allocator->realloc = mem_arena_realloc;
allocator->realloc_aligned = mem_arena_realloc_aligned;
}
wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj;

View File

@@ -33,6 +33,9 @@ BEGIN_C_LINKAGE
* the Arena is initialised. Wrapper macros are provided for easier use.
*/
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer);
Allocator wapp_mem_arena_allocator_init_with_buffer(u8 *buffer, u64 buffer_size);
void wapp_mem_arena_allocator_temp_begin(const Allocator *allocator);
void wapp_mem_arena_allocator_temp_end(const Allocator *allocator);
void wapp_mem_arena_allocator_clear(Allocator *allocator);
void wapp_mem_arena_allocator_destroy(Allocator *allocator);

View File

@@ -29,23 +29,23 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
}
// Handle first node
const Str8Node *first_node = wapp_dbl_list_get(Str8, Str8Node, parts, 0);
wapp_str8_copy_str8_capped(dst, first_node->item);
Str8 *first_node = wapp_dbl_list_get(Str8, parts, 0);
wapp_str8_copy_str8_capped(dst, first_node);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
const Str8Node *node = first_node;
Str8 *node = first_node;
u64 node_index = 1;
b8 running = node_index < parts->node_count;
while (running && node->next) {
node = node->next;
if (node->item->size == 0) {
continue;
while (running) {
node = wapp_dbl_list_get(Str8, parts, node_index);
if (node->size == 0) {
goto CPATH_JOIN_LOOP_END;
}
if (dst->size > 0) {
char dst_last = wapp_str8_get(dst, dst->size - 1);
char node_start = wapp_str8_get(node->item, 0);
char node_start = wapp_str8_get(node, 0);
b8 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP;
if (add_path_sep) {
@@ -53,8 +53,9 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
}
}
wapp_str8_concat_capped(dst, node->item);
wapp_str8_concat_capped(dst, node);
CPATH_JOIN_LOOP_END:
++node_index;
running = node_index < parts->node_count;
}
@@ -106,7 +107,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
} else {
for (u64 i = 0; i < levels; ++i) {
wapp_dbl_list_pop_back(Str8, Str8Node, parts);
wapp_dbl_list_pop_back(Str8, parts);
}
u64 alignment = sizeof(void *) * 2;

View File

@@ -18,7 +18,7 @@ BEGIN_C_LINKAGE
#define WAPP_PATH_MAX PATH_MAX
#elif defined(WAPP_PLATFORM_WINDOWS)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Windows.h>
#define WAPP_PATH_SEP '\\'
#define WAPP_PATH_MAX MAX_PATH
#else

View File

@@ -6,67 +6,66 @@
#include "../../common/aliases/aliases.h"
#include "../../base/array/array.h"
#include "../../base/strings/str8/str8.h"
#include <stdio.h>
File *wapp_file_open(Str8RO *filepath, FileAccessMode mode) {
wapp_persist const char *modes[FILE_ACCESS_MODE_COUNT] = {
[WAPP_FA_MODE_R] = "r",
[WAPP_FA_MODE_W] = "w",
[WAPP_FA_MODE_A] = "a",
[WAPP_FA_MODE_R_EX] = "r+",
[WAPP_FA_MODE_W_EX] = "w+",
[WAPP_FA_MODE_A_EX] = "a+",
[WAPP_FA_MODE_RB] = "rb",
[WAPP_FA_MODE_WB] = "wb",
[WAPP_FA_MODE_AB] = "ab",
[WAPP_FA_MODE_RB_EX] = "rb+",
[WAPP_FA_MODE_WB_EX] = "wb+",
[WAPP_FA_MODE_AB_EX] = "ab+",
[WAPP_FA_MODE_WX] = "wx",
[WAPP_FA_MODE_WX_EX] = "wx+",
[WAPP_FA_MODE_WBX] = "wbx",
[WAPP_FA_MODE_WBX_EX] = "wbx+",
};
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
WFile *wapp_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_debug_assert(allocator != NULL && filepath != NULL, "`allocator` and `filepath` should not be NULL");
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return fopen((const char *)tmp, modes[mode]);
return _file_open(allocator, filepath, mode);
}
u64 wapp_file_get_current_position(File *file) {
i64 wapp_file_get_current_position(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return (u64)ftell(file);
return _file_seek(file, 0, WAPP_SEEK_CURRENT);
}
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin) {
i64 wapp_file_seek(WFile *file, i64 offset, FileSeekOrigin origin) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
// TODO (Abdelrahman): Revisit conversion to long
return fseek(file, (long)offset, origin);
return _file_seek(file, offset, origin);
}
u64 wapp_file_get_length(File *file) {
i64 wapp_file_get_length(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
u64 current = wapp_file_get_current_position(file);
i64 current = wapp_file_get_current_position(file);
wapp_file_seek(file, 0, WAPP_SEEK_END);
_file_seek(file, 0, WAPP_SEEK_END);
u64 output = ftell(file);
i64 output = wapp_file_get_current_position(file);
// Restore position
wapp_file_seek(file, current, WAPP_SEEK_START);
_file_seek(file, current, WAPP_SEEK_START);
return output;
}
u64 wapp_file_read(GenericArray dst_buf, File *file, u64 item_count) {
u64 wapp_file_read(void *dst_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(dst_buf != NULL && file != NULL,
"`dst_buf` and `file` should not be NULL.");
u64 file_length = wapp_file_get_length(file);
i64 file_length = wapp_file_get_length(file);
if (file_length < 0) {
return 0;
}
return _file_read(dst_buf, byte_count, file, file_length);
}
i64 wapp_file_write(const void *src_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(src_buf != NULL && file != NULL,
"`src_buf` and `file` should not be NULL.");
return _file_write(src_buf, file, byte_count);
}
u64 wapp_file_read_array(GenericArray dst_buf, WFile *file, u64 item_count) {
wapp_debug_assert(dst_buf != NULL && file != NULL,
"`dst_buf` and `file` should not be NULL.");
i64 _file_length = wapp_file_get_length(file);
if (_file_length < 0) {
return 0;
}
u64 file_length = (u64)_file_length;
u64 item_size = wapp_array_item_size(dst_buf);
u64 dst_byte_capacity = wapp_array_capacity(dst_buf) * item_size;
u64 req_byte_count = item_count * item_size;
@@ -78,15 +77,17 @@ u64 wapp_file_read(GenericArray dst_buf, File *file, u64 item_count) {
copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity;
}
u64 count = fread(dst_buf, sizeof(u8), copy_byte_count, file);
if (ferror(file)) { return 0; }
u64 byte_count = _file_read(dst_buf, copy_byte_count, file, file_length);
if (byte_count == 0) {
return 0;
}
wapp_array_set_count(dst_buf, count / item_size);
wapp_array_set_count(dst_buf, byte_count / item_size);
return wapp_array_count(dst_buf);
}
u64 wapp_file_write(const GenericArray src_buf, File *file, u64 item_count) {
i64 wapp_file_write_array(const GenericArray src_buf, WFile *file, u64 item_count) {
wapp_debug_assert(src_buf != NULL && file != NULL,
"`src_buf` and `file` should not be NULL.");
@@ -95,15 +96,34 @@ u64 wapp_file_write(const GenericArray src_buf, File *file, u64 item_count) {
u64 req_byte_count = item_count * item_size;
u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count;
return fwrite(src_buf, sizeof(u8), to_copy, file);
i64 bytes_written = _file_write(src_buf, file, to_copy);
if (bytes_written < 0) {
return 0;
}
i32 wapp_file_flush(File *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fflush(file);
return (u64)bytes_written / item_size;
}
i32 wapp_file_close(File *file) {
i32 wapp_file_flush(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fclose(file);
return _file_flush(file);
}
i32 wapp_file_close(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return _file_close(file);
}
i32 wapp_file_rename(Str8RO *old_filepath, Str8RO *new_filepath) {
wapp_debug_assert(old_filepath != NULL && new_filepath != NULL,
"`old_filepath` and `new_filepath` should not be NULL");
wapp_debug_assert(old_filepath->size < WAPP_PATH_MAX, "`old_filepath` exceeds max path limit.");
wapp_debug_assert(new_filepath->size < WAPP_PATH_MAX, "`new_filepath` exceeds max path limit.");
return _file_rename(old_filepath, new_filepath);
}
i32 wapp_file_remove(Str8RO *filepath) {
wapp_debug_assert(filepath != NULL, "`filepath` should not be NULL");
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
return _file_remove(filepath);
}

View File

@@ -3,51 +3,58 @@
#ifndef FILE_H
#define FILE_H
#include "../../base/mem/allocator/mem_allocator.h"
#include "../../common/aliases/aliases.h"
#include "../../base/strings/str8/str8.h"
#include <stdio.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef FILE File;
typedef struct WFile WFile;
typedef enum {
WAPP_FA_MODE_R, // Equivalent to r
WAPP_FA_MODE_W, // Equivalent to w
WAPP_FA_MODE_A, // Equivalent to a
WAPP_FA_MODE_R_EX, // Equivalent to r+
WAPP_FA_MODE_W_EX, // Equivalent to w+
WAPP_FA_MODE_A_EX, // Equivalent to a+
WAPP_FA_MODE_RB, // Equivalent to rb
WAPP_FA_MODE_WB, // Equivalent to wb
WAPP_FA_MODE_AB, // Equivalent to ab
WAPP_FA_MODE_RB_EX, // Equivalent to rb+
WAPP_FA_MODE_WB_EX, // Equivalent to wb+
WAPP_FA_MODE_AB_EX, // Equivalent to ab+
WAPP_FA_MODE_WX, // Equivalent to wx
WAPP_FA_MODE_WX_EX, // Equivalent to wx+
WAPP_FA_MODE_WBX, // Equivalent to wbx
WAPP_FA_MODE_WBX_EX, // Equivalent to wbx+
WAPP_ACCESS_READ, // Equivalent to r
WAPP_ACCESS_WRITE, // Equivalent to w
WAPP_ACCESS_APPEND, // Equivalent to a
WAPP_ACCESS_READ_EX, // Equivalent to r+
WAPP_ACCESS_WRITE_EX, // Equivalent to w+
WAPP_ACCESS_APPEND_EX, // Equivalent to a+
WAPP_ACCESS_WRITE_FAIL_ON_EXIST, // Equivalent to wx
WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX, // Equivalent to wx+
FILE_ACCESS_MODE_COUNT,
} FileAccessMode;
typedef enum {
WAPP_SEEK_START = SEEK_SET,
WAPP_SEEK_CURRENT = SEEK_CUR,
WAPP_SEEK_END = SEEK_END,
WAPP_SEEK_START,
WAPP_SEEK_CURRENT,
WAPP_SEEK_END,
FILE_SEEK_ORIGIN_COUNT,
} FileSeekOrigin;
File *wapp_file_open(Str8RO *filename, FileAccessMode mode);
u64 wapp_file_get_current_position(File *file);
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin);
u64 wapp_file_get_length(File *file);
u64 wapp_file_read(GenericArray dst_buf, File *file, u64 item_count);
u64 wapp_file_write(const GenericArray src_buf, File *file, u64 item_count);
i32 wapp_file_flush(File *file);
i32 wapp_file_close(File *file);
WFile *wapp_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode);
i64 wapp_file_get_current_position(WFile *file);
i64 wapp_file_seek(WFile *file, i64 offset, FileSeekOrigin origin);
i64 wapp_file_get_length(WFile *file);
u64 wapp_file_read(void *dst_buf, WFile *file, u64 byte_count);
i64 wapp_file_write(const void *src_buf, WFile *file, u64 byte_count);
u64 wapp_file_read_array(GenericArray dst_buf, WFile *file, u64 item_count);
i64 wapp_file_write_array(const GenericArray src_buf, WFile *file, u64 item_count);
i32 wapp_file_flush(WFile *file);
i32 wapp_file_close(WFile *file);
i32 wapp_file_rename(Str8RO *old_filepath, Str8RO *new_filepath);
i32 wapp_file_remove(Str8RO *filepath);
extern WFile *_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode);
extern i64 _file_seek(WFile *file, i64 offset, FileSeekOrigin origin);
extern u64 _file_read(void *dst_buf, u64 byte_count, WFile *file, u64 file_length);
extern i64 _file_write(const void *src_buf, WFile *file, u64 byte_count);
extern i32 _file_flush(WFile *file);
extern i32 _file_close(WFile *file);
extern i32 _file_rename(Str8RO *old_filepath, Str8RO *new_filepath);
extern i32 _file_remove(Str8RO *filepath);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE

View File

@@ -0,0 +1,119 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "file_posix.h"
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_POSIX
#include "../file.h"
#include "../../cpath/cpath.h"
#include "../../../common/aliases/aliases.h"
#include "../../../base/array/array.h"
#include "../../../base/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_APPLE
#define _FILE_OFFSET_BITS 64
#define lseek64 lseek
#endif // !WAPP_PLATFORM_APPLE
#define __USE_LARGEFILE64
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
wapp_intern i32 file_flags[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = O_RDONLY,
[WAPP_ACCESS_WRITE] = O_WRONLY | O_CREAT,
[WAPP_ACCESS_APPEND] = O_WRONLY | O_APPEND | O_CREAT,
[WAPP_ACCESS_READ_EX] = O_RDWR,
[WAPP_ACCESS_WRITE_EX] = O_RDWR | O_CREAT,
[WAPP_ACCESS_APPEND_EX] = O_RDWR | O_APPEND | O_CREAT,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = O_WRONLY | O_CREAT | O_EXCL,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = O_RDWR | O_CREAT | O_EXCL,
};
wapp_intern mode_t file_modes[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = 0,
[WAPP_ACCESS_WRITE] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_APPEND] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_READ_EX] = 0,
[WAPP_ACCESS_WRITE_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_APPEND_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
};
wapp_intern i32 file_seek_origins[FILE_SEEK_ORIGIN_COUNT] = {
[WAPP_SEEK_START] = SEEK_SET,
[WAPP_SEEK_CURRENT] = SEEK_CUR,
[WAPP_SEEK_END] = SEEK_END,
};
WFile *_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
i32 fd = open((const char *)tmp, file_flags[mode], file_modes[mode]);
if (fd < 0) {
return NULL;
}
WFile *output = wapp_mem_allocator_alloc(allocator, sizeof(WFile));
if (output) {
output->fd = fd;
}
return output;
}
i64 _file_seek(WFile *file, i64 offset, FileSeekOrigin origin) {
return lseek64(file->fd, offset, file_seek_origins[origin]);
}
u64 _file_read(void *dst_buf, u64 byte_count, WFile *file, u64 file_length) {
u64 copy_byte_count = file_length <= byte_count ? file_length : byte_count;
i64 count = read(file->fd, dst_buf, copy_byte_count);
if (count < 0) { return 0; }
return count;
}
i64 _file_write(const void *src_buf, WFile *file, u64 byte_count) {
return write(file->fd, src_buf, byte_count);
}
i32 _file_flush(WFile *file) {
return fsync(file->fd);
}
i32 _file_close(WFile *file) {
return close(file->fd);
}
i32 _file_rename(Str8RO *old_filepath, Str8RO *new_filepath) {
wapp_persist c8 old_tmp[WAPP_PATH_MAX] = {0};
wapp_persist c8 new_tmp[WAPP_PATH_MAX] = {0};
memset(old_tmp, 0, WAPP_PATH_MAX);
memcpy(old_tmp, old_filepath->buf, old_filepath->size);
memset(new_tmp, 0, WAPP_PATH_MAX);
memcpy(new_tmp, new_filepath->buf, new_filepath->size);
i32 link_result = link((const char *)old_tmp, (const char *)new_tmp);
if (link_result == 0) {
_file_remove(old_filepath);
}
return link_result;
}
i32 _file_remove(Str8RO *filepath) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return unlink((const char *)tmp);
}
#endif // !WAPP_PLATFORM_POSIX

View File

@@ -0,0 +1,27 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef FILE_POSIX_H
#define FILE_POSIX_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_POSIX
#define END_OF_LINE "\n"
struct WFile {
i32 fd;
};
#endif // !WAPP_PLATFORM_POSIX
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !FILE_POSIX_H

159
src/os/file/win/file_win.c Normal file
View File

@@ -0,0 +1,159 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "file_win.h"
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "../file.h"
#include "../../cpath/cpath.h"
#include "../../../common/aliases/aliases.h"
#include "../../../base/array/array.h"
#include "../../../base/strings/str8/str8.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <fileapi.h>
#include <intsafe.h>
wapp_intern DWORD file_accesses[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = FILE_READ_DATA,
[WAPP_ACCESS_WRITE] = FILE_WRITE_DATA,
[WAPP_ACCESS_APPEND] = FILE_APPEND_DATA,
[WAPP_ACCESS_READ_EX] = FILE_READ_DATA | FILE_WRITE_DATA,
[WAPP_ACCESS_WRITE_EX] = FILE_READ_DATA | FILE_WRITE_DATA,
[WAPP_ACCESS_APPEND_EX] = FILE_READ_DATA | FILE_APPEND_DATA,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = FILE_WRITE_DATA,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = FILE_READ_DATA | FILE_WRITE_DATA,
};
wapp_intern DWORD creation_dispositions[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = OPEN_EXISTING,
[WAPP_ACCESS_WRITE] = CREATE_ALWAYS,
[WAPP_ACCESS_APPEND] = OPEN_ALWAYS,
[WAPP_ACCESS_READ_EX] = OPEN_EXISTING,
[WAPP_ACCESS_WRITE_EX] = CREATE_ALWAYS,
[WAPP_ACCESS_APPEND_EX] = OPEN_ALWAYS,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = CREATE_NEW,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = CREATE_NEW,
};
wapp_intern DWORD sharing_modes[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = FILE_SHARE_READ | FILE_SHARE_WRITE,
[WAPP_ACCESS_WRITE] = FILE_SHARE_READ,
[WAPP_ACCESS_APPEND] = FILE_SHARE_READ,
[WAPP_ACCESS_READ_EX] = FILE_SHARE_READ | FILE_SHARE_WRITE,
[WAPP_ACCESS_WRITE_EX] = FILE_SHARE_READ,
[WAPP_ACCESS_APPEND_EX] = FILE_SHARE_READ,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = FILE_SHARE_READ,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = FILE_SHARE_READ,
};
wapp_intern DWORD file_seek_origins[FILE_SEEK_ORIGIN_COUNT] = {
[WAPP_SEEK_START] = FILE_BEGIN,
[WAPP_SEEK_CURRENT] = FILE_CURRENT,
[WAPP_SEEK_END] = FILE_END,
};
WFile *_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
HANDLE fh = CreateFileA((LPCSTR)tmp,
file_accesses[mode],
sharing_modes[mode],
NULL,
creation_dispositions[mode],
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fh == INVALID_HANDLE_VALUE) {
return NULL;
}
WFile *output = wapp_mem_allocator_alloc(allocator, sizeof(WFile));
if (output) {
output->fh = fh;
}
return output;
}
i64 _file_seek(WFile *file, i64 offset, FileSeekOrigin origin) {
LARGE_INTEGER distance = {0};
LARGE_INTEGER output = {0};
distance.QuadPart = offset;
if (!SetFilePointerEx(file->fh, distance, &output, file_seek_origins[origin])) {
return -1;
}
return output.QuadPart;
}
u64 _file_read(void* dst_buf, u64 byte_count, WFile* file, u64 file_length) {
u64 copy_byte_count = file_length <= byte_count ? file_length : byte_count;
wapp_debug_assert(copy_byte_count <= DWORD_MAX, "Attempting to read large number of bytes at once");
DWORD read_count = 0;
if (!ReadFile(file->fh, dst_buf, (DWORD)copy_byte_count, &read_count, NULL)) {
return 0;
}
return (u64)read_count;
}
i64 _file_write(const void *src_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(byte_count <= DWORD_MAX, "Attempting to write large number of bytes at once");
DWORD write_count = 0;
if (!WriteFile(file->fh, src_buf, (DWORD)byte_count, &write_count, NULL)) {
return 0;
}
return (i64)write_count;
}
i32 _file_flush(WFile *file) {
if (!FlushFileBuffers(file->fh)) {
return -1;
}
return 0;
}
i32 _file_close(WFile *file) {
if (!CloseHandle(file->fh)) {
return -1;
}
return 0;
}
i32 _file_rename(Str8RO *old_filepath, Str8RO *new_filepath) {
wapp_persist c8 old_tmp[WAPP_PATH_MAX] = {0};
wapp_persist c8 new_tmp[WAPP_PATH_MAX] = {0};
memset(old_tmp, 0, WAPP_PATH_MAX);
memcpy(old_tmp, old_filepath->buf, old_filepath->size);
memset(new_tmp, 0, WAPP_PATH_MAX);
memcpy(new_tmp, new_filepath->buf, new_filepath->size);
if (!MoveFile((LPCSTR)old_tmp, (LPCSTR)new_tmp)) {
return -1;
}
return 0;
}
i32 _file_remove(Str8RO *filepath) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
if (!DeleteFile((LPCSTR)tmp)) {
return -1;
}
return 0;
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@@ -0,0 +1,31 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef FILE_WIN_H
#define FILE_WIN_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_WINDOWS
#define END_OF_LINE "\r\n"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <fileapi.h>
struct WFile {
HANDLE fh;
};
#endif // !WAPP_PLATFORM_WINDOWS
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !FILE_WIN_H

View File

@@ -5,6 +5,7 @@
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include "../../../common/misc/misc_utils.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
@@ -31,10 +32,7 @@ struct CMDResult {
CMDError error;
b8 exited;
#ifdef WAPP_PLATFORM_WINDOWS
#include "../../../../common/misc/misc_utils.h"
wapp_misc_utils_padding_size(sizeof(b8) + sizeof(i32) + sizeof(CMDError));
#endif // !WAPP_PLATFORM_WINDOWS
wapp_misc_utils_reserve_padding(sizeof(b8) + sizeof(i32) + sizeof(CMDError));
};
#ifdef WAPP_PLATFORM_CPP

View File

@@ -7,7 +7,7 @@
#ifdef WAPP_PLATFORM_WINDOWS
#include "../terminal_colours.h"
#include "../../../../../common/misc/misc_utils.h"
#include "../../../../common/misc/misc_utils.h"
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
@@ -19,7 +19,7 @@ struct TermcolourData {
WORD default_colour;
WORD current_colour;
wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD));
wapp_misc_utils_reserve_padding(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD));
};
wapp_intern void init_data(TermcolourData *data);

View File

@@ -5,6 +5,8 @@
#include "wapp_os.h"
#include "file/file.c"
#include "file/posix/file_posix.c"
#include "file/win/file_win.c"
#include "shell/termcolour/posix/termcolour_posix.c"
#include "shell/termcolour/win/termcolour_win.c"
#include "shell/termcolour/termcolour.c"

View File

@@ -4,6 +4,8 @@
#define WAPP_CORE_H
#include "file/file.h"
#include "file/posix/file_posix.h"
#include "file/win/file_win.h"
#include "shell/termcolour/termcolour.h"
#include "shell/termcolour/terminal_colours.h"
#include "shell/commander/commander.h"

View File

@@ -10,7 +10,7 @@
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#define wapp_tester_result(PASSED) (TestFuncResult{wapp_str8_lit_ro(__func__), PASSED})
#define wapp_tester_result(PASSED) (TestFuncResult{wapp_str8_lit_ro(__func__), PASSED, {}})
#else
#define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED})
#endif // !WAPP_PLATFORM_CPP
@@ -22,9 +22,7 @@ struct TestFuncResult {
Str8 name;
b8 passed;
#ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_padding_size(sizeof(Str8RO) + sizeof(b8));
#endif // WAPP_PLATFORM_WINDOWS
wapp_misc_utils_reserve_padding(sizeof(Str8) + sizeof(b8));
};
typedef TestFuncResult(TestFunc)(void);

View File

@@ -20,11 +20,17 @@ struct WUUID {
Str8 uuid;
};
// TODO (Abdelrahman): Update UUID implementation to work properly with C++ and tests for validation
#define wapp_uuid_gen_uuid4() *(wapp_uuid_init_uuid4(&wapp_uuid_create()))
/* Low level UUID API */
#ifdef WAPP_PLATFORM_CPP
#define wapp_uuid_create() ([&](){ return WUUID{wapp_str8_buf(UUID_BUF_LENGTH)}; })
#else
#define wapp_uuid_create() ((WUUID){.uuid = wapp_str8_buf(UUID_BUF_LENGTH)})
#endif
// Just returns the same pointer that was passed in with the UUID initialised.
// Fails when passed a NULL pointer.

View File

@@ -2,6 +2,13 @@
#include "wapp.h"
#include <stdlib.h>
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {0};
wapp_intern Allocator temp_allocator = {0};
TestFuncResult test_arena_allocator(void) {
Allocator allocator = wapp_mem_arena_allocator_init(4096);
b8 result = allocator.obj != NULL && allocator.alloc != NULL &&
@@ -15,3 +22,46 @@ TestFuncResult test_arena_allocator(void) {
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_with_buffer(void) {
u8 buffer[KiB(4)] = {0};
Allocator allocator = wapp_mem_arena_allocator_init_with_buffer(buffer, KiB(4));
b8 result = allocator.obj != NULL && allocator.alloc != NULL &&
allocator.alloc_aligned != NULL &&
allocator.realloc != NULL && allocator.realloc_aligned != NULL &&
allocator.free == NULL;
void *ptr = wapp_mem_allocator_alloc(&allocator, 20);
result = result && (ptr != NULL);
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_begin(void) {
temp_allocator = wapp_mem_arena_allocator_init_with_buffer(temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
wapp_mem_arena_allocator_temp_begin(&temp_allocator);
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_end(void) {
wapp_mem_arena_allocator_temp_end(&temp_allocator);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_allocator_destroy(&temp_allocator);
return wapp_tester_result(result);
}

View File

@@ -2,6 +2,13 @@
#include "wapp.h"
#include <stdlib.h>
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {};
wapp_intern Allocator temp_allocator = {};
TestFuncResult test_arena_allocator(void) {
Allocator allocator = wapp_mem_arena_allocator_init(4096);
b8 result = allocator.obj != nullptr && allocator.alloc != nullptr &&
@@ -15,3 +22,46 @@ TestFuncResult test_arena_allocator(void) {
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_with_buffer(void) {
u8 buffer[KiB(4)] = {0};
Allocator allocator = wapp_mem_arena_allocator_init_with_buffer(buffer, KiB(4));
b8 result = allocator.obj != NULL && allocator.alloc != NULL &&
allocator.alloc_aligned != NULL &&
allocator.realloc != NULL && allocator.realloc_aligned != NULL &&
allocator.free == NULL;
void *ptr = wapp_mem_allocator_alloc(&allocator, 20);
result = result && (ptr != NULL);
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_begin(void) {
temp_allocator = wapp_mem_arena_allocator_init_with_buffer(temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
wapp_mem_arena_allocator_temp_begin(&temp_allocator);
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_end(void) {
wapp_mem_arena_allocator_temp_end(&temp_allocator);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_allocator_destroy(&temp_allocator);
return wapp_tester_result(result);
}

View File

@@ -4,5 +4,8 @@
#include "wapp.h"
TestFuncResult test_arena_allocator(void);
TestFuncResult test_arena_allocator_with_buffer(void);
TestFuncResult test_arena_allocator_temp_begin(void);
TestFuncResult test_arena_allocator_temp_end(void);
#endif // !TEST_ALLOCATOR_H

View File

@@ -3,13 +3,26 @@
#include <stdlib.h>
#define ARENA_CAPACITY KiB(16)
#define ARENA_BUF_SIZE KiB(4)
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern Arena *arena = NULL;
wapp_intern i32 count = 20;
wapp_intern i32 *array = NULL;
wapp_intern Arena *buf_arena = NULL;
wapp_intern u8 buf[ARENA_BUF_SIZE] = {0};
wapp_intern Arena *temp_arena = NULL;
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {0};
TestFuncResult test_arena_init(void) {
b8 result = wapp_mem_arena_init(&arena, ARENA_CAPACITY);
TestFuncResult test_arena_init_buffer(void) {
b8 result = wapp_mem_arena_init_buffer(&buf_arena, buf, ARENA_BUF_SIZE);
return wapp_tester_result(result);
}
TestFuncResult test_arena_init_allocated(void) {
b8 result = wapp_mem_arena_init_allocated(&arena, ARENA_CAPACITY);
return wapp_tester_result(result);
}
@@ -17,7 +30,7 @@ TestFuncResult test_arena_init(void) {
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
Arena *large_arena = NULL;
u64 capacity = GiB(512);
b8 result = wapp_mem_arena_init(&large_arena, capacity);
b8 result = wapp_mem_arena_init_allocated(&large_arena, capacity);
if (result) {
wapp_mem_arena_destroy(&large_arena);
}
@@ -25,6 +38,17 @@ TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
return wapp_tester_result(result);
}
TestFuncResult test_arena_alloc_with_buffer(void) {
i32 *arr = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = arr != NULL;
for (i32 i = 0; i < count; ++i) {
arr[i] = i * 10;
}
return wapp_tester_result(result);
}
TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) {
array = wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = array != NULL;
@@ -89,6 +113,32 @@ TestFuncResult test_arena_realloc_smaller_size(void) {
return wapp_tester_result(true);
}
TestFuncResult test_arena_temp_begin(void) {
b8 result = wapp_mem_arena_init_buffer(&temp_arena, temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num1 != NULL;
wapp_mem_arena_temp_begin(temp_arena);
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_temp_end(void) {
wapp_mem_arena_temp_end(temp_arena);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_destroy(&temp_arena);
return wapp_tester_result(result);
}
TestFuncResult test_arena_clear(void) {
wapp_mem_arena_clear(arena);
b8 result = true;
@@ -103,7 +153,14 @@ TestFuncResult test_arena_clear(void) {
return wapp_tester_result(result);
}
TestFuncResult test_arena_destroy(void) {
TestFuncResult test_arena_destroy_buffer(void) {
wapp_mem_arena_destroy(&buf_arena);
b8 result = buf_arena == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_destroy_allocated(void) {
wapp_mem_arena_destroy(&arena);
b8 result = arena == NULL;

View File

@@ -3,13 +3,26 @@
#include <stdlib.h>
#define ARENA_CAPACITY KiB(16)
#define ARENA_BUF_SIZE KiB(4)
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern Arena *arena = nullptr;
wapp_intern Arena *arena = NULL;
wapp_intern i32 count = 20;
wapp_intern i32 *array = nullptr;
wapp_intern i32 *array = NULL;
wapp_intern Arena *buf_arena = NULL;
wapp_intern u8 buf[ARENA_BUF_SIZE] = {};
wapp_intern Arena *temp_arena = NULL;
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {};
TestFuncResult test_arena_init(void) {
b8 result = wapp_mem_arena_init(&arena, ARENA_CAPACITY);
TestFuncResult test_arena_init_buffer(void) {
b8 result = wapp_mem_arena_init_buffer(&buf_arena, buf, ARENA_BUF_SIZE);
return wapp_tester_result(result);
}
TestFuncResult test_arena_init_allocated(void) {
b8 result = wapp_mem_arena_init_allocated(&arena, ARENA_CAPACITY);
return wapp_tester_result(result);
}
@@ -17,7 +30,7 @@ TestFuncResult test_arena_init(void) {
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
Arena *large_arena = nullptr;
u64 capacity = GiB(512);
b8 result = wapp_mem_arena_init(&large_arena, capacity);
b8 result = wapp_mem_arena_init_allocated(&large_arena, capacity);
if (result) {
wapp_mem_arena_destroy(&large_arena);
}
@@ -25,6 +38,17 @@ TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
return wapp_tester_result(result);
}
TestFuncResult test_arena_alloc_with_buffer(void) {
i32 *arr = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = arr != NULL;
for (i32 i = 0; i < count; ++i) {
arr[i] = i * 10;
}
return wapp_tester_result(result);
}
TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) {
array = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = array != nullptr;
@@ -89,6 +113,32 @@ TestFuncResult test_arena_realloc_smaller_size(void) {
return wapp_tester_result(true);
}
TestFuncResult test_arena_temp_begin(void) {
b8 result = wapp_mem_arena_init_buffer(&temp_arena, temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num1 != NULL;
wapp_mem_arena_temp_begin(temp_arena);
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_temp_end(void) {
wapp_mem_arena_temp_end(temp_arena);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_destroy(&temp_arena);
return wapp_tester_result(result);
}
TestFuncResult test_arena_clear(void) {
wapp_mem_arena_clear(arena);
b8 result = true;
@@ -103,7 +153,14 @@ TestFuncResult test_arena_clear(void) {
return wapp_tester_result(result);
}
TestFuncResult test_arena_destroy(void) {
TestFuncResult test_arena_destroy_buffer(void) {
wapp_mem_arena_destroy(&buf_arena);
b8 result = buf_arena == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_destroy_allocated(void) {
wapp_mem_arena_destroy(&arena);
b8 result = arena == nullptr;

View File

@@ -3,13 +3,18 @@
#include "wapp.h"
TestFuncResult test_arena_init(void);
TestFuncResult test_arena_init_buffer(void);
TestFuncResult test_arena_init_allocated(void);
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void);
TestFuncResult test_arena_alloc_with_buffer(void);
TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void);
TestFuncResult test_arena_alloc_fails_when_over_capacity(void);
TestFuncResult test_arena_realloc_bigger_size(void);
TestFuncResult test_arena_realloc_smaller_size(void);
TestFuncResult test_arena_clear(void);
TestFuncResult test_arena_destroy(void);
TestFuncResult test_arena_temp_begin(void);
TestFuncResult test_arena_temp_end(void);
TestFuncResult test_arena_destroy_buffer(void);
TestFuncResult test_arena_destroy_allocated(void);
#endif // !TEST_ARENA_H

View File

@@ -25,10 +25,10 @@ TestFuncResult test_i32_array(void) {
TestFuncResult test_i32_array_with_capacity(void) {
b8 result;
I32Array array1 = wapp_array_with_capacity(i32, 64, false);
I32Array array1 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
result = wapp_array_count(array1) == 0 && wapp_array_capacity(array1) == 64;
I32Array array2 = wapp_array_with_capacity(i32, 64, true);
I32Array array2 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_FILLED);
result = wapp_array_count(array2) == 64 && wapp_array_capacity(array2) == 64;
return wapp_tester_result(result);
@@ -79,7 +79,7 @@ TestFuncResult test_i32_array_set(void) {
TestFuncResult test_i32_array_append_capped(void) {
b8 result;
I32Array array = wapp_array_with_capacity(i32, 64, false);
I32Array array = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
wapp_array_append_capped(i32, array, &((i32){10}));
result = wapp_array_count(array) == 1;
@@ -150,7 +150,7 @@ TestFuncResult test_i32_array_alloc_capacity(void) {
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
u64 capacity = 32;
I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, false);
I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, ARRAY_INIT_NONE);
result = array && wapp_array_capacity(array) == capacity;
@@ -166,7 +166,7 @@ TestFuncResult test_i32_array_append_alloc(void) {
I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, 1, 2);
I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &((i32){10}));
I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &((i32){10}), ARRAY_INIT_NONE);
result = arr_ptr == array1;
u64 count = 4;
@@ -174,7 +174,7 @@ TestFuncResult test_i32_array_append_alloc(void) {
b8 running = true;
while (running) {
i32 num = (i32)index;
arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num);
arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num, ARRAY_INIT_NONE);
++index;
running = index < count;
@@ -194,10 +194,10 @@ TestFuncResult test_i32_array_extend_alloc(void) {
I32Array array2 = wapp_array(i32, 1, 2);
I32Array array3 = wapp_array(i32, 1, 2, 3, 4);
I32Array arr_ptr = wapp_array_extend_alloc(i32, &allocator, array1, array3);
I32Array arr_ptr = wapp_array_extend_alloc(i32, &allocator, array1, array3, ARRAY_INIT_NONE);
result = arr_ptr == array1;
arr_ptr = wapp_array_extend_alloc(i32, &allocator, array2, array3);
arr_ptr = wapp_array_extend_alloc(i32, &allocator, array2, array3, ARRAY_INIT_NONE);
result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator);
@@ -215,7 +215,7 @@ TestFuncResult test_i32_array_copy_alloc(void) {
I32Array array = NULL;
u64 expected_count = 5;
array = wapp_array_copy_alloc(i32, &allocator, dst1, src);
array = wapp_array_copy_alloc(i32, &allocator, dst1, src, ARRAY_INIT_NONE);
result = wapp_array_count(array) == expected_count && array == dst1;
u64 index = 0;
@@ -228,7 +228,7 @@ TestFuncResult test_i32_array_copy_alloc(void) {
}
expected_count = 5;
array = wapp_array_copy_alloc(i32, &allocator, dst2, src);
array = wapp_array_copy_alloc(i32, &allocator, dst2, src, ARRAY_INIT_NONE);
result = result && wapp_array_count(array) == expected_count && array != dst2;
index = 0;
@@ -249,7 +249,7 @@ TestFuncResult test_i32_array_pop(void) {
b8 result;
I32Array array1 = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array_with_capacity(i32, 32, false);
I32Array array2 = wapp_array_with_capacity(i32, 32, ARRAY_INIT_NONE);
i32 item1 = wapp_array_pop(i32, array1);
i32 item2 = wapp_array_pop(i32, array2);

View File

@@ -25,10 +25,10 @@ TestFuncResult test_i32_array(void) {
TestFuncResult test_i32_array_with_capacity(void) {
b8 result;
I32Array array1 = wapp_array_with_capacity(i32, 64, false);
I32Array array1 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
result = wapp_array_count(array1) == 0 && wapp_array_capacity(array1) == 64;
I32Array array2 = wapp_array_with_capacity(i32, 64, true);
I32Array array2 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_FILLED);
result = wapp_array_count(array2) == 64 && wapp_array_capacity(array2) == 64;
return wapp_tester_result(result);
@@ -79,7 +79,7 @@ TestFuncResult test_i32_array_set(void) {
TestFuncResult test_i32_array_append_capped(void) {
b8 result;
I32Array array = wapp_array_with_capacity(i32, 64, false);
I32Array array = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
i32 item1 = 10;
wapp_array_append_capped(i32, array, &item1);
@@ -152,7 +152,7 @@ TestFuncResult test_i32_array_alloc_capacity(void) {
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
u64 capacity = 32;
I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, false);
I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, ARRAY_INIT_NONE);
result = array && wapp_array_capacity(array) == capacity;
@@ -169,7 +169,7 @@ TestFuncResult test_i32_array_append_alloc(void) {
I32Array array2 = wapp_array(i32, 1, 2);
i32 num = 10;
I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &num);
I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &num, ARRAY_INIT_NONE);
result = arr_ptr == array1;
u64 count = 4;
@@ -177,7 +177,7 @@ TestFuncResult test_i32_array_append_alloc(void) {
b8 running = true;
while (running) {
num = (i32)index;
arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num);
arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num, ARRAY_INIT_NONE);
++index;
running = index < count;
@@ -197,10 +197,10 @@ TestFuncResult test_i32_array_extend_alloc(void) {
I32Array array2 = wapp_array(i32, 1, 2);
I32Array array3 = wapp_array(i32, 1, 2, 3, 4);
I32Array array = wapp_array_extend_alloc(i32, &allocator, array1, array3);
I32Array array = wapp_array_extend_alloc(i32, &allocator, array1, array3, ARRAY_INIT_NONE);
result = array == array1;
array = wapp_array_extend_alloc(i32, &allocator, array2, array3);
array = wapp_array_extend_alloc(i32, &allocator, array2, array3, ARRAY_INIT_NONE);
result = result && array != array2;
wapp_mem_arena_allocator_destroy(&allocator);
@@ -218,7 +218,7 @@ TestFuncResult test_i32_array_copy_alloc(void) {
I32Array array = nullptr;
u64 expected_count = 5;
array = wapp_array_copy_alloc(i32, &allocator, dst1, src);
array = wapp_array_copy_alloc(i32, &allocator, dst1, src, ARRAY_INIT_NONE);
result = wapp_array_count(array) == expected_count && array == dst1;
u64 index = 0;
@@ -231,7 +231,7 @@ TestFuncResult test_i32_array_copy_alloc(void) {
}
expected_count = 5;
array = wapp_array_copy_alloc(i32, &allocator, dst2, src);
array = wapp_array_copy_alloc(i32, &allocator, dst2, src, ARRAY_INIT_NONE);
result = result && wapp_array_count(array) == expected_count && array != dst2;
index = 0;
@@ -265,7 +265,7 @@ TestFuncResult test_i32_array_pop(void) {
b8 result;
I32Array array1 = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array_with_capacity(i32, 32, false);
I32Array array2 = wapp_array_with_capacity(i32, 32, ARRAY_INIT_NONE);
i32 item1 = wapp_array_pop(i32, array1);
i32 item2 = wapp_array_pop(i32, array2);

View File

@@ -16,16 +16,16 @@ TestFuncResult test_cpath_join_path(void) {
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
Str8List parts = wapp_dbl_list(Str8, Str8List);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_str8(tmp));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("home"));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("abdelrahman"));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("Documents"));
Str8List parts = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("home"));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("abdelrahman"));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("Documents"));
wapp_cpath_join_path(&out, &parts);
result = wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -33,8 +33,8 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected);
wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("home"));
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_push_front(Str8, &parts, &wapp_str8_node_from_str8(tmp));
wapp_dbl_list_pop_front(Str8, &parts);
wapp_dbl_list_push_front(Str8, &parts, &tmp);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -42,8 +42,8 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected);
wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_push_front(Str8, &parts, &wapp_str8_node_from_cstr("home"));
wapp_dbl_list_pop_front(Str8, &parts);
wapp_dbl_list_push_front(Str8, &parts, &wapp_str8_lit("home"));
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -53,24 +53,24 @@ TestFuncResult test_cpath_join_path(void) {
wapp_dbl_list_empty(Str8, &parts);
wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_str8(tmp));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr(""));
wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit(""));
wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr(""));
wapp_dbl_list_pop_front(Str8, &parts);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit(""));
wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_back(Str8, Str8Node, &parts);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("home"));
wapp_dbl_list_pop_back(Str8, &parts);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("home"));
wapp_str8_copy_cstr_capped(&expected, "home");

View File

@@ -16,24 +16,23 @@ TestFuncResult test_cpath_join_path(void) {
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
Str8List parts = wapp_dbl_list(Str8, Str8List);
Str8List parts = wapp_dbl_list(Str8);
Str8Node tmp_node = wapp_str8_node_from_str8(tmp);
wapp_dbl_list_push_back(Str8, &parts, &tmp_node);
wapp_dbl_list_push_back(Str8, &parts, &tmp);
Str8Node home_node = wapp_str8_node_from_cstr("home");
wapp_dbl_list_push_back(Str8, &parts, &home_node);
Str8 home = wapp_str8_lit("home");
wapp_dbl_list_push_back(Str8, &parts, &home);
Str8Node user_node = wapp_str8_node_from_cstr("abdelrahman");
wapp_dbl_list_push_back(Str8, &parts, &user_node);
Str8 user = wapp_str8_lit("abdelrahman");
wapp_dbl_list_push_back(Str8, &parts, &user);
Str8Node docs_node = wapp_str8_node_from_cstr("Documents");
wapp_dbl_list_push_back(Str8, &parts, &docs_node);
Str8 docs = wapp_str8_lit("Documents");
wapp_dbl_list_push_back(Str8, &parts, &docs);
wapp_cpath_join_path(&out, &parts);
result = wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -42,10 +41,9 @@ TestFuncResult test_cpath_join_path(void) {
Str8RO str = wapp_str8_lit_ro("home");
wapp_str8_concat_capped(&tmp, &str);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_pop_front(Str8, &parts);
Str8Node tmp_node_2 = wapp_str8_node_from_str8(tmp);
wapp_dbl_list_push_front(Str8, &parts, &tmp_node_2);
wapp_dbl_list_push_front(Str8, &parts, &tmp);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -53,10 +51,10 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected);
wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_pop_front(Str8, &parts);
Str8Node home_node_2 = wapp_str8_node_from_cstr("home");
wapp_dbl_list_push_front(Str8, &parts, &home_node_2);
Str8 home_2 = wapp_str8_lit("home");
wapp_dbl_list_push_front(Str8, &parts, &home_2);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -67,31 +65,30 @@ TestFuncResult test_cpath_join_path(void) {
wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP);
Str8Node tmp_node_3 = wapp_str8_node_from_str8(tmp);
wapp_dbl_list_push_back(Str8, &parts, &tmp_node_3);
wapp_dbl_list_push_back(Str8, &parts, &tmp);
Str8Node empty_node = wapp_str8_node_from_cstr("");
wapp_dbl_list_push_back(Str8, &parts, &empty_node);
Str8 empty = wapp_str8_lit("");
wapp_dbl_list_push_back(Str8, &parts, &empty);
wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts);
wapp_dbl_list_pop_front(Str8, &parts);
Str8Node empty_node_2 = wapp_str8_node_from_cstr("");
wapp_dbl_list_push_back(Str8, &parts, &empty_node_2);
Str8 empty_2 = wapp_str8_lit("");
wapp_dbl_list_push_back(Str8, &parts, &empty_2);
wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_back(Str8, Str8Node, &parts);
wapp_dbl_list_pop_back(Str8, &parts);
Str8Node home_node_3 = wapp_str8_node_from_cstr("home");
wapp_dbl_list_push_back(Str8, &parts, &home_node_3);
Str8 home_3 = wapp_str8_lit("home");
wapp_dbl_list_push_back(Str8, &parts, &home_3);
wapp_str8_copy_cstr_capped(&expected, "home");

118
tests/file/test_file.c Normal file
View File

@@ -0,0 +1,118 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_file.h"
#define DST_CAPACITY 5
wapp_intern Allocator arena = {0};
wapp_intern Str8RO test_filename = wapp_str8_lit_ro_initialiser_list("wapptest.bin");
wapp_intern Str8RO new_filename = wapp_str8_lit_ro_initialiser_list("wapptest2.bin");
wapp_intern WFile *test_fp = NULL;
wapp_intern I32Array src_array1 = wapp_array(i32, 0, 1, 2, 3, 4);
wapp_intern I32Array src_array2 = wapp_array(i32, 5, 6, 7, 8, 9);
wapp_intern I32Array src_array3 = wapp_array(i32, 10, 11, 12, 13, 14);
wapp_intern I32Array dst_array = wapp_array_with_capacity(i32, DST_CAPACITY, false);
wapp_intern i32 dst_buf[DST_CAPACITY] = {0};
TestFuncResult test_wapp_file_open(void) {
arena = wapp_mem_arena_allocator_init(KiB(16));
test_fp = wapp_file_open(&arena, &test_filename, WAPP_ACCESS_WRITE_EX);
return wapp_tester_result(test_fp != NULL);
}
TestFuncResult test_wapp_file_get_current_position(void) {
i64 pos = wapp_file_get_current_position(test_fp);
return wapp_tester_result(pos == 0);
}
TestFuncResult test_wapp_file_seek(void) {
wapp_file_write_array((GenericArray)src_array1, test_fp, wapp_array_count(src_array1));
i64 seek_result = wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
b8 result = seek_result == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1));
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_get_length(void) {
i64 length = wapp_file_get_length(test_fp);
return wapp_tester_result(length == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1)));
}
TestFuncResult test_wapp_file_read(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 byte_count = DST_CAPACITY * sizeof(i32);
u64 count = wapp_file_read((void *)dst_buf, test_fp, byte_count);
b8 result = count == byte_count;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (dst_buf[index] == *wapp_array_get(i32, src_array1, index));
++index;
running = index < DST_CAPACITY;
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
u64 expected_count = wapp_array_count(src_array2) * wapp_array_item_size(src_array2);
i64 count = wapp_file_write((void *)src_array2, test_fp, expected_count);
return wapp_tester_result(count >= 0 && (u64)count == expected_count);
}
TestFuncResult test_wapp_file_read_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 count = wapp_file_read_array((GenericArray)dst_array, test_fp, wapp_array_count(src_array1));
b8 result = count == wapp_array_count(src_array1) &&
wapp_array_count(dst_array) == wapp_array_count(src_array1);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (*wapp_array_get(i32, dst_array, index) == *wapp_array_get(i32, src_array1, index));
++index;
running = index < wapp_array_count(dst_array);
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
i64 count = wapp_file_write_array((GenericArray)src_array3, test_fp, wapp_array_count(src_array3));
return wapp_tester_result(count >= 0 && (u64)count == wapp_array_count(src_array3));
}
TestFuncResult test_wapp_file_flush(void) {
i32 flush_result = wapp_file_flush(test_fp);
return wapp_tester_result(flush_result == 0);
}
TestFuncResult test_wapp_file_close(void) {
i32 close_result = wapp_file_close(test_fp);
return wapp_tester_result(close_result == 0);
}
TestFuncResult test_wapp_file_rename(void) {
i32 rename_result = wapp_file_rename(&test_filename, &new_filename);
return wapp_tester_result(rename_result == 0);
}
TestFuncResult test_wapp_file_remove(void) {
i32 remove_result = wapp_file_remove(&new_filename);
return wapp_tester_result(remove_result == 0);
}

122
tests/file/test_file.cc Normal file
View File

@@ -0,0 +1,122 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_file.h"
#define DST_CAPACITY 5
wapp_intern Allocator arena = {};
wapp_intern Str8RO test_filename = wapp_str8_lit_ro_initialiser_list("wapptest.bin");
wapp_intern Str8RO new_filename = wapp_str8_lit_ro_initialiser_list("wapptest2.bin");
wapp_intern WFile *test_fp = NULL;
wapp_intern i32 dst_buf[DST_CAPACITY] = {0};
wapp_intern I32Array src_array1;
wapp_intern I32Array src_array2;
wapp_intern I32Array src_array3;
wapp_intern I32Array dst_array ;
TestFuncResult test_wapp_file_open(void) {
arena = wapp_mem_arena_allocator_init(KiB(16));
src_array1 = wapp_array(i32, 0, 1, 2, 3, 4);
src_array2 = wapp_array(i32, 5, 6, 7, 8, 9);
src_array3 = wapp_array(i32, 10, 11, 12, 13, 14);
dst_array = wapp_array_with_capacity(i32, DST_CAPACITY, false);
test_fp = wapp_file_open(&arena, &test_filename, WAPP_ACCESS_WRITE_EX);
return wapp_tester_result(test_fp != NULL);
}
TestFuncResult test_wapp_file_get_current_position(void) {
i64 pos = wapp_file_get_current_position(test_fp);
return wapp_tester_result(pos == 0);
}
TestFuncResult test_wapp_file_seek(void) {
wapp_file_write_array((GenericArray)src_array1, test_fp, wapp_array_count(src_array1));
i64 seek_result = wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
b8 result = seek_result == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1));
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_get_length(void) {
i64 length = wapp_file_get_length(test_fp);
return wapp_tester_result(length == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1)));
}
TestFuncResult test_wapp_file_read(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 byte_count = DST_CAPACITY * sizeof(i32);
u64 count = wapp_file_read((void *)dst_buf, test_fp, byte_count);
b8 result = count == byte_count;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (dst_buf[index] == *wapp_array_get(i32, src_array1, index));
++index;
running = index < DST_CAPACITY;
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
u64 expected_count = wapp_array_count(src_array2) * wapp_array_item_size(src_array2);
i64 count = wapp_file_write((void *)src_array2, test_fp, expected_count);
return wapp_tester_result(count >= 0 && (u64)count == expected_count);
}
TestFuncResult test_wapp_file_read_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 count = wapp_file_read_array((GenericArray)dst_array, test_fp, wapp_array_count(src_array1));
b8 result = count == wapp_array_count(src_array1) &&
wapp_array_count(dst_array) == wapp_array_count(src_array1);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (*wapp_array_get(i32, dst_array, index) == *wapp_array_get(i32, src_array1, index));
++index;
running = index < wapp_array_count(dst_array);
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
i64 count = wapp_file_write_array((GenericArray)src_array3, test_fp, wapp_array_count(src_array3));
return wapp_tester_result(count >= 0 && (u64)count == wapp_array_count(src_array3));
}
TestFuncResult test_wapp_file_flush(void) {
i32 flush_result = wapp_file_flush(test_fp);
return wapp_tester_result(flush_result == 0);
}
TestFuncResult test_wapp_file_close(void) {
i32 close_result = wapp_file_close(test_fp);
return wapp_tester_result(close_result == 0);
}
TestFuncResult test_wapp_file_rename(void) {
i32 rename_result = wapp_file_rename(&test_filename, &new_filename);
return wapp_tester_result(rename_result == 0);
}
TestFuncResult test_wapp_file_remove(void) {
i32 remove_result = wapp_file_remove(&new_filename);
return wapp_tester_result(remove_result == 0);
}

21
tests/file/test_file.h Normal file
View File

@@ -0,0 +1,21 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TEST_FILE_H
#define TEST_FILE_H
#include "wapp.h"
TestFuncResult test_wapp_file_open(void);
TestFuncResult test_wapp_file_get_current_position(void);
TestFuncResult test_wapp_file_seek(void);
TestFuncResult test_wapp_file_get_length(void);
TestFuncResult test_wapp_file_read(void);
TestFuncResult test_wapp_file_write(void);
TestFuncResult test_wapp_file_read_array(void);
TestFuncResult test_wapp_file_write_array(void);
TestFuncResult test_wapp_file_flush(void);
TestFuncResult test_wapp_file_close(void);
TestFuncResult test_wapp_file_rename(void);
TestFuncResult test_wapp_file_remove(void);
#endif // !TEST_FILE_H

98
tests/queue/test_queue.c Normal file
View File

@@ -0,0 +1,98 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "wapp.h"
#include "test_queue.h"
#define CAPACITY 8
TestFuncResult test_queue_push(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = ((i32 *)(queue.items)) + i;
result = result && value != NULL && *value == (i32)i;
}
return wapp_tester_result(result);
}
TestFuncResult test_queue_push_alloc(void) {
Allocator arena = wapp_mem_arena_allocator_init(MiB(64));
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
i32 item = 8;
u64 new_capacity = CAPACITY * 2;
I32Queue *new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
u64 capacity = wapp_queue_capacity(&queue);
result = result && capacity == new_capacity;
for (u64 i = 0; i < 2; ++i) {
wapp_queue_pop(i32, &queue);
}
u64 remaining = wapp_queue_capacity(&queue) - queue.count;
for (u64 i = 0; i < remaining; ++i) {
item = remaining + i;
wapp_queue_push(i32, &queue, &item);
}
++item;
new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
result = result && wapp_queue_capacity(&queue) == new_capacity * 2;
i32 *arr = (i32 *)queue.items;
for (u64 i = 0; i < queue.count; ++i) {
// NOTE (Abdelrahman): First queue value is currently 2
result = result && arr[i] == (i32)(2 + i);
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_queue_pop(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
u64 half_count = queue.count / 2;
for (u64 i = 0; i < half_count; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)i;
}
for (u64 i = 0; i < half_count; ++i) {
i32 item = (i32)i + CAPACITY;
wapp_queue_push(i32, &queue, &item);
}
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)half_count + (i32)i;
}
return wapp_tester_result(result);
}

96
tests/queue/test_queue.cc Normal file
View File

@@ -0,0 +1,96 @@
#include "wapp.h"
#include "test_queue.h"
#define CAPACITY 8
TestFuncResult test_queue_push(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = ((i32 *)(queue.items)) + i;
result = result && value != NULL && *value == (i32)i;
}
return wapp_tester_result(result);
}
TestFuncResult test_queue_push_alloc(void) {
Allocator arena = wapp_mem_arena_allocator_init(MiB(64));
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
i32 item = 8;
u64 new_capacity = CAPACITY * 2;
I32Queue *new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
u64 capacity = wapp_queue_capacity(&queue);
result = result && capacity == new_capacity;
for (u64 i = 0; i < 2; ++i) {
wapp_queue_pop(i32, &queue);
}
u64 remaining = wapp_queue_capacity(&queue) - queue.count;
for (u64 i = 0; i < remaining; ++i) {
item = remaining + i;
wapp_queue_push(i32, &queue, &item);
}
++item;
new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
result = result && wapp_queue_capacity(&queue) == new_capacity * 2;
i32 *arr = (i32 *)queue.items;
for (u64 i = 0; i < queue.count; ++i) {
// NOTE (Abdelrahman): First queue value is currently 2
result = result && arr[i] == (i32)(2 + i);
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_queue_pop(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
u64 half_count = queue.count / 2;
for (u64 i = 0; i < half_count; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)i;
}
for (u64 i = 0; i < half_count; ++i) {
i32 item = (i32)i + CAPACITY;
wapp_queue_push(i32, &queue, &item);
}
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)half_count + (i32)i;
}
return wapp_tester_result(result);
}

12
tests/queue/test_queue.h Normal file
View File

@@ -0,0 +1,12 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TEST_QUEUE_H
#define TEST_QUEUE_H
#include "wapp.h"
TestFuncResult test_queue_push(void);
TestFuncResult test_queue_push_alloc(void);
TestFuncResult test_queue_pop(void);
#endif // !TEST_QUEUE_H

View File

@@ -5,9 +5,9 @@
#include <string.h>
TestFuncResult test_commander_cmd_success(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("hello world"));
Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("hello world"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
@@ -17,8 +17,8 @@ TestFuncResult test_commander_cmd_success(void) {
}
TestFuncResult test_commander_cmd_failure(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("grep"));
Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("grep"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
b8 failed = result.exited && result.exit_code != EXIT_SUCCESS &&
@@ -33,9 +33,9 @@ TestFuncResult test_commander_cmd_out_buf_success(void) {
char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr(msg));
Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
@@ -50,9 +50,9 @@ TestFuncResult test_commander_cmd_out_buf_failure(void) {
char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr(msg));
Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 failed = !result.exited && result.exit_code != EXIT_SUCCESS &&

View File

@@ -5,9 +5,9 @@
#include <string.h>
TestFuncResult test_commander_cmd_success(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List);
Str8Node echo = wapp_str8_node_from_cstr("echo");
Str8Node msg = wapp_str8_node_from_cstr("hello world");
Str8List cmd = wapp_dbl_list(Str8);
Str8 echo = wapp_str8_lit("echo");
Str8 msg = wapp_str8_lit("hello world");
wapp_dbl_list_push_back(Str8, &cmd, &echo);
wapp_dbl_list_push_back(Str8, &cmd, &msg);
@@ -19,8 +19,8 @@ TestFuncResult test_commander_cmd_success(void) {
}
TestFuncResult test_commander_cmd_failure(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List);
Str8Node grep = wapp_str8_node_from_cstr("grep");
Str8List cmd = wapp_dbl_list(Str8);
Str8 grep = wapp_str8_lit("grep");
wapp_dbl_list_push_back(Str8, &cmd, &grep);
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, nullptr, &cmd);
@@ -36,9 +36,9 @@ TestFuncResult test_commander_cmd_out_buf_success(void) {
char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List);
Str8Node echo = wapp_str8_node_from_cstr("echo");
Str8Node arg = wapp_str8_node_from_cstr(msg);
Str8List cmd = wapp_dbl_list(Str8);
Str8 echo = wapp_str8_lit("echo");
Str8 arg = wapp_str8_lit(msg);
wapp_dbl_list_push_back(Str8, &cmd, &echo);
wapp_dbl_list_push_back(Str8, &cmd, &arg);
@@ -55,9 +55,9 @@ TestFuncResult test_commander_cmd_out_buf_failure(void) {
char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List);
Str8Node echo = wapp_str8_node_from_cstr("echo");
Str8Node arg = wapp_str8_node_from_cstr(msg);
Str8List cmd = wapp_dbl_list(Str8);
Str8 echo = wapp_str8_lit("echo");
Str8 arg = wapp_str8_lit(msg);
wapp_dbl_list_push_back(Str8, &cmd, &echo);
wapp_dbl_list_push_back(Str8, &cmd, &arg);

View File

@@ -443,8 +443,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1]));
Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1;
running1 = index1 < count1;
@@ -453,8 +453,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2]));
Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2;
running2 = index2 < count2;
@@ -488,8 +488,8 @@ TestFuncResult test_str8_split_with_max(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index]));
Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node, &(splits[index]));
++index;
running = index < count;
@@ -535,8 +535,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1]));
Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1;
running1 = index1 < count1;
@@ -545,8 +545,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2]));
Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2;
running2 = index2 < count2;
@@ -580,8 +580,8 @@ TestFuncResult test_str8_rsplit_with_max(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index]));
Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node, &(splits[index]));
++index;
running = index < count;

View File

@@ -443,8 +443,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1]));
Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1;
running1 = index1 < count1;
@@ -453,8 +453,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2]));
Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2;
running2 = index2 < count2;
@@ -488,8 +488,8 @@ TestFuncResult test_str8_split_with_max(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index]));
Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node, &(splits[index]));
++index;
running = index < count;
@@ -535,8 +535,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1]));
Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1;
running1 = index1 < count1;
@@ -545,8 +545,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2]));
Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2;
running2 = index2 < count2;
@@ -580,8 +580,8 @@ TestFuncResult test_str8_rsplit_with_max(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index]));
Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node, &(splits[index]));
++index;
running = index < count;

View File

@@ -10,33 +10,28 @@ TestFuncResult test_str8_list_get(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, &list, 0);
result = node->item == &s1 && wapp_str8_equal(node->item, &s1);
Str8 *node = wapp_dbl_list_get(Str8, &list, 0);
result = node == &s1 && wapp_str8_equal(node, &s1);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 1);
result = result && node->item == &s2 && wapp_str8_equal(node->item, &s2);
node = wapp_dbl_list_get(Str8, &list, 1);
result = result && node == &s2 && wapp_str8_equal(node, &s2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2);
result = result && node->item == &s3 && wapp_str8_equal(node->item, &s3);
node = wapp_dbl_list_get(Str8, &list, 2);
result = result && node == &s3 && wapp_str8_equal(node, &s3);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 3);
result = result && node->item == &s4 && wapp_str8_equal(node->item, &s4);
node = wapp_dbl_list_get(Str8, &list, 3);
result = result && node == &s4 && wapp_str8_equal(node, &s4);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 4);
result = result && node->item == &s5 && wapp_str8_equal(node->item, &s5);
node = wapp_dbl_list_get(Str8, &list, 4);
result = result && node == &s5 && wapp_str8_equal(node, &s5);
return wapp_tester_result(result);
}
@@ -48,19 +43,16 @@ TestFuncResult test_str8_list_push_front(void) {
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_front(Str8, &list, &n1);
result = list.first == list.last && list.first == &n1 && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_front(Str8, &list, &s1);
result = list.first == list.last && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_front(Str8, &list, &n2);
result = result && list.first == &n2 && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_front(Str8, &list, &s2);
result = result && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_front(Str8, &list, &n3);
result = result && list.first == &n3 && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
wapp_dbl_list_push_front(Str8, &list, &s3);
result = result && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result);
}
@@ -72,19 +64,16 @@ TestFuncResult test_str8_list_push_back(void) {
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
result = list.first == list.last && list.last == &n1 && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_back(Str8, &list, &s1);
result = list.first == list.last && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_back(Str8, &list, &n2);
result = result && list.last == &n2 && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_back(Str8, &list, &s2);
result = result && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_back(Str8, &list, &n3);
result = result && list.last == &n3 && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
wapp_dbl_list_push_back(Str8, &list, &s3);
result = result && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result);
}
@@ -100,28 +89,21 @@ TestFuncResult test_str8_list_insert(void) {
Str8 s6 = wapp_str8_lit("6");
Str8 s7 = wapp_str8_lit("7");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8Node n6 = wapp_str8_node_from_str8(s6);
Str8Node n7 = wapp_str8_node_from_str8(s7);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node;
wapp_dbl_list_insert(Str8, &list, &n6, 2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2);
result = node != NULL && node->item == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6;
wapp_dbl_list_insert(Str8, &list, &n7, 5);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 5);
result = result && node != NULL && node->item == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7;
Str8 *node;
wapp_dbl_list_insert(Str8, &list, &s6, 2);
node = wapp_dbl_list_get(Str8, &list, 2);
result = node != NULL && node == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6;
wapp_dbl_list_insert(Str8, &list, &s7, 5);
node = wapp_dbl_list_get(Str8, &list, 5);
result = result && node != NULL && node == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7;
return wapp_tester_result(result);
}
@@ -135,33 +117,28 @@ TestFuncResult test_str8_list_pop_front(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
Str8 *node = wapp_dbl_list_pop_front(Str8, &list);
result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
@@ -175,33 +152,28 @@ TestFuncResult test_str8_list_pop_back(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_front(Str8, &list, &n1);
wapp_dbl_list_push_front(Str8, &list, &n2);
wapp_dbl_list_push_front(Str8, &list, &n3);
wapp_dbl_list_push_front(Str8, &list, &n4);
wapp_dbl_list_push_front(Str8, &list, &n5);
wapp_dbl_list_push_front(Str8, &list, &s1);
wapp_dbl_list_push_front(Str8, &list, &s2);
wapp_dbl_list_push_front(Str8, &list, &s3);
wapp_dbl_list_push_front(Str8, &list, &s4);
wapp_dbl_list_push_front(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
Str8 *node = wapp_dbl_list_pop_back(Str8, &list);
result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
@@ -215,33 +187,28 @@ TestFuncResult test_str8_list_remove(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
Str8 *node = wapp_dbl_list_remove(Str8, &list, 0);
result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
@@ -249,11 +216,11 @@ TestFuncResult test_str8_list_remove(void) {
TestFuncResult test_str8_list_empty(void) {
b8 result;
Str8List list = wapp_dbl_list(Str8, Str8List);
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("Hello"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("from"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("wizapp"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("stdlib"));
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("Hello"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("from"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("wizapp"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("stdlib"));
wapp_dbl_list_empty(Str8, &list);

View File

@@ -10,33 +10,28 @@ TestFuncResult test_str8_list_get(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, &list, 0);
result = node->item == &s1 && wapp_str8_equal(node->item, &s1);
Str8 *node = wapp_dbl_list_get(Str8, &list, 0);
result = node == &s1 && wapp_str8_equal(node, &s1);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 1);
result = result && node->item == &s2 && wapp_str8_equal(node->item, &s2);
node = wapp_dbl_list_get(Str8, &list, 1);
result = result && node == &s2 && wapp_str8_equal(node, &s2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2);
result = result && node->item == &s3 && wapp_str8_equal(node->item, &s3);
node = wapp_dbl_list_get(Str8, &list, 2);
result = result && node == &s3 && wapp_str8_equal(node, &s3);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 3);
result = result && node->item == &s4 && wapp_str8_equal(node->item, &s4);
node = wapp_dbl_list_get(Str8, &list, 3);
result = result && node == &s4 && wapp_str8_equal(node, &s4);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 4);
result = result && node->item == &s5 && wapp_str8_equal(node->item, &s5);
node = wapp_dbl_list_get(Str8, &list, 4);
result = result && node == &s5 && wapp_str8_equal(node, &s5);
return wapp_tester_result(result);
}
@@ -48,19 +43,16 @@ TestFuncResult test_str8_list_push_front(void) {
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_front(Str8, &list, &n1);
result = list.first == list.last && list.first == &n1 && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_front(Str8, &list, &s1);
result = list.first == list.last && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_front(Str8, &list, &n2);
result = result && list.first == &n2 && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_front(Str8, &list, &s2);
result = result && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_front(Str8, &list, &n3);
result = result && list.first == &n3 && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
wapp_dbl_list_push_front(Str8, &list, &s3);
result = result && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result);
}
@@ -72,19 +64,16 @@ TestFuncResult test_str8_list_push_back(void) {
Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
result = list.first == list.last && list.last == &n1 && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_back(Str8, &list, &s1);
result = list.first == list.last && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_back(Str8, &list, &n2);
result = result && list.last == &n2 && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_back(Str8, &list, &s2);
result = result && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_back(Str8, &list, &n3);
result = result && list.last == &n3 && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
wapp_dbl_list_push_back(Str8, &list, &s3);
result = result && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result);
}
@@ -100,28 +89,21 @@ TestFuncResult test_str8_list_insert(void) {
Str8 s6 = wapp_str8_lit("6");
Str8 s7 = wapp_str8_lit("7");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8Node n6 = wapp_str8_node_from_str8(s6);
Str8Node n7 = wapp_str8_node_from_str8(s7);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node;
wapp_dbl_list_insert(Str8, &list, &n6, 2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2);
result = node != NULL && node->item == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6;
wapp_dbl_list_insert(Str8, &list, &n7, 5);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 5);
result = result && node != NULL && node->item == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7;
Str8 *node;
wapp_dbl_list_insert(Str8, &list, &s6, 2);
node = wapp_dbl_list_get(Str8, &list, 2);
result = node != NULL && node == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6;
wapp_dbl_list_insert(Str8, &list, &s7, 5);
node = wapp_dbl_list_get(Str8, &list, 5);
result = result && node != NULL && node == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7;
return wapp_tester_result(result);
}
@@ -135,33 +117,28 @@ TestFuncResult test_str8_list_pop_front(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
Str8 *node = wapp_dbl_list_pop_front(Str8, &list);
result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
@@ -175,33 +152,28 @@ TestFuncResult test_str8_list_pop_back(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_front(Str8, &list, &n1);
wapp_dbl_list_push_front(Str8, &list, &n2);
wapp_dbl_list_push_front(Str8, &list, &n3);
wapp_dbl_list_push_front(Str8, &list, &n4);
wapp_dbl_list_push_front(Str8, &list, &n5);
wapp_dbl_list_push_front(Str8, &list, &s1);
wapp_dbl_list_push_front(Str8, &list, &s2);
wapp_dbl_list_push_front(Str8, &list, &s3);
wapp_dbl_list_push_front(Str8, &list, &s4);
wapp_dbl_list_push_front(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
Str8 *node = wapp_dbl_list_pop_back(Str8, &list);
result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
@@ -215,33 +187,28 @@ TestFuncResult test_str8_list_remove(void) {
Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &n1);
wapp_dbl_list_push_back(Str8, &list, &n2);
wapp_dbl_list_push_back(Str8, &list, &n3);
wapp_dbl_list_push_back(Str8, &list, &n4);
wapp_dbl_list_push_back(Str8, &list, &n5);
wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
Str8 *node = wapp_dbl_list_remove(Str8, &list, 0);
result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result);
}
@@ -249,18 +216,18 @@ TestFuncResult test_str8_list_remove(void) {
TestFuncResult test_str8_list_empty(void) {
b8 result;
Str8List list = wapp_dbl_list(Str8, Str8List);
Str8List list = wapp_dbl_list(Str8);
Str8Node hello = wapp_str8_node_from_cstr("Hello");
Str8 hello = wapp_str8_lit("Hello");
wapp_dbl_list_push_back(Str8, &list, &hello);
Str8Node from = wapp_str8_node_from_cstr("from");
Str8 from = wapp_str8_lit("from");
wapp_dbl_list_push_back(Str8, &list, &from);
Str8Node wizapp = wapp_str8_node_from_cstr("wizapp");
Str8 wizapp = wapp_str8_lit("wizapp");
wapp_dbl_list_push_back(Str8, &list, &wizapp);
Str8Node stdlib = wapp_str8_node_from_cstr("stdlib");
Str8 stdlib = wapp_str8_lit("stdlib");
wapp_dbl_list_push_back(Str8, &list, &stdlib);
wapp_dbl_list_empty(Str8, &list);

View File

@@ -4,7 +4,9 @@
#include "test_arena.h"
#include "test_str8_array.h"
#include "test_i32_array.h"
#include "test_queue.h"
#include "test_cpath.h"
#include "test_file.h"
#include "test_shell_commander.h"
#include "wapp.h"
#include <stdlib.h>
@@ -12,14 +14,22 @@
int main(void) {
wapp_tester_run_tests(
test_arena_allocator,
test_arena_init,
test_arena_allocator_with_buffer,
test_arena_allocator_temp_begin,
test_arena_allocator_temp_end,
test_arena_init_buffer,
test_arena_init_allocated,
test_arena_init_succeeds_when_reserving_very_large_size,
test_arena_alloc_with_buffer,
test_arena_alloc_succeeds_when_within_capacity,
test_arena_alloc_fails_when_over_capacity,
test_arena_realloc_bigger_size,
test_arena_realloc_smaller_size,
test_arena_temp_begin,
test_arena_temp_end,
test_arena_clear,
test_arena_destroy,
test_arena_destroy_buffer,
test_arena_destroy_allocated,
test_str8_array,
test_i32_array,
test_i32_array_with_capacity,
@@ -34,6 +44,9 @@ int main(void) {
test_i32_array_copy_alloc,
test_i32_array_pop,
test_i32_array_clear,
test_queue_push,
test_queue_push_alloc,
test_queue_pop,
test_str8_lit,
test_str8_lit_ro,
test_str8_buf,
@@ -70,6 +83,18 @@ int main(void) {
test_cpath_join_path,
test_cpath_dirname,
test_cpath_dirup,
test_wapp_file_open,
test_wapp_file_get_current_position,
test_wapp_file_seek,
test_wapp_file_get_length,
test_wapp_file_read,
test_wapp_file_write,
test_wapp_file_read_array,
test_wapp_file_write_array,
test_wapp_file_flush,
test_wapp_file_close,
test_wapp_file_rename,
test_wapp_file_remove,
test_commander_cmd_success,
test_commander_cmd_failure,
test_commander_cmd_out_buf_success,

View File

@@ -4,7 +4,9 @@
#include "test_arena.h"
#include "test_str8_array.h"
#include "test_i32_array.h"
#include "test_queue.h"
#include "test_cpath.h"
#include "test_file.h"
#include "test_shell_commander.h"
#include "wapp.h"
#include <stdlib.h>
@@ -12,14 +14,22 @@
int main(void) {
wapp_tester_run_tests(
test_arena_allocator,
test_arena_init,
test_arena_allocator_with_buffer,
test_arena_allocator_temp_begin,
test_arena_allocator_temp_end,
test_arena_init_buffer,
test_arena_init_allocated,
test_arena_init_succeeds_when_reserving_very_large_size,
test_arena_alloc_with_buffer,
test_arena_alloc_succeeds_when_within_capacity,
test_arena_alloc_fails_when_over_capacity,
test_arena_realloc_bigger_size,
test_arena_realloc_smaller_size,
test_arena_temp_begin,
test_arena_temp_end,
test_arena_clear,
test_arena_destroy,
test_arena_destroy_buffer,
test_arena_destroy_allocated,
test_str8_array,
test_i32_array,
test_i32_array_with_capacity,
@@ -34,6 +44,9 @@ int main(void) {
test_i32_array_copy_alloc,
test_i32_array_pop,
test_i32_array_clear,
test_queue_push,
test_queue_push_alloc,
test_queue_pop,
test_str8_lit,
test_str8_lit_ro,
test_str8_buf,
@@ -70,6 +83,18 @@ int main(void) {
test_cpath_join_path,
test_cpath_dirname,
test_cpath_dirup,
test_wapp_file_open,
test_wapp_file_get_current_position,
test_wapp_file_seek,
test_wapp_file_get_length,
test_wapp_file_read,
test_wapp_file_write,
test_wapp_file_read_array,
test_wapp_file_write_array,
test_wapp_file_flush,
test_wapp_file_close,
test_wapp_file_rename,
test_wapp_file_remove,
test_commander_cmd_success,
test_commander_cmd_failure,
test_commander_cmd_out_buf_success,