summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsteven-na <noreply.github@stvnc.dev>2026-09-07 18:11:21 -0700
committersteven-na <noreply.github@stvnc.dev>2026-09-07 18:11:21 -0700
commit81caeb5ffc0748273157bf26c3299dfee9c12a6d (patch)
tree05ad674efd0f08d205868c61f063605c43ed302e /src
parentfd475232ee12089f817f237cc755fe4444ec483b (diff)
Utility functions
Diffstat (limited to 'src')
-rw-r--r--src/binary.c13
-rw-r--r--src/binary.h28
-rw-r--r--src/smrt_arena.h3
-rw-r--r--src/string.c39
-rw-r--r--src/string.h21
-rw-r--r--src/unity.c1
6 files changed, 99 insertions, 6 deletions
diff --git a/src/binary.c b/src/binary.c
new file mode 100644
index 0000000..bf5ac89
--- /dev/null
+++ b/src/binary.c
@@ -0,0 +1,13 @@
+#include "binary.h"
+
+strng_t *strng_u64_bin(smrt_arena_t *arena, u64 n) {
+ strng_t *s = strng_new(arena, 64);
+ s->len = 64;
+ for (u8 i = 0; i < 64; i++) {
+ b8 set = (n & (1ull << i)) != 0;
+ ((u8*)s)[STRNG_BASE_POS + (63 - i)] = set ? '1' : '0';
+ }
+
+ return s;
+}
+
diff --git a/src/binary.h b/src/binary.h
new file mode 100644
index 0000000..139d2bf
--- /dev/null
+++ b/src/binary.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "common.h"
+#include "log.h"
+#include "string.h"
+
+// Binary representation of u64
+strng_t *strng_u64_bin(smrt_arena_t *arena, u64 n);
+
+static inline strng_view_t uint_to_binsv_impl(smrt_arena_t *arena, u64 n, u8 bits) {
+ strng_t *b = strng_u64_bin(arena, n);
+ strng_view_t svb = sv_from(b);
+ sv_set_len_right(&svb, bits);
+ return svb;
+}
+
+// Converts n (u8-u64) to a strng_view_t representing the 0s and 1s
+#define UINT_TO_BINSV(arena, n) uint_to_binsv_impl(arena, n, \
+ _Generic(n, u8: 8, u16: 16, u32: 32, default: 64))
+
+#define LOG_UINT_BINREP(label, n) \
+ do { \
+ smrta_temp_t _macro_t = QUICK_SCRATCH; \
+ auto _macro_n = (n); \
+ strng_view_t _macro_svb = UINT_TO_BINSV(_macro_t.arena, _macro_n); \
+ log_debug(label": 0b%.*s", SV_FMT(_macro_svb)); \
+ QUICK_SCRATCH_E(_macro_t); \
+ } while (0)
diff --git a/src/smrt_arena.h b/src/smrt_arena.h
index 1b6725f..fe40509 100644
--- a/src/smrt_arena.h
+++ b/src/smrt_arena.h
@@ -26,6 +26,9 @@ smrt_arena_t * smrt_arena_create(u64 reserve_size, u64 commit_size, b32 auto_
#define SMRTA_ALLOC_ARRAY(arena, T, n) (T*)smrt_arena_push(arena, sizeof(T) * (n), true)
+#define QUICK_SCRATCH smrta_scratch_start(NULL, 0)
+#define QUICK_SCRATCH_E(scratch) smrta_scratch_end(scratch)
+
typedef struct {
smrt_arena_t *arena;
u64 start_pos;
diff --git a/src/string.c b/src/string.c
index 63c886a..0925a43 100644
--- a/src/string.c
+++ b/src/string.c
@@ -5,6 +5,7 @@
#include <immintrin.h>
#include <ctype.h>
+#include <stdlib.h>
#include <string.h>
strng_t *strng_new(smrt_arena_t *arena, u64 size) {
@@ -79,6 +80,13 @@ i32 strng_set(strng_t *string, char const *c) {
return 0;
}
+i32 strng_set_ic(strng_t *string, u64 i, char c) {
+ if (i >= string->alloc_size) return -1;
+ if (i >= string->len) string->len = i+1;
+ memset(STRNG_TO(string)+i, c, 1);
+ return 0;
+}
+
i32 strng_app(strng_t *dest, strng_t const *source) {
u64 slen = source->len;
u64 nlen = dest->len + slen;
@@ -123,6 +131,13 @@ void strng_clear(strng_t *string) {
string->len = 0;
}
+char *strng_malloc_str(strng_t const *string) {
+ char *s = malloc(string->len);
+ if (!s) return NULL;
+ memcpy(s, STRNG_TO(string), string->len);
+ return s;
+}
+
strng_view_t sv_from_chars(char const* c) { u64 l = strlen(c);
return (strng_view_t){
.start=0,
@@ -214,6 +229,20 @@ void sv_set_len_right(strng_view_t *sv, u64 n) {
sv->start = sv->end - n + 1;
}
+char sv_get_start(strng_view_t const *sv) {
+ if (sv_len(sv)) {
+ return *(sv->string + sv->start);
+ }
+ return 0;
+}
+
+char sv_get_end(strng_view_t const *sv){
+ if (sv_len(sv)) {
+ return *(sv->string + sv->end);
+ }
+ return 0;
+}
+
i32 sv_find_substr(strng_view_t const *sv, char const *_needle) {
u64 nlen = strlen(_needle);
u64 hlen = sv_len(sv);
@@ -279,6 +308,16 @@ lt_32:
return -1;
}
+u64 sv_count_c(strng_view_t const *sv, char n) {
+ // TODO: simd
+ u64 x = 0;
+ for (u64 i = 0; i < sv_len(sv); i++) {
+ char c = *((u8*)(SV_TO(*sv))+i);
+ if (c == n) x++;
+ }
+ return x;
+}
+
b32 sv_starts_with(strng_view_t const *sv, char const *prefix) {
u64 plen = strlen(prefix);
u64 hlen = sv_len(sv);
diff --git a/src/string.h b/src/string.h
index ea4fd9b..13a433a 100644
--- a/src/string.h
+++ b/src/string.h
@@ -17,11 +17,12 @@ typedef struct {
char const *string;
} strng_view_t;
-strng_t * strng_new(smrt_arena_t *arena, u64 size);
-strng_t *strng_from(smrt_arena_t *arena, char const *c);
-strng_t * strng_dup(smrt_arena_t *arena, strng_t const *src);
- char * strng_str(smrt_arena_t *arena, strng_t const *string);
- i32 strng_set(strng_t *string, char const *c);
+strng_t * strng_new(smrt_arena_t *arena, u64 size);
+strng_t *strng_from(smrt_arena_t *arena, char const *c);
+strng_t * strng_dup(smrt_arena_t *arena, strng_t const *src);
+ char * strng_str(smrt_arena_t *arena, strng_t const *string);
+ i32 strng_set(strng_t *string, char const *c);
+ i32 strng_set_ic(strng_t *string, u64 i, char c);
// Append to strng, returns -1 if no space, new len otherwise
i32 strng_app(strng_t *dest, strng_t const *source);
// Append char* to strng, returns -1 if no space, new len otherwise
@@ -30,6 +31,8 @@ strng_t * strng_dup(smrt_arena_t *arena, strng_t const *src);
i32 strng_app_v(strng_t *dest, strng_view_t const *source);
void strng_clear(strng_t *string);
+char *strng_malloc_str(strng_t const *string);
+
#define STRNG_TO(s) (char *)((u8*)(s)+STRNG_BASE_POS)
#define STRNG_FMT(s) (i32)s->len, (char *)((u8*)(s)+STRNG_BASE_POS)
@@ -69,7 +72,7 @@ static inline strng_view_t sv_subv(strng_view_t const *src,
.max = src->max
};
}
-static inline strng_view_t sv_drop_left(strng_view_t const *src, u64 n) {
+static inline strng_view_t sv_drop_left(strng_view_t const *src, u64 n) {
u64 src_len = sv_len(src);
u64 m = MIN(src_len, n);
return sv_subv(src, m, src_len - m);
@@ -107,6 +110,9 @@ static inline void sv_pop_right(strng_view_t *sv) { if (sv->end >= sv->start)
static inline void sv_popn_left (strng_view_t *sv, u64 n) { for (u64 i = 0; i < n; i++) sv_pop_left(sv); }
static inline void sv_popn_right(strng_view_t *sv, u64 n) { for (u64 i = 0; i < n; i++) sv_pop_right(sv); }
+char sv_get_start(strng_view_t const *sv);
+char sv_get_end(strng_view_t const *sv);
+
static inline void sv_reset(strng_view_t *sv) {
sv->start=0;
sv->end = sv->max;
@@ -119,6 +125,9 @@ i32 sv_find_substr(strng_view_t const *sv, char const *needle);
// Returns -1 if not found, otherwise distance from sv->start
i32 sv_find_char(strng_view_t const *sv, char n);
+// Count occurrences of n in sv.
+u64 sv_count_c(strng_view_t const *sv, char n);
+
b32 sv_starts_with(strng_view_t const *sv, char const *prefix);
b32 sv_ends_with(strng_view_t const *sv, char const *suffix);
static inline b32 sv_starts_with_c(strng_view_t const *sv, char c) { return
diff --git a/src/unity.c b/src/unity.c
index a694f13..3247458 100644
--- a/src/unity.c
+++ b/src/unity.c
@@ -17,6 +17,7 @@
// Data structures
#include "string.c"
+#include "binary.c"
#include "vec2.c"
#include "slidingwindow.c"
#include "vec2sw.c"