10 Commits

Author SHA1 Message Date
abdelrahman d5578f009a Update stream utilities and fix peek logic
Release / release (push) Successful in 4s
2026-08-30 17:13:32 +01:00
abdelrahman b3830683f6 Print changelog contents to stdout
Release / release (push) Successful in 3s
2026-08-30 14:34:21 +01:00
abdelrahman 0060c51c12 Only extract changelog for new releases
Release / release (push) Successful in 3s
2026-08-30 14:31:11 +01:00
abdelrahman 23613d16b7 Update release workflow
Release / release (push) Successful in 4s
2026-08-30 14:20:47 +01:00
abdelrahman 8cd1d56b4a Save extracted changelog in workspace 2026-08-30 14:20:40 +01:00
abdelrahman 6b8fe820aa Remove empty line for testing
Release / release (push) Failing after 1s
2026-08-30 13:49:15 +01:00
abdelrahman 2554810306 Use python3 in release workflow
Release / release (push) Failing after 3s
2026-08-30 13:48:24 +01:00
abdelrahman 08029141d4 Extract version changelog in release process
Release / release (push) Failing after 4s
2026-08-30 13:45:40 +01:00
abdelrahman a1123b361d Include CHANGELOG file in release packages 2026-08-30 13:45:21 +01:00
abdelrahman f4d2e551b5 Add CHANGELOG 2026-08-30 12:39:03 +01:00
13 changed files with 243 additions and 38 deletions
+30 -12
View File
@@ -34,6 +34,21 @@ jobs:
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Extract version changelog
if: steps.tag.outputs.version
id: changelog
run: |
VERSION="${{ steps.tag.outputs.version }}"
CHANGELOG_FILE=$(python3 scripts/get_changelog.py $VERSION)
if [[ $? != 0 ]]; then
echo "No changelog found for version $VERSION"
exit 1
fi
cat "$CHANGELOG_FILE"
echo "changelog_file=$CHANGELOG_FILE" >> $GITHUB_OUTPUT
- name: Build Artifacts
if: steps.tag.outputs.version
run: |
@@ -46,17 +61,17 @@ jobs:
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
}')
CHANGELOG_FILE="${{ steps.changelog.outputs.changelog_file }}"
RESPONSE=$(jq -n \
--arg tag "v$VERSION" \
--arg name "wapp-v$VERSION" \
--rawfile body "$CHANGELOG_FILE" \
'{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false}' \
| curl -s -X POST \
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
-H "Content-Type: application/json" \
--data-binary @- \
"https://git.thewizardapprentice.com/api/v1/repos/${{ gitea.repository }}/releases")
echo "$RESPONSE"
RELEASE_ID=$(echo $RESPONSE | jq -r '.id')
@@ -78,4 +93,7 @@ jobs:
- name: Cleanup
if: steps.tag.outputs.version
run: rm -rf dist/*
run: |
CHANGELOG_FILE="${{ steps.changelog.outputs.changelog_file }}"
rm -rf dist/*
rm -f "$CHANGELOG_FILE"
+44
View File
@@ -0,0 +1,44 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [2.4.0] - 2026-08-30
### Added
- `wpStreamHasCount`, `wpStreamPeekWithOffset` and `wpStreamConsumeCount` utilities
### Fixed
- Logic for peeking at stream contents
## [2.3.0] - 2026-08-29
### Added
- Compiler detection macros:
- `WP_PLATFORM_CLANG` for the clang compiler
- `WP_PLATFORM_CLANGPP` for the clang++ compiler
- `WP_PLATFORM_CLANG_MAJOR` Major version number for the clang/clang++ compiler
- `WP_PLATFORM_CLANG_MINOR` Minor version number for the clang/clang++ compiler
- `WP_PLATFORM_CLANG_PATCH` Patch version number for the clang/clang++ compiler
- `WP_PLATFORM_GCC` for the gcc compiler
- `WP_PLATFORM_GPP` for the g++ compiler
- `WP_PLATFORM_GCC_MAJOR` Major version number for the gcc/g++ compiler
- `WP_PLATFORM_GCC_MINOR` Minor version number for the gcc/g++ compiler
- `WP_PLATFORM_GCC_PATCH` Patch version number for the gcc/g++ compiler
- `WP_PLATFORM_MSVC` for Microsoft's Visual C++ compiler
- `WP_PLATFORM_MSVC_FULL_VERSION` Full version string for the MSVC compiler
- `WP_PLATFORM_MSVC_VERSION` Version string for the MSVC compiler
- Generic `WpStream` struct to wrap a stream of data
- `WpVoidPtrStream`, `WpC8Stream`, `WpC16Stream`, `WpC32Stream`, `WpU8Stream`, `WpU16Stream`, `WpU32Stream`, `WpU64Stream`, `WpB8Stream`, `WpI8Stream`, `WpI16Stream`, `WpI32Stream`, `WpI64Stream`, `WpF32Stream`, `WpF64Stream`, `WpF128Stream`, `WpUptrStream`, `WpIptrStream` and `WpStr8Stream` aliases for `WpStream` for readability
- Utilities for working with data streams:
- `wpStreamAtEnd`
- `wpStreamHasNext`
- `wpStreamPeek`
- `wpStreamConsume`
+1 -1
View File
@@ -1 +1 @@
2.3.0
2.4.0
+1
View File
@@ -1,6 +1,7 @@
#!/bin/bash
cp -r src wapp
cp CHANGELOG.md wapp
mkdir -p dist
+56
View File
@@ -0,0 +1,56 @@
import os
import re
import argparse
from pathlib import Path
VERSION_HEADER = re.compile(r"\[\d+.\d+.\d+\]")
SCRIPT_DIR = Path(__file__).absolute().parent.parent
def main():
parser = argparse.ArgumentParser()
parser.add_argument("version")
args = parser.parse_args()
changelog = get_changelog(args.version)
outfilename = save_changelog(args.version, changelog)
print(outfilename)
def get_changelog(version: str) -> list[str]:
changelog = SCRIPT_DIR / "CHANGELOG.md"
with changelog.open("r") as infile:
lines = infile.readlines()
start = -1
end = -1
for i, line in enumerate(lines):
if start == -1:
match = re.search(version, line)
if match is None:
continue
start = i
else:
match = VERSION_HEADER.search(line)
if match is not None:
end = i
break
if start == -1:
exit(1)
return lines[start:end] if end > -1 else lines[start:]
def save_changelog(version: str, lines: list[str]) -> str:
version_changelog = SCRIPT_DIR / f"wapp-changelog-{version}.md"
with version_changelog.open("w") as outfile:
outfile.writelines(lines)
return str(version_changelog)
if __name__ == "__main__":
main()
+14 -11
View File
@@ -6,28 +6,31 @@
void _streamValidate(const WpStream *stream, u64 item_size);
b8 _streamAtEnd(const WpStream *stream, u64 item_size) {
_streamValidate(stream, item_size);
b8 wpStreamAtEnd(const WpStream *stream) {
return stream->position >= stream->count;
}
b8 _streamHasNext(const WpStream *stream, u64 item_size) {
_streamValidate(stream, item_size);
return stream->position + 1 < stream->count;
b8 _streamHasCount(const WpStream *stream, u64 count) {
return stream->position + count <= stream->count;
}
void *_streamPeek(const WpStream *stream, u64 item_size) {
if (_streamHasNext(stream, item_size)) {
u64 index = (stream->position + 1) * stream->item_size;
void *_streamPeekWithOffset(const WpStream *stream, u64 offset, u64 item_size) {
_streamValidate(stream, item_size);
if (_streamHasCount(stream, offset + 1)) {
u64 index = (stream->position + offset) * stream->item_size;
return (void *)(&((u8 *)(stream->data))[index]);
}
return NULL;
}
void *_streamConsume(WpStream *stream, u64 item_size) {
if (!_streamAtEnd(stream, item_size)) {
u64 index = stream->position++ * stream->item_size;
void *_streamConsumeCount(WpStream *stream, u64 count, u64 item_size) {
_streamValidate(stream, item_size);
if (_streamHasCount(stream, count)) {
u64 index = stream->position * stream->item_size;
stream->position += count;
return (void *)(&((u8 *)(stream->data))[index]);
}
+13 -8
View File
@@ -58,15 +58,20 @@ typedef WpStream WpStr8Stream;
)
#endif
#define wpStreamAtEnd(TYPE, STREAM) _streamAtEnd(STREAM, sizeof(TYPE))
#define wpStreamHasNext(TYPE, STREAM) _streamHasNext(STREAM, sizeof(TYPE))
#define wpStreamPeek(TYPE, STREAM) ((TYPE *)_streamPeek(STREAM, sizeof(TYPE)))
#define wpStreamConsume(TYPE, STREAM) ((TYPE *)_streamConsume(STREAM, sizeof(TYPE)))
#define wpStreamHasNext(STREAM) _streamHasCount(STREAM, 1)
#define wpStreamHasCount(STREAM, COUNT) _streamHasCount(STREAM, COUNT)
#define wpStreamPeek(TYPE, STREAM) ((TYPE *)_streamPeekWithOffset(STREAM, 0, sizeof(TYPE)))
#define wpStreamPeekWithOffset(TYPE, STREAM, OFFSET) \
((TYPE *)_streamPeekWithOffset(STREAM, OFFSET, sizeof(TYPE)))
#define wpStreamConsume(TYPE, STREAM) ((TYPE *)_streamConsumeCount(STREAM, 1, sizeof(TYPE)))
#define wpStreamConsumeCount(TYPE, STREAM, COUNT) \
((TYPE *)_streamConsumeCount(STREAM, COUNT, sizeof(TYPE)))
b8 _streamAtEnd(const WpStream *stream, u64 item_size);
b8 _streamHasNext(const WpStream *stream, u64 item_size);
void *_streamPeek(const WpStream *stream, u64 item_size);
void *_streamConsume(WpStream *stream, u64 item_size);
b8 wpStreamAtEnd(const WpStream *stream);
b8 _streamHasCount(const WpStream *stream, u64 count);
void *_streamPeekWithOffset(const WpStream *stream, u64 offset, u64 item_size);
void *_streamConsumeCount(WpStream *stream, u64 count, u64 item_size);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
+8
View File
@@ -6,6 +6,10 @@
#include "../os/file/file.h"
#include "../base/strings/str8/str8.h"
#ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP
typedef enum {
WP_LOG_LEVEL_FATAL,
WP_LOG_LEVEL_CRITICAL,
@@ -31,4 +35,8 @@ void wpLogError(const WpLogger *logger, WpStr8 msg);
void wpLogCritical(const WpLogger *logger, WpStr8 msg);
void wpLogFatal(const WpLogger *logger, WpStr8 msg);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WP_PLATFORM_CPP
#endif // !LOG_H
+35 -3
View File
@@ -1,6 +1,7 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_stream.h"
#include <stdio.h>
#define COUNT 3
@@ -12,7 +13,7 @@ WpTestFuncResult test_stream_at_end(void) {
for (u32 i = 0; i < COUNT; ++i) {
wpStreamConsume(c8, &stream);
result = result && (i == 2 ? wpStreamAtEnd(c8, &stream) : !wpStreamAtEnd(c8, &stream));
result = result && (i == 2 ? wpStreamAtEnd(&stream) : !wpStreamAtEnd(&stream));
}
return wpTesterResult(result);
@@ -25,15 +26,31 @@ WpTestFuncResult test_stream_peek(void) {
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = NULL;
while (!wpStreamAtEnd(c8, &stream)) {
for (u32 i = 0; i <= COUNT; ++i) {
c = wpStreamPeek(c8, &stream);
wpStreamConsume(c8, &stream);
result = result && (wpStreamAtEnd(c8, &stream) ? c == NULL : c != NULL);
result = result && (i == 3 ? c == NULL : c != NULL);
}
return wpTesterResult(result);
}
WpTestFuncResult test_stream_peek_with_offset(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
u64 offset = 2;
c8 *c = wpStreamPeekWithOffset(c8, &stream, offset);
result = result && *c == characters[offset];
c = wpStreamPeekWithOffset(c8, &stream, 5);
result = result && c == NULL;
return wpTesterResult(result);
}
WpTestFuncResult test_stream_consume(void) {
b8 result = true;
@@ -48,3 +65,18 @@ WpTestFuncResult test_stream_consume(void) {
return wpTesterResult(result);
}
WpTestFuncResult test_stream_consume_count(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = wpStreamConsumeCount(c8, &stream, COUNT);
result = result && c != NULL && wpStreamAtEnd(&stream);
c = wpStreamConsumeCount(c8, &stream, COUNT);
result = result && c == NULL;
return wpTesterResult(result);
}
+35 -3
View File
@@ -1,6 +1,7 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_stream.h"
#include <stdio.h>
#define COUNT 3
@@ -12,7 +13,7 @@ WpTestFuncResult test_stream_at_end(void) {
for (u32 i = 0; i < COUNT; ++i) {
wpStreamConsume(c8, &stream);
result = result && (i == 2 ? wpStreamAtEnd(c8, &stream) : !wpStreamAtEnd(c8, &stream));
result = result && (i == 2 ? wpStreamAtEnd(&stream) : !wpStreamAtEnd(&stream));
}
return wpTesterResult(result);
@@ -25,15 +26,31 @@ WpTestFuncResult test_stream_peek(void) {
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = NULL;
while (!wpStreamAtEnd(c8, &stream)) {
for (u32 i = 0; i <= COUNT; ++i) {
c = wpStreamPeek(c8, &stream);
wpStreamConsume(c8, &stream);
result = result && (wpStreamAtEnd(c8, &stream) ? c == NULL : c != NULL);
result = result && (i == 3 ? c == NULL : c != NULL);
}
return wpTesterResult(result);
}
WpTestFuncResult test_stream_peek_with_offset(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
u64 offset = 2;
c8 *c = wpStreamPeekWithOffset(c8, &stream, offset);
result = result && *c == characters[offset];
c = wpStreamPeekWithOffset(c8, &stream, 5);
result = result && c == NULL;
return wpTesterResult(result);
}
WpTestFuncResult test_stream_consume(void) {
b8 result = true;
@@ -48,3 +65,18 @@ WpTestFuncResult test_stream_consume(void) {
return wpTesterResult(result);
}
WpTestFuncResult test_stream_consume_count(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = wpStreamConsumeCount(c8, &stream, COUNT);
result = result && c != NULL && wpStreamAtEnd(&stream);
c = wpStreamConsumeCount(c8, &stream, COUNT);
result = result && c == NULL;
return wpTesterResult(result);
}
+2
View File
@@ -7,6 +7,8 @@
WpTestFuncResult test_stream_at_end(void);
WpTestFuncResult test_stream_peek(void);
WpTestFuncResult test_stream_peek_with_offset(void);
WpTestFuncResult test_stream_consume(void);
WpTestFuncResult test_stream_consume_count(void);
#endif // !TEST_STREAM_H
+2
View File
@@ -50,7 +50,9 @@ int main(void) {
test_queue_pop,
test_stream_at_end,
test_stream_peek,
test_stream_peek_with_offset,
test_stream_consume,
test_stream_consume_count,
test_str8_lit,
test_str8_lit_ro,
test_str8_buf,
+2
View File
@@ -50,7 +50,9 @@ int main(void) {
test_queue_pop,
test_stream_at_end,
test_stream_peek,
test_stream_peek_with_offset,
test_stream_consume,
test_stream_consume_count,
test_str8_lit,
test_str8_lit_ro,
test_str8_buf,