83 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
f3ee1ee468 Unify struct names and tags 2026-01-02 14:00:00 +00:00
7be1b42107 Reformat tests 2026-01-02 01:12:01 +00:00
41cac2ef7f Reformat os 2026-01-02 00:49:21 +00:00
24716505be Reformat prng 2026-01-02 00:38:44 +00:00
7e21961943 Reformat uuid 2026-01-02 00:36:05 +00:00
6f27d5ea91 Reformat common 2026-01-02 00:30:55 +00:00
54691a8ede Reformat base 2026-01-02 00:29:24 +00:00
ab91bb2c9e Update Makefile 2025-12-29 23:40:49 +00:00
52303c81ae Rename os memory functions 2025-12-29 23:29:40 +00:00
2372ae6675 Remove inline 2025-12-29 23:13:46 +00:00
ad2de98093 Switch to using tabs instead of spaces (#9)
Reviewed-on: #9
2025-12-29 22:46:52 +00:00
aa6ef1ec2c Reformat 2025-12-29 15:44:34 +00:00
5e939a7158 Add option to fill array when allocating 2025-12-28 18:49:27 +00:00
1cbb148a1f Add ability to fill array with capacity 2025-12-28 18:31:49 +00:00
a065dfb573 Expand data size utilities 2025-12-24 08:53:12 +00:00
3904b3a1ee Node validation checks against list 2025-12-17 05:20:27 +00:00
d15022603f Refactor array validation to function 2025-12-17 04:34:49 +00:00
debf6ed8eb Add vim info 2025-12-17 04:29:26 +00:00
6c5352e9de Fix _dbl_list_pop_front bug 2025-12-17 04:23:57 +00:00
4ea30f0762 No codegen doubly-linked list (#8)
Reviewed-on: #8
Co-authored-by: Abdelrahman <said.abdelrahman89@gmail.com>
Co-committed-by: Abdelrahman <said.abdelrahman89@gmail.com>
2025-12-17 03:53:13 +00:00
110 changed files with 5715 additions and 11600 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

@@ -1,4 +1,4 @@
.PHONY: help full base os prng testing uuid all clean builddir build-test run-test codegen install build-lib ccodegen .PHONY: help full base os prng testing uuid all clean builddir build-test run-test install build-lib
# External variables # External variables
CC = clang CC = clang
@@ -7,7 +7,6 @@ AR = ar
BUILD_TYPE = Debug BUILD_TYPE = Debug
BUILD_DIR = libwapp-build/$(PLATFORM)-$(BUILD_TYPE) BUILD_DIR = libwapp-build/$(PLATFORM)-$(BUILD_TYPE)
INSTALL_PREFIX = dist INSTALL_PREFIX = dist
CODEGEN_INPUT = ""
RUNTIME_ASSERT = true RUNTIME_ASSERT = true
# Internal variables # Internal variables
@@ -22,13 +21,14 @@ override TEST_INCLUDE := -Isrc $(shell find tests -type d | xargs -I{} ech
override TEST_SRC := $(shell find tests -type f -name "*.c" | xargs -I{} echo -n "{} ") override TEST_SRC := $(shell find tests -type f -name "*.c" | xargs -I{} echo -n "{} ")
override TEST_C_SRC := src/wapp.c $(TEST_SRC) override TEST_C_SRC := src/wapp.c $(TEST_SRC)
override TEST_CXX_SRC := $(shell find tests -type f -name "*.cc" | xargs -I{} echo -n "{} ") override TEST_CXX_SRC := $(shell find tests -type f -name "*.cc" | xargs -I{} echo -n "{} ")
override LIB_NAME := wapp override LIB_BASENAME := wapp
override OBJ_OUT := $(BUILD_DIR)/$(LIB_NAME).o override OBJ_OUT := $(BUILD_DIR)/$(LIB_BASENAME).o
override LIB_OUT := $(BUILD_DIR)/lib$(LIB_NAME).a override LIB_STATIC_NAME := lib$(LIB_BASENAME).a
override LIB_OUT := $(BUILD_DIR)/$(LIB_STATIC_NAME)
override TEST_C_OUT := $(BUILD_DIR)/wapptest override TEST_C_OUT := $(BUILD_DIR)/wapptest
override TEST_CXX_OUT := $(BUILD_DIR)/wapptestcc override TEST_CXX_OUT := $(BUILD_DIR)/wapptestcc
override ABS_INSTALL_PREFIX := $(shell mkdir -p $(INSTALL_PREFIX) && realpath $(INSTALL_PREFIX)) override ABS_INSTALL_PREFIX := $(shell mkdir -p $(INSTALL_PREFIX) && realpath $(INSTALL_PREFIX))
override INCLUDE_INSTALL := $(ABS_INSTALL_PREFIX)/include/$(LIB_NAME) override INCLUDE_INSTALL := $(ABS_INSTALL_PREFIX)/include/$(LIB_BASENAME)
override LIB_INSTALL := $(ABS_INSTALL_PREFIX)/lib override LIB_INSTALL := $(ABS_INSTALL_PREFIX)/lib
override HEADER_INSTALL_CMD := scripts/header_install.sh override HEADER_INSTALL_CMD := scripts/header_install.sh
@@ -46,7 +46,7 @@ endif
# Disable runtime asserts # Disable runtime asserts
ifeq ($(RUNTIME_ASSERT), false) ifeq ($(RUNTIME_ASSERT), false)
override BUILD_FLAGS += WAPP_NO_RUNTIME_ASSERT override BUILD_FLAGS += -DWAPP_NO_RUNTIME_ASSERT
endif endif
ifeq ($(CC),gcc) ifeq ($(CC),gcc)
@@ -95,7 +95,7 @@ ifeq ($(KERNEL), Darwin)
ECHO_E = echo ECHO_E = echo
endif endif
all: clean builddir codegen run-c-test full run-cc-test all: clean builddir run-c-test full run-cc-test
help: help:
@$(ECHO_E) "$(BOLD)$(BLUE)Available build variables:$(RESET)" @$(ECHO_E) "$(BOLD)$(BLUE)Available build variables:$(RESET)"
@@ -105,7 +105,6 @@ help:
@$(ECHO_E) " $(GREEN)BUILD_TYPE$(RESET) Build type $(MAGENTA)[Debug | RelWithDebInfo | Release] $(YELLOW)(Default: Debug)$(RESET)." @$(ECHO_E) " $(GREEN)BUILD_TYPE$(RESET) Build type $(MAGENTA)[Debug | RelWithDebInfo | Release] $(YELLOW)(Default: Debug)$(RESET)."
@$(ECHO_E) " $(GREEN)BUILD_DIR$(RESET) Directory where build files will be written." @$(ECHO_E) " $(GREEN)BUILD_DIR$(RESET) Directory where build files will be written."
@$(ECHO_E) " $(GREEN)INSTALL_PREFIX$(RESET) Prefix where library and include files will be installed." @$(ECHO_E) " $(GREEN)INSTALL_PREFIX$(RESET) Prefix where library and include files will be installed."
@$(ECHO_E) " $(GREEN)CODEGEN_INPUT$(RESET) Input file for code generation (See $(CYAN)codegen_custom_data_example.json$(RESET) for an example)."
@$(ECHO_E) " $(GREEN)RUNTIME_ASSERT$(RESET) Whether runtime asserts are enabled $(MAGENTA)[true | false] $(YELLOW)(Default: true)$(RESET)." @$(ECHO_E) " $(GREEN)RUNTIME_ASSERT$(RESET) Whether runtime asserts are enabled $(MAGENTA)[true | false] $(YELLOW)(Default: true)$(RESET)."
@$(ECHO_E) " $(GREEN)$(RESET) $(BOLD)$(BG_RED)DISCLAIMER:$(RESET) Using this flag is not recommended as it disables safety checks" @$(ECHO_E) " $(GREEN)$(RESET) $(BOLD)$(BG_RED)DISCLAIMER:$(RESET) Using this flag is not recommended as it disables safety checks"
@$(ECHO_E) " $(GREEN)$(RESET) potentially leading to Undefined Behaviour." @$(ECHO_E) " $(GREEN)$(RESET) potentially leading to Undefined Behaviour."
@@ -147,6 +146,8 @@ uuid: install
clean: clean:
@rm -rf "$(BUILD_DIR)" @rm -rf "$(BUILD_DIR)"
@rm -rf "$(INCLUDE_INSTALL)"
@rm -f "$(LIB_INSTALL)/$(LIB_STATIC_NAME)"
builddir: builddir:
@mkdir -p "$(BUILD_DIR)" @mkdir -p "$(BUILD_DIR)"
@@ -167,10 +168,7 @@ run-cc-test: build-cc-test
@export LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:"$(BUILD_DIR)" && "$(TEST_CXX_OUT)" @export LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:"$(BUILD_DIR)" && "$(TEST_CXX_OUT)"
@rm "$(TEST_CXX_OUT)" @rm "$(TEST_CXX_OUT)"
codegen: install: build-lib
python3 -m codegen -f $(CODEGEN_INPUT)
install: codegen build-lib
@mkdir -p "$(LIB_INSTALL)" @mkdir -p "$(LIB_INSTALL)"
@cp -v "$(LIB_OUT)" "$(LIB_INSTALL)" @cp -v "$(LIB_OUT)" "$(LIB_INSTALL)"
@mkdir -p "$(INCLUDE_INSTALL)" @mkdir -p "$(INCLUDE_INSTALL)"
@@ -180,6 +178,3 @@ build-lib: builddir
$(CC) -c $(CSTD) $(CFLAGS) $(BUILD_FLAGS) $(LIBFLAGS) $(LIB_SRC) -o "$(OBJ_OUT)" $(CC) -c $(CSTD) $(CFLAGS) $(BUILD_FLAGS) $(LIBFLAGS) $(LIB_SRC) -o "$(OBJ_OUT)"
$(AR) r "$(LIB_OUT)" "$(OBJ_OUT)" $(AR) r "$(LIB_OUT)" "$(OBJ_OUT)"
@rm "$(OBJ_OUT)" @rm "$(OBJ_OUT)"
ccodegen:
$(CC) $(CSTD) $(CFLAGS) $(BUILD_FLAGS) $(LIBFLAGS) -Isrc/os src/os/wapp_os.c ccodegen/*.c -o ccgen

View File

@@ -1,3 +1,5 @@
# Wizard Apprentice Standard Library # Wizard Apprentice Standard Library
A base layer 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 $OutDir > $null
mkdir -p $TestsDir > $null mkdir -p $TestsDir > $null
# Run code generation
Invoke-Expression "python -m codegen"
# Build and run C tests # Build and run C tests
Invoke-Expression "$Compiler $GeneralFlags $CStd $IncludeDirs $TestIncludeDirs $SrcFiles $TestCSrcFiles $TestCOutputFlags" -ErrorAction Stop Invoke-Expression "$Compiler $GeneralFlags $CStd $IncludeDirs $TestIncludeDirs $SrcFiles $TestCSrcFiles $TestCOutputFlags" -ErrorAction Stop
Invoke-Expression "$TestsDir/$TestCOutputBasename.exe" Invoke-Expression "$TestsDir/$TestCOutputBasename.exe"

BIN
ccgen

Binary file not shown.

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,503 +0,0 @@
from enum import Enum
from pathlib import Path
from typing import Optional, Union, List, Dict, Type, Any, TypeVar, cast
from dataclasses import dataclass, asdict, field, fields
from codegen.constants import WAPP_SRC_ROOT
from codegen.utils import convert_to_relative
E = TypeVar("E", bound="Enum")
S = TypeVar("S", bound="SerialisableDataclass")
F = TypeVar("F", bound="CFile")
@dataclass
class SerialisableDataclass:
def to_dict(self) -> Dict[str, Any]:
d = asdict(self)
for f in fields(self):
member = getattr(self, f.name)
if isinstance(member, list):
d[f.name] = [self.__serialise_member(i) for i in member]
else:
d[f.name] = self.__serialise_member(member)
return d
def __serialise_member(self, member: Any) -> Any:
if isinstance(member, Enum):
return member.value
elif isinstance(member, SerialisableDataclass):
return member.to_dict()
return member
@staticmethod
def to_enum_value(value: Any, _type: Type[E]) -> "E":
if isinstance(value, _type):
return value
return _type(value)
@staticmethod
def to_c_usertype(value: dict[str, Any]) -> "CUserType":
try:
output = CStruct.from_dict(value)
except TypeError:
output = CEnum.from_dict(value)
return output
@staticmethod
def to_cdatatype(value: Any) -> "CDataType":
if isinstance(value, dict):
output = SerialisableDataclass.to_c_usertype(value)
else:
try:
output = CType(value)
except ValueError:
output = value
return output
@classmethod
def from_dict(cls: Type[S], d: Dict[str, Any]) -> "S":
return cls(**d)
class CType(Enum):
VOID = "void"
BOOL = "b8"
CHAR = "char"
C8 = "c8"
C16 = "c16"
C32 = "c32"
I8 = "i8"
I16 = "i16"
I32 = "i32"
I64 = "i64"
U8 = "u8"
U16 = "u16"
U32 = "u32"
U64 = "u64"
F32 = "f32"
F64 = "f64"
F128 = "f128"
IPTR = "iptr"
UPTR = "uptr"
def __str__(self) -> str:
return self.value
class CQualifier(Enum):
NONE = ""
CONST = "const "
EXTERNAL = "wapp_extern "
INTERNAL = "wapp_intern "
PERSISTENT = "wapp_persist "
def __str__(self) -> str:
return self.value
class CPointerType(Enum):
NONE = ""
SINGLE = "*"
DOUBLE = "**"
def __str__(self) -> str:
return self.value
@dataclass
class CPointer(SerialisableDataclass):
_type: CPointerType = CPointerType.NONE
qualifier: CQualifier = CQualifier.NONE
def __str__(self) -> str:
return str(self._type) + str(self.qualifier)
@classmethod
def from_dict(cls: Type["CPointer"], d: Dict[str, Any]) -> "CPointer":
ptr = CPointer(**d)
ptr._type = CPointer.to_enum_value(ptr._type, CPointerType)
ptr.qualifier = CPointer.to_enum_value(ptr.qualifier, CQualifier)
return ptr
@dataclass
class CEnumVal(SerialisableDataclass):
name: str
value: Optional[int] = None
def __str__(self) -> str:
return self.name + "" if self.value is None else f" = {self.value}"
@dataclass
class CEnum(SerialisableDataclass):
name: str
values: List[CEnumVal]
typedef: bool = False
def __str__(self) -> str:
if self.typedef:
header = "typedef enum {\n"
footer = f"}} {self.name};\n"
else:
header = f"enum {self.name} {{\n"
footer = "};\n"
values = ""
for value in self.values:
values += f" {str(value)},\n"
return header + values + footer
@classmethod
def from_dict(cls: Type["CEnum"], d: Dict[str, Any]) -> "CEnum":
e = CEnum(**d)
e.values = [CEnumVal.from_dict(v) for v in e.values if isinstance(v, dict)]
return e
@dataclass
class CMacro(SerialisableDataclass):
name: str
value: str
def __str__(self) -> str:
return f"#define {self.name} {self.value}\n"
@dataclass
class CStruct(SerialisableDataclass):
name: str
cargs: List["CArg"]
typedef_name: Optional[str] = None
def __str__(self) -> str:
return self.declare() + self.define()
def declare(self) -> str:
declaration = f"typedef struct {self.name} {self.typedef_name if self.typedef_name is not None else self.name};\n"
return declaration
def define(self):
definition = f"struct {self.name} {{\n"
args = ""
for arg in self.cargs:
args += f" {str(arg)};\n"
footer = "};\n"
return definition + args + footer;
@classmethod
def from_dict(cls: Type["CStruct"], d: Dict[str, Any]) -> "CStruct":
s = CStruct(**d)
s.cargs = [CArg.from_dict(v) for v in s.cargs if isinstance(v, dict)]
return s
CUserType = Union[CStruct, CEnum]
CDataType = Union[CType, CUserType, str]
@dataclass
class CArg(SerialisableDataclass):
name: str
_type: CDataType
array: bool = False
pointer: CPointer = field(default_factory=CPointer)
qualifier: CQualifier = CQualifier.NONE
def __str__(self) -> str:
qualifier = str(self.qualifier)
_type = get_datatype_string(self._type) + " "
pointer = str(self.pointer)
array = "[]" if self.array else ""
return qualifier + _type + pointer + self.name + array
@classmethod
def from_dict(cls: Type["CArg"], d: Dict[str, Any]) -> "CArg":
arg = CArg(**d)
arg._type = CArg.to_cdatatype(arg._type)
if isinstance(arg.pointer, dict):
arg.pointer = CPointer.from_dict(arg.pointer)
arg.qualifier = CArg.to_enum_value(arg.qualifier, CQualifier)
return arg
@dataclass
class CFunc(SerialisableDataclass):
name: str
ret_type: CDataType
args: List[CArg]
body: str
pointer: CPointer = field(default_factory=CPointer)
qualifiers: List[CQualifier] = field(default_factory=list)
def __str__(self) -> str:
qualifiers = ""
for qualifier in self.qualifiers:
if qualifier == CQualifier.NONE:
continue
if len(qualifiers) > 0:
qualifiers += " "
qualifiers += f"{str(qualifier)}"
args = ""
for i, arg in enumerate(self.args):
args += f"{str(arg)}"
if i + 1 < len(self.args):
args += ", "
return qualifiers + get_datatype_string(self.ret_type) + " " + str(self.pointer) + self.name + f"({args})"
def declare(self) -> str:
return f"{str(self)};\n"
def define(self) -> str:
return f"{str(self)} {{\n{self.body}\n}}\n\n"
@classmethod
def from_dict(cls: Type["CFunc"], d: Dict[str, Any]) -> "CFunc":
f = CFunc(**d)
f.ret_type = CFunc.to_cdatatype(f.ret_type)
f.args = [CArg.from_dict(v) for v in f.args if isinstance(v, dict)]
f.qualifiers = [CFunc.to_enum_value(v, CQualifier) for v in f.qualifiers]
if isinstance(f.pointer, dict):
f.pointer = CPointer.from_dict(f.pointer)
return f
@dataclass
class CInclude(SerialisableDataclass):
header: Union[str, "CHeader"]
local: bool = False
same_dir: bool = False
def __str__(self) -> str:
if isinstance(self.header, CHeader):
name = f"{self.header.name}.{self.header.extension}"
else:
name = self.header
if self.local:
open_symbol = '"'
close_symbol = '"'
if self.same_dir:
name = f"./{name}"
else:
open_symbol = '<'
close_symbol = '>'
return f"#include {open_symbol}{name}{close_symbol}\n"
@classmethod
def from_dict(cls: Type["CInclude"], d: Dict[str, Any]) -> "CInclude":
inc = CInclude(**d)
if isinstance(inc.header, dict):
inc.header = CHeader.from_dict(inc.header)
return inc
@dataclass
class CFile(SerialisableDataclass):
name: str
extension: str
includes: List[CInclude] = field(default_factory=list)
types: List[CUserType] = field(default_factory=list)
funcs: List[CFunc] = field(default_factory=list)
decl_types: List[CStruct] = field(default_factory=list)
macros: List[CMacro] = field(default_factory=list)
c_macros: List[CMacro] = field(default_factory=list)
cpp_macros: List[CMacro] = field(default_factory=list)
def save(self, output_dir: Path):
self.includes.extend(
[
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "aliases" / "aliases.h", output_dir)).replace("\\", "/"),
local=True,
),
CInclude(
header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "platform" / "platform.h", output_dir)).replace("\\", "/"),
local=True,
)
]
)
output_file = output_dir / f"{self.name}.{self.extension}"
with open(output_file, "w+") as outfile:
outfile.write(str(self))
def __str__(self) -> str:
return """\
/**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN.
*/
"""
@classmethod
def from_dict(cls: Type["CFile"], d: Dict[str, Any]) -> "CFile":
f = CFile(**d)
f.deserialise_c_file_data()
return f
def deserialise_c_file_data(self) -> None:
self.includes = [CInclude.from_dict(v) for v in self.includes if isinstance(v, dict)]
self.types = [CFile.to_c_usertype(v) for v in self.types if isinstance(v, dict)]
self.funcs = [CFunc.from_dict(v) for v in self.funcs if isinstance(v, dict)]
self.decl_types = [CStruct.from_dict(v) for v in self.decl_types if isinstance(v, dict)]
self.macros = [CMacro.from_dict(v) for v in self.macros if isinstance(v, dict)]
self.c_macros = [CMacro.from_dict(v) for v in self.c_macros if isinstance(v, dict)]
self.cpp_macros = [CMacro.from_dict(v) for v in self.cpp_macros if isinstance(v, dict)]
@dataclass
class CHeader(CFile):
extension: str = "h"
def __str__(self) -> str:
name_upper = self.name.upper()
header_guard_name = f"{name_upper}_H"
header_guard_open = f"#ifndef {header_guard_name}\n#define {header_guard_name}\n\n"
header_guard_close = f"#endif // !{header_guard_name}\n"
c_linkage_open = "#ifdef WAPP_PLATFORM_CPP\nBEGIN_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n"
c_linkage_close = "\n#ifdef WAPP_PLATFORM_CPP\nEND_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n"
includes = _get_includes_string(self.includes)
macros = ""
for macro in self.macros:
macros += str(macro)
if len(macros) > 0:
macros += "\n"
if len(self.cpp_macros) > 0:
macros += "#ifdef WAPP_PLATFORM_CPP\n"
for macro in self.cpp_macros:
macros += str(macro)
macros += "#else\n"
for macro in self.c_macros:
macros += str(macro)
macros += "#endif // !WAPP_PLATFORM_CPP\n\n"
forward_declarations = ""
for _type in self.decl_types:
forward_declarations += _type.declare()
if len(forward_declarations) > 0:
forward_declarations += "\n"
types = ""
for _type in self.types:
types += str(_type) + "\n"
funcs = ""
for func in self.funcs:
funcs += func.declare()
return (
super().__str__() +
header_guard_open +
includes +
c_linkage_open +
macros +
forward_declarations +
types +
funcs +
c_linkage_close +
header_guard_close
)
@classmethod
def from_dict(cls: Type["CHeader"], d: Dict[str, Any]) -> "CHeader":
return cast("CHeader", super().from_dict(d))
@dataclass
class CSource(CFile):
extension: str = "c"
internal_funcs: List[CFunc] = field(default_factory=list)
def __str__(self) -> str:
includes = _get_includes_string(self.includes)
macros = ""
for macro in self.macros:
macros += str(macro)
if len(macros) > 0:
macros += "\n"
forward_declarations = ""
for _type in self.decl_types:
forward_declarations += _type.declare()
if len(forward_declarations) > 0:
forward_declarations += "\n"
types = ""
for _type in self.types:
types += str(_type) + "\n"
internal_funcs_decl = ""
internal_funcs_def = ""
for func in self.internal_funcs:
internal_funcs_decl += func.declare()
internal_funcs_def += func.define()
if len(internal_funcs_decl) > 0:
internal_funcs_decl += "\n"
funcs = ""
for func in self.funcs:
funcs += func.define()
return (
super().__str__() +
includes +
macros +
forward_declarations +
types +
internal_funcs_decl +
funcs +
internal_funcs_def
)
@classmethod
def from_dict(cls: Type["CSource"], d: Dict[str, Any]) -> "CSource":
s = CSource(**d)
s.deserialise_c_file_data()
s.internal_funcs = [CFunc.from_dict(v) for v in s.funcs if isinstance(v, dict)]
return s
def get_datatype_string(_type: CDataType) -> str:
if isinstance(_type, CType):
return str(_type)
elif isinstance(_type, CStruct) or isinstance(_type, CEnum):
return _type.name
elif isinstance(_type, str):
return _type
def _get_includes_string(includes: List[CInclude]) -> str:
output = ""
for include in sorted(includes, key=lambda inc: inc.local, reverse=True):
output += str(include)
if len(output) > 0:
output += "\n"
return output

View File

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

View File

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

View File

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

View File

@@ -1,26 +0,0 @@
wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL");
if (index == 0) {{
wapp_{Tlower}_list_push_front(list, node);
return;
}} else if (index == list->node_count) {{
wapp_{Tlower}_list_push_back(list, node);
return;
}}
{NodeType} *dst_node = wapp_{Tlower}_list_get(list, index);
if (!dst_node) {{
return;
}}
{ListType} node_list = {Tlower}_node_to_list(node);
list->node_count += node_list.node_count;
{NodeType} *prev = dst_node->prev;
dst_node->prev = node_list.last;
prev->next = node_list.first;
node_list.first->prev = prev;
node_list.last->next = dst_node;

View File

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

View File

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

View File

@@ -1,22 +0,0 @@
wapp_debug_assert(list != NULL, "`list` should not be NULL");
{NodeType} *output = NULL;
if (list->node_count == 0) {{
goto RETURN_{Tupper}_LIST_POP_BACK;
}}
output = list->last;
if (list->node_count == 1) {{
*list = ({ListType}){{0}};
goto RETURN_{Tupper}_LIST_POP_BACK;
}}
--(list->node_count);
list->last = output->prev;
output->prev = output->next = NULL;
RETURN_{Tupper}_LIST_POP_BACK:
return output;

View File

@@ -1,22 +0,0 @@
wapp_debug_assert(list != NULL, "`list` should not be NULL");
{NodeType} *output = NULL;
if (list->node_count == 0) {{
goto RETURN_{Tupper}_LIST_POP_FRONT;
}}
output = list->first;
if (list->node_count == 1) {{
*list = ({ListType}){{0}};
goto RETURN_{Tupper}_LIST_POP_FRONT;
}}
--(list->node_count);
list->first = output->next;
output->prev = output->next = NULL;
RETURN_{Tupper}_LIST_POP_FRONT:
return output;

View File

@@ -1,18 +0,0 @@
wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL");
{ListType} node_list = {Tlower}_node_to_list(node);
if (list->node_count == 0) {{
*list = node_list;
return;
}}
list->node_count += node_list.node_count;
{NodeType} *last = list->last;
if (last) {{
last->next = node_list.first;
}}
list->last = node_list.last;
node_list.first->prev = last;

View File

@@ -1,18 +0,0 @@
wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL");
{ListType} node_list = {Tlower}_node_to_list(node);
if (list->node_count == 0) {{
*list = node_list;
return;
}}
list->node_count += node_list.node_count;
{NodeType} *first = list->first;
if (first) {{
first->prev = node_list.last;
}}
list->first = node_list.first;
node_list.last->next = first;

View File

@@ -1,26 +0,0 @@
wapp_debug_assert(list != NULL, "`list` should not be NULL");
{NodeType} *output = NULL;
if (index == 0) {{
output = wapp_{Tlower}_list_pop_front(list);
goto RETURN_{Tupper}_LIST_REMOVE;
}} else if (index == list->node_count) {{
output = wapp_{Tlower}_list_pop_back(list);
goto RETURN_{Tupper}_LIST_REMOVE;
}}
output = wapp_{Tlower}_list_get(list, index);
if (!output) {{
goto RETURN_{Tupper}_LIST_REMOVE;
}}
output->prev->next = output->next;
output->next->prev = output->prev;
--(list->node_count);
output->prev = output->next = NULL;
RETURN_{Tupper}_LIST_REMOVE:
return output;

View File

@@ -1,13 +0,0 @@
{ListType} output = {{.first = node, .last = node, .node_count = 1}};
while (output.first->prev != NULL) {{
output.first = output.first->prev;
++(output.node_count);
}}
while (output.last->next != NULL) {{
output.last = output.last->next;
++(output.node_count);
}}
return output;

View File

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

View File

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

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,69 +7,115 @@
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include <stddef.h> #include <stddef.h>
#define _offset_pointer(PTR, OFFSET) ((void *)((uptr)(PTR) + (OFFSET))) #define _array_header(ARRAY) (ArrayHeader *)(wapp_pointer_offset(ARRAY, (i64)sizeof(ArrayHeader) * -1))
void *_array_get(Array *array, u64 index, u64 item_size) { wapp_persist inline void _array_validate(const GenericArray array, u64 item_size);
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == array->magic, "`array` is not a valid wapp array");
wapp_runtime_assert(item_size == array->item_size, "Invalid item type provided");
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
return _offset_pointer(array->items, array->item_size * index); u64 _array_count(GenericArray array) {
wapp_debug_assert(array != NULL, "`array` should not be NULL");
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
return header->count;
} }
void _array_set(Array *array, u64 index, void *value, u64 item_size) { u64 _array_capacity(GenericArray array) {
wapp_debug_assert(array != NULL, "`array` should not be NULL");
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
return header->capacity;
}
u64 _array_item_size(GenericArray array) {
wapp_debug_assert(array != NULL, "`array` should not be NULL");
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
return header->item_size;
}
void _array_set_count(GenericArray array, u64 count) {
wapp_debug_assert(array != NULL, "`array` should not be NULL");
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
header->count = count;
}
void *_array_get(GenericArray array, u64 index, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
_array_validate(array, item_size);
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(index < header->count, "`index` is out of bounds");
return wapp_pointer_offset(array, header->item_size * index);
}
void _array_set(GenericArray array, u64 index, void *value, u64 item_size) {
void *item = _array_get(array, index, item_size); void *item = _array_get(array, index, item_size);
memcpy(item, value, array->item_size);
ArrayHeader *header = _array_header(array);
memcpy(item, value, header->item_size);
} }
void _array_append_capped(Array *array, void *value, u64 item_size) { void _array_append_capped(GenericArray array, void *value, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL"); wapp_runtime_assert(array != NULL, "`array` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == array->magic, "`array` is not a valid wapp array"); _array_validate(array, item_size);
wapp_runtime_assert(item_size == array->item_size, "Invalid item type provided");
if (array->count >= array->capacity) { return; } ArrayHeader *header = _array_header(array);
if (header->count >= header->capacity) { return; }
u64 index = (array->count)++; u64 index = (header->count)++;
_array_set(array, index, value, item_size); _array_set(array, index, value, item_size);
} }
void _array_extend_capped(Array *dst, const Array *src, u64 item_size) { void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_size) {
wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL"); wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == dst->magic, "`dst` is not a valid wapp array"); _array_validate(dst, item_size);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == src->magic, "`src` is not a valid wapp array"); _array_validate(src, item_size);
wapp_runtime_assert(item_size == dst->item_size && item_size == src->item_size, "Invalid item type provided");
u64 remaining_capacity = dst->capacity - dst->count; ArrayHeader *src_header = _array_header(src);
ArrayHeader *dst_header = _array_header(dst);
u64 remaining_capacity = dst_header->capacity - dst_header->count;
u64 copy_count = src->count < remaining_capacity ? src->count : remaining_capacity; u64 copy_count = src_header->count < remaining_capacity ? src_header->count : remaining_capacity;
void *dst_ptr = _offset_pointer(dst->items, dst->count * dst->item_size); void *dst_ptr = wapp_pointer_offset(dst, dst_header->count * dst_header->item_size);
memcpy(dst_ptr, src->items, copy_count * src->item_size); memcpy(dst_ptr, src, copy_count * src_header->item_size);
dst->count += copy_count; dst_header->count += copy_count;
} }
void _array_copy_capped(Array *dst, const Array *src, u64 item_size) { void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size) {
wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL"); wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == dst->magic, "`dst` is not a valid wapp array"); _array_validate(dst, item_size);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == src->magic, "`src` is not a valid wapp array"); _array_validate(src, item_size);
wapp_runtime_assert(item_size == dst->item_size && item_size == src->item_size, "Invalid item type provided");
_array_clear(dst, item_size); _array_clear(dst, item_size);
u64 copy_count = src->count < dst->capacity ? src->count : dst->capacity;
memcpy(dst->items, src->items, copy_count * src->item_size); ArrayHeader *src_header = _array_header(src);
dst->count = copy_count; ArrayHeader *dst_header = _array_header(dst);
u64 copy_count = src_header->count < dst_header->capacity ? src_header->count : dst_header->capacity;
memcpy((void *)dst, (void *)src, copy_count * src_header->item_size);
dst_header->count = copy_count;
} }
Array *_array_append_alloc(const Allocator *allocator, Array *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"); wapp_runtime_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == array->magic, "`array` is not a valid wapp array"); _array_validate(array, item_size);
wapp_runtime_assert(item_size == array->item_size, "Invalid item type provided");
Array *output = array; GenericArray output = array;
if (array->count >= array->capacity) { ArrayHeader *header = _array_header(array);
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2); if (header->count >= header->capacity) {
output = (Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size); u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(header->capacity * 2);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity, flags,
header->item_size);
if (!output) { if (!output) {
output = array; output = array;
goto RETURN_ARRAY_APPEND_ALLOC; goto RETURN_ARRAY_APPEND_ALLOC;
@@ -79,22 +125,29 @@ Array *_array_append_alloc(const Allocator *allocator, Array *array, void *value
_array_append_capped(output, value, item_size); _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_ARRAY_APPEND_ALLOC:
return output; return output;
} }
Array *_array_extend_alloc(const Allocator *allocator, Array *dst, const Array *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"); wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == dst->magic, "`dst` is not a valid wapp array"); _array_validate(dst, item_size);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == src->magic, "`src` is not a valid wapp array"); _array_validate(src, item_size);
wapp_runtime_assert(item_size == dst->item_size && item_size == src->item_size, "Invalid item type provided");
Array *output = dst; GenericArray output = dst;
u64 remaining_capacity = dst->capacity - dst->count; ArrayHeader *src_header = _array_header(src);
if (src->count >= remaining_capacity) { ArrayHeader *dst_header = _array_header(dst);
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2); u64 remaining_capacity = dst_header->capacity - dst_header->count;
output = (Array *)_array_alloc_capacity(allocator, new_capacity, dst->item_size); 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,
flags, dst_header->item_size);
if (!output) { if (!output) {
output = dst; output = dst;
goto RETURN_ARRAY_EXTEND_ALLOC; goto RETURN_ARRAY_EXTEND_ALLOC;
@@ -104,21 +157,28 @@ Array *_array_extend_alloc(const Allocator *allocator, Array *dst, const Array *
_array_extend_capped(output, src, item_size); _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_ARRAY_EXTEND_ALLOC:
return output; return output;
} }
Array *_array_copy_alloc(const Allocator *allocator, Array *dst, const Array *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"); wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == dst->magic, "`dst` is not a valid wapp array"); _array_validate(dst, item_size);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == src->magic, "`src` is not a valid wapp array"); _array_validate(src, item_size);
wapp_runtime_assert(item_size == dst->item_size && item_size == src->item_size, "Invalid item type provided");
Array *output = dst; GenericArray output = dst;
if (src->count >= dst->capacity) { ArrayHeader *src_header = _array_header(src);
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2); ArrayHeader *dst_header = _array_header(dst);
output = (Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size); 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,
flags, src_header->item_size);
if (!output) { if (!output) {
output = dst; output = dst;
goto RETURN_ARRAY_COPY_ALLOC; goto RETURN_ARRAY_COPY_ALLOC;
@@ -127,49 +187,80 @@ Array *_array_copy_alloc(const Allocator *allocator, Array *dst, const Array *sr
_array_copy_capped(output, src, item_size); _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_ARRAY_COPY_ALLOC:
return output; return output;
} }
void *_array_pop(Array *array, u64 item_size) { void *_array_pop(GenericArray array, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL"); wapp_runtime_assert(array != NULL, "`array` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == array->magic, "`array` is not a valid wapp array"); _array_validate(array, item_size);
wapp_runtime_assert(item_size == array->item_size, "Invalid item type provided");
if (array->count == 0) { return NULL; } ArrayHeader *header = _array_header(array);
if (header->count == 0) { return NULL; }
u64 index = array->count - 1; u64 index = header->count - 1;
void *out = _array_get(array, index, item_size); void *out = _array_get(array, index, item_size);
--(array->count); --(header->count);
return out; return out;
} }
void _array_clear(Array *array, u64 item_size) { void _array_clear(GenericArray array, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL"); wapp_runtime_assert(array != NULL, "`array` should not be NULL");
wapp_runtime_assert(WAPP_ARRAY_MAGIC == array->magic, "`array` is not a valid wapp array"); _array_validate(array, item_size);
wapp_runtime_assert(item_size == array->item_size, "Invalid item type provided");
array->count = 0; ArrayHeader *header = _array_header(array);
header->count = 0;
} }
Array *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size) { 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"); wapp_runtime_assert(allocator != NULL, "`allocator` should not be NULL");
Array *output = NULL; GenericArray output = NULL;
u64 allocation_size = sizeof(Array) + item_size * capacity; u64 allocation_size = _array_calc_alloc_size(capacity, item_size);
void *buffer = wapp_mem_allocator_alloc(allocator, allocation_size);
output = wapp_mem_allocator_alloc(allocator, allocation_size); if (!buffer) {
if (!output) {
goto RETURN_ARRAY_ALLOC; goto RETURN_ARRAY_ALLOC;
} }
output->magic = WAPP_ARRAY_MAGIC; output = _array_from_preallocated_buffer(buffer, allocation_size, flags, item_size);
output->count = 0;
output->capacity = capacity;
output->item_size = item_size;
output->items = (void *)(output + 1);
RETURN_ARRAY_ALLOC: RETURN_ARRAY_ALLOC:
return output; 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");
wapp_runtime_assert(item_size == header->item_size, "Invalid item type provided");
}

View File

@@ -12,139 +12,202 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define WAPP_ARRAY_MAGIC (u64)0x57415F415252 #define WAPP_ARRAY_MAGIC (u64)0x57415f415252
#define _calc_array_count(TYPE, ...) wapp_misc_utils_va_args_count(TYPE, __VA_ARGS__) #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 _calc_array_capacity(TYPE, ...) wapp_misc_utils_u64_round_up_pow2(_calc_array_count(TYPE, __VA_ARGS__) * 2)
#define wapp_array_alloc_capacity(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, CAPACITY) \ typedef struct Str8 Str8;
((ARRAY_TYPE *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(ELEM_TYPE)))
#define WAPP_DEF_ARRAY_TYPE(T, NAME) \ // NOTE (Abdelrahman): Typedefs to distinguish arrays from regular pointers
typedef struct { \ typedef void *GenericArray;
u64 magic; \ typedef void **VoidPtrArray;
u64 count; \ typedef c8 *C8Array;
u64 capacity; \ typedef c16 *C16Array;
u64 item_size; \ typedef c32 *C32Array;
T *items; \ typedef u8 *U8Array;
} NAME typedef u16 *U16Array;
typedef u32 *U32Array;
typedef u64 *U64Array;
typedef b8 *B8Array;
typedef i8 *I8Array;
typedef i16 *I16Array;
typedef i32 *I32Array;
typedef i64 *I64Array;
typedef f32 *F32Array;
typedef f64 *F64Array;
typedef f128 *F128Array;
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 #ifdef WAPP_PLATFORM_CPP
#define wapp_array(ELEM_TYPE, ARRAY_TYPE, ...) ([&]() { \ #define wapp_array(TYPE, ...) ([&]() { \
wapp_persist ELEM_TYPE items[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE{}).items)) ? \ u64 capacity = _calc_array_capacity(TYPE, __VA_ARGS__); \
_calc_array_capacity(ELEM_TYPE, __VA_ARGS__) : -1 \
] = {__VA_ARGS__}; \
\ \
return ARRAY_TYPE{ \ TYPE items[_calc_array_capacity(TYPE, __VA_ARGS__)] = {__VA_ARGS__}; \
WAPP_ARRAY_MAGIC, \
_calc_array_count(ELEM_TYPE, __VA_ARGS__), \
_calc_array_capacity(ELEM_TYPE, __VA_ARGS__), \
sizeof(ELEM_TYPE), \
items, \
}; \
}())
#define wapp_array_with_capacity(ELEM_TYPE, ARRAY_TYPE, CAPACITY) ([&]() { \
wapp_persist ELEM_TYPE items[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE{}).items)) ? \
CAPACITY : -1] = {}; \
\ \
return ARRAY_TYPE{ \ wapp_persist u8 array[ \
WAPP_ARRAY_MAGIC, \ sizeof(ArrayHeader) + _calc_array_capacity(TYPE, __VA_ARGS__) * sizeof(TYPE) \
0, \ ] = {0}; \
CAPACITY, \ ArrayHeader *header = (ArrayHeader *)array; \
sizeof(ELEM_TYPE), \ header->magic = WAPP_ARRAY_MAGIC; \
items, \ header->count = _calc_array_count(TYPE, __VA_ARGS__); \
}; \ header->capacity = _calc_array_capacity(TYPE, __VA_ARGS__); \
header->item_size = sizeof(TYPE); \
\
u8 *buf = (u8 *)(header + 1); \
memcpy(buf, items, capacity * sizeof(TYPE)); \
return (TYPE *)buf; \
}()) }())
#define wapp_array_pop(ELEM_TYPE, ARRAY_PTR) ([&]() { \ #define wapp_array_with_capacity(TYPE, CAPACITY, FLAGS) ([&]() { \
if (ARRAY_PTR == NULL || (ARRAY_PTR)->count == 0) { \ wapp_persist u8 array[ \
ELEM_TYPE result{}; \ sizeof(ArrayHeader) + CAPACITY * sizeof(TYPE) \
] = {0}; \
ArrayHeader *header = (ArrayHeader *)array; \
header->magic = WAPP_ARRAY_MAGIC; \
header->count = (FLAGS & ARRAY_INIT_FILLED) ? CAPACITY : 0; \
header->capacity = CAPACITY; \
header->item_size = sizeof(TYPE); \
\
return (TYPE *)(header + 1); \
}())
#define wapp_array_pop(TYPE, ARRAY) ([&]() { \
if (ARRAY == NULL || _array_count((GenericArray)ARRAY) == 0) { \
TYPE result{}; \
return result; \ return result; \
} \ } \
\ \
return *((ELEM_TYPE *)_array_pop((Array *)ARRAY_PTR, sizeof(ELEM_TYPE))); \ return *((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))); \
}()) }())
#else #else
#define wapp_array(ELEM_TYPE, ARRAY_TYPE, ...) \ #define _stack_array(TYPE, SIZE) struct {ArrayHeader header; \
((ARRAY_TYPE){ \ TYPE items[SIZE]; \
wapp_misc_utils_reserve_padding(sizeof(ArrayHeader) + \
sizeof(TYPE) * SIZE);}
#define wapp_array(TYPE, ...) \
((TYPE *)( \
(_stack_array(TYPE, _calc_array_capacity(TYPE, __VA_ARGS__))){ \
.header = { \
.magic = WAPP_ARRAY_MAGIC, \ .magic = WAPP_ARRAY_MAGIC, \
.count = _calc_array_count(ELEM_TYPE, __VA_ARGS__), \ .count = _calc_array_count(TYPE, __VA_ARGS__), \
.capacity = _calc_array_capacity(ELEM_TYPE, __VA_ARGS__), \ .capacity = _calc_array_capacity(TYPE, __VA_ARGS__), \
.item_size = sizeof(ELEM_TYPE), \ .item_size = sizeof(TYPE), \
.items = (ELEM_TYPE[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE){0}.items)) ? \ }, \
_calc_array_capacity(ELEM_TYPE, __VA_ARGS__) : \ .items = {__VA_ARGS__}, \
-1]){__VA_ARGS__} \ }.items \
}) ))
#define wapp_array_with_capacity(ELEM_TYPE, ARRAY_TYPE, CAPACITY) \ #define wapp_array_with_capacity(TYPE, CAPACITY, FLAGS) \
((ARRAY_TYPE){ \ ((TYPE *)( \
(_stack_array(TYPE, CAPACITY)){ \
.header = { \
.magic = WAPP_ARRAY_MAGIC, \ .magic = WAPP_ARRAY_MAGIC, \
.count = 0, \ .count = (FLAGS & ARRAY_INIT_FILLED) ? CAPACITY : 0, \
.capacity = CAPACITY, \ .capacity = CAPACITY, \
.item_size = sizeof(ELEM_TYPE), \ .item_size = sizeof(TYPE), \
.items = (ELEM_TYPE[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE){0}.items)) ? \ }, \
CAPACITY : -1]){0} \ .items = {0}, \
}) }.items \
#define wapp_array_pop(ELEM_TYPE, ARRAY_PTR) \ ))
(ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ #define wapp_array_pop(TYPE, ARRAY) \
*((ELEM_TYPE *)_array_pop((Array *)ARRAY_PTR, sizeof(ELEM_TYPE))) : \ (ARRAY == NULL || _array_count((GenericArray)ARRAY) == 0 ? \
(ELEM_TYPE){0} \ (TYPE){0} : \
*((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))) \
) )
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define wapp_array_get(ELEM_TYPE, ARRAY_PTR, INDEX) \ #define wapp_array_count(ARRAY) \
((ELEM_TYPE *)_array_get((Array *)ARRAY_PTR, INDEX, sizeof(ELEM_TYPE))) (_array_count((GenericArray)ARRAY))
#define wapp_array_set(ELEM_TYPE, ARRAY_PTR, INDEX, VALUE_PTR) \ #define wapp_array_capacity(ARRAY) \
_array_set((Array *)ARRAY_PTR, INDEX, (void *)VALUE_PTR, sizeof(ELEM_TYPE)) (_array_capacity((GenericArray)ARRAY))
#define wapp_array_append_capped(ELEM_TYPE, ARRAY_PTR, VALUE_PTR) \ #define wapp_array_item_size(ARRAY) \
_array_append_capped((Array *)ARRAY_PTR, (void *)VALUE_PTR, sizeof(ELEM_TYPE)) (_array_item_size((GenericArray)ARRAY))
#define wapp_array_extend_capped(ELEM_TYPE, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ #define wapp_array_set_count(ARRAY, COUNT) \
_array_extend_capped((Array *)DST_ARRAY_PTR, (Array *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE)) (_array_set_count((GenericArray)ARRAY, COUNT))
#define wapp_array_copy_capped(ELEM_TYPE, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ #define wapp_array_get(TYPE, ARRAY, INDEX) \
_array_copy_capped((Array *)DST_ARRAY_PTR, (Array *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE)) ((TYPE *)_array_get((GenericArray)ARRAY, \
#define wapp_array_append_alloc(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, ARRAY_PTR, VALUE_PTR) \ INDEX, \
(ARRAY_TYPE *)_array_append_alloc(ALLOCATOR_PTR, (Array *)ARRAY_PTR, (void *)VALUE_PTR, sizeof(ELEM_TYPE)) sizeof(TYPE)))
#define wapp_array_extend_alloc(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ #define wapp_array_set(TYPE, ARRAY, INDEX, VALUE_PTR) \
(ARRAY_TYPE *)_array_extend_alloc(ALLOCATOR_PTR, (Array *)DST_ARRAY_PTR, (Array *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE)) (_array_set((GenericArray)ARRAY, \
#define wapp_array_copy_alloc(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ INDEX, \
(ARRAY_TYPE *)_array_copy_alloc(ALLOCATOR_PTR, (Array *)DST_ARRAY_PTR, (Array *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE)) (u8 *)VALUE_PTR, \
#define wapp_array_clear(ELEM_TYPE, ARRAY_PTR) \ sizeof(TYPE)))
_array_clear((Array *)ARRAY_PTR, sizeof(ELEM_TYPE)) #define wapp_array_append_capped(TYPE, ARRAY, VALUE_PTR) \
(_array_append_capped((GenericArray)ARRAY, \
(u8 *)VALUE_PTR, \
sizeof(TYPE)))
#define wapp_array_extend_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
(_array_extend_capped((GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE)))
#define wapp_array_copy_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
(_array_copy_capped((GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
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, \
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, \
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, \
FLAGS, \
sizeof(TYPE)))
#define wapp_array_clear(TYPE, ARRAY) \
(_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)))
WAPP_DEF_ARRAY_TYPE(void, Array);
void *_array_get(Array *array, u64 index, u64 item_size); typedef struct header ArrayHeader;
void _array_set(Array *array, u64 index, void *value, u64 item_size); struct header {
void _array_append_capped(Array *array, void *value, u64 item_size); u64 magic;
void _array_extend_capped(Array *dst, const Array *src, u64 item_size); u64 count;
void _array_copy_capped(Array *dst, const Array *src, u64 item_size); u64 capacity;
Array *_array_append_alloc(const Allocator *allocator, Array *array, void *value, u64 item_size); u64 item_size;
Array *_array_extend_alloc(const Allocator *allocator, Array *dst, const Array *src, u64 item_size); };
Array *_array_copy_alloc(const Allocator *allocator, Array *dst, const Array *src, u64 item_size);
void *_array_pop(Array *array, u64 item_size);
void _array_clear(Array *array, u64 item_size);
Array *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size);
// Base array types u64 _array_count(GenericArray array);
typedef struct str8 Str8; u64 _array_capacity(GenericArray array);
u64 _array_item_size(GenericArray array);
WAPP_DEF_ARRAY_TYPE(void *, VoidPtrArray); void _array_set_count(GenericArray array, u64 count);
WAPP_DEF_ARRAY_TYPE(c8 , C8Array); void *_array_get(GenericArray array, u64 index, u64 item_size);
WAPP_DEF_ARRAY_TYPE(c16 , C16Array); void _array_set(GenericArray array, u64 index, void *value, u64 item_size);
WAPP_DEF_ARRAY_TYPE(c32 , C32Array); void _array_append_capped(GenericArray array, void *value, u64 item_size);
WAPP_DEF_ARRAY_TYPE(u8 , U8Array); void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_size);
WAPP_DEF_ARRAY_TYPE(u16 , U16Array); void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size);
WAPP_DEF_ARRAY_TYPE(u32 , U32Array); GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value,
WAPP_DEF_ARRAY_TYPE(u64 , U64Array); ArrayInitFlags flags, u64 item_size);
WAPP_DEF_ARRAY_TYPE(b8 , B8Array); GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
WAPP_DEF_ARRAY_TYPE(i8 , I8Array); ArrayInitFlags flags, u64 item_size);
WAPP_DEF_ARRAY_TYPE(i16 , I16Array); GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
WAPP_DEF_ARRAY_TYPE(i32 , I32Array); ArrayInitFlags flags, u64 item_size);
WAPP_DEF_ARRAY_TYPE(i64 , I64Array); void *_array_pop(GenericArray array, u64 item_size);
WAPP_DEF_ARRAY_TYPE(f32 , F32Array); void _array_clear(GenericArray array, u64 item_size);
WAPP_DEF_ARRAY_TYPE(f64 , F64Array); u64 _array_calc_alloc_size(u64 capacity, u64 item_size);
WAPP_DEF_ARRAY_TYPE(f128 , F128Array); GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, ArrayInitFlags flags,
WAPP_DEF_ARRAY_TYPE(uptr , UptrArray); u64 item_size);
WAPP_DEF_ARRAY_TYPE(iptr , IptrArray); GenericArray _array_from_preallocated_buffer(void *buffer, u64 buffer_size, ArrayInitFlags flags,
WAPP_DEF_ARRAY_TYPE(Str8 , Str8Array); u64 item_size);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,9 @@
/** // vim:fileencoding=utf-8:foldmethod=marker
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN.
*/
#ifndef DBL_LIST_H #ifndef DBL_LIST_H
#define DBL_LIST_H #define DBL_LIST_H
#include "../mem/allocator/mem_allocator.h"
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h" #include "../../common/platform/platform.h"
@@ -12,506 +11,171 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP #define WAPP_DBL_LIST_MAGIC (u64)0x57415f444c5354
#define wapp_void_ptr_list_node(ITEM_PTR) VoidPNode{ITEM_PTR, nullptr, nullptr} #define WAPP_DBL_NODE_MAGIC (u64)0x57415f444e44
#define wapp_str8_list_node(ITEM_PTR) Str8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_b8_list_node(ITEM_PTR) B8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_char_list_node(ITEM_PTR) CharNode{ITEM_PTR, nullptr, nullptr}
#define wapp_c8_list_node(ITEM_PTR) C8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_c16_list_node(ITEM_PTR) C16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_c32_list_node(ITEM_PTR) C32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i8_list_node(ITEM_PTR) I8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i16_list_node(ITEM_PTR) I16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i32_list_node(ITEM_PTR) I32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i64_list_node(ITEM_PTR) I64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u8_list_node(ITEM_PTR) U8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u16_list_node(ITEM_PTR) U16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u32_list_node(ITEM_PTR) U32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u64_list_node(ITEM_PTR) U64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f32_list_node(ITEM_PTR) F32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f64_list_node(ITEM_PTR) F64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f128_list_node(ITEM_PTR) F128Node{ITEM_PTR, nullptr, nullptr}
#define wapp_iptr_list_node(ITEM_PTR) IptrNode{ITEM_PTR, nullptr, nullptr}
#define wapp_uptr_list_node(ITEM_PTR) UptrNode{ITEM_PTR, nullptr, nullptr}
#else
#define wapp_void_ptr_list_node(ITEM_PTR) ((VoidPNode){.item = ITEM_PTR})
#define wapp_str8_list_node(ITEM_PTR) ((Str8Node){.item = ITEM_PTR})
#define wapp_b8_list_node(ITEM_PTR) ((B8Node){.item = ITEM_PTR})
#define wapp_char_list_node(ITEM_PTR) ((CharNode){.item = ITEM_PTR})
#define wapp_c8_list_node(ITEM_PTR) ((C8Node){.item = ITEM_PTR})
#define wapp_c16_list_node(ITEM_PTR) ((C16Node){.item = ITEM_PTR})
#define wapp_c32_list_node(ITEM_PTR) ((C32Node){.item = ITEM_PTR})
#define wapp_i8_list_node(ITEM_PTR) ((I8Node){.item = ITEM_PTR})
#define wapp_i16_list_node(ITEM_PTR) ((I16Node){.item = ITEM_PTR})
#define wapp_i32_list_node(ITEM_PTR) ((I32Node){.item = ITEM_PTR})
#define wapp_i64_list_node(ITEM_PTR) ((I64Node){.item = ITEM_PTR})
#define wapp_u8_list_node(ITEM_PTR) ((U8Node){.item = ITEM_PTR})
#define wapp_u16_list_node(ITEM_PTR) ((U16Node){.item = ITEM_PTR})
#define wapp_u32_list_node(ITEM_PTR) ((U32Node){.item = ITEM_PTR})
#define wapp_u64_list_node(ITEM_PTR) ((U64Node){.item = ITEM_PTR})
#define wapp_f32_list_node(ITEM_PTR) ((F32Node){.item = ITEM_PTR})
#define wapp_f64_list_node(ITEM_PTR) ((F64Node){.item = ITEM_PTR})
#define wapp_f128_list_node(ITEM_PTR) ((F128Node){.item = ITEM_PTR})
#define wapp_iptr_list_node(ITEM_PTR) ((IptrNode){.item = ITEM_PTR})
#define wapp_uptr_list_node(ITEM_PTR) ((UptrNode){.item = ITEM_PTR})
#endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8;
typedef struct GenericNode GenericNode; typedef struct GenericNode GenericNode;
struct GenericNode {
void *item; typedef struct {
u64 magic;
u64 item_size;
GenericNode *prev; GenericNode *prev;
GenericNode *next; GenericNode *next;
} NodeHeader;
struct GenericNode {
NodeHeader header;
void *item;
}; };
typedef struct GenericList GenericList; typedef struct {
struct GenericList { u64 magic;
u64 node_count;
u64 item_size;
GenericNode *first; GenericNode *first;
GenericNode *last; GenericNode *last;
u64 node_count; } GenericList;
};
typedef struct VoidPNode VoidPNode; // NOTE (Abdelrahman): GenericList typedefs for readability
struct VoidPNode { typedef GenericList VoidPtrList;
void * *item; typedef GenericList C8List;
VoidPNode *prev; typedef GenericList C16List;
VoidPNode *next; 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;
typedef struct VoidPList VoidPList; // NOTE (Abdelrahman): GenericNode typedefs for readability
struct VoidPList { typedef GenericNode VoidPtrNode;
VoidPNode *first; typedef GenericNode C8Node;
VoidPNode *last; typedef GenericNode C16Node;
u64 node_count; 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;
typedef struct Str8Node Str8Node; #ifdef WAPP_PLATFORM_CPP
struct Str8Node { #define wapp_dbl_list(TYPE) \
Str8 *item; GenericList{WAPP_DBL_LIST_MAGIC, 0, sizeof(TYPE), nullptr, nullptr}
Str8Node *prev; #define _dbl_list_node(TYPE, ITEM_PTR) ([&]() { \
Str8Node *next; wapp_persist GenericNode node = { \
}; NodeHeader{WAPP_DBL_NODE_MAGIC, sizeof(TYPE), nullptr, nullptr}, \
ITEM_PTR, \
}; \
\
return &node; \
}())
#else
#define wapp_dbl_list(TYPE) ( \
(GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(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
typedef struct Str8List Str8List; #define wapp_dbl_list_alloc(TYPE, ALLOCATOR) \
struct Str8List { (_dbl_list_alloc(ALLOCATOR, sizeof(TYPE)))
Str8Node *first; #define wapp_dbl_list_get(TYPE, LIST_PTR, ITEM_INDEX) \
Str8Node *last; ((TYPE *)(_dbl_list_get(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item))
u64 node_count; #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)))
typedef struct B8Node B8Node; GenericList *_dbl_list_alloc(const Allocator *allocator, u64 item_size);
struct B8Node { GenericNode *_dbl_list_node_alloc(const Allocator *allocator, void *item, u64 item_size);
b8 *item; GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size);
B8Node *prev; void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size);
B8Node *next; void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size);
}; void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size);
GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size);
typedef struct B8List B8List; GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size);
struct B8List { GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size);
B8Node *first; void _dbl_list_empty(GenericList *list, u64 item_size);
B8Node *last;
u64 node_count;
};
typedef struct CharNode CharNode;
struct CharNode {
char *item;
CharNode *prev;
CharNode *next;
};
typedef struct CharList CharList;
struct CharList {
CharNode *first;
CharNode *last;
u64 node_count;
};
typedef struct C8Node C8Node;
struct C8Node {
c8 *item;
C8Node *prev;
C8Node *next;
};
typedef struct C8List C8List;
struct C8List {
C8Node *first;
C8Node *last;
u64 node_count;
};
typedef struct C16Node C16Node;
struct C16Node {
c16 *item;
C16Node *prev;
C16Node *next;
};
typedef struct C16List C16List;
struct C16List {
C16Node *first;
C16Node *last;
u64 node_count;
};
typedef struct C32Node C32Node;
struct C32Node {
c32 *item;
C32Node *prev;
C32Node *next;
};
typedef struct C32List C32List;
struct C32List {
C32Node *first;
C32Node *last;
u64 node_count;
};
typedef struct I8Node I8Node;
struct I8Node {
i8 *item;
I8Node *prev;
I8Node *next;
};
typedef struct I8List I8List;
struct I8List {
I8Node *first;
I8Node *last;
u64 node_count;
};
typedef struct I16Node I16Node;
struct I16Node {
i16 *item;
I16Node *prev;
I16Node *next;
};
typedef struct I16List I16List;
struct I16List {
I16Node *first;
I16Node *last;
u64 node_count;
};
typedef struct I32Node I32Node;
struct I32Node {
i32 *item;
I32Node *prev;
I32Node *next;
};
typedef struct I32List I32List;
struct I32List {
I32Node *first;
I32Node *last;
u64 node_count;
};
typedef struct I64Node I64Node;
struct I64Node {
i64 *item;
I64Node *prev;
I64Node *next;
};
typedef struct I64List I64List;
struct I64List {
I64Node *first;
I64Node *last;
u64 node_count;
};
typedef struct U8Node U8Node;
struct U8Node {
u8 *item;
U8Node *prev;
U8Node *next;
};
typedef struct U8List U8List;
struct U8List {
U8Node *first;
U8Node *last;
u64 node_count;
};
typedef struct U16Node U16Node;
struct U16Node {
u16 *item;
U16Node *prev;
U16Node *next;
};
typedef struct U16List U16List;
struct U16List {
U16Node *first;
U16Node *last;
u64 node_count;
};
typedef struct U32Node U32Node;
struct U32Node {
u32 *item;
U32Node *prev;
U32Node *next;
};
typedef struct U32List U32List;
struct U32List {
U32Node *first;
U32Node *last;
u64 node_count;
};
typedef struct U64Node U64Node;
struct U64Node {
u64 *item;
U64Node *prev;
U64Node *next;
};
typedef struct U64List U64List;
struct U64List {
U64Node *first;
U64Node *last;
u64 node_count;
};
typedef struct F32Node F32Node;
struct F32Node {
f32 *item;
F32Node *prev;
F32Node *next;
};
typedef struct F32List F32List;
struct F32List {
F32Node *first;
F32Node *last;
u64 node_count;
};
typedef struct F64Node F64Node;
struct F64Node {
f64 *item;
F64Node *prev;
F64Node *next;
};
typedef struct F64List F64List;
struct F64List {
F64Node *first;
F64Node *last;
u64 node_count;
};
typedef struct F128Node F128Node;
struct F128Node {
f128 *item;
F128Node *prev;
F128Node *next;
};
typedef struct F128List F128List;
struct F128List {
F128Node *first;
F128Node *last;
u64 node_count;
};
typedef struct IptrNode IptrNode;
struct IptrNode {
iptr *item;
IptrNode *prev;
IptrNode *next;
};
typedef struct IptrList IptrList;
struct IptrList {
IptrNode *first;
IptrNode *last;
u64 node_count;
};
typedef struct UptrNode UptrNode;
struct UptrNode {
uptr *item;
UptrNode *prev;
UptrNode *next;
};
typedef struct UptrList UptrList;
struct UptrList {
UptrNode *first;
UptrNode *last;
u64 node_count;
};
VoidPNode *wapp_void_ptr_list_get(const VoidPList *list, u64 index);
void wapp_void_ptr_list_push_front(VoidPList *list, VoidPNode *node);
void wapp_void_ptr_list_push_back(VoidPList *list, VoidPNode *node);
void wapp_void_ptr_list_insert(VoidPList *list, VoidPNode *node, u64 index);
VoidPNode *wapp_void_ptr_list_pop_front(VoidPList *list);
VoidPNode *wapp_void_ptr_list_pop_back(VoidPList *list);
VoidPNode *wapp_void_ptr_list_remove(VoidPList *list, u64 index);
void wapp_void_ptr_list_empty(VoidPList *list);
Str8Node *wapp_str8_list_get(const Str8List *list, u64 index);
void wapp_str8_list_push_front(Str8List *list, Str8Node *node);
void wapp_str8_list_push_back(Str8List *list, Str8Node *node);
void wapp_str8_list_insert(Str8List *list, Str8Node *node, u64 index);
Str8Node *wapp_str8_list_pop_front(Str8List *list);
Str8Node *wapp_str8_list_pop_back(Str8List *list);
Str8Node *wapp_str8_list_remove(Str8List *list, u64 index);
void wapp_str8_list_empty(Str8List *list);
B8Node *wapp_b8_list_get(const B8List *list, u64 index);
void wapp_b8_list_push_front(B8List *list, B8Node *node);
void wapp_b8_list_push_back(B8List *list, B8Node *node);
void wapp_b8_list_insert(B8List *list, B8Node *node, u64 index);
B8Node *wapp_b8_list_pop_front(B8List *list);
B8Node *wapp_b8_list_pop_back(B8List *list);
B8Node *wapp_b8_list_remove(B8List *list, u64 index);
void wapp_b8_list_empty(B8List *list);
CharNode *wapp_char_list_get(const CharList *list, u64 index);
void wapp_char_list_push_front(CharList *list, CharNode *node);
void wapp_char_list_push_back(CharList *list, CharNode *node);
void wapp_char_list_insert(CharList *list, CharNode *node, u64 index);
CharNode *wapp_char_list_pop_front(CharList *list);
CharNode *wapp_char_list_pop_back(CharList *list);
CharNode *wapp_char_list_remove(CharList *list, u64 index);
void wapp_char_list_empty(CharList *list);
C8Node *wapp_c8_list_get(const C8List *list, u64 index);
void wapp_c8_list_push_front(C8List *list, C8Node *node);
void wapp_c8_list_push_back(C8List *list, C8Node *node);
void wapp_c8_list_insert(C8List *list, C8Node *node, u64 index);
C8Node *wapp_c8_list_pop_front(C8List *list);
C8Node *wapp_c8_list_pop_back(C8List *list);
C8Node *wapp_c8_list_remove(C8List *list, u64 index);
void wapp_c8_list_empty(C8List *list);
C16Node *wapp_c16_list_get(const C16List *list, u64 index);
void wapp_c16_list_push_front(C16List *list, C16Node *node);
void wapp_c16_list_push_back(C16List *list, C16Node *node);
void wapp_c16_list_insert(C16List *list, C16Node *node, u64 index);
C16Node *wapp_c16_list_pop_front(C16List *list);
C16Node *wapp_c16_list_pop_back(C16List *list);
C16Node *wapp_c16_list_remove(C16List *list, u64 index);
void wapp_c16_list_empty(C16List *list);
C32Node *wapp_c32_list_get(const C32List *list, u64 index);
void wapp_c32_list_push_front(C32List *list, C32Node *node);
void wapp_c32_list_push_back(C32List *list, C32Node *node);
void wapp_c32_list_insert(C32List *list, C32Node *node, u64 index);
C32Node *wapp_c32_list_pop_front(C32List *list);
C32Node *wapp_c32_list_pop_back(C32List *list);
C32Node *wapp_c32_list_remove(C32List *list, u64 index);
void wapp_c32_list_empty(C32List *list);
I8Node *wapp_i8_list_get(const I8List *list, u64 index);
void wapp_i8_list_push_front(I8List *list, I8Node *node);
void wapp_i8_list_push_back(I8List *list, I8Node *node);
void wapp_i8_list_insert(I8List *list, I8Node *node, u64 index);
I8Node *wapp_i8_list_pop_front(I8List *list);
I8Node *wapp_i8_list_pop_back(I8List *list);
I8Node *wapp_i8_list_remove(I8List *list, u64 index);
void wapp_i8_list_empty(I8List *list);
I16Node *wapp_i16_list_get(const I16List *list, u64 index);
void wapp_i16_list_push_front(I16List *list, I16Node *node);
void wapp_i16_list_push_back(I16List *list, I16Node *node);
void wapp_i16_list_insert(I16List *list, I16Node *node, u64 index);
I16Node *wapp_i16_list_pop_front(I16List *list);
I16Node *wapp_i16_list_pop_back(I16List *list);
I16Node *wapp_i16_list_remove(I16List *list, u64 index);
void wapp_i16_list_empty(I16List *list);
I32Node *wapp_i32_list_get(const I32List *list, u64 index);
void wapp_i32_list_push_front(I32List *list, I32Node *node);
void wapp_i32_list_push_back(I32List *list, I32Node *node);
void wapp_i32_list_insert(I32List *list, I32Node *node, u64 index);
I32Node *wapp_i32_list_pop_front(I32List *list);
I32Node *wapp_i32_list_pop_back(I32List *list);
I32Node *wapp_i32_list_remove(I32List *list, u64 index);
void wapp_i32_list_empty(I32List *list);
I64Node *wapp_i64_list_get(const I64List *list, u64 index);
void wapp_i64_list_push_front(I64List *list, I64Node *node);
void wapp_i64_list_push_back(I64List *list, I64Node *node);
void wapp_i64_list_insert(I64List *list, I64Node *node, u64 index);
I64Node *wapp_i64_list_pop_front(I64List *list);
I64Node *wapp_i64_list_pop_back(I64List *list);
I64Node *wapp_i64_list_remove(I64List *list, u64 index);
void wapp_i64_list_empty(I64List *list);
U8Node *wapp_u8_list_get(const U8List *list, u64 index);
void wapp_u8_list_push_front(U8List *list, U8Node *node);
void wapp_u8_list_push_back(U8List *list, U8Node *node);
void wapp_u8_list_insert(U8List *list, U8Node *node, u64 index);
U8Node *wapp_u8_list_pop_front(U8List *list);
U8Node *wapp_u8_list_pop_back(U8List *list);
U8Node *wapp_u8_list_remove(U8List *list, u64 index);
void wapp_u8_list_empty(U8List *list);
U16Node *wapp_u16_list_get(const U16List *list, u64 index);
void wapp_u16_list_push_front(U16List *list, U16Node *node);
void wapp_u16_list_push_back(U16List *list, U16Node *node);
void wapp_u16_list_insert(U16List *list, U16Node *node, u64 index);
U16Node *wapp_u16_list_pop_front(U16List *list);
U16Node *wapp_u16_list_pop_back(U16List *list);
U16Node *wapp_u16_list_remove(U16List *list, u64 index);
void wapp_u16_list_empty(U16List *list);
U32Node *wapp_u32_list_get(const U32List *list, u64 index);
void wapp_u32_list_push_front(U32List *list, U32Node *node);
void wapp_u32_list_push_back(U32List *list, U32Node *node);
void wapp_u32_list_insert(U32List *list, U32Node *node, u64 index);
U32Node *wapp_u32_list_pop_front(U32List *list);
U32Node *wapp_u32_list_pop_back(U32List *list);
U32Node *wapp_u32_list_remove(U32List *list, u64 index);
void wapp_u32_list_empty(U32List *list);
U64Node *wapp_u64_list_get(const U64List *list, u64 index);
void wapp_u64_list_push_front(U64List *list, U64Node *node);
void wapp_u64_list_push_back(U64List *list, U64Node *node);
void wapp_u64_list_insert(U64List *list, U64Node *node, u64 index);
U64Node *wapp_u64_list_pop_front(U64List *list);
U64Node *wapp_u64_list_pop_back(U64List *list);
U64Node *wapp_u64_list_remove(U64List *list, u64 index);
void wapp_u64_list_empty(U64List *list);
F32Node *wapp_f32_list_get(const F32List *list, u64 index);
void wapp_f32_list_push_front(F32List *list, F32Node *node);
void wapp_f32_list_push_back(F32List *list, F32Node *node);
void wapp_f32_list_insert(F32List *list, F32Node *node, u64 index);
F32Node *wapp_f32_list_pop_front(F32List *list);
F32Node *wapp_f32_list_pop_back(F32List *list);
F32Node *wapp_f32_list_remove(F32List *list, u64 index);
void wapp_f32_list_empty(F32List *list);
F64Node *wapp_f64_list_get(const F64List *list, u64 index);
void wapp_f64_list_push_front(F64List *list, F64Node *node);
void wapp_f64_list_push_back(F64List *list, F64Node *node);
void wapp_f64_list_insert(F64List *list, F64Node *node, u64 index);
F64Node *wapp_f64_list_pop_front(F64List *list);
F64Node *wapp_f64_list_pop_back(F64List *list);
F64Node *wapp_f64_list_remove(F64List *list, u64 index);
void wapp_f64_list_empty(F64List *list);
F128Node *wapp_f128_list_get(const F128List *list, u64 index);
void wapp_f128_list_push_front(F128List *list, F128Node *node);
void wapp_f128_list_push_back(F128List *list, F128Node *node);
void wapp_f128_list_insert(F128List *list, F128Node *node, u64 index);
F128Node *wapp_f128_list_pop_front(F128List *list);
F128Node *wapp_f128_list_pop_back(F128List *list);
F128Node *wapp_f128_list_remove(F128List *list, u64 index);
void wapp_f128_list_empty(F128List *list);
IptrNode *wapp_iptr_list_get(const IptrList *list, u64 index);
void wapp_iptr_list_push_front(IptrList *list, IptrNode *node);
void wapp_iptr_list_push_back(IptrList *list, IptrNode *node);
void wapp_iptr_list_insert(IptrList *list, IptrNode *node, u64 index);
IptrNode *wapp_iptr_list_pop_front(IptrList *list);
IptrNode *wapp_iptr_list_pop_back(IptrList *list);
IptrNode *wapp_iptr_list_remove(IptrList *list, u64 index);
void wapp_iptr_list_empty(IptrList *list);
UptrNode *wapp_uptr_list_get(const UptrList *list, u64 index);
void wapp_uptr_list_push_front(UptrList *list, UptrNode *node);
void wapp_uptr_list_push_back(UptrList *list, UptrNode *node);
void wapp_uptr_list_insert(UptrList *list, UptrNode *node, u64 index);
UptrNode *wapp_uptr_list_pop_front(UptrList *list);
UptrNode *wapp_uptr_list_pop_back(UptrList *list);
UptrNode *wapp_uptr_list_remove(UptrList *list, u64 index);
void wapp_uptr_list_empty(UptrList *list);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -17,8 +17,8 @@ typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *allo
typedef void *(MemReallocAlignedFunc)(void *ptr, u64 old_size, u64 new_size, u64 alignment, void *alloc_obj); typedef void *(MemReallocAlignedFunc)(void *ptr, u64 old_size, u64 new_size, u64 alignment, void *alloc_obj);
typedef void (MemFreeFunc)(void **ptr, u64 size, void *alloc_obj); typedef void (MemFreeFunc)(void **ptr, u64 size, void *alloc_obj);
typedef struct allocator Allocator; typedef struct Allocator Allocator;
struct allocator { struct Allocator {
void *obj; void *obj;
MemAllocFunc *alloc; MemAllocFunc *alloc;
MemAllocAlignedFunc *alloc_aligned; MemAllocAlignedFunc *alloc_aligned;

View File

@@ -3,13 +3,12 @@
#include "mem_utils.h" #include "mem_utils.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include <stddef.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) { void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
wapp_debug_assert(ptr != NULL, "`ptr` should not be NULL"); 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 p = (uptr)ptr;
uptr align = (uptr)alignment; 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

@@ -275,15 +275,15 @@ void wapp_str8_to_upper(Str8 *dst, Str8RO *src) {
} }
} }
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src) { void wapp_str8_from_bytes(Str8 *dst, const U8Array src) {
wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL"); wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL");
u64 size = src->count * src->item_size; u64 size = wapp_array_count(src) * wapp_array_item_size(src);
wapp_debug_assert(dst->capacity >= size, "`dst` does not have enough capacity"); wapp_debug_assert(dst->capacity >= size, "`dst` does not have enough capacity");
dst->size = size; dst->size = size;
memcpy(dst->buf, src->items, size); memcpy(dst->buf, src, size);
} }
i64 wapp_str8_find(Str8RO *str, Str8RO substr) { i64 wapp_str8_find(Str8RO *str, Str8RO substr) {
@@ -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) { 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"); wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List)); Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
if (delimiter->size > str->size) { if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str); Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); if (full) {
if (node) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
node->item = full;
wapp_str8_list_push_back(output, node);
} }
goto RETURN_STR8_SPLIT; 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); before_str = wapp_str8_alloc_substr(allocator, str, start, start + end);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); if (before_str) {
if (node && before_str) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, before_str);
node->item = before_str;
wapp_str8_list_push_back(output, node);
} }
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8)); 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 // Ensure the last part of the string after the delimiter is added to the list
rest = wapp_str8_alloc_substr(allocator, str, start, str->size); rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); if (rest) {
if (node && rest) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, rest);
node->item = rest;
wapp_str8_list_push_back(output, node);
} }
RETURN_STR8_SPLIT: 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) { 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"); wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List)); Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
if (delimiter->size > str->size) { if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str); Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); if (full) {
if (node && full) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
node->item = full;
wapp_str8_list_push_back(output, node);
} }
goto RETURN_STR8_SPLIT; 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); after_str = wapp_str8_alloc_substr(allocator, rest, end + delimiter->size, str->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); if (after_str) {
if (node) { wapp_dbl_list_push_front_alloc(Str8, allocator, output, after_str);
node->item = after_str;
wapp_str8_list_push_front(output, node);
} }
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8)); 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); rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node)); if (rest) {
if (node && rest) { wapp_dbl_list_push_front_alloc(Str8, allocator, output, rest);
node->item = rest;
wapp_str8_list_push_front(output, node);
} }
RETURN_STR8_SPLIT: 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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
Str8Node *node; Str8 *node;
u64 node_index = 0; u64 node_index = 0;
b8 running = node_index < list->node_count; b8 running = node_index < list->node_count;
while (running) { while (running) {
node = wapp_str8_list_get(list, node_index); node = wapp_dbl_list_get(Str8, list, node_index);
if (!node) { if (!node) {
break; break;
} }
wapp_str8_concat_capped(output, node->item); wapp_str8_concat_capped(output, node);
// NOTE (Abdelrahman): Comparison extracted to variable to silence // NOTE (Abdelrahman): Comparison extracted to variable to silence
// MSVC Spectre mitigation warnings // 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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
Str8Node* node; Str8 *node;
u64 node_index = 0; u64 node_index = 0;
u64 output = 0; u64 output = 0;
b8 running = node_index < list->node_count; b8 running = node_index < list->node_count;
while (running) { while (running) {
node = wapp_str8_list_get(list, node_index); node = wapp_dbl_list_get(Str8, list, node_index);
if (!node) { if (!node) {
break; break;
} }
output += node->item->size; output += node->size;
++node_index; ++node_index;
running = node_index < list->node_count; running = node_index < list->node_count;
} }

View File

@@ -15,8 +15,8 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8; typedef struct Str8 Str8;
struct str8 { struct Str8 {
u64 capacity; u64 capacity;
u64 size; u64 size;
c8 *buf; c8 *buf;
@@ -58,7 +58,9 @@ typedef const Str8 Str8RO;
// address of compound literals is valid in C to create a string on the stack // address of compound literals is valid in C to create a string on the stack
#define wapp_str8_lit(STRING) ((Str8){.capacity = (sizeof(STRING) - 1) * 2, \ #define wapp_str8_lit(STRING) ((Str8){.capacity = (sizeof(STRING) - 1) * 2, \
.size = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \
.buf = memcpy(&((c8 [sizeof(STRING) * 2]){0}), STRING, sizeof(STRING))}) .buf = memcpy(&((c8 [sizeof(STRING) * 2]){0}), \
STRING, \
sizeof(STRING))})
#define wapp_str8_lit_ro(STRING) ((Str8RO){.capacity = sizeof(STRING) - 1, \ #define wapp_str8_lit_ro(STRING) ((Str8RO){.capacity = sizeof(STRING) - 1, \
.size = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \
.buf = (c8 *)STRING}) .buf = (c8 *)STRING})
@@ -99,7 +101,7 @@ void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity);
void wapp_str8_format(Str8 *dst, const char *format, ...); void wapp_str8_format(Str8 *dst, const char *format, ...);
void wapp_str8_to_lower(Str8 *dst, Str8RO *src); void wapp_str8_to_lower(Str8 *dst, Str8RO *src);
void wapp_str8_to_upper(Str8 *dst, Str8RO *src); void wapp_str8_to_upper(Str8 *dst, Str8RO *src);
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src); void wapp_str8_from_bytes(Str8 *dst, const U8Array src);
/** /**
* Str8 find functions * Str8 find functions
@@ -119,19 +121,6 @@ Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8R
/** /**
* Str8 list utilities * Str8 list utilities
*/ */
#ifdef WAPP_PLATFORM_CPP
#define wapp_str8_node_from_cstr(STRING) wapp_str8_list_node([&]() { \
wapp_persist Str8 str = wapp_str8_lit(STRING); \
return &str; \
}())
#define wapp_str8_node_from_str8(STRING) wapp_str8_list_node([&]() { \
wapp_persist Str8 str = STRING; \
return &str; \
}())
#else
#define wapp_str8_node_from_cstr(STRING) wapp_str8_list_node(&wapp_str8_lit(STRING))
#define wapp_str8_node_from_str8(STRING) wapp_str8_list_node(&(STRING))
#endif // !WAPP_PLATFORM_CPP
u64 wapp_str8_list_total_size(const Str8List *list); u64 wapp_str8_list_total_size(const Str8List *list);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP

View File

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

View File

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

View File

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

View File

@@ -9,12 +9,21 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define KB(SIZE) (SIZE * 1024ull) #define KiB(SIZE) (((u64)SIZE) << 10)
#define MB(SIZE) (KB(SIZE) * 1024) #define MiB(SIZE) (((u64)SIZE) << 20)
#define GB(SIZE) (MB(SIZE) * 1024) #define GiB(SIZE) (((u64)SIZE) << 30)
#define TB(SIZE) (GB(SIZE) * 1024) #define TiB(SIZE) (((u64)SIZE) << 40)
#define PiB(SIZE) (((u64)SIZE) << 50)
#define EiB(SIZE) (((u64)SIZE) << 60)
#define wapp_misc_utils_padding_size(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))] #define KB(SIZE) (((u64)SIZE) * 1000llu)
#define MB(SIZE) (KB(SIZE) * 1000llu)
#define GB(SIZE) (MB(SIZE) * 1000llu)
#define TB(SIZE) (GB(SIZE) * 1000llu)
#define PB(SIZE) (TB(SIZE) * 1000llu)
#define EB(SIZE) (PB(SIZE) * 1000llu)
#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_1(X) (((u64)X) | (((u64)X) >> 1))
#define U64_RSHIFT_OR_2(X) (((u64)X) | (((u64)X) >> 2)) #define U64_RSHIFT_OR_2(X) (((u64)X) | (((u64)X) >> 2))
@@ -38,6 +47,9 @@ BEGIN_C_LINKAGE
) + 1 \ ) + 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 #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -6,7 +6,6 @@
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h" #include "../../../common/misc/misc_utils.h"
#include "../../../base/mem/utils/mem_utils.h" #include "../../../base/mem/utils/mem_utils.h"
#include <stdlib.h>
#include <string.h> #include <string.h>
#ifndef DEFAULT_ALIGNMENT #ifndef DEFAULT_ALIGNMENT
@@ -15,47 +14,72 @@
#define DEFAULT_ALIGNMENT (2 * sizeof(void *)) #define DEFAULT_ALIGNMENT (2 * sizeof(void *))
#endif /* ifndef DEFAULT_ALIGNMENT */ #endif /* ifndef DEFAULT_ALIGNMENT */
#define ARENA_MINIMUM_CAPACITY KB(16) // Allocate minimum of 4 pages #define ARENA_MINIMUM_CAPACITY KiB(16) // Allocate minimum of 4 pages
struct arena { typedef enum {
ARENA_STORAGE_TYPE_ALLOCATED,
ARENA_STORAGE_TYPE_BUFFER,
} ArenaStorageType;
struct Arena {
u8 *buf; u8 *buf;
u8 *offset; u8 *offset;
u8 *prev_offset;
u64 capacity; u64 capacity;
ArenaStorageType type;
b8 committed; b8 committed;
#ifdef WAPP_PLATFORM_WINDOWS wapp_misc_utils_reserve_padding(sizeof(u8 *) * 3 + sizeof(u64) + sizeof(ArenaStorageType) + sizeof(b8));
wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(b8));
#endif // ifdef WAPP_PLATFORM_WINDOWS
}; };
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) { if (!arena || *arena || base_capacity == 0) {
return false; return false;
} }
*arena = (Arena *)calloc(1, sizeof(Arena)); u64 size = sizeof(Arena) + (base_capacity >= ARENA_MINIMUM_CAPACITY ? base_capacity : ARENA_MINIMUM_CAPACITY);
Arena *arena_ptr = *arena; u64 alloc_size = wapp_misc_utils_u64_round_up_pow2(size);
if (!arena_ptr) { 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; return false;
} }
u64 arena_capacity = wapp_misc_utils_u64_round_up_pow2( b8 committed = (flags & WAPP_MEM_ALLOC_COMMIT) == WAPP_MEM_ALLOC_COMMIT;
base_capacity >= ARENA_MINIMUM_CAPACITY ?
base_capacity :
ARENA_MINIMUM_CAPACITY
);
arena_ptr->buf = (u8 *)wapp_mem_util_alloc(NULL, arena_capacity, WAPP_MEM_ACCESS_READ_WRITE, flags, #ifdef WAPP_PLATFORM_WINDOWS
zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED); 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); wapp_mem_arena_destroy(arena);
return false; return false;
} }
arena_ptr->capacity = arena_capacity; Arena *arena_ptr = *arena;
arena_ptr->offset = arena_ptr->buf; arena_ptr->type = ARENA_STORAGE_TYPE_ALLOCATED;
arena_ptr->committed = (flags & WAPP_MEM_ALLOC_COMMIT) == WAPP_MEM_ALLOC_COMMIT; arena_ptr->committed = committed;
return true; return true;
} }
@@ -77,8 +101,8 @@ void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
arena->offset = output + size; arena->offset = output + size;
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
if (!(arena->committed)) { if (arena->type == ARENA_STORAGE_TYPE_ALLOCATED && !(arena->committed)) {
wapp_mem_util_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start), wapp_os_mem_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start),
WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT, WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_UNINITIALISED); 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) { 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 || if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) { arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL; 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) { 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 || if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) { arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL; return NULL;
@@ -123,6 +151,27 @@ void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64
return new_ptr; 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) { void wapp_mem_arena_clear(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL"); 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"); wapp_debug_assert(arena != NULL && (*arena) != NULL, "`arena` double pointer is not valid");
Arena *arena_ptr = *arena; Arena *arena_ptr = *arena;
if (arena_ptr->buf) {
wapp_mem_util_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; *arena = NULL;
} }

View File

@@ -11,27 +11,30 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef struct arena Arena; typedef struct Arena Arena;
#define wapp_mem_arena_init(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, false)) (wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
#define wapp_mem_arena_init_commit(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated_commit(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false)) (wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false))
#define wapp_mem_arena_init_zero(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, true)) (wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, true))
#define wapp_mem_arena_init_commit_and_zero(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated_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)) (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 * control over how the Arena is initialised. Wrapper macros are provided for
* easier use. * 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(Arena *arena, u64 size);
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment); void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size); void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size);
void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment); 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_clear(Arena *arena);
void wapp_mem_arena_destroy(Arena **arena); void wapp_mem_arena_destroy(Arena **arena);

View File

@@ -4,55 +4,83 @@
#include "mem_arena.h" #include "mem_arena.h"
#include "../../mem/mem_os.h" #include "../../mem/mem_os.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
wapp_intern inline void *mem_arena_alloc(u64 size, void *alloc_obj); wapp_intern void initialise_arena_allocator(Allocator *allocator);
wapp_intern inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj); wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj);
wapp_intern inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); wapp_intern void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj);
wapp_intern inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, 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); void *alloc_obj);
Allocator wapp_mem_arena_allocator_init_with_buffer(u8 *buffer, u64 buffer_size) {
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
Allocator allocator = {0}; 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) { if (!initialised) {
return allocator; return allocator;
} }
allocator.alloc = mem_arena_alloc; initialise_arena_allocator(&allocator);
allocator.alloc_aligned = mem_arena_alloc_aligned;
allocator.realloc = mem_arena_realloc;
allocator.realloc_aligned = mem_arena_realloc_aligned;
return 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) { 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)); wapp_mem_arena_clear((Arena *)(allocator->obj));
} }
void wapp_mem_arena_allocator_destroy(Allocator *allocator) { 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))); wapp_mem_arena_destroy((Arena **)(&(allocator->obj)));
*allocator = (Allocator){0}; *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 inline void *mem_arena_alloc(u64 size, void *alloc_obj) { wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_alloc(arena, size); return wapp_mem_arena_alloc(arena, size);
} }
wapp_intern inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj) { wapp_intern void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_alloc_aligned(arena, size, alignment); return wapp_mem_arena_alloc_aligned(arena, size, alignment);
} }
wapp_intern inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj) { wapp_intern void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_realloc(arena, ptr, old_size, new_size); return wapp_mem_arena_realloc(arena, ptr, old_size, new_size);
} }
wapp_intern inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, wapp_intern void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj) { void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment); return wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment);

View File

@@ -33,6 +33,9 @@ BEGIN_C_LINKAGE
* the Arena is initialised. Wrapper macros are provided for easier use. * the Arena is initialised. Wrapper macros are provided for easier use.
*/ */
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer); 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_clear(Allocator *allocator);
void wapp_mem_arena_allocator_destroy(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 // Handle first node
const Str8Node *first_node = wapp_str8_list_get(parts, 0); Str8 *first_node = wapp_dbl_list_get(Str8, parts, 0);
wapp_str8_copy_str8_capped(dst, first_node->item); wapp_str8_copy_str8_capped(dst, first_node);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
const Str8Node *node = first_node; Str8 *node = first_node;
u64 node_index = 1; u64 node_index = 1;
b8 running = node_index < parts->node_count; b8 running = node_index < parts->node_count;
while (running && node->next) { while (running) {
node = node->next; node = wapp_dbl_list_get(Str8, parts, node_index);
if (node->item->size == 0) { if (node->size == 0) {
continue; goto CPATH_JOIN_LOOP_END;
} }
if (dst->size > 0) { if (dst->size > 0) {
char dst_last = wapp_str8_get(dst, dst->size - 1); char dst_last = wapp_str8_get(dst, dst->size - 1);
char node_start = wapp_str8_get(node->item, 0); char node_start = wapp_str8_get(node, 0);
b8 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP; b8 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP;
if (add_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; ++node_index;
running = node_index < parts->node_count; running = node_index < parts->node_count;
} }
@@ -87,7 +88,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
goto RETURN_DIRUP; goto RETURN_DIRUP;
} }
Allocator tmp_arena = wapp_mem_arena_allocator_init(MB(8)); Allocator tmp_arena = wapp_mem_arena_allocator_init(MiB(8));
if (wapp_mem_allocator_invalid(&tmp_arena)) { if (wapp_mem_allocator_invalid(&tmp_arena)) {
goto RETURN_DIRUP; goto RETURN_DIRUP;
} }
@@ -106,7 +107,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.'); wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
} else { } else {
for (u64 i = 0; i < levels; ++i) { for (u64 i = 0; i < levels; ++i) {
wapp_str8_list_pop_back(parts); wapp_dbl_list_pop_back(Str8, parts);
} }
u64 alignment = sizeof(void *) * 2; u64 alignment = sizeof(void *) * 2;

View File

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

View File

@@ -6,69 +6,68 @@
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../base/array/array.h" #include "../../base/array/array.h"
#include "../../base/strings/str8/str8.h" #include "../../base/strings/str8/str8.h"
#include <stdio.h>
File *wapp_file_open(Str8RO *filepath, FileAccessMode mode) { WFile *wapp_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_persist const char *modes[FILE_ACCESS_MODE_COUNT] = { wapp_debug_assert(allocator != NULL && filepath != NULL, "`allocator` and `filepath` should not be NULL");
[WAPP_FA_MODE_R] = "r",
[WAPP_FA_MODE_W] = "w",
[WAPP_FA_MODE_A] = "a",
[WAPP_FA_MODE_R_EX] = "r+",
[WAPP_FA_MODE_W_EX] = "w+",
[WAPP_FA_MODE_A_EX] = "a+",
[WAPP_FA_MODE_RB] = "rb",
[WAPP_FA_MODE_WB] = "wb",
[WAPP_FA_MODE_AB] = "ab",
[WAPP_FA_MODE_RB_EX] = "rb+",
[WAPP_FA_MODE_WB_EX] = "wb+",
[WAPP_FA_MODE_AB_EX] = "ab+",
[WAPP_FA_MODE_WX] = "wx",
[WAPP_FA_MODE_WX_EX] = "wx+",
[WAPP_FA_MODE_WBX] = "wbx",
[WAPP_FA_MODE_WBX_EX] = "wbx+",
};
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit."); wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
return _file_open(allocator, filepath, mode);
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return fopen((const char *)tmp, modes[mode]);
} }
u64 wapp_file_get_current_position(File *file) { i64 wapp_file_get_current_position(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); 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."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
// TODO (Abdelrahman): Revisit conversion to long return _file_seek(file, offset, origin);
return fseek(file, (long)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."); 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 // Restore position
wapp_file_seek(file, current, WAPP_SEEK_START); _file_seek(file, current, WAPP_SEEK_START);
return output; return output;
} }
u64 wapp_file_read(Array *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, wapp_debug_assert(dst_buf != NULL && file != NULL,
"`dst_buf` and `file` should not be 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);
u64 item_size = dst_buf->item_size; if (file_length < 0) {
u64 dst_byte_capacity = dst_buf->capacity * item_size; 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; u64 req_byte_count = item_count * item_size;
u64 copy_byte_count = 0; u64 copy_byte_count = 0;
@@ -78,32 +77,53 @@ u64 wapp_file_read(Array *dst_buf, File *file, u64 item_count) {
copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity; copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity;
} }
u64 count = fread(dst_buf->items, sizeof(u8), copy_byte_count, file); u64 byte_count = _file_read(dst_buf, copy_byte_count, file, file_length);
if (ferror(file)) { return 0; } if (byte_count == 0) {
return 0;
}
dst_buf->count = count / item_size; wapp_array_set_count(dst_buf, byte_count / item_size);
return dst_buf->count; return wapp_array_count(dst_buf);
} }
u64 wapp_file_write(const Array *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, wapp_debug_assert(src_buf != NULL && file != NULL,
"`src_buf` and `file` should not be NULL."); "`src_buf` and `file` should not be NULL.");
u64 item_size = src_buf->item_size; u64 item_size = wapp_array_item_size(src_buf);
u64 src_byte_count = src_buf->count * item_size; u64 src_byte_count = wapp_array_count(src_buf) * item_size;
u64 req_byte_count = item_count * item_size; u64 req_byte_count = item_count * item_size;
u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count; u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count;
return fwrite(src_buf->items, sizeof(u8), to_copy, file); i64 bytes_written = _file_write(src_buf, file, to_copy);
if (bytes_written < 0) {
return 0;
}
return (u64)bytes_written / item_size;
} }
i32 wapp_file_flush(File *file) { i32 wapp_file_flush(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fflush(file); return _file_flush(file);
} }
i32 wapp_file_close(File *file) { i32 wapp_file_close(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fclose(file); 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 #ifndef FILE_H
#define FILE_H #define FILE_H
#include "../../base/mem/allocator/mem_allocator.h"
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../base/strings/str8/str8.h" #include "../../base/strings/str8/str8.h"
#include <stdio.h>
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef FILE File; typedef struct WFile WFile;
typedef enum { typedef enum {
WAPP_FA_MODE_R, // Equivalent to r WAPP_ACCESS_READ, // Equivalent to r
WAPP_FA_MODE_W, // Equivalent to w WAPP_ACCESS_WRITE, // Equivalent to w
WAPP_FA_MODE_A, // Equivalent to a WAPP_ACCESS_APPEND, // Equivalent to a
WAPP_FA_MODE_R_EX, // Equivalent to r+ WAPP_ACCESS_READ_EX, // Equivalent to r+
WAPP_FA_MODE_W_EX, // Equivalent to w+ WAPP_ACCESS_WRITE_EX, // Equivalent to w+
WAPP_FA_MODE_A_EX, // Equivalent to a+ WAPP_ACCESS_APPEND_EX, // Equivalent to a+
WAPP_FA_MODE_RB, // Equivalent to rb WAPP_ACCESS_WRITE_FAIL_ON_EXIST, // Equivalent to wx
WAPP_FA_MODE_WB, // Equivalent to wb WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX, // Equivalent to wx+
WAPP_FA_MODE_AB, // Equivalent to ab
WAPP_FA_MODE_RB_EX, // Equivalent to rb+
WAPP_FA_MODE_WB_EX, // Equivalent to wb+
WAPP_FA_MODE_AB_EX, // Equivalent to ab+
WAPP_FA_MODE_WX, // Equivalent to wx
WAPP_FA_MODE_WX_EX, // Equivalent to wx+
WAPP_FA_MODE_WBX, // Equivalent to wbx
WAPP_FA_MODE_WBX_EX, // Equivalent to wbx+
FILE_ACCESS_MODE_COUNT, FILE_ACCESS_MODE_COUNT,
} FileAccessMode; } FileAccessMode;
typedef enum { typedef enum {
WAPP_SEEK_START = SEEK_SET, WAPP_SEEK_START,
WAPP_SEEK_CURRENT = SEEK_CUR, WAPP_SEEK_CURRENT,
WAPP_SEEK_END = SEEK_END, WAPP_SEEK_END,
FILE_SEEK_ORIGIN_COUNT,
} FileSeekOrigin; } FileSeekOrigin;
File *wapp_file_open(Str8RO *filename, FileAccessMode mode); WFile *wapp_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode);
u64 wapp_file_get_current_position(File *file); i64 wapp_file_get_current_position(WFile *file);
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin); i64 wapp_file_seek(WFile *file, i64 offset, FileSeekOrigin origin);
u64 wapp_file_get_length(File *file); i64 wapp_file_get_length(WFile *file);
u64 wapp_file_read(Array *dst_buf, File *file, u64 item_count); u64 wapp_file_read(void *dst_buf, WFile *file, u64 byte_count);
u64 wapp_file_write(const Array *src_buf, File *file, u64 item_count); i64 wapp_file_write(const void *src_buf, WFile *file, u64 byte_count);
i32 wapp_file_flush(File *file); u64 wapp_file_read_array(GenericArray dst_buf, WFile *file, u64 item_count);
i32 wapp_file_close(File *file); 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 #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE 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

@@ -15,8 +15,8 @@
#error "Unrecognised platform" #error "Unrecognised platform"
#endif #endif
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) { void *wapp_os_mem_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
void *output = mem_util_allocate(addr, size, access, flags, type); void *output = os_mem_allocate(addr, size, access, flags, type);
if (type == WAPP_MEM_INIT_INITIALISED) { if (type == WAPP_MEM_INIT_INITIALISED) {
memset(output, 0, size); memset(output, 0, size);
@@ -25,6 +25,6 @@ void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags
return output; return output;
} }
void wapp_mem_util_free(void *ptr, u64 size) { void wapp_os_mem_free(void *ptr, u64 size) {
mem_util_free(ptr, size); os_mem_free(ptr, size);
} }

View File

@@ -20,11 +20,11 @@ BEGIN_C_LINKAGE
#error "Unrecognised platform" #error "Unrecognised platform"
#endif #endif
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type); void *wapp_os_mem_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
void wapp_mem_util_free(void *ptr, u64 size); void wapp_os_mem_free(void *ptr, u64 size);
wapp_extern void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type); wapp_extern void *os_mem_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
wapp_extern void mem_util_free(void *ptr, u64 size); wapp_extern void os_mem_free(void *ptr, u64 size);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -18,7 +18,7 @@ wapp_intern const i32 access_types[] = {
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PROT_READ | PROT_WRITE | PROT_EXEC, [WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PROT_READ | PROT_WRITE | PROT_EXEC,
}; };
void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) { void *os_mem_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
(void)type; (void)type;
i32 alloc_flags = flags | MAP_ANON | MAP_PRIVATE; i32 alloc_flags = flags | MAP_ANON | MAP_PRIVATE;
@@ -29,7 +29,7 @@ void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags fl
return mmap(addr, size, access_types[access], alloc_flags, -1, 0); return mmap(addr, size, access_types[access], alloc_flags, -1, 0);
} }
void mem_util_free(void *ptr, u64 size) { void os_mem_free(void *ptr, u64 size) {
munmap(ptr, size); munmap(ptr, size);
} }

View File

@@ -21,7 +21,7 @@ wapp_intern const i32 access_types[] = {
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PAGE_EXECUTE_READWRITE, [WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PAGE_EXECUTE_READWRITE,
}; };
void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) { void *os_mem_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
// Ensure memory is committed if it's meant to be initialised // Ensure memory is committed if it's meant to be initialised
if (type == WAPP_MEM_INIT_INITIALISED) { if (type == WAPP_MEM_INIT_INITIALISED) {
flags |= WAPP_MEM_ALLOC_COMMIT; flags |= WAPP_MEM_ALLOC_COMMIT;
@@ -30,7 +30,7 @@ void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags fl
return VirtualAlloc(addr, (SIZE_T)size, flags, access_types[access]); return VirtualAlloc(addr, (SIZE_T)size, flags, access_types[access]);
} }
void mem_util_free(void *ptr, u64 size) { void os_mem_free(void *ptr, u64 size) {
VirtualFree(ptr, size, MEM_RELEASE); VirtualFree(ptr, size, MEM_RELEASE);
} }

View File

@@ -17,15 +17,15 @@
#define CMD_BUF_LEN 8192 #define CMD_BUF_LEN 8192
#define OUT_BUF_LEN 4096 #define OUT_BUF_LEN 4096
wapp_intern inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf); wapp_intern CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf);
wapp_intern inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf); wapp_intern CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf);
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd) { CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd) {
if (!cmd) { if (!cmd) {
return CMD_NO_EXIT(SHELL_ERR_INVALID_ARGS); return CMD_NO_EXIT(SHELL_ERR_INVALID_ARGS);
} }
Allocator arena = wapp_mem_arena_allocator_init(KB(500)); Allocator arena = wapp_mem_arena_allocator_init(KiB(500));
Str8 *cmd_str = wapp_str8_join(&arena, cmd, &wapp_str8_lit_ro(" ")); Str8 *cmd_str = wapp_str8_join(&arena, cmd, &wapp_str8_lit_ro(" "));
if (!cmd_str) { if (!cmd_str) {
@@ -43,7 +43,7 @@ CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_bu
return output; return output;
} }
wapp_intern inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) { wapp_intern CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) {
char cmd_buf[CMD_BUF_LEN] = {0}; char cmd_buf[CMD_BUF_LEN] = {0};
wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN); wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN);
@@ -83,7 +83,7 @@ EXECUTE_COMMAND_CLOSE:
return output; return output;
} }
wapp_intern inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) { wapp_intern CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) {
Str8 out = wapp_str8_buf(OUT_BUF_LEN); Str8 out = wapp_str8_buf(OUT_BUF_LEN);
out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp); out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp);

View File

@@ -5,6 +5,7 @@
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h" #include "../../../common/platform/platform.h"
#include "../../../common/misc/misc_utils.h"
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
@@ -25,16 +26,13 @@ typedef enum {
SHELL_ERR_PROC_EXIT_FAIL, SHELL_ERR_PROC_EXIT_FAIL,
} CMDError; } CMDError;
typedef struct commander_result CMDResult; typedef struct CMDResult CMDResult;
struct commander_result { struct CMDResult {
i32 exit_code; i32 exit_code;
CMDError error; CMDError error;
b8 exited; b8 exited;
#ifdef WAPP_PLATFORM_WINDOWS wapp_misc_utils_reserve_padding(sizeof(b8) + sizeof(i32) + sizeof(CMDError));
#include "../../../../common/misc/misc_utils.h"
wapp_misc_utils_padding_size(sizeof(b8) + sizeof(i32) + sizeof(CMDError));
#endif // !WAPP_PLATFORM_WINDOWS
}; };
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP

View File

@@ -7,19 +7,19 @@
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#include "../terminal_colours.h" #include "../terminal_colours.h"
#include "../../../../../common/misc/misc_utils.h" #include "../../../../common/misc/misc_utils.h"
#include <stdio.h> #include <stdio.h>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
typedef struct termcolour_data TermcolourData; typedef struct TermcolourData TermcolourData;
struct termcolour_data { struct TermcolourData {
HANDLE handle; HANDLE handle;
WORD default_colour; WORD default_colour;
WORD current_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); wapp_intern void init_data(TermcolourData *data);

View File

@@ -5,6 +5,8 @@
#include "wapp_os.h" #include "wapp_os.h"
#include "file/file.c" #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/posix/termcolour_posix.c"
#include "shell/termcolour/win/termcolour_win.c" #include "shell/termcolour/win/termcolour_win.c"
#include "shell/termcolour/termcolour.c" #include "shell/termcolour/termcolour.c"

View File

@@ -4,6 +4,8 @@
#define WAPP_CORE_H #define WAPP_CORE_H
#include "file/file.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/termcolour.h"
#include "shell/termcolour/terminal_colours.h" #include "shell/termcolour/terminal_colours.h"
#include "shell/commander/commander.h" #include "shell/commander/commander.h"

View File

@@ -7,8 +7,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
typedef struct split_mix_64_state SplitMix64State; typedef struct SplitMix64State SplitMix64State;
struct split_mix_64_state { struct SplitMix64State {
u64 seed; u64 seed;
}; };

View File

@@ -10,8 +10,8 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef struct xor_256_state XOR256State; typedef struct XOR256State XOR256State;
struct xor_256_state { struct XOR256State {
u64 x; u64 x;
u64 y; u64 y;
u64 z; u64 z;

View File

@@ -10,21 +10,19 @@
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE 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 #else
#define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED}) #define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED})
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL) #define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL)
typedef struct test_func_result TestFuncResult; typedef struct TestFuncResult TestFuncResult;
struct test_func_result { struct TestFuncResult {
Str8 name; Str8 name;
b8 passed; b8 passed;
#ifdef WAPP_PLATFORM_WINDOWS wapp_misc_utils_reserve_padding(sizeof(Str8) + sizeof(b8));
wapp_misc_utils_padding_size(sizeof(Str8RO) + sizeof(b8));
#endif // WAPP_PLATFORM_WINDOWS
}; };
typedef TestFuncResult(TestFunc)(void); typedef TestFuncResult(TestFunc)(void);

View File

@@ -9,8 +9,8 @@
#define UUID_STR_FORMAT ("%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64) #define UUID_STR_FORMAT ("%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64)
typedef struct uuid4 UUID4; typedef struct UUID4 UUID4;
struct uuid4 { struct UUID4 {
u64 high; u64 high;
u64 low; u64 low;
}; };

View File

@@ -15,16 +15,22 @@ BEGIN_C_LINKAGE
#define WAPP_UUID_SPEC WAPP_STR8_SPEC #define WAPP_UUID_SPEC WAPP_STR8_SPEC
#define wapp_uuid_varg(WUUID) wapp_str8_varg((WUUID).uuid) #define wapp_uuid_varg(WUUID) wapp_str8_varg((WUUID).uuid)
typedef struct wapp_uuid WUUID; typedef struct WUUID WUUID;
struct wapp_uuid { struct WUUID {
Str8 uuid; 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())) #define wapp_uuid_gen_uuid4() *(wapp_uuid_init_uuid4(&wapp_uuid_create()))
/* Low level UUID API */ /* 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)}) #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. // Just returns the same pointer that was passed in with the UUID initialised.
// Fails when passed a NULL pointer. // Fails when passed a NULL pointer.

View File

@@ -2,6 +2,13 @@
#include "wapp.h" #include "wapp.h"
#include <stdlib.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) { TestFuncResult test_arena_allocator(void) {
Allocator allocator = wapp_mem_arena_allocator_init(4096); Allocator allocator = wapp_mem_arena_allocator_init(4096);
b8 result = allocator.obj != NULL && allocator.alloc != NULL && b8 result = allocator.obj != NULL && allocator.alloc != NULL &&
@@ -15,3 +22,46 @@ TestFuncResult test_arena_allocator(void) {
return wapp_tester_result(result); 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 "wapp.h"
#include <stdlib.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) { TestFuncResult test_arena_allocator(void) {
Allocator allocator = wapp_mem_arena_allocator_init(4096); Allocator allocator = wapp_mem_arena_allocator_init(4096);
b8 result = allocator.obj != nullptr && allocator.alloc != nullptr && b8 result = allocator.obj != nullptr && allocator.alloc != nullptr &&
@@ -15,3 +22,46 @@ TestFuncResult test_arena_allocator(void) {
return wapp_tester_result(result); 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" #include "wapp.h"
TestFuncResult test_arena_allocator(void); 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 #endif // !TEST_ALLOCATOR_H

View File

@@ -2,22 +2,35 @@
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
#define ARENA_CAPACITY KB(16) #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 Arena *arena = NULL;
wapp_intern i32 count = 20; wapp_intern i32 count = 20;
wapp_intern i32 *array = NULL; 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) { TestFuncResult test_arena_init_buffer(void) {
b8 result = wapp_mem_arena_init(&arena, ARENA_CAPACITY); 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); return wapp_tester_result(result);
} }
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) { TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
Arena *large_arena = NULL; Arena *large_arena = NULL;
u64 capacity = GB(512); 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) { if (result) {
wapp_mem_arena_destroy(&large_arena); 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); 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) { TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) {
array = wapp_mem_arena_alloc(arena, count * sizeof(i32)); array = wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = array != NULL; b8 result = array != NULL;
@@ -89,6 +113,32 @@ TestFuncResult test_arena_realloc_smaller_size(void) {
return wapp_tester_result(true); 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) { TestFuncResult test_arena_clear(void) {
wapp_mem_arena_clear(arena); wapp_mem_arena_clear(arena);
b8 result = true; b8 result = true;
@@ -103,7 +153,14 @@ TestFuncResult test_arena_clear(void) {
return wapp_tester_result(result); 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); wapp_mem_arena_destroy(&arena);
b8 result = arena == NULL; b8 result = arena == NULL;

View File

@@ -2,22 +2,35 @@
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
#define ARENA_CAPACITY KB(16) #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 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) { TestFuncResult test_arena_init_buffer(void) {
b8 result = wapp_mem_arena_init(&arena, ARENA_CAPACITY); 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); return wapp_tester_result(result);
} }
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) { TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
Arena *large_arena = nullptr; Arena *large_arena = nullptr;
u64 capacity = GB(512); 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) { if (result) {
wapp_mem_arena_destroy(&large_arena); 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); 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) { TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) {
array = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32)); array = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = array != nullptr; b8 result = array != nullptr;
@@ -89,6 +113,32 @@ TestFuncResult test_arena_realloc_smaller_size(void) {
return wapp_tester_result(true); 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) { TestFuncResult test_arena_clear(void) {
wapp_mem_arena_clear(arena); wapp_mem_arena_clear(arena);
b8 result = true; b8 result = true;
@@ -103,7 +153,14 @@ TestFuncResult test_arena_clear(void) {
return wapp_tester_result(result); 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); wapp_mem_arena_destroy(&arena);
b8 result = arena == nullptr; b8 result = arena == nullptr;

View File

@@ -3,13 +3,18 @@
#include "wapp.h" #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_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_succeeds_when_within_capacity(void);
TestFuncResult test_arena_alloc_fails_when_over_capacity(void); TestFuncResult test_arena_alloc_fails_when_over_capacity(void);
TestFuncResult test_arena_realloc_bigger_size(void); TestFuncResult test_arena_realloc_bigger_size(void);
TestFuncResult test_arena_realloc_smaller_size(void); TestFuncResult test_arena_realloc_smaller_size(void);
TestFuncResult test_arena_clear(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 #endif // !TEST_ARENA_H

View File

@@ -4,15 +4,15 @@
TestFuncResult test_i32_array(void) { TestFuncResult test_i32_array(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7); I32Array array = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7);
result = array.count == 7 && array.capacity == 16; result = wapp_array_count(array) == 7 && wapp_array_capacity(array) == 16;
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && *item == (i32)(index + 1); result = result && item && *item == (i32)(index + 1);
++index; ++index;
@@ -25,8 +25,11 @@ TestFuncResult test_i32_array(void) {
TestFuncResult test_i32_array_with_capacity(void) { TestFuncResult test_i32_array_with_capacity(void) {
b8 result; b8 result;
I32Array array = wapp_array_with_capacity(i32, I32Array, 64); I32Array array1 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
result = array.count == 0 && array.capacity == 64; result = wapp_array_count(array1) == 0 && wapp_array_capacity(array1) == 64;
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); return wapp_tester_result(result);
} }
@@ -34,14 +37,14 @@ TestFuncResult test_i32_array_with_capacity(void) {
TestFuncResult test_i32_array_get(void) { TestFuncResult test_i32_array_get(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && *item == (i32)index; result = result && item && *item == (i32)index;
++index; ++index;
@@ -54,16 +57,16 @@ TestFuncResult test_i32_array_get(void) {
TestFuncResult test_i32_array_set(void) { TestFuncResult test_i32_array_set(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)(index * 2); i32 num = (i32)(index * 2);
wapp_array_set(i32, &array, index, &num); wapp_array_set(i32, array, index, &num);
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && *item == (i32)(index * 2); result = result && item && *item == (i32)(index * 2);
++index; ++index;
@@ -76,17 +79,17 @@ TestFuncResult test_i32_array_set(void) {
TestFuncResult test_i32_array_append_capped(void) { TestFuncResult test_i32_array_append_capped(void) {
b8 result; b8 result;
I32Array array = wapp_array_with_capacity(i32, I32Array, 64); I32Array array = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
wapp_array_append_capped(i32, &array, &((i32){10})); wapp_array_append_capped(i32, array, &((i32){10}));
result = array.count == 1; result = wapp_array_count(array) == 1;
i32 *item = wapp_array_get(i32, &array, 0); i32 *item = wapp_array_get(i32, array, 0);
result = result && item && *item == 10; result = result && item && *item == 10;
array = wapp_array(i32, I32Array, 1); array = wapp_array(i32, 1);
wapp_array_append_capped(i32, &array, &((i32){10})); wapp_array_append_capped(i32, array, &((i32){10}));
result = result && array.count == 2; result = result && wapp_array_count(array) == 2;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -94,14 +97,14 @@ TestFuncResult test_i32_array_append_capped(void) {
TestFuncResult test_i32_array_extend_capped(void) { TestFuncResult test_i32_array_extend_capped(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array1 = wapp_array(i32, 1, 2, 3, 4);
I32Array array2 = wapp_array(i32, I32Array, 10, 20); I32Array array2 = wapp_array(i32, 10, 20);
result = array1.count == 4 && array2.count == 2; result = wapp_array_count(array1) == 4 && wapp_array_count(array2) == 2;
wapp_array_extend_capped(i32, &array1, &array2); wapp_array_extend_capped(i32, array1, array2);
result = result && array1.count == 6; result = result && wapp_array_count(array1) == 6;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -109,31 +112,31 @@ TestFuncResult test_i32_array_extend_capped(void) {
TestFuncResult test_i32_array_copy_capped(void) { TestFuncResult test_i32_array_copy_capped(void) {
b8 result; b8 result;
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
u64 expected_count = 5; u64 expected_count = 5;
wapp_array_copy_capped(i32, &dst1, &src); wapp_array_copy_capped(i32, dst1, src);
result = dst1.count == expected_count; result = wapp_array_count(dst1) == expected_count;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst1, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst1, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 4; expected_count = 4;
wapp_array_copy_capped(i32, &dst2, &src); wapp_array_copy_capped(i32, dst2, src);
result = result && dst2.count == expected_count; result = result && wapp_array_count(dst2) == expected_count;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst2, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst2, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -145,11 +148,11 @@ TestFuncResult test_i32_array_copy_capped(void) {
TestFuncResult test_i32_array_alloc_capacity(void) { TestFuncResult test_i32_array_alloc_capacity(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
u64 capacity = 32; u64 capacity = 32;
I32Array *array = wapp_array_alloc_capacity(i32, I32Array, &allocator, capacity); I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, ARRAY_INIT_NONE);
result = array && array->capacity == capacity; result = array && wapp_array_capacity(array) == capacity;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -159,24 +162,24 @@ TestFuncResult test_i32_array_alloc_capacity(void) {
TestFuncResult test_i32_array_append_alloc(void) { TestFuncResult test_i32_array_append_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
I32Array *arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array1, &((i32){10})); I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &((i32){10}), ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = arr_ptr == array1;
u64 count = 4; u64 count = 4;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)index; i32 num = (i32)index;
arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array2, &num); arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num, ARRAY_INIT_NONE);
++index; ++index;
running = index < count; running = index < count;
} }
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -186,16 +189,16 @@ TestFuncResult test_i32_array_append_alloc(void) {
TestFuncResult test_i32_array_extend_alloc(void) { TestFuncResult test_i32_array_extend_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
I32Array array3 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array3 = wapp_array(i32, 1, 2, 3, 4);
I32Array *arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array1, &array3); I32Array arr_ptr = wapp_array_extend_alloc(i32, &allocator, array1, array3, ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = arr_ptr == array1;
arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array2, &array3); arr_ptr = wapp_array_extend_alloc(i32, &allocator, array2, array3, ARRAY_INIT_NONE);
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -205,33 +208,33 @@ TestFuncResult test_i32_array_extend_alloc(void) {
TestFuncResult test_i32_array_copy_alloc(void) { TestFuncResult test_i32_array_copy_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
I32Array *array_ptr = NULL; I32Array array = NULL;
u64 expected_count = 5; u64 expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst1, &src); array = wapp_array_copy_alloc(i32, &allocator, dst1, src, ARRAY_INIT_NONE);
result = array_ptr->count == expected_count && array_ptr == &dst1; result = wapp_array_count(array) == expected_count && array == dst1;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 5; expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst2, &src); array = wapp_array_copy_alloc(i32, &allocator, dst2, src, ARRAY_INIT_NONE);
result = result && array_ptr->count == expected_count && array_ptr != &dst2; result = result && wapp_array_count(array) == expected_count && array != dst2;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -245,11 +248,11 @@ TestFuncResult test_i32_array_copy_alloc(void) {
TestFuncResult test_i32_array_pop(void) { TestFuncResult test_i32_array_pop(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array_with_capacity(i32, I32Array, 32); I32Array array2 = wapp_array_with_capacity(i32, 32, ARRAY_INIT_NONE);
i32 item1 = wapp_array_pop(i32, &array1); i32 item1 = wapp_array_pop(i32, array1);
i32 item2 = wapp_array_pop(i32, &array2); i32 item2 = wapp_array_pop(i32, array2);
result = item1 == 8 && item2 == 0; result = item1 == 8 && item2 == 0;
@@ -259,12 +262,12 @@ TestFuncResult test_i32_array_pop(void) {
TestFuncResult test_i32_array_clear(void) { TestFuncResult test_i32_array_clear(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
result = array.count == 9; result = wapp_array_count(array) == 9;
wapp_array_clear(i32, &array); wapp_array_clear(i32, array);
result = result && array.count == 0; result = result && wapp_array_count(array) == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }

View File

@@ -4,15 +4,15 @@
TestFuncResult test_i32_array(void) { TestFuncResult test_i32_array(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7); I32Array array = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7);
result = array.count == 7 && array.capacity == 16; result = wapp_array_count(array) == 7 && wapp_array_capacity(array) == 16;
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)(index + 1)); result = result && item && (*item == (i32)(index + 1));
++index; ++index;
@@ -25,8 +25,11 @@ TestFuncResult test_i32_array(void) {
TestFuncResult test_i32_array_with_capacity(void) { TestFuncResult test_i32_array_with_capacity(void) {
b8 result; b8 result;
I32Array array = wapp_array_with_capacity(i32, I32Array, 64); I32Array array1 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
result = array.count == 0 && array.capacity == 64; result = wapp_array_count(array1) == 0 && wapp_array_capacity(array1) == 64;
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); return wapp_tester_result(result);
} }
@@ -34,14 +37,14 @@ TestFuncResult test_i32_array_with_capacity(void) {
TestFuncResult test_i32_array_get(void) { TestFuncResult test_i32_array_get(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)index); result = result && item && (*item == (i32)index);
++index; ++index;
@@ -54,16 +57,16 @@ TestFuncResult test_i32_array_get(void) {
TestFuncResult test_i32_array_set(void) { TestFuncResult test_i32_array_set(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)(index * 2); i32 num = (i32)(index * 2);
wapp_array_set(i32, &array, index, &num); wapp_array_set(i32, array, index, &num);
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)(index * 2)); result = result && item && (*item == (i32)(index * 2));
++index; ++index;
@@ -76,19 +79,19 @@ TestFuncResult test_i32_array_set(void) {
TestFuncResult test_i32_array_append_capped(void) { TestFuncResult test_i32_array_append_capped(void) {
b8 result; b8 result;
I32Array array = wapp_array_with_capacity(i32, I32Array, 64); I32Array array = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
i32 item1 = 10; i32 item1 = 10;
wapp_array_append_capped(i32, &array, &item1); wapp_array_append_capped(i32, array, &item1);
result = array.count == 1; result = wapp_array_count(array) == 1;
i32 *item = wapp_array_get(i32, &array, 0); i32 *item = wapp_array_get(i32, array, 0);
result = result && item && *item == 10; result = result && item && *item == 10;
array = wapp_array(i32, I32Array, 1); array = wapp_array(i32, 1);
i32 item2 = 10; i32 item2 = 10;
wapp_array_append_capped(i32, &array, &item2); wapp_array_append_capped(i32, array, &item2);
result = result && array.count == 2; result = result && wapp_array_count(array) == 2;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -96,14 +99,14 @@ TestFuncResult test_i32_array_append_capped(void) {
TestFuncResult test_i32_array_extend_capped(void) { TestFuncResult test_i32_array_extend_capped(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array1 = wapp_array(i32, 1, 2, 3, 4);
I32Array array2 = wapp_array(i32, I32Array, 10, 20); I32Array array2 = wapp_array(i32, 10, 20);
result = array1.count == 4 && array2.count == 2; result = wapp_array_count(array1) == 4 && wapp_array_count(array2) == 2;
wapp_array_extend_capped(i32, &array1, &array2); wapp_array_extend_capped(i32, array1, array2);
result = result && array1.count == 6; result = result && wapp_array_count(array1) == 6;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -111,31 +114,31 @@ TestFuncResult test_i32_array_extend_capped(void) {
TestFuncResult test_i32_array_copy_capped(void) { TestFuncResult test_i32_array_copy_capped(void) {
b8 result; b8 result;
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
u64 expected_count = 5; u64 expected_count = 5;
wapp_array_copy_capped(i32, &dst1, &src); wapp_array_copy_capped(i32, dst1, src);
result = dst1.count == expected_count; result = wapp_array_count(dst1) == expected_count;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst1, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst1, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 4; expected_count = 4;
wapp_array_copy_capped(i32, &dst2, &src); wapp_array_copy_capped(i32, dst2, src);
result = result && dst2.count == expected_count; result = result && wapp_array_count(dst2) == expected_count;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst2, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst2, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -147,11 +150,11 @@ TestFuncResult test_i32_array_copy_capped(void) {
TestFuncResult test_i32_array_alloc_capacity(void) { TestFuncResult test_i32_array_alloc_capacity(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
u64 capacity = 32; u64 capacity = 32;
I32Array *array = wapp_array_alloc_capacity(i32, I32Array, &allocator, capacity); I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, ARRAY_INIT_NONE);
result = array && array->capacity == capacity; result = array && wapp_array_capacity(array) == capacity;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -161,25 +164,25 @@ TestFuncResult test_i32_array_alloc_capacity(void) {
TestFuncResult test_i32_array_append_alloc(void) { TestFuncResult test_i32_array_append_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
i32 num = 10; i32 num = 10;
I32Array *arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array1, &num); I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &num, ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = arr_ptr == array1;
u64 count = 4; u64 count = 4;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
num = (i32)index; num = (i32)index;
arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array2, &num); arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num, ARRAY_INIT_NONE);
++index; ++index;
running = index < count; running = index < count;
} }
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -189,16 +192,16 @@ TestFuncResult test_i32_array_append_alloc(void) {
TestFuncResult test_i32_array_extend_alloc(void) { TestFuncResult test_i32_array_extend_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
I32Array array3 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array3 = wapp_array(i32, 1, 2, 3, 4);
I32Array *arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array1, &array3); I32Array array = wapp_array_extend_alloc(i32, &allocator, array1, array3, ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = array == array1;
arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array2, &array3); array = wapp_array_extend_alloc(i32, &allocator, array2, array3, ARRAY_INIT_NONE);
result = result && arr_ptr != &array2; result = result && array != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -208,33 +211,33 @@ TestFuncResult test_i32_array_extend_alloc(void) {
TestFuncResult test_i32_array_copy_alloc(void) { TestFuncResult test_i32_array_copy_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
I32Array *array_ptr = nullptr; I32Array array = nullptr;
u64 expected_count = 5; u64 expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst1, &src); array = wapp_array_copy_alloc(i32, &allocator, dst1, src, ARRAY_INIT_NONE);
result = array_ptr->count == expected_count && array_ptr == &dst1; result = wapp_array_count(array) == expected_count && array == dst1;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 5; expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst2, &src); array = wapp_array_copy_alloc(i32, &allocator, dst2, src, ARRAY_INIT_NONE);
result = result && array_ptr->count == expected_count && array_ptr != &dst2; result = result && wapp_array_count(array) == expected_count && array != dst2;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -248,12 +251,12 @@ TestFuncResult test_i32_array_copy_alloc(void) {
TestFuncResult test_i32_array_clear(void) { TestFuncResult test_i32_array_clear(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
result = array.count == 9; result = wapp_array_count(array) == 9;
wapp_array_clear(i32, &array); wapp_array_clear(i32, array);
result = result && array.count == 0; result = result && wapp_array_count(array) == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -261,11 +264,11 @@ TestFuncResult test_i32_array_clear(void) {
TestFuncResult test_i32_array_pop(void) { TestFuncResult test_i32_array_pop(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array_with_capacity(i32, I32Array, 32); I32Array array2 = wapp_array_with_capacity(i32, 32, ARRAY_INIT_NONE);
i32 item1 = wapp_array_pop(i32, &array1); i32 item1 = wapp_array_pop(i32, array1);
i32 item2 = wapp_array_pop(i32, &array2); i32 item2 = wapp_array_pop(i32, array2);
result = item1 == 8 && item2 == 0; result = item1 == 8 && item2 == 0;

View File

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

View File

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

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(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
Str8List parts = {0}; Str8List parts = wapp_dbl_list(Str8);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_str8(tmp)); wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("home")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("home"));
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("abdelrahman")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("abdelrahman"));
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("Documents")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("Documents"));
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = wapp_str8_equal(&out, &expected); result = wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_front(&parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); 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); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("home")); wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("home"));
wapp_str8_list_pop_front(&parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_list_push_front(&parts, &wapp_str8_node_from_str8(tmp)); wapp_dbl_list_push_front(Str8, &parts, &tmp);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -42,35 +42,35 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP);
wapp_str8_list_pop_front(&parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_list_push_front(&parts, &wapp_str8_node_from_cstr("home")); wapp_dbl_list_push_front(Str8, &parts, &wapp_str8_lit("home"));
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_empty(&parts); wapp_dbl_list_empty(Str8, &parts);
wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_str8(tmp)); wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit(""));
wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_front(&parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit(""));
wapp_str8_format(&expected, "%s", ""); wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_back(&parts); wapp_dbl_list_pop_back(Str8, &parts);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("home")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("home"));
wapp_str8_copy_cstr_capped(&expected, "home"); wapp_str8_copy_cstr_capped(&expected, "home");
@@ -81,7 +81,7 @@ TestFuncResult test_cpath_join_path(void) {
} }
TestFuncResult test_cpath_dirname(void) { TestFuncResult test_cpath_dirname(void) {
Allocator arena = wapp_mem_arena_allocator_init(MB(8)); Allocator arena = wapp_mem_arena_allocator_init(MiB(8));
if (wapp_mem_allocator_invalid(&arena)) { if (wapp_mem_allocator_invalid(&arena)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -129,7 +129,7 @@ TestFuncResult test_cpath_dirname(void) {
} }
TestFuncResult test_cpath_dirup(void) { TestFuncResult test_cpath_dirup(void) {
Allocator arena = wapp_mem_arena_allocator_init(MB(8)); Allocator arena = wapp_mem_arena_allocator_init(MiB(8));
if (wapp_mem_allocator_invalid(&arena)) { if (wapp_mem_allocator_invalid(&arena)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }

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(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
Str8List parts = {}; Str8List parts = wapp_dbl_list(Str8);
Str8Node tmp_node = wapp_str8_node_from_str8(tmp); wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_str8_list_push_back(&parts, &tmp_node);
Str8Node home_node = wapp_str8_node_from_cstr("home"); Str8 home = wapp_str8_lit("home");
wapp_str8_list_push_back(&parts, &home_node); wapp_dbl_list_push_back(Str8, &parts, &home);
Str8Node user_node = wapp_str8_node_from_cstr("abdelrahman"); Str8 user = wapp_str8_lit("abdelrahman");
wapp_str8_list_push_back(&parts, &user_node); wapp_dbl_list_push_back(Str8, &parts, &user);
Str8Node docs_node = wapp_str8_node_from_cstr("Documents"); Str8 docs = wapp_str8_lit("Documents");
wapp_str8_list_push_back(&parts, &docs_node); wapp_dbl_list_push_back(Str8, &parts, &docs);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = wapp_str8_equal(&out, &expected); result = wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_front(&parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); 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"); Str8RO str = wapp_str8_lit_ro("home");
wapp_str8_concat_capped(&tmp, &str); wapp_str8_concat_capped(&tmp, &str);
wapp_str8_list_pop_front(&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);
wapp_str8_list_push_front(&parts, &tmp_node_2);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -53,45 +51,44 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP);
wapp_str8_list_pop_front(&parts); wapp_dbl_list_pop_front(Str8, &parts);
Str8Node home_node_2 = wapp_str8_node_from_cstr("home"); Str8 home_2 = wapp_str8_lit("home");
wapp_str8_list_push_front(&parts, &home_node_2); wapp_dbl_list_push_front(Str8, &parts, &home_2);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_empty(&parts); wapp_dbl_list_empty(Str8, &parts);
wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP); 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);
wapp_str8_list_push_back(&parts, &tmp_node_3);
Str8Node empty_node = wapp_str8_node_from_cstr(""); Str8 empty = wapp_str8_lit("");
wapp_str8_list_push_back(&parts, &empty_node); wapp_dbl_list_push_back(Str8, &parts, &empty);
wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_front(&parts); wapp_dbl_list_pop_front(Str8, &parts);
Str8Node empty_node_2 = wapp_str8_node_from_cstr(""); Str8 empty_2 = wapp_str8_lit("");
wapp_str8_list_push_back(&parts, &empty_node_2); wapp_dbl_list_push_back(Str8, &parts, &empty_2);
wapp_str8_format(&expected, "%s", ""); wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_back(&parts); wapp_dbl_list_pop_back(Str8, &parts);
Str8Node home_node_3 = wapp_str8_node_from_cstr("home"); Str8 home_3 = wapp_str8_lit("home");
wapp_str8_list_push_back(&parts, &home_node_3); wapp_dbl_list_push_back(Str8, &parts, &home_3);
wapp_str8_copy_cstr_capped(&expected, "home"); wapp_str8_copy_cstr_capped(&expected, "home");
@@ -102,7 +99,7 @@ TestFuncResult test_cpath_join_path(void) {
} }
TestFuncResult test_cpath_dirname(void) { TestFuncResult test_cpath_dirname(void) {
Allocator arena = wapp_mem_arena_allocator_init(MB(8)); Allocator arena = wapp_mem_arena_allocator_init(MiB(8));
if (wapp_mem_allocator_invalid(&arena)) { if (wapp_mem_allocator_invalid(&arena)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -152,7 +149,7 @@ TestFuncResult test_cpath_dirname(void) {
} }
TestFuncResult test_cpath_dirup(void) { TestFuncResult test_cpath_dirup(void) {
Allocator arena = wapp_mem_arena_allocator_init(MB(8)); Allocator arena = wapp_mem_arena_allocator_init(MiB(8));
if (wapp_mem_allocator_invalid(&arena)) { if (wapp_mem_allocator_invalid(&arena)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }

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> #include <string.h>
TestFuncResult test_commander_cmd_success(void) { TestFuncResult test_commander_cmd_success(void) {
Str8List cmd = {0}; Str8List cmd = wapp_dbl_list(Str8);
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("hello world")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("hello world"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS && 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) { TestFuncResult test_commander_cmd_failure(void) {
Str8List cmd = {0}; Str8List cmd = wapp_dbl_list(Str8);
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("grep")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("grep"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
b8 failed = result.exited && result.exit_code != EXIT_SUCCESS && 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"; char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg); wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = {0}; Str8List cmd = wapp_dbl_list(Str8);
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr(msg)); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS && 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"; char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg); wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = {0}; Str8List cmd = wapp_dbl_list(Str8);
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr(msg)); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 failed = !result.exited && result.exit_code != EXIT_SUCCESS && b8 failed = !result.exited && result.exit_code != EXIT_SUCCESS &&

View File

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

View File

@@ -77,7 +77,7 @@ TestFuncResult test_str8_buf(void) {
TestFuncResult test_str8_alloc_buf(void) { TestFuncResult test_str8_alloc_buf(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -105,7 +105,7 @@ TEST_ALLOC_BUF_CLEANUP:
TestFuncResult test_str8_alloc_cstr(void) { TestFuncResult test_str8_alloc_cstr(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -126,7 +126,7 @@ TestFuncResult test_str8_alloc_cstr(void) {
TestFuncResult test_str8_alloc_str8(void) { TestFuncResult test_str8_alloc_str8(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -146,7 +146,7 @@ TestFuncResult test_str8_alloc_str8(void) {
TestFuncResult test_str8_alloc_substr(void) { TestFuncResult test_str8_alloc_substr(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -289,7 +289,7 @@ TestFuncResult test_str8_slice(void) {
TestFuncResult test_str8_alloc_concat(void) { TestFuncResult test_str8_alloc_concat(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("Hello world"); Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me."); Str8 suffix1 = wapp_str8_lit(" from me.");
@@ -410,7 +410,7 @@ TestFuncResult test_str8_rfind(void) {
TestFuncResult test_str8_split(void) { TestFuncResult test_str8_split(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
@@ -443,8 +443,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_str8_list_get(list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; 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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_str8_list_get(list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -467,7 +467,7 @@ TestFuncResult test_str8_split(void) {
TestFuncResult test_str8_split_with_max(void) { TestFuncResult test_str8_split_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
@@ -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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_str8_list_get(list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -502,7 +502,7 @@ TestFuncResult test_str8_split_with_max(void) {
TestFuncResult test_str8_rsplit(void) { TestFuncResult test_str8_rsplit(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
@@ -535,8 +535,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_str8_list_get(list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; 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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_str8_list_get(list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -559,7 +559,7 @@ TestFuncResult test_str8_rsplit(void) {
TestFuncResult test_str8_rsplit_with_max(void) { TestFuncResult test_str8_rsplit_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
@@ -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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_str8_list_get(list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -594,7 +594,7 @@ TestFuncResult test_str8_rsplit_with_max(void) {
TestFuncResult test_str8_join(void) { TestFuncResult test_str8_join(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
@@ -616,10 +616,10 @@ TestFuncResult test_str8_from_bytes(void) {
b8 result; b8 result;
Str8 str = wapp_str8_buf(1024); Str8 str = wapp_str8_buf(1024);
U8Array bytes = wapp_array(u8, U8Array, 'W', 'A', 'P', 'P'); U8Array bytes = wapp_array(u8, 'W', 'A', 'P', 'P');
wapp_str8_from_bytes(&str, &bytes); wapp_str8_from_bytes(&str, bytes);
result = str.size == bytes.count * bytes.item_size; result = str.size == wapp_array_count(bytes) * wapp_array_item_size(bytes);
result = result && wapp_str8_equal(&str, &wapp_str8_lit_ro("WAPP")); result = result && wapp_str8_equal(&str, &wapp_str8_lit_ro("WAPP"));
return wapp_tester_result(result); return wapp_tester_result(result);

View File

@@ -77,7 +77,7 @@ TestFuncResult test_str8_buf(void) {
TestFuncResult test_str8_alloc_buf(void) { TestFuncResult test_str8_alloc_buf(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -105,7 +105,7 @@ TestFuncResult test_str8_alloc_buf(void) {
TestFuncResult test_str8_alloc_cstr(void) { TestFuncResult test_str8_alloc_cstr(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -126,7 +126,7 @@ TestFuncResult test_str8_alloc_cstr(void) {
TestFuncResult test_str8_alloc_str8(void) { TestFuncResult test_str8_alloc_str8(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -146,7 +146,7 @@ TestFuncResult test_str8_alloc_str8(void) {
TestFuncResult test_str8_alloc_substr(void) { TestFuncResult test_str8_alloc_substr(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(KB(100)); Allocator allocator = wapp_mem_arena_allocator_init(KiB(100));
if (wapp_mem_allocator_invalid(&allocator)) { if (wapp_mem_allocator_invalid(&allocator)) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -289,7 +289,7 @@ TestFuncResult test_str8_slice(void) {
TestFuncResult test_str8_alloc_concat(void) { TestFuncResult test_str8_alloc_concat(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("Hello world"); Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me."); Str8 suffix1 = wapp_str8_lit(" from me.");
@@ -410,7 +410,7 @@ TestFuncResult test_str8_rfind(void) {
TestFuncResult test_str8_split(void) { TestFuncResult test_str8_split(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
@@ -443,8 +443,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_str8_list_get(list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; 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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_str8_list_get(list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -467,7 +467,7 @@ TestFuncResult test_str8_split(void) {
TestFuncResult test_str8_split_with_max(void) { TestFuncResult test_str8_split_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
@@ -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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_str8_list_get(list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -502,7 +502,7 @@ TestFuncResult test_str8_split_with_max(void) {
TestFuncResult test_str8_rsplit(void) { TestFuncResult test_str8_rsplit(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
@@ -535,8 +535,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_str8_list_get(list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; 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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_str8_list_get(list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -559,7 +559,7 @@ TestFuncResult test_str8_rsplit(void) {
TestFuncResult test_str8_rsplit_with_max(void) { TestFuncResult test_str8_rsplit_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
@@ -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 // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_str8_list_get(list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -594,7 +594,7 @@ TestFuncResult test_str8_rsplit_with_max(void) {
TestFuncResult test_str8_join(void) { TestFuncResult test_str8_join(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
@@ -617,10 +617,10 @@ TestFuncResult test_str8_from_bytes(void) {
Str8 str = wapp_str8_buf(1024); Str8 str = wapp_str8_buf(1024);
Str8 expected = wapp_str8_lit_ro("WAPP"); Str8 expected = wapp_str8_lit_ro("WAPP");
U8Array bytes = wapp_array(u8, U8Array, 'W', 'A', 'P', 'P'); U8Array bytes = wapp_array(u8, 'W', 'A', 'P', 'P');
wapp_str8_from_bytes(&str, &bytes); wapp_str8_from_bytes(&str, bytes);
result = str.size == bytes.count * bytes.item_size; result = str.size == wapp_array_count(bytes) * wapp_array_item_size(bytes);
result = result && wapp_str8_equal(&str, &expected); result = result && wapp_str8_equal(&str, &expected);
return wapp_tester_result(result); return wapp_tester_result(result);

View File

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

View File

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

View File

@@ -4,7 +4,9 @@
#include "test_arena.h" #include "test_arena.h"
#include "test_str8_array.h" #include "test_str8_array.h"
#include "test_i32_array.h" #include "test_i32_array.h"
#include "test_queue.h"
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
@@ -12,14 +14,22 @@
int main(void) { int main(void) {
wapp_tester_run_tests( wapp_tester_run_tests(
test_arena_allocator, 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_init_succeeds_when_reserving_very_large_size,
test_arena_alloc_with_buffer,
test_arena_alloc_succeeds_when_within_capacity, test_arena_alloc_succeeds_when_within_capacity,
test_arena_alloc_fails_when_over_capacity, test_arena_alloc_fails_when_over_capacity,
test_arena_realloc_bigger_size, test_arena_realloc_bigger_size,
test_arena_realloc_smaller_size, test_arena_realloc_smaller_size,
test_arena_temp_begin,
test_arena_temp_end,
test_arena_clear, test_arena_clear,
test_arena_destroy, test_arena_destroy_buffer,
test_arena_destroy_allocated,
test_str8_array, test_str8_array,
test_i32_array, test_i32_array,
test_i32_array_with_capacity, test_i32_array_with_capacity,
@@ -34,6 +44,9 @@ int main(void) {
test_i32_array_copy_alloc, test_i32_array_copy_alloc,
test_i32_array_pop, test_i32_array_pop,
test_i32_array_clear, test_i32_array_clear,
test_queue_push,
test_queue_push_alloc,
test_queue_pop,
test_str8_lit, test_str8_lit,
test_str8_lit_ro, test_str8_lit_ro,
test_str8_buf, test_str8_buf,
@@ -70,6 +83,18 @@ int main(void) {
test_cpath_join_path, test_cpath_join_path,
test_cpath_dirname, test_cpath_dirname,
test_cpath_dirup, 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_success,
test_commander_cmd_failure, test_commander_cmd_failure,
test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_success,

View File

@@ -4,7 +4,9 @@
#include "test_arena.h" #include "test_arena.h"
#include "test_str8_array.h" #include "test_str8_array.h"
#include "test_i32_array.h" #include "test_i32_array.h"
#include "test_queue.h"
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
@@ -12,14 +14,22 @@
int main(void) { int main(void) {
wapp_tester_run_tests( wapp_tester_run_tests(
test_arena_allocator, 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_init_succeeds_when_reserving_very_large_size,
test_arena_alloc_with_buffer,
test_arena_alloc_succeeds_when_within_capacity, test_arena_alloc_succeeds_when_within_capacity,
test_arena_alloc_fails_when_over_capacity, test_arena_alloc_fails_when_over_capacity,
test_arena_realloc_bigger_size, test_arena_realloc_bigger_size,
test_arena_realloc_smaller_size, test_arena_realloc_smaller_size,
test_arena_temp_begin,
test_arena_temp_end,
test_arena_clear, test_arena_clear,
test_arena_destroy, test_arena_destroy_buffer,
test_arena_destroy_allocated,
test_str8_array, test_str8_array,
test_i32_array, test_i32_array,
test_i32_array_with_capacity, test_i32_array_with_capacity,
@@ -27,13 +37,16 @@ int main(void) {
test_i32_array_set, test_i32_array_set,
test_i32_array_append_capped, test_i32_array_append_capped,
test_i32_array_extend_capped, test_i32_array_extend_capped,
test_i32_array_clear,
test_i32_array_pop,
test_i32_array_copy_capped, test_i32_array_copy_capped,
test_i32_array_alloc_capacity, test_i32_array_alloc_capacity,
test_i32_array_append_alloc, test_i32_array_append_alloc,
test_i32_array_extend_alloc, test_i32_array_extend_alloc,
test_i32_array_copy_alloc, test_i32_array_copy_alloc,
test_i32_array_pop,
test_i32_array_clear,
test_queue_push,
test_queue_push_alloc,
test_queue_pop,
test_str8_lit, test_str8_lit,
test_str8_lit_ro, test_str8_lit_ro,
test_str8_buf, test_str8_buf,
@@ -70,6 +83,18 @@ int main(void) {
test_cpath_join_path, test_cpath_join_path,
test_cpath_dirname, test_cpath_dirname,
test_cpath_dirup, 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_success,
test_commander_cmd_failure, test_commander_cmd_failure,
test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_success,