all repos — conver-tool @ 99aae0a6e47779e7794bd643e2ae0ce15621db20

A command line tool to manage ConVer projects.

Removed STC for now, keeping things basic.
h3rald h3rald@h3rald.com
Tue, 09 Jun 2026 16:30:55 +0200
commit

99aae0a6e47779e7794bd643e2ae0ce15621db20

parent

5895116f9f90db06368d1162cb7839742d81206c

20 files changed, 188 insertions(+), 2516 deletions(-)

jump to
M MakefileMakefile

@@ -1,7 +1,7 @@

CC = gcc CFLAGS = -std=c99 -Ivendor/stc/include -Wall -O2 -SRCS = vendor/stc/stc.c src/conver.c +SRCS = src/conver.c OBJS = $(SRCS:.c=.o) conver: $(OBJS)
M src/conver.csrc/conver.c

@@ -1,5 +1,169 @@

#include "conver.h" +#if defined(_WIN32) || defined(_WIN64) +# define FS_WINDOWS +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include <windows.h> +#else +# define FS_POSIX +# include <sys/stat.h> +#endif + +void print_error(conver_result_t result) +{ + switch (result) + { + case CONVER_OK: + break; + case CONVER_ERR_OPEN: + fprintf(stderr, "ERROR: Unable to open file.\n"); + break; + case CONVER_ERR_WRITE: + fprintf(stderr, "ERROR: Unable to write file.\n"); + break; + case CONVER_ERR_READ: + fprintf(stderr, "ERROR: Unable to read file.\n"); + break; + case CONVER_ERR_ALLOC: + fprintf(stderr, "ERROR: Unable to allocate memory for file.\n"); + break; + case CONVER_ERR_STAT: + fprintf(stderr, "ERROR: Unable to get file/directory information.\n"); + break; + } +} + +int fs_dir_exists(const char *path) { +#ifdef FS_WINDOWS + DWORD attr = GetFileAttributesA(path); + return (attr != INVALID_FILE_ATTRIBUTES) && + (attr & FILE_ATTRIBUTE_DIRECTORY); +#else + struct stat st; + return (stat(path, &st) == 0) && S_ISDIR(st.st_mode); +#endif +} + +int fs_file_exists(const char *path) { +#ifdef FS_WINDOWS + DWORD attr = GetFileAttributesA(path); + return (attr != INVALID_FILE_ATTRIBUTES) && + !(attr & FILE_ATTRIBUTE_DIRECTORY); +#else + struct stat st; + return (stat(path, &st) == 0) && S_ISREG(st.st_mode); +#endif +} + +static conver_result_t fs_open_write(const char *path, const char *mode, + const void *data, size_t size) { + FILE *f = fopen(path, mode); + if (!f) return CONVER_ERR_OPEN; + if (size > 0) { + size_t written = fwrite(data, 1, size, f); + if (written != size) { + fclose(f); + return CONVER_ERR_WRITE; + } + } + fclose(f); + return CONVER_OK; +} + +conver_result_t fs_file_create(const char *path) { + return fs_open_write(path, "w", NULL, 0); +} + +conver_result_t fs_file_create_b(const char *path) { + return fs_open_write(path, "wb", NULL, 0); +} + +conver_result_t fs_write(const char *path, const char *text) { + size_t len = 0; + const char *p = text; + while (*p++) len++; /* strlen without <string.h> dependency */ + return fs_open_write(path, "w", text, len); +} + +conver_result_t fs_write_b(const char *path, const void *data, size_t size) { + return fs_open_write(path, "wb", data, size); +} + +conver_result_t fs_append(const char *path, const char *text) { + size_t len = 0; + const char *p = text; + while (*p++) len++; + return fs_open_write(path, "a", text, len); +} + +conver_result_t fs_append_b(const char *path, const void *data, size_t size) { + return fs_open_write(path, "ab", data, size); +} + +static conver_result_t fs_read_all(const char *path, const char *mode, + void **out_buf, size_t *out_len, int nul_term) { + *out_buf = NULL; + if (out_len) *out_len = 0; + + FILE *f = fopen(path, mode); + if (!f) return CONVER_ERR_OPEN; + + /* Determine file size via seek (works for both text and binary, + though on Windows text mode may report a slightly larger size — + we handle that with the actual bytes-read count below). */ + if (fseek(f, 0, SEEK_END) != 0) { fclose(f); return CONVER_ERR_READ; } + long file_size = ftell(f); + if (file_size < 0) { fclose(f); return CONVER_ERR_READ; } + rewind(f); + + size_t alloc_size = (size_t)file_size + (nul_term ? 1 : 0); + unsigned char *buf = (unsigned char *)malloc(alloc_size ? alloc_size : 1); + if (!buf) { fclose(f); return CONVER_ERR_ALLOC; } + + size_t bytes_read = fread(buf, 1, (size_t)file_size, f); + /* On Windows, text mode converts \r\n → \n so bytes_read <= file_size. + Check ferror *before* fclose while the FILE* is still valid. */ + int read_err = ferror(f); + fclose(f); + + if (read_err || (bytes_read == 0 && file_size > 0)) { + free(buf); + return CONVER_ERR_READ; + } + + if (nul_term) buf[bytes_read] = '\0'; + + *out_buf = buf; + if (out_len) *out_len = bytes_read; + return CONVER_OK; +} + +conver_result_t fs_read(const char *path, char **out_buf, size_t *out_len) { + return fs_read_all(path, "r", (void **)out_buf, out_len, 1); +} + +conver_result_t fs_read_b(const char *path, unsigned char **out_buf, size_t *out_len) { + return fs_read_all(path, "rb", (void **)out_buf, out_len, 0); +} + +//// Commands + +void command_init() +{ + int write_all = 0; + if (!fs_dir_exists(CONVER_DIR)) + { + write_all = 1; + } + if (write_all || !fs_file_exists(CONVER_DRAFT_FILE)) + { + printf("Creating %s...\n", CONVER_DRAFT_FILE); + print_error(fs_file_create(CONVER_DRAFT_FILE)); + } +} + //// Main int main(int argc, char *argv[])

@@ -14,6 +178,10 @@ if ((strcmp(arg, "-v") == 0 || strcmp(arg, "--version") == 0))

{ printf("%04X\n", CONVER_VERSION); return 0; + } + if ((strcmp(arg, "init") == 0)) + { + command_init(); } } }
M src/conver.hsrc/conver.h

@@ -3,12 +3,27 @@ #define CONVER_H

#define CONVER_VERSION 0x100D -#include <stdio.h> -#include "stc/cstr.h" +#define CONVER_DIR ".conver" +#define CONVER_DRAFT_FILE ".conver/draft.txt" +#define CONVER_RELEASE_FILE ".conver/release.txt" +#define CONVER_LEGACY_FILE ".conver/legacy.txt" +#define CONVER_HISTORY_FILE ".conver/history.txt" +#define CONVER_RELEASES_FILE ".conver/releases.bin" + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> -#define i_pro_key cstr -#include <stc/vec.h> +typedef enum { + CONVER_OK = 0, + CONVER_ERR_OPEN = -1, + CONVER_ERR_WRITE = -2, + CONVER_ERR_READ = -3, + CONVER_ERR_ALLOC = -4, + CONVER_ERR_STAT = -5 +} conver_result_t;
D vendor/stc/include/stc/common.h

@@ -1,354 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef STC_COMMON_H_INCLUDED -#define STC_COMMON_H_INCLUDED - -#ifdef _MSC_VER - #pragma warning(disable: 4116 4996) // unnamed type definition in parentheses -#endif -#include <inttypes.h> -#include <stddef.h> -#include <stdbool.h> -#include <string.h> -#include <assert.h> - -#ifndef ISIZE_MAX - typedef ptrdiff_t isize_t; - typedef isize_t isize; // [deprecated] - #define ISIZE_MIN PTRDIFF_MIN - #define ISIZE_MAX PTRDIFF_MAX -#endif -#if defined __GNUC__ || defined __clang__ || \ - defined __TINYC__ || _MSC_FULL_VER >= 193933428 - #define STC_HAS_TYPEOF -#endif -#if defined __GNUC__ - #define c_GNUATTR(...) __attribute__((__VA_ARGS__)) -#else - #define c_GNUATTR(...) -#endif -#define STC_INLINE static inline c_GNUATTR(unused) -#define c_ZI PRIiPTR -#define c_ZU PRIuPTR -#define c_NPOS INTPTR_MAX - -// Macro overloading feature support -#define c_MACRO_OVERLOAD(name, ...) \ - c_JOIN(name ## _,c_NUMARGS(__VA_ARGS__))(__VA_ARGS__) -#define c_JOIN0(a, b) a ## b -#define c_JOIN(a, b) c_JOIN0(a, b) -#define c_NUMARGS(...) _c_APPLY_ARG_N((__VA_ARGS__, _c_RSEQ_N)) -#define _c_APPLY_ARG_N(args) _c_ARG_N args -#define _c_RSEQ_N 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, -#define _c_ARG_N(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,N,...) N - -// Saturated overloading -// #define foo(...) foo_I(__VA_ARGS__, c_COMMA_N(foo_3), c_COMMA_N(foo_2), c_COMMA_N(foo_1),)(__VA_ARGS__) -// #define foo_I(a,b,c, n, ...) c_TUPLE_AT_1(n, foo_n,) -#define c_TUPLE_AT_1(x,y,...) y -#define c_COMMA_N(x) ,x -#define c_EXPAND(...) __VA_ARGS__ - -// Select arg, e.g. for #define i_type A,B then c_GETARG(2, i_type) is B -#define c_GETARG(N, ...) c_ARG_##N(__VA_ARGS__,) -#define c_ARG_1(a, ...) a -#define c_ARG_2(a, b, ...) b -#define c_ARG_3(a, b, c, ...) c -#define c_ARG_4(a, b, c, d, ...) d - -#define _i_new_n(T, n) ((T*)i_malloc((n)*c_sizeof(T))) -#define _i_new_zeros(T, n) ((T*)i_calloc(n, c_sizeof(T))) -#define _i_realloc_n(ptr, old_n, n) i_realloc(ptr, (old_n)*c_sizeof *(ptr), (n)*c_sizeof *(ptr)) -#define _i_free_n(ptr, n) i_free(ptr, (n)*c_sizeof *(ptr)) - -#ifndef __cplusplus - #define c_new(T, ...) ((T*)c_safe_memcpy(c_malloc(c_sizeof(T)), ((T[]){__VA_ARGS__}), c_sizeof(T))) - #define c_literal(T) (T) - #define c_make_array(T, ...) ((T[])__VA_ARGS__) - #define c_make_array2d(T, N, ...) ((T[][N])__VA_ARGS__) -#else - #include <new> - #define c_new(T, ...) new (c_malloc(c_sizeof(T))) T(__VA_ARGS__) - #define c_literal(T) T - template<typename T, int M, int N> struct _c_Array { T data[M][N]; }; - #define c_make_array(T, ...) (_c_Array<T, 1, sizeof((T[])__VA_ARGS__)/sizeof(T)>{{__VA_ARGS__}}.data[0]) - #define c_make_array2d(T, N, ...) (_c_Array<T, sizeof((T[][N])__VA_ARGS__)/sizeof(T[N]), N>{__VA_ARGS__}.data) -#endif - -#ifdef STC_ALLOCATOR - #define c_malloc c_JOIN(STC_ALLOCATOR, _malloc) - #define c_calloc c_JOIN(STC_ALLOCATOR, _calloc) - #define c_realloc c_JOIN(STC_ALLOCATOR, _realloc) - #define c_free c_JOIN(STC_ALLOCATOR, _free) -#else - #define c_malloc(sz) malloc(c_i2u_cast(sz)) - #define c_calloc(n, sz) calloc(c_i2u_cast(n), c_i2u_cast(sz)) - #define c_realloc(ptr, old_sz, sz) realloc(ptr, c_i2u_cast(1 ? (sz) : (old_sz))) - #define c_free(ptr, sz) ((void)(sz), free(ptr)) -#endif - -#define c_new_n(T, n) ((T*)c_malloc((n)*c_sizeof(T))) -#define c_free_n(ptr, n) c_free(ptr, (n)*c_sizeof *(ptr)) -#define c_free_obj(ptr) c_free_n(ptr, 1) -#define c_realloc_n(ptr, old_n, n) c_realloc(ptr, (old_n)*c_sizeof *(ptr), (n)*c_sizeof *(ptr)) -#define c_delete_n(T, ptr, n) do { \ - T* _tp = ptr; isize_t _n = n, _i = _n; \ - while (_i--) T##_drop((_tp + _i)); \ - c_free(_tp, _n*c_sizeof(T)); \ -} while (0) - -#define c_static_assert(expr) (void)sizeof(int[(expr) ? 1 : -1]) -#if defined STC_NDEBUG || defined NDEBUG - #define c_assert(expr) (void)sizeof(expr) -#else - #define c_assert(expr) assert(expr) -#endif -#define c_container_of(p, C, m) ((C*)((char*)(1 ? (p) : &((C*)0)->m) - offsetof(C, m))) -#define c_countof(a) (isize_t)(sizeof(a)/sizeof 0[a]) -#define c_as_mut(Tp, p) ((Tp)(1 ? (p) : (Tp)0)) -#define c_safe_cast(T, From, x) ((T)(1 ? (x) : (From){0})) - -// expect signed ints to/from these (use with gcc -Wconversion) -#define c_sizeof (isize_t)sizeof -#define c_strlen(s) (isize_t)strlen(s) -#define c_strncmp(a, b, ilen) strncmp(a, b, c_i2u_cast(ilen)) -#define c_memcpy(d, s, ilen) memcpy(d, s, c_i2u_cast(ilen)) -#define c_memmove(d, s, ilen) memmove(d, s, c_i2u_cast(ilen)) -#define c_memset(d, val, ilen) memset(d, val, c_i2u_cast(ilen)) -#define c_memcmp(a, b, ilen) memcmp(a, b, c_i2u_cast(ilen)) -// library internal, but may be useful in user code: -#define c_u2i_cast(u) (isize_t)(1 ? (u) : (size_t)1) // warns if u is signed -#define c_i2u_cast(i) (size_t)(1 ? (i) : -1) // warns if i is unsigned -#define c_uless(a, b) ((size_t)(a) < (size_t)(b)) -#define c_litstrlen(literal) (c_sizeof("" literal) - 1) - -// x, y are i_keyraw* type, which defaults to i_key*. vp is i_key* type. -#define c_memcmp_eq(x, y) (memcmp(x, y, sizeof *(x)) == 0) -#define c_default_eq(x, y) (*(x) == *(y)) -#define c_default_less(x, y) (*(x) < *(y)) -#define c_default_cmp(x, y) (c_default_less(y, x) - c_default_less(x, y)) -#define c_default_hash(vp) c_hash_n(vp, sizeof *(vp)) -#define c_default_clone(v) (v) -#define c_default_toraw(vp) (*(vp)) -#define c_default_drop(vp) ((void) (vp)) - -// Control block macros - -// [deprecated]: -#define c_init(...) c_make(__VA_ARGS__) -#define c_items(...) c_each_item(__VA_ARGS__) -#define c_foritems(...) for (c_each_item(__VA_ARGS__)) -#define c_foreach(...) for (c_each(__VA_ARGS__)) -#define c_foreach_kv(...) for (c_each_kv(__VA_ARGS__)) -#define c_forrange(...) for (c_range(__VA_ARGS__)) -#define c_forrange32(...) for (c_range32(__VA_ARGS__)) -#define c_arraylen(a) c_countof(a) -#define c_const_cast(Tp, p) c_as_mut(Tp, p) -// End [deprecated] - -// New: -#define c_each(...) c_MACRO_OVERLOAD(c_each, __VA_ARGS__) -#define c_each_3(it, C, cnt) \ - C##_iter it = C##_begin(&cnt); it.ref; C##_next(&it) -#define c_each_4(it, C, start, end) \ - _c_each(it, C, start, (end).ref, _) - -#define c_each_ref(v, C, cnt) \ - C##_value* v = (C##_value*)&v; v; ) \ - for (C##_iter v##_itr_ = C##_begin(&cnt); (v = v##_itr_.ref); C##_next(&v##_itr_) - -#define c_each_n(...) c_MACRO_OVERLOAD(c_each_n, __VA_ARGS__) -#define c_each_n_3(it, C, cnt) c_each_n_4(it, C, cnt, INTPTR_MAX) -#define c_each_n_4(it, C, cnt, n) \ - struct {C##_iter iter; C##_value* ref; isize_t size, index;} \ - it = {.iter=C##_begin(&cnt), .size=n}; (it.ref = it.iter.ref) && it.index < it.size; C##_next(&it.iter), ++it.index - -#define c_each_reverse(...) c_MACRO_OVERLOAD(c_each_reverse, __VA_ARGS__) -#define c_each_reverse_3(it, C, cnt) /* works for stack, vec, queue, deque */ \ - C##_iter it = C##_rbegin(&cnt); it.ref; C##_rnext(&it) -#define c_each_reverse_4(it, C, start, end) \ - _c_each(it, C, start, (end).ref, _r) - -#define _c_each(it, C, start, endref, rev) /* private */ \ - C##_iter it = (start), *_endref_##it = c_safe_cast(C##_iter*, C##_value*, endref) \ - ; it.ref != (C##_value*)_endref_##it; C##rev##next(&it) - -#define c_each_kv(...) c_MACRO_OVERLOAD(c_each_kv, __VA_ARGS__) -#define c_each_kv_4(key, val, C, cnt) /* structured binding for maps */ \ - _c_each_kv(key, val, C, C##_begin(&cnt), NULL) -#define c_each_kv_5(key, val, C, start, end) \ - _c_each_kv(key, val, C, start, (end).ref) - -#define _c_each_kv(key, val, C, start, endref) /* private */ \ - const C##_key *key = (const C##_key*)&key; key; ) \ - for (C##_mapped *val; key; key = NULL) \ - for (C##_iter _it_##key = start, *_endref_##key = c_safe_cast(C##_iter*, C##_value*, endref); \ - _it_##key.ref != (C##_value*)_endref_##key && (key = &_it_##key.ref->first, val = &_it_##key.ref->second); \ - C##_next(&_it_##key) - -#define c_each_item(it, T, ...) \ - struct {T* ref; int size, index;} \ - it = {.ref=c_make_array(T, __VA_ARGS__), .size=(int)(sizeof((T[])__VA_ARGS__)/sizeof(T))} \ - ; it.index < it.size ; ++it.ref, ++it.index - -// c_range, c_range32: python-like int range iteration -#define c_range_t(...) c_MACRO_OVERLOAD(c_range_t, __VA_ARGS__) -#define c_range_t_3(T, i, stop) c_range_t_4(T, i, 0, stop) -#define c_range_t_4(T, i, start, stop) \ - T i=start, _c_end_##i=stop; i < _c_end_##i; ++i -#define c_range_t_5(T, i, start, stop, step) \ - T i=start, _c_inc_##i=step, _c_end_##i=(stop) - (_c_inc_##i > 0) \ - ; (_c_inc_##i > 0) == (i <= _c_end_##i) ; i += _c_inc_##i - -#define c_range(...) c_MACRO_OVERLOAD(c_range, __VA_ARGS__) -#define c_range_1(stop) c_range_t_4(isize_t, _c_i1, 0, stop) -#define c_range_2(i, stop) c_range_t_4(isize_t, i, 0, stop) -#define c_range_3(i, start, stop) c_range_t_4(isize_t, i, start, stop) -#define c_range_4(i, start, stop, step) c_range_t_5(isize_t, i, start, stop, step) - -#define c_range32(...) c_MACRO_OVERLOAD(c_range32, __VA_ARGS__) -#define c_range32_2(i, stop) c_range_t_4(int32_t, i, 0, stop) -#define c_range32_3(i, start, stop) c_range_t_4(int32_t, i, start, stop) -#define c_range32_4(i, start, stop, step) c_range_t_5(int32_t, i, start, stop, step) - -// make container from a literal list -#define c_make(C, ...) \ - C##_from_n(c_make_array(C##_raw, __VA_ARGS__), c_sizeof((C##_raw[])__VA_ARGS__)/c_sizeof(C##_raw)) - -// put multiple raw-type elements from a literal list into a container -#define c_put_items(C, cnt, ...) \ - C##_put_n(cnt, c_make_array(C##_raw, __VA_ARGS__), c_sizeof((C##_raw[])__VA_ARGS__)/c_sizeof(C##_raw)) - -// drop multiple containers of same type -#define c_drop(C, ...) \ - do { for (c_each_item(_c_i2, C*, {__VA_ARGS__})) C##_drop(*_c_i2.ref); } while(0) - -// RAII scopes -#define c_defer(...) \ - for (int _c_i3 = 0; _c_i3++ == 0; __VA_ARGS__) - -#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__) -#define c_with_2(init, deinit) \ - for (int _c_i4 = 0; _c_i4 == 0; ) for (init; _c_i4++ == 0; deinit) -#define c_with_3(init, condition, deinit) \ - for (int _c_i5 = 0; _c_i5 == 0; ) for (init; _c_i5++ == 0 && (condition); deinit) - -// General functions - -STC_INLINE void* c_safe_memcpy(void* dst, const void* src, isize_t size) - { return dst ? memcpy(dst, src, (size_t)size) : NULL; } - -#if INTPTR_MAX == INT64_MAX - #define FNV_BASIS 0xcbf29ce484222325 - #define FNV_PRIME 0x00000100000001b3 -#else - #define FNV_BASIS 0x811c9dc5 - #define FNV_PRIME 0x01000193 -#endif - -STC_INLINE size_t c_basehash_n(const void* key, isize_t len) { - const uint8_t* msg = (const uint8_t*)key; - size_t h = FNV_BASIS, block = 0; - - while (len >= c_sizeof h) { - memcpy(&block, msg, sizeof h); - h ^= block; - h *= FNV_PRIME; - msg += c_sizeof h; - len -= c_sizeof h; - } - while (len--) { - h ^= *(msg++); - h *= FNV_PRIME; - } - return h; -} - -STC_INLINE size_t c_hash_n(const void* key, isize_t len) { - uint64_t b8; uint32_t b4; - switch (len) { - case 8: memcpy(&b8, key, 8); return (size_t)(b8 * 0xc6a4a7935bd1e99d); - case 4: memcpy(&b4, key, 4); return b4 * FNV_BASIS; - default: return c_basehash_n(key, len); - } -} - -STC_INLINE size_t c_hash_str(const char *str) { - const uint8_t* msg = (const uint8_t*)str; - size_t h = FNV_BASIS; - while (*msg) { - h ^= *(msg++); - h *= FNV_PRIME; - } - return h; -} - -#define c_hash_mix(...) /* non-commutative hash combine */ \ - c_hash_mix_n(c_make_array(size_t, {__VA_ARGS__}), c_sizeof((size_t[]){__VA_ARGS__})/c_sizeof(size_t)) - -STC_INLINE size_t c_hash_mix_n(size_t h[], isize_t n) { - for (isize_t i = 1; i < n; ++i) h[0] += h[0] ^ h[i]; - return h[0]; -} - -// generic typesafe swap -#ifdef STC_HAS_TYPEOF -#define c_swap(xp, yp) do { \ - __typeof__(xp) _xp = (xp), _yp = (yp); \ - __typeof__(0[xp]) _tv = *_xp; *_xp = *_yp; *_yp = _tv; \ -} while (0) -#else -#define c_swap(xp, yp) do { \ - (void)sizeof((xp) == (yp)); \ - char _tv[sizeof *(xp)]; \ - void *_xp = xp, *_yp = yp; \ - memcpy(_tv, _xp, sizeof _tv); \ - memcpy(_xp, _yp, sizeof _tv); \ - memcpy(_yp, _tv, sizeof _tv); \ -} while (0) -#endif - -// get next power of two -STC_INLINE isize_t c_next_pow2(isize_t n) { - n--; - n |= n >> 1, n |= n >> 2; - n |= n >> 4, n |= n >> 8; - n |= n >> 16; - #if INTPTR_MAX == INT64_MAX - n |= n >> 32; - #endif - return n + 1; -} - -STC_INLINE char* c_strnstrn(const char *str, isize_t slen, const char *needle, isize_t nlen) { - if (nlen == 0) return (char *)str; - if (nlen > slen) return NULL; - slen -= nlen; - do { - if (*str == *needle && !c_memcmp(str, needle, nlen)) - return (char *)str; - ++str; - } while (slen--); - return NULL; -} -#endif // STC_COMMON_H_INCLUDED
D vendor/stc/include/stc/cstr.h

@@ -1,52 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* A string type with short string optimization in C99. - * Stores up to a 22 bytes long string inside a 24 bytes string representation (x64). - */ -#define i_header // external linkage by default. override with i_static. -#include "priv/linkage.h" - -#ifndef STC_CSTR_H_INCLUDED -#define STC_CSTR_H_INCLUDED - -#include "common.h" -#include "types.h" -#include "priv/utf8_prv.h" -#include "priv/cstr_prv.h" - -#endif // STC_CSTR_H_INCLUDED - -#if defined i_implement || \ - defined STC_CSTR_CORE || \ - defined STC_CSTR_MISC || \ - defined STC_CSTR_IO || \ - defined STC_CSTR_UTF8 - #include "priv/cstr_prv.c" -#endif // i_implement - -#if defined i_import || defined STC_CSTR_UTF8 - #include "priv/utf8_prv.c" -#endif - -#include "priv/linkage2.h"
D vendor/stc/include/stc/priv/cstr_prv.c

@@ -1,299 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -// ------------------- STC_CSTR_CORE -------------------- -#if !defined STC_CSTR_CORE_C_INCLUDED && \ - (defined i_implement || defined STC_CSTR_CORE) -#define STC_CSTR_CORE_C_INCLUDED - -void cstr_drop(const cstr* self) { - if (cstr_is_long(self)) - cstr_l_drop(self); -} - -cstr* cstr_take(cstr* self, const cstr s) { - if (cstr_is_long(self) && self->lon.data != s.lon.data) - cstr_l_drop(self); - *self = s; - return self; -} - -size_t cstr_hash(const cstr *self) { - csview sv = cstr_sv(self); - return c_hash_str(sv.buf); -} - -isize_t cstr_find_sv(const cstr* self, csview search) { - csview sv = cstr_sv(self); - char* res = c_strnstrn(sv.buf, sv.size, search.buf, search.size); - return res ? (res - sv.buf) : c_NPOS; -} - -char* _cstr_init(cstr* self, const isize_t len, const isize_t cap) { - if (cap > cstr_s_cap) { - self->lon.data = (char *)c_malloc(cap + 1); - cstr_l_set_size(self, len); - cstr_l_set_cap(self, cap); - return self->lon.data; - } - cstr_s_set_size(self, len); - return self->sml.data; -} - -char* cstr_reserve(cstr* self, const isize_t cap) { - if (cstr_is_long(self)) { - if (cap > cstr_l_cap(self)) { - self->lon.data = (char *)c_realloc(self->lon.data, cstr_l_cap(self) + 1, cap + 1); - cstr_l_set_cap(self, cap); - } - return self->lon.data; - } - /* from short to long: */ - if (cap > cstr_s_cap) { - char* data = (char *)c_malloc(cap + 1); - const isize_t len = cstr_s_size(self); - /* copy full short buffer to emulate realloc() */ - c_memcpy(data, self->sml.data, c_sizeof self->sml); - self->lon.data = data; - self->lon.size = (size_t)len; - cstr_l_set_cap(self, cap); - return data; - } - return self->sml.data; -} - -char* cstr_resize(cstr* self, const isize_t size, const char value) { - cstr_buf b = cstr_getbuf(self); - if (size > b.size) { - if (size > b.cap && (b.data = cstr_reserve(self, size)) == NULL) - return NULL; - c_memset(b.data + b.size, value, size - b.size); - } - _cstr_set_size(self, size); - return b.data; -} - -isize_t cstr_find_at(const cstr* self, const isize_t pos, const char* search) { - csview sv = cstr_sv(self); - if (pos > sv.size) return c_NPOS; - const char* res = strstr((char*)sv.buf + pos, search); - return res ? (res - sv.buf) : c_NPOS; -} - -char* cstr_assign_n(cstr* self, const char* str, const isize_t len) { - char* d = cstr_reserve(self, len); - if (d) { _cstr_set_size(self, len); c_memmove(d, str, len); } - return d; -} - -char* cstr_append_n(cstr* self, const char* str, const isize_t len) { - cstr_buf b = cstr_getbuf(self); - if (b.size + len > b.cap) { - const size_t off = (size_t)(str - b.data); - b.data = cstr_reserve(self, b.size*3/2 + len); - if (b.data == NULL) return NULL; - if (off <= (size_t)b.size) str = b.data + off; /* handle self append */ - } - c_memcpy(b.data + b.size, str, len); - _cstr_set_size(self, b.size + len); - return b.data; -} - -void cstr_erase(cstr* self, const isize_t pos, isize_t len) { - cstr_buf b = cstr_getbuf(self); - if (len > b.size - pos) len = b.size - pos; - c_memmove(&b.data[pos], &b.data[pos + len], b.size - (pos + len)); - _cstr_set_size(self, b.size - len); -} -#endif // STC_CSTR_CORE_C_INCLUDED - - -// ------------------- STC_CSTR_MISC -------------------- -#if !defined STC_CSTR_MISC_C_INCLUDED && \ - (defined i_implement || defined STC_CSTR_MISC) -#define STC_CSTR_MISC_C_INCLUDED - -void cstr_shrink_to_fit(cstr* self) { - cstr_buf b = cstr_getbuf(self); - if (b.size == b.cap) - return; - if (b.size > cstr_s_cap) { - self->lon.data = (char *)c_realloc(self->lon.data, cstr_l_cap(self) + 1, b.size + 1); - cstr_l_set_cap(self, b.size); - } else if (b.cap > cstr_s_cap) { - c_memcpy(self->sml.data, b.data, b.size + 1); - cstr_s_set_size(self, b.size); - c_free(b.data, b.cap + 1); - } -} - -char* _cstr_internal_move(cstr* self, const isize_t pos1, const isize_t pos2) { - cstr_buf b = cstr_getbuf(self); - if (pos1 != pos2) { - const isize_t newlen = (b.size + pos2 - pos1); - if (newlen > b.cap) - b.data = cstr_reserve(self, b.size*3/2 + pos2 - pos1); - c_memmove(&b.data[pos2], &b.data[pos1], b.size - pos1); - _cstr_set_size(self, newlen); - } - return b.data; -} - -cstr cstr_from_replace(csview in, csview search, csview repl, int32_t count) { - cstr out = cstr_init(); - isize_t from = 0; char* res; - if (count == 0) count = INT32_MAX; - if (search.size) - while (count-- && (res = c_strnstrn(in.buf + from, in.size - from, search.buf, search.size))) { - const isize_t pos = (res - in.buf); - cstr_append_n(&out, in.buf + from, pos - from); - cstr_append_n(&out, repl.buf, repl.size); - from = pos + search.size; - } - cstr_append_n(&out, in.buf + from, in.size - from); - return out; -} -#endif // STC_CSTR_MISC_C_INCLUDED - - -// ------------------- STC_CSTR_IO -------------------- -#if !defined STC_CSTR_IO_C_INCLUDED && \ - (defined i_import || defined STC_CSTR_IO) -#define STC_CSTR_IO_C_INCLUDED - -char* cstr_append_uninit(cstr *self, isize_t len) { - cstr_buf b = cstr_getbuf(self); - if (b.size + len > b.cap && (b.data = cstr_reserve(self, b.size*3/2 + len)) == NULL) - return NULL; - _cstr_set_size(self, b.size + len); - return b.data + b.size; -} - -bool cstr_getdelim(cstr *self, const int delim, FILE *fp) { - int c = fgetc(fp); - if (c == EOF) - return false; - isize_t pos = 0; - cstr_buf b = cstr_getbuf(self); - for (;;) { - if (c == delim || c == EOF) { - _cstr_set_size(self, pos); - return true; - } - if (pos == b.cap) { - _cstr_set_size(self, pos); - char* data = cstr_reserve(self, (b.cap = b.cap*3/2 + 16)); - b.data = data; - } - b.data[pos++] = (char) c; - c = fgetc(fp); - } -} - -isize_t cstr_vfmt(cstr* self, isize_t start, const char* fmt, va_list args) { - va_list args2; - va_copy(args2, args); - const int n = vsnprintf(NULL, 0ULL, fmt, args); - vsnprintf(cstr_reserve(self, start + n) + start, (size_t)n+1, fmt, args2); - va_end(args2); - _cstr_set_size(self, start + n); - return n; -} - -cstr cstr_from_fmt(const char* fmt, ...) { - cstr s = cstr_init(); - va_list args; - va_start(args, fmt); - cstr_vfmt(&s, 0, fmt, args); - va_end(args); - return s; -} - -isize_t cstr_append_fmt(cstr* self, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - const isize_t n = cstr_vfmt(self, cstr_size(self), fmt, args); - va_end(args); - return n; -} - -/* NB! self-data in args is UB */ -isize_t cstr_printf(cstr* self, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - const isize_t n = cstr_vfmt(self, 0, fmt, args); - va_end(args); - return n; -} -#endif // STC_CSTR_IO_C_INCLUDED - -// ------------------- STC_CSTR_UTF8 -------------------- -#if !defined STC_CSTR_UTF8_C_INCLUDED && \ - (defined i_import || defined STC_CSTR_UTF8 || defined STC_UTF8_PRV_C_INCLUDED) -#define STC_CSTR_UTF8_C_INCLUDED - -#include <ctype.h> - -void cstr_u8_erase(cstr* self, const isize_t u8pos, const isize_t u8len) { - csview b = cstr_sv(self); - csview span = cutf8_subview(b.buf, u8pos, u8len); - c_memmove((void *)&span.buf[0], &span.buf[span.size], b.size - span.size - (span.buf - b.buf)); - _cstr_set_size(self, b.size - span.size); -} - -bool cstr_u8_valid(const cstr* self) - { return cutf8_valid(cstr_str(self)); } - -static int toLower(int c) - { return c >= 'A' && c <= 'Z' ? c + 32 : c; } -static int toUpper(int c) - { return c >= 'a' && c <= 'z' ? c - 32 : c; } -static struct { - int (*conv_asc)(int); - uint32_t (*conv_utf)(uint32_t); -} -fn_tocase[] = {{toLower, cutf8_casefold}, - {toLower, cutf8_tolower}, - {toUpper, cutf8_toupper}}; - -cstr cstr_tocase_sv(csview sv, int k) { - cstr out = {0}; - char *buf = cstr_reserve(&out, sv.size*3/2); - isize_t sz = 0; - cutf8_decode_t d = {.state=0}; - const char* end = sv.buf + sv.size; - - while (sv.buf < end) { - sv.buf += cutf8_decode_codepoint(&d, sv.buf, end); - - if (d.codep < 0x80) - buf[sz++] = (char)fn_tocase[k].conv_asc((int)d.codep); - else { - uint32_t cp = fn_tocase[k].conv_utf(d.codep); - sz += cutf8_encode(buf + sz, cp); - } - } - _cstr_set_size(&out, sz); - cstr_shrink_to_fit(&out); - return out; -} -#endif // i_import STC_CSTR_UTF8_C_INCLUDED
D vendor/stc/include/stc/priv/cstr_prv.h

@@ -1,425 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -// IWYU pragma: private, include "stc/cstr.h" -#ifndef STC_CSTR_PRV_H_INCLUDED -#define STC_CSTR_PRV_H_INCLUDED - -#include <stdio.h> /* FILE*, vsnprintf */ -#include <stdlib.h> /* malloc */ -#include <stddef.h> /* size_t */ -#include <stdarg.h> /* cstr_vfmt() */ -/**************************** PRIVATE API **********************************/ - -#if defined __GNUC__ && !defined __clang__ - // linkage.h already does diagnostic push - // Warns wrongfully on -O3 on cstr_assign(&str, "literal longer than 23 ..."); - #pragma GCC diagnostic ignored "-Warray-bounds" -#endif - -enum { cstr_s_cap = sizeof(cstr_buf) - 2 }; -#define cstr_s_size(s) ((isize_t)(s)->sml.size) -#define cstr_s_set_size(s, len) ((s)->sml.data[(s)->sml.size = (uint8_t)(len)] = 0) -#define cstr_s_data(s) (s)->sml.data - -#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - #define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8) - #define cstr_l_cap(s) (isize_t)(~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1)) - #define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_((uintptr_t)(cap), 1)) -#else - #define cstr_l_cap(s) (isize_t)(~(s)->lon.ncap) - #define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~(uintptr_t)(cap)) -#endif -#define cstr_l_size(s) (isize_t)((s)->lon.size) -#define cstr_l_set_size(s, len) ((s)->lon.data[(s)->lon.size = (uintptr_t)(len)] = 0) -#define cstr_l_data(s) (s)->lon.data -#define cstr_l_drop(s) c_free((s)->lon.data, cstr_l_cap(s) + 1) - -#define cstr_is_long(s) ((s)->sml.size >= 128) -extern char* _cstr_init(cstr* self, isize_t len, isize_t cap); -extern char* _cstr_internal_move(cstr* self, isize_t pos1, isize_t pos2); - -/**************************** PUBLIC API **********************************/ - -#define cstr_init() (c_literal(cstr){0}) -#define cstr_lit(literal) cstr_from_n(literal, c_litstrlen(literal)) - -extern cstr cstr_from_replace(csview sv, csview search, csview repl, int32_t count); -extern cstr cstr_from_fmt(const char* fmt, ...) c_GNUATTR(format(printf, 1, 2)); - -extern void cstr_drop(const cstr* self); -extern cstr* cstr_take(cstr* self, const cstr s); -extern char* cstr_reserve(cstr* self, isize_t cap); -extern void cstr_shrink_to_fit(cstr* self); -extern char* cstr_resize(cstr* self, isize_t size, char value); -extern isize_t cstr_find_at(const cstr* self, isize_t pos, const char* search); -extern isize_t cstr_find_sv(const cstr* self, csview search); -extern char* cstr_assign_n(cstr* self, const char* str, isize_t len); -extern char* cstr_append_n(cstr* self, const char* str, isize_t len); -extern isize_t cstr_append_fmt(cstr* self, const char* fmt, ...) c_GNUATTR(format(printf, 2, 3)); -extern char* cstr_append_uninit(cstr *self, isize_t len); - -extern bool cstr_getdelim(cstr *self, int delim, FILE *fp); -extern void cstr_erase(cstr* self, isize_t pos, isize_t len); -extern isize_t cstr_printf(cstr* self, const char* fmt, ...) c_GNUATTR(format(printf, 2, 3)); -extern isize_t cstr_vfmt(cstr* self, isize_t start, const char* fmt, va_list args); -extern size_t cstr_hash(const cstr *self); -extern bool cstr_u8_valid(const cstr* self); -extern void cstr_u8_erase(cstr* self, isize_t u8pos, isize_t u8len); - -STC_INLINE cstr_buf cstr_getbuf(cstr* s) { - return cstr_is_long(s) ? c_literal(cstr_buf){s->lon.data, cstr_l_size(s), cstr_l_cap(s)} - : c_literal(cstr_buf){s->sml.data, cstr_s_size(s), cstr_s_cap}; -} -STC_INLINE zsview cstr_zv(const cstr* s) { - return cstr_is_long(s) ? c_literal(zsview){s->lon.data, cstr_l_size(s)} - : c_literal(zsview){s->sml.data, cstr_s_size(s)}; -} -STC_INLINE csview cstr_sv(const cstr* s) { - return cstr_is_long(s) ? c_literal(csview){s->lon.data, cstr_l_size(s)} - : c_literal(csview){s->sml.data, cstr_s_size(s)}; -} - -STC_INLINE cstr cstr_from_n(const char* str, const isize_t len) { - cstr s; - c_memcpy(_cstr_init(&s, len, len), str, len); - return s; -} - -STC_INLINE cstr cstr_from(const char* str) - { return cstr_from_n(str, c_strlen(str)); } - -STC_INLINE cstr cstr_from_sv(csview sv) - { return cstr_from_n(sv.buf, sv.size); } - -STC_INLINE cstr cstr_from_zv(zsview zv) - { return cstr_from_n(zv.str, zv.size); } - -STC_INLINE cstr cstr_with_size(const isize_t size, const char value) { - cstr s; - c_memset(_cstr_init(&s, size, size), value, size); - return s; -} - -STC_INLINE cstr cstr_with_capacity(const isize_t cap) { - cstr s; - _cstr_init(&s, 0, cap); - return s; -} - -STC_INLINE cstr cstr_move(cstr* self) { - cstr tmp = *self; - *self = cstr_init(); - return tmp; -} - -STC_INLINE cstr cstr_clone(cstr s) { - csview sv = cstr_sv(&s); - return cstr_from_n(sv.buf, sv.size); -} - -#define SSO_CALL(s, call) (cstr_is_long(s) ? cstr_l_##call : cstr_s_##call) - -STC_INLINE void _cstr_set_size(cstr* self, isize_t len) - { SSO_CALL(self, set_size(self, len)); } - -STC_INLINE void cstr_clear(cstr* self) - { _cstr_set_size(self, 0); } - -STC_INLINE char* cstr_data(cstr* self) - { return SSO_CALL(self, data(self)); } - -STC_INLINE const char* cstr_str(const cstr* self) - { return SSO_CALL(self, data(self)); } - -STC_INLINE const char* cstr_toraw(const cstr* self) - { return SSO_CALL(self, data(self)); } - -STC_INLINE isize_t cstr_size(const cstr* self) - { return SSO_CALL(self, size(self)); } - -STC_INLINE bool cstr_is_empty(const cstr* self) - { return cstr_size(self) == 0; } - -STC_INLINE isize_t cstr_capacity(const cstr* self) - { return cstr_is_long(self) ? cstr_l_cap(self) : cstr_s_cap; } - -STC_INLINE isize_t cstr_to_index(const cstr* self, cstr_iter it) - { return it.ref - cstr_str(self); } - -STC_INLINE cstr cstr_from_s(cstr s, isize_t pos, isize_t len) - { return cstr_from_n(cstr_str(&s) + pos, len); } - -STC_INLINE csview cstr_subview(const cstr* self, isize_t pos, isize_t len) { - csview sv = cstr_sv(self); - c_assert(((size_t)pos <= (size_t)sv.size) & (len >= 0)); - if (pos + len > sv.size) len = sv.size - pos; - return c_literal(csview){sv.buf + pos, len}; -} - -STC_INLINE zsview cstr_tail(const cstr* self, isize_t len) { - c_assert(len >= 0); - csview sv = cstr_sv(self); - if (len > sv.size) len = sv.size; - return c_literal(zsview){&sv.buf[sv.size - len], len}; -} - -// BEGIN utf8 functions ===== - -STC_INLINE cstr cstr_u8_from(const char* str, isize_t u8pos, isize_t u8len) - { str = cutf8_at(str, u8pos); return cstr_from_n(str, cutf8_to_index(str, u8len)); } - -STC_INLINE isize_t cstr_u8_size(const cstr* self) - { return cutf8_count(cstr_str(self)); } - -STC_INLINE isize_t cstr_u8_to_index(const cstr* self, isize_t u8pos) - { return cutf8_to_index(cstr_str(self), u8pos); } - -STC_INLINE zsview cstr_u8_tail(const cstr* self, isize_t u8len) { - csview sv = cstr_sv(self); - const char* p = &sv.buf[sv.size]; - while (u8len && p != sv.buf) - u8len -= (*--p & 0xC0) != 0x80; - return c_literal(zsview){p, sv.size - (p - sv.buf)}; -} - -STC_INLINE csview cstr_u8_subview(const cstr* self, isize_t u8pos, isize_t u8len) - { return cutf8_subview(cstr_str(self), u8pos, u8len); } - -STC_INLINE cstr_iter cstr_u8_at(const cstr* self, isize_t u8pos) { - cstr_iter it = {.u8={{cutf8_at(cstr_str(self), u8pos)}}}; - it.chr.size = cutf8_decode_codepoint(&it.u8.dec, it.ref, NULL); - if (*it.ref == '\0') it.ref = NULL; - return it; -} - -// utf8 iterator -STC_INLINE cstr_iter cstr_begin(const cstr* self) { - cstr_iter it = {.u8={{cstr_str(self)}}}; - if (*it.ref == '\0') it.ref = NULL; - else it.chr.size = cutf8_decode_codepoint(&it.u8.dec, it.ref, NULL); - return it; -} - -STC_INLINE cstr_iter cstr_end(const cstr* self) { - (void)self; cstr_iter it = {0}; return it; -} - -STC_INLINE void cstr_next(cstr_iter* it) { - it->ref += it->chr.size; - if (*it->ref == '\0') it->ref = NULL; - else it->chr.size = cutf8_decode_codepoint(&it->u8.dec, it->ref, NULL); -} - -STC_INLINE cstr_iter cstr_advance(cstr_iter it, isize_t u8pos) { - it.ref = cutf8_offset(it.ref, u8pos); - if (*it.ref == '\0') it.ref = NULL; - else it.chr.size = cutf8_decode_codepoint(&it.u8.dec, it.ref, NULL); - return it; -} - -STC_INLINE uint32_t cstr_codepoint(const cstr_iter* it) - { return it->u8.dec.codep; } - - -// utf8 case conversion: requires `#define i_import` before including cstr.h in one TU. -extern cstr cstr_tocase_sv(csview sv, int k); - -STC_INLINE cstr cstr_casefold_sv(csview sv) - { return cstr_tocase_sv(sv, 0); } - -STC_INLINE cstr cstr_tolower_sv(csview sv) - { return cstr_tocase_sv(sv, 1); } - -STC_INLINE cstr cstr_toupper_sv(csview sv) - { return cstr_tocase_sv(sv, 2); } - -STC_INLINE cstr cstr_tolower(const char* str) - { return cstr_tolower_sv(c_sv(str, c_strlen(str))); } - -STC_INLINE cstr cstr_toupper(const char* str) - { return cstr_toupper_sv(c_sv(str, c_strlen(str))); } - -STC_INLINE void cstr_lowercase(cstr* self) - { cstr_take(self, cstr_tolower_sv(cstr_sv(self))); } - -STC_INLINE void cstr_uppercase(cstr* self) - { cstr_take(self, cstr_toupper_sv(cstr_sv(self))); } - -STC_INLINE bool cstr_istarts_with(const cstr* self, const char* sub) { - csview sv = cstr_sv(self); - isize_t len = c_strlen(sub); - return len <= sv.size && !cutf8_icmp_sv((sv.size = len, sv), c_sv(sub, len)); -} - -STC_INLINE bool cstr_iends_with(const cstr* self, const char* sub) { - csview sv = cstr_sv(self); - isize_t len = c_strlen(sub); - return len <= sv.size && !cutf8_icmp(sv.buf + sv.size - len, sub); -} - -STC_INLINE int cstr_icmp(const cstr* s1, const cstr* s2) - { return cutf8_icmp(cstr_str(s1), cstr_str(s2)); } - -STC_INLINE bool cstr_ieq(const cstr* s1, const cstr* s2) { - csview x = cstr_sv(s1), y = cstr_sv(s2); - return x.size == y.size && !cutf8_icmp_sv(x, y); -} - -STC_INLINE bool cstr_iequals(const cstr* self, const char* str) - { return !cutf8_icmp(cstr_str(self), str); } - -// END utf8 ===== - -STC_INLINE int cstr_cmp(const cstr* s1, const cstr* s2) - { return strcmp(cstr_str(s1), cstr_str(s2)); } - -STC_INLINE bool cstr_eq(const cstr* s1, const cstr* s2) { - csview x = cstr_sv(s1), y = cstr_sv(s2); - return x.size == y.size && !c_memcmp(x.buf, y.buf, x.size); -} - -STC_INLINE bool cstr_equals(const cstr* self, const char* str) - { return !strcmp(cstr_str(self), str); } - -STC_INLINE bool cstr_equals_sv(const cstr* self, csview sv) - { return sv.size == cstr_size(self) && !c_memcmp(cstr_str(self), sv.buf, sv.size); } - -STC_INLINE isize_t cstr_find(const cstr* self, const char* search) { - const char *str = cstr_str(self), *res = strstr((char*)str, search); - return res ? (res - str) : c_NPOS; -} - -STC_INLINE bool cstr_contains(const cstr* self, const char* search) - { return strstr((char*)cstr_str(self), search) != NULL; } - -STC_INLINE bool cstr_contains_sv(const cstr* self, csview search) - { return cstr_find_sv(self, search) != c_NPOS; } - - -STC_INLINE bool cstr_starts_with_sv(const cstr* self, csview sub) { - if (sub.size > cstr_size(self)) return false; - return !c_memcmp(cstr_str(self), sub.buf, sub.size); -} - -STC_INLINE bool cstr_starts_with(const cstr* self, const char* sub) { - const char* str = cstr_str(self); - while (*sub && *str == *sub) ++str, ++sub; - return !*sub; -} - -STC_INLINE bool cstr_ends_with_sv(const cstr* self, csview sub) { - csview sv = cstr_sv(self); - if (sub.size > sv.size) return false; - return !c_memcmp(sv.buf + sv.size - sub.size, sub.buf, sub.size); -} - -STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub) - { return cstr_ends_with_sv(self, c_sv(sub, c_strlen(sub))); } - -STC_INLINE char* cstr_assign(cstr* self, const char* str) - { return cstr_assign_n(self, str, c_strlen(str)); } - -STC_INLINE char* cstr_assign_sv(cstr* self, csview sv) - { return cstr_assign_n(self, sv.buf, sv.size); } - -STC_INLINE char* cstr_copy(cstr* self, cstr s) { - csview sv = cstr_sv(&s); - return cstr_assign_n(self, sv.buf, sv.size); -} - - -STC_INLINE char* cstr_push(cstr* self, const char* chr) - { return cstr_append_n(self, chr, cutf8_chr_size(chr)); } - -STC_INLINE void cstr_pop(cstr* self) { - csview sv = cstr_sv(self); - const char* s = sv.buf + sv.size; - while ((*--s & 0xC0) == 0x80) ; - _cstr_set_size(self, (s - sv.buf)); -} - -STC_INLINE char* cstr_append(cstr* self, const char* str) - { return cstr_append_n(self, str, c_strlen(str)); } - -STC_INLINE char* cstr_append_sv(cstr* self, csview sv) - { return cstr_append_n(self, sv.buf, sv.size); } - -STC_INLINE char* cstr_append_s(cstr* self, cstr s) - { return cstr_append_sv(self, cstr_sv(&s)); } - -#define cstr_join(self, sep, vec) do { \ - struct _vec_s { cstr* data; ptrdiff_t size; } \ - *_vec = (struct _vec_s*)&(vec); \ - (void)sizeof((vec).data == _vec->data && &(vec).size == &_vec->size); \ - cstr_join_sn(self, sep, _vec->data, _vec->size); \ -} while (0); - -#define cstr_join_items(self, sep, ...) \ - cstr_join_n(self, sep, c_make_array(const char*, __VA_ARGS__), c_sizeof((const char*[])__VA_ARGS__)/c_sizeof(char*)) - -STC_INLINE void cstr_join_n(cstr* self, const char* sep, const char* arr[], isize_t n) { - const char* _sep = cstr_is_empty(self) ? "" : sep; - while (n--) { cstr_append(self, _sep); cstr_append(self, *arr++); _sep = sep; } -} -STC_INLINE void cstr_join_sn(cstr* self, const char* sep, const cstr arr[], isize_t n) { - const char* _sep = cstr_is_empty(self) ? "" : sep; - while (n--) { cstr_append(self, _sep); cstr_append_s(self, *arr++); _sep = sep; } -} - - -STC_INLINE void cstr_replace_sv(cstr* self, csview search, csview repl, int32_t count) - { cstr_take(self, cstr_from_replace(cstr_sv(self), search, repl, count)); } - -STC_INLINE void cstr_replace_nfirst(cstr* self, const char* search, const char* repl, int32_t count) - { cstr_replace_sv(self, c_sv(search, c_strlen(search)), c_sv(repl, c_strlen(repl)), count); } - -STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl) - { cstr_replace_nfirst(self, search, repl, INT32_MAX); } - - -STC_INLINE void cstr_replace_at_sv(cstr* self, isize_t pos, isize_t len, const csview repl) { - char* d = _cstr_internal_move(self, pos + len, pos + repl.size); - c_memcpy(d + pos, repl.buf, repl.size); -} -STC_INLINE void cstr_replace_at(cstr* self, isize_t pos, isize_t len, const char* repl) - { cstr_replace_at_sv(self, pos, len, c_sv(repl, c_strlen(repl))); } - -STC_INLINE void cstr_u8_replace(cstr* self, isize_t u8pos, isize_t u8len, const char* repl) { - const char* s = cstr_str(self); csview span = cutf8_subview(s, u8pos, u8len); - cstr_replace_at(self, span.buf - s, span.size, repl); -} - - -STC_INLINE void cstr_insert_sv(cstr* self, isize_t pos, csview sv) - { cstr_replace_at_sv(self, pos, 0, sv); } - -STC_INLINE void cstr_insert(cstr* self, isize_t pos, const char* str) - { cstr_replace_at_sv(self, pos, 0, c_sv(str, c_strlen(str))); } - -STC_INLINE void cstr_u8_insert(cstr* self, isize_t u8pos, const char* str) - { cstr_insert(self, cutf8_to_index(cstr_str(self), u8pos), str); } - -STC_INLINE bool cstr_getline(cstr *self, FILE *fp) - { return cstr_getdelim(self, '\n', fp); } - -#endif // STC_CSTR_PRV_H_INCLUDED
D vendor/stc/include/stc/priv/linkage.h

@@ -1,77 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#undef STC_API -#undef STC_DEF - -#if !defined i_implement && (defined STC_IMPLEMENT || defined i_import) - #define i_implement -#endif -#if !(defined i_static || defined STC_STATIC) && (defined i_header || defined STC_HEADER || defined i_implement) - #define STC_API extern - #define STC_DEF -#else - #if defined __GNUC__ || defined __clang__ || defined __INTEL_LLVM_COMPILER - #define STC_API static __attribute__((unused)) - #else - #define STC_API static inline - #endif - #define STC_DEF static - #undef i_implement - #define i_implement -#endif - -#if defined i_aux && defined i_allocator - #define _i_aux_alloc -#endif -#ifndef i_allocator - #define i_allocator c -#endif -#ifndef i_free - #define i_malloc c_JOIN(i_allocator, _malloc) - #define i_calloc c_JOIN(i_allocator, _calloc) - #define i_realloc c_JOIN(i_allocator, _realloc) - #define i_free c_JOIN(i_allocator, _free) -#endif - -#if defined __clang__ && !defined __cplusplus - #pragma clang diagnostic push - #pragma clang diagnostic warning "-Wall" - #pragma clang diagnostic warning "-Wextra" - #pragma clang diagnostic warning "-Wpedantic" - #pragma clang diagnostic warning "-Wconversion" - #pragma clang diagnostic warning "-Wwrite-strings" - // ignored - #pragma clang diagnostic ignored "-Wmissing-field-initializers" -#elif defined __GNUC__ && !defined __cplusplus - #pragma GCC diagnostic push - #pragma GCC diagnostic warning "-Wall" - #pragma GCC diagnostic warning "-Wextra" - #pragma GCC diagnostic warning "-Wpedantic" - #pragma GCC diagnostic warning "-Wconversion" - #pragma GCC diagnostic warning "-Wwrite-strings" - // ignored - #pragma GCC diagnostic ignored "-Wclobbered" - #pragma GCC diagnostic ignored "-Wimplicit-fallthrough=3" - #pragma GCC diagnostic ignored "-Wstringop-overflow=" - #pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif
D vendor/stc/include/stc/priv/linkage2.h

@@ -1,42 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#undef i_aux -#undef _i_aux_alloc - -#undef i_allocator -#undef i_malloc -#undef i_calloc -#undef i_realloc -#undef i_free - -#undef i_static -#undef i_header -#undef i_implement -#undef i_import - -#if defined __clang__ && !defined __cplusplus - #pragma clang diagnostic pop -#elif defined __GNUC__ && !defined __cplusplus - #pragma GCC diagnostic pop -#endif
D vendor/stc/include/stc/priv/template.h

@@ -1,320 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -// IWYU pragma: private -#ifndef _i_template -#define _i_template - -#ifndef STC_TEMPLATE_H_INCLUDED -#define STC_TEMPLATE_H_INCLUDED - - #define _c_MEMB(name) c_JOIN(Self, name) - #define _c_DEFTYPES(macro, SELF, ...) macro(SELF, __VA_ARGS__) - #define _m_value _c_MEMB(_value) - #define _m_key _c_MEMB(_key) - #define _m_mapped _c_MEMB(_mapped) - #define _m_rmapped _c_MEMB(_rmapped) - #define _m_raw _c_MEMB(_raw) - #define _m_keyraw _c_MEMB(_keyraw) - #define _m_iter _c_MEMB(_iter) - #define _m_result _c_MEMB(_result) - #define _m_node _c_MEMB(_node) - - #define c_OPTION(flag) ((i_opt) & (flag)) - #define c_declared (1<<0) - #define c_no_atomic (1<<1) - #define c_use_arc2 (1<<2) - #define c_use_rc2 c_use_arc2 - #define c_no_clone (1<<3) - #define c_use_cmp (1<<5) - #define c_use_eq (1<<6) - #define c_use_compare (c_use_cmp | c_use_eq) - #define c_compare_key (1<<7) - #define c_class_key (1<<8) - #define c_class_val (1<<9) - #define c_pro_key (1<<10) - #define c_pro_val (1<<11) - - #define c_use_comp c_use_compare // [deprecated] - #define c_comp_key c_compare_key // [deprecated] - #define c_keycomp c_compare_key // [deprecated] - #define c_cmpclass c_compare_key // [deprecated] - #define c_keyclass c_class_key // [deprecated] - #define c_valclass c_class_val // [deprecated] - #define c_keypro c_pro_key // [deprecated] - #define c_valpro c_pro_val // [deprecated] -#endif -#ifdef i_keycomp // [deprecated] - #define i_compare_key i_keycomp -#elif defined i_comp_key // [deprecated] - #define i_compare_key i_comp_key -#elif defined i_keyclass // [deprecated] - #define i_class_key i_keyclass -#elif defined i_keypro // [deprecated] - #define i_pro_key i_keypro -#endif -#if defined i_valclass // [deprecated] - #define i_class_val i_valclass -#elif defined i_valpro // [deprecated] - #define i_pro_val i_valpro -#endif - -#if defined T && !defined i_type - #define i_type T -#endif -#if defined i_type && c_NUMARGS(i_type) > 1 - #define Self c_GETARG(1, i_type) - #define i_key c_GETARG(2, i_type) - #ifdef _i_is_map - #define i_val c_GETARG(3, i_type) - #if c_NUMARGS(i_type) == 4 - #define i_opt c_GETARG(4, i_type)+0 - #endif - #elif c_NUMARGS(i_type) >= 3 - #define i_opt c_GETARG(3, i_type)+0 - #endif -#elif !defined Self && defined i_type - #define Self i_type -#elif !defined Self - #define Self c_JOIN(_i_prefix, i_tag) -#endif - -#if defined i_aux && c_NUMARGS(i_aux) == 2 - // shorthand for defining i_aux AND i_allocator as a one-liner combo. - #define _i_aux_alloc - #define _i_aux_def c_GETARG(1, i_aux) aux; - #undef i_allocator // override: - #define i_allocator c_GETARG(2, i_aux) -#elif defined i_aux - #define _i_aux_def i_aux aux; -#else - #define _i_aux_def -#endif - -#if c_OPTION(c_declared) - #define i_declared -#endif -#if c_OPTION(c_use_cmp) - #define i_use_cmp -#endif -#if c_OPTION(c_use_eq) - #define i_use_eq -#endif -#if c_OPTION(c_no_clone) || defined _i_is_arc - #define i_no_clone -#endif -#if c_OPTION(c_class_key) - #define i_class_key i_key -#endif -#if c_OPTION(c_class_val) - #define i_class_val i_val -#endif -#if c_OPTION(c_compare_key) - #define i_compare_key i_key - #define i_use_cmp - #define i_use_eq -#endif -#if c_OPTION(c_pro_key) - #define i_pro_key i_key -#endif -#if c_OPTION(c_pro_val) - #define i_pro_val i_val -#endif - -#if defined i_pro_key - #define i_class_key i_pro_key - #define i_compare_key c_JOIN(i_pro_key, _raw) -#endif - -#if defined i_compare_key - #define i_keyraw i_compare_key -#elif defined i_class_key && !defined i_keyraw - // Also bind comparisons functions when c_class_key is specified. - #define i_compare_key i_key -#elif defined i_keyraw && !defined i_keyfrom - // Define _i_no_put when i_keyfrom is not explicitly defined and i_keyraw is. - // In this case, i_keytoraw needs to be defined (may be done later in this file). - #define _i_no_put -#endif - -// Bind to i_key "class members": _clone, _drop, _from and _toraw (when conditions are met). -#if defined i_class_key - #ifndef i_key - #define i_key i_class_key - #endif - #if !defined i_keyclone && !defined i_no_clone - #define i_keyclone c_JOIN(i_class_key, _clone) - #endif - #ifndef i_keydrop - #define i_keydrop c_JOIN(i_class_key, _drop) - #endif - #if !defined i_keyfrom && defined i_keyraw - #define i_keyfrom c_JOIN(i_class_key, _from) - #endif - #if !defined i_keytoraw && defined i_keyraw - #define i_keytoraw c_JOIN(i_class_key, _toraw) - #endif -#endif - -// Define when container has support for sorting (cmp) and linear search (eq) -#if defined i_use_cmp || defined i_cmp || defined i_less || defined _i_sorted - #define _i_has_cmp -#endif -#if defined i_use_eq || defined i_eq || defined i_hash || defined _i_hasher - #define _i_has_eq -#endif - -// Bind to i_compare_key "class members": _cmp, _eq and _hash (when conditions are met). -#if defined i_compare_key - #if !(defined i_cmp || defined i_less) && defined _i_has_cmp - #define i_cmp c_JOIN(i_compare_key, _cmp) - #endif - #if !defined i_eq && defined _i_has_eq - #define i_eq c_JOIN(i_compare_key, _eq) - #endif - #if !(defined i_hash || defined i_no_hash) - #define i_hash c_JOIN(i_compare_key, _hash) - #endif -#endif - -#if !defined i_key - #error "No i_key defined" -#elif defined i_keyraw && !(c_OPTION(c_compare_key) || defined i_keytoraw) - #error "If i_compare_key / i_keyraw is defined, i_keytoraw must be defined too" -#elif !defined i_no_clone && (defined i_keyclone ^ defined i_keydrop) - #error "Both i_keyclone and i_keydrop must be defined, if any (unless i_no_clone defined)." -#elif defined i_from || defined i_drop - #error "i_from / i_drop not supported. Use i_keyfrom/i_keydrop" -#elif defined i_keyto || defined i_valto - #error i_keyto / i_valto not supported. Use i_keytoraw / i_valtoraw -#elif defined i_keyraw && defined i_use_cmp && !defined _i_has_cmp - #error "For smap / sset / pqueue, i_cmp or i_less must be defined when i_keyraw is defined." -#endif - -// Fill in missing i_eq, i_less, i_cmp functions with defaults. -#if !defined i_eq - #define i_eq(x, y) *x == *y // works for integral types - #define _i_has_default_eq -#endif -#if !defined i_less && defined i_cmp - #define i_less(x, y) (i_cmp(x, y)) < 0 -#elif !defined i_less - #define i_less(x, y) *x < *y // works for integral types -#endif -#if !defined i_cmp && defined i_less - #define i_cmp(x, y) (i_less(y, x)) - (i_less(x, y)) -#endif -#if !(defined i_hash || defined i_no_hash) - #define i_hash c_default_hash -#endif - -#define _i_no_emplace -#define _i_is_trivial - -#ifndef i_tag - #define i_tag i_key -#endif -#ifndef i_keyfrom - #define i_keyfrom c_default_clone -#else - #undef _i_no_emplace -#endif -#ifndef i_keyraw - #define i_keyraw i_key -#endif -#ifndef i_keytoraw - #define i_keytoraw c_default_toraw -#endif -#ifndef i_keyclone - #define i_keyclone c_default_clone -#endif -#ifndef i_keydrop - #define i_keydrop c_default_drop -#else - #undef _i_is_trivial -#endif - -#if defined _i_is_map // ---- process hashmap/sortedmap value i_val, ... ---- - -#if defined i_pro_val - #define i_class_val i_pro_val - #define i_valraw c_JOIN(i_pro_val, _raw) -#endif - -#ifdef i_class_val - #ifndef i_val - #define i_val i_class_val - #endif - #if !defined i_valclone && !defined i_no_clone - #define i_valclone c_JOIN(i_class_val, _clone) - #endif - #ifndef i_valdrop - #define i_valdrop c_JOIN(i_class_val, _drop) - #endif - #if !defined i_valfrom && defined i_valraw - #define i_valfrom c_JOIN(i_class_val, _from) - #endif - #if !defined i_valtoraw && defined i_valraw - #define i_valtoraw c_JOIN(i_class_val, _toraw) - #endif -#endif - -#ifndef i_val - #error "i_val* must be defined for maps" -#elif defined i_valraw && !defined i_valtoraw - #error "If i_valraw is defined, i_valtoraw must be defined too" -#elif !defined i_no_clone && (defined i_valclone ^ defined i_valdrop) - #error "Both i_valclone and i_valdrop must be defined, if any" -#endif - -#ifndef i_valfrom - #define i_valfrom c_default_clone - #ifdef i_valraw - #define _i_no_put - #endif -#else - #undef _i_no_emplace -#endif -#ifndef i_valraw - #define i_valraw i_val -#endif -#ifndef i_valtoraw - #define i_valtoraw c_default_toraw -#endif -#ifndef i_valclone - #define i_valclone c_default_clone -#endif -#ifndef i_valdrop - #define i_valdrop c_default_drop -#else - #undef _i_is_trivial -#endif - -#endif // !_i_is_map - -#ifndef i_val - #define i_val i_key -#endif -#ifndef i_valraw - #define i_valraw i_keyraw -#endif -#endif // STC_TEMPLATE_H_INCLUDED
D vendor/stc/include/stc/priv/template2.h

@@ -1,77 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -// IWYU pragma: private -#undef T // alias for i_type -#undef i_type -#undef i_class -#undef i_tag -#undef i_opt -#undef i_capacity - -#undef i_compare_key // define i_keyraw, and bind i_cmp, i_eq, i_hash "class members" -#undef i_class_key -#undef i_pro_key -#undef i_cmpclass // [deprecated] -#undef i_keycomp // [deprecated] -#undef i_keyclass // [deprecated] -#undef i_keypro // [deprecated] - -#undef i_key -#undef i_keyclone -#undef i_keydrop -#undef i_keyraw -#undef i_keyfrom -#undef i_keytoraw -#undef i_cmp -#undef i_less -#undef i_eq -#undef i_hash - -#undef i_class_val -#undef i_pro_val -#undef i_valclass // [deprecated] -#undef i_valpro // [deprecated] - -#undef i_val -#undef i_valclone -#undef i_valdrop -#undef i_valraw -#undef i_valfrom -#undef i_valtoraw - -#undef i_use_cmp -#undef i_use_eq -#undef i_no_hash -#undef i_no_clone -#undef i_declared - -#undef _i_no_put -#undef _i_no_emplace -#undef _i_is_trivial -#undef _i_aux_def -#undef _i_has_cmp -#undef _i_has_eq -#undef _i_has_default_eq -#undef _i_prefix -#undef _i_template -#undef Self
D vendor/stc/include/stc/priv/utf8_decode.h

@@ -1,41 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef STC_UTF8_DECODE_H_INCLUDED -#define STC_UTF8_DECODE_H_INCLUDED - -enum { cutf8_ACCEPT=0, cutf8_REJECT=12 }; - -extern int cutf8_decode_codepoint(cutf8_decode_t* d, const char* s, const char* end); // s < end -extern uint32_t cutf8_peek(const char* s); - -static inline uint32_t cutf8_decode(cutf8_decode_t* d, const uint32_t byte) { - /* decode next utf8 codepoint. https://bjoern.hoehrmann.de/utf-8/decoder/dfa */ - extern const uint8_t cutf8_dtab[]; /* utf8_decode.c */ - - const uint32_t type = cutf8_dtab[byte]; - d->codep = d->state ? (byte & 0x3fu) | (d->codep << 6) - : (0xffU >> type) & byte; - return d->state = cutf8_dtab[256 + d->state + type]; -} - -#endif // STC_UTF8_DECODE_H_INCLUDED
D vendor/stc/include/stc/priv/utf8_prv.h

@@ -1,172 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -// IWYU pragma: private, include "stc/utf8.h" -#ifndef STC_UTF8_PRV_H_INCLUDED -#define STC_UTF8_PRV_H_INCLUDED - -#include <ctype.h> - -// The following functions assume valid utf8 strings: - -/* number of bytes in a utf8 codepoint given its first byte */ -STC_INLINE int cutf8_chr_size(const char *s) { - // Every nibble represents the utf8 length given the - // first 4 bits of a utf8 encoded byte. - return (int)((0x4322000011111111ull >> (((uint8_t)*s >> 4) << 2)) & 0xf); -} - -/* number of codepoints in the utf8 string s */ -STC_INLINE isize_t cutf8_count(const char *s) { - isize_t size = 0; - while (*s) - size += (*++s & 0xC0) != 0x80; - return size; -} - -STC_INLINE isize_t cutf8_count_n(const char *s, isize_t nbytes) { - isize_t size = 0; - while (nbytes-- != 0 && *s != 0) { - size += (*++s & 0xC0) != 0x80; - } - return size; -} - -STC_INLINE const char* cutf8_at(const char *s, isize_t u8pos) { - while ((u8pos > 0) & (*s != 0)) - u8pos -= (*++s & 0xC0) != 0x80; - c_assert(u8pos == 0); - return s; -} - -STC_INLINE const char* cutf8_offset(const char* s, isize_t u8pos) { - int inc = 1; - if (u8pos < 0) u8pos = -u8pos, inc = -1; - while (u8pos && *s) - u8pos -= (*(s += inc) & 0xC0) != 0x80; - c_assert(u8pos == 0); - return s; -} - -STC_INLINE isize_t cutf8_to_index(const char* s, isize_t u8pos) - { return cutf8_at(s, u8pos) - s; } - -STC_INLINE csview cutf8_subview(const char *s, isize_t u8pos, isize_t u8len) { - csview span; - span.buf = cutf8_at(s, u8pos); - span.size = cutf8_to_index(span.buf, u8len); - return span; -} - -// ------------------------------------------------------ -// Functions below must be linked with utf8_prv.c and utf8_decode.c -// To call them, either define i_import before including -// one of cstr, csview, zsview, or link with src/libstc.a - -#include "utf8_decode.h" - -extern bool cutf8_valid(const char* s); -extern bool cutf8_valid_n(const char* s, isize_t nbytes); -extern int cutf8_encode(char *out, uint32_t c); -extern uint32_t cutf8_casefold(uint32_t c); -extern uint32_t cutf8_tolower(uint32_t c); -extern uint32_t cutf8_toupper(uint32_t c); -extern int cutf8_icmp_sv(const csview s1, const csview s2); - -STC_INLINE uint32_t cutf8_peek_at(const char* s, isize_t offset) - { return cutf8_peek(cutf8_offset(s, offset)); } - -STC_INLINE bool cutf8_isupper(uint32_t c) - { return c < 128 ? (c >= 'A') & (c <= 'Z') : cutf8_tolower(c) != c; } - -STC_INLINE bool cutf8_islower(uint32_t c) - { return c < 128 ? (c >= 'a') & (c <= 'z') : cutf8_toupper(c) != c; } - -/* case-insensitive utf8 string comparison */ -STC_INLINE int cutf8_icmp(const char* s1, const char* s2) { - return cutf8_icmp_sv(c_sv(s1, INTPTR_MAX), c_sv(s2, INTPTR_MAX)); -} - -// ------------------------------------------------------ -// Functions below must be linked with ucd_prv.c content - -enum cutf8_group { - U8G_Cc, U8G_L, U8G_Lm, U8G_Lt, U8G_Nd, U8G_Nl, U8G_No, - U8G_P, U8G_Pc, U8G_Pd, U8G_Pe, U8G_Pf, U8G_Pi, U8G_Ps, - U8G_Sc, U8G_Sk, U8G_Sm, U8G_Zl, U8G_Zp, U8G_Zs, - U8G_Arabic, U8G_Bengali, U8G_Cyrillic, - U8G_Devanagari, U8G_Georgian, U8G_Greek, - U8G_Han, U8G_Hiragana, U8G_Katakana, - U8G_Latin, U8G_Thai, - U8G_SIZE -}; - -extern bool cutf8_isgroup(int group, uint32_t c); - -STC_INLINE bool cutf8_isdigit(uint32_t c) - { return c < 128 ? (c >= '0') & (c <= '9') : cutf8_isgroup(U8G_Nd, c); } - -STC_INLINE bool cutf8_isalpha(uint32_t c) - { return (c < 128 ? isalpha((int)c) != 0 : cutf8_isgroup(U8G_L, c)); } - -STC_INLINE bool cutf8_iscased(uint32_t c) { - if (c < 128) return isalpha((int)c) != 0; - return cutf8_toupper(c) != c || cutf8_tolower(c) != c || cutf8_isgroup(U8G_Lt, c); -} - -STC_INLINE bool cutf8_isalnum(uint32_t c) { - if (c < 128) return isalnum((int)c) != 0; - return cutf8_isgroup(U8G_L, c) || cutf8_isgroup(U8G_Nd, c); -} - -STC_INLINE bool cutf8_isword(uint32_t c) { - if (c < 128) return (isalnum((int)c) != 0) | (c == '_'); - return cutf8_isgroup(U8G_L, c) || cutf8_isgroup(U8G_Nd, c) || cutf8_isgroup(U8G_Pc, c); -} - -STC_INLINE bool cutf8_isblank(uint32_t c) { - if (c < 128) return (c == ' ') | (c == '\t'); - return cutf8_isgroup(U8G_Zs, c); -} - -STC_INLINE bool cutf8_isspace(uint32_t c) { - if (c < 128) return isspace((int)c) != 0; - return ((c == 8232) | (c == 8233)) || cutf8_isgroup(U8G_Zs, c); -} - -#define c_lowerbound(T, c, at, less, N, ret) do { \ - int _n = N, _i = 0, _mid = _n/2; \ - T _c = c; \ - while (_n > 0) { \ - if (less(at((_i + _mid)), &_c)) { \ - _i += _mid + 1; \ - _n -= _mid + 1; \ - _mid = _n*7/8; \ - } else { \ - _n = _mid; \ - _mid = _n/8; \ - } \ - } \ - *(ret) = _i; \ -} while (0) - -#endif // STC_UTF8_PRV_H_INCLUDED
D vendor/stc/include/stc/sys/finalize.h

@@ -1,5 +0,0 @@

-#ifndef i_extend - #include "../priv/linkage2.h" - #include "../priv/template2.h" -#endif -#undef i_extend
D vendor/stc/include/stc/types.h

@@ -1,234 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef STC_TYPES_H_INCLUDED -#define STC_TYPES_H_INCLUDED - -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> - -#define c_true(...) __VA_ARGS__ -#define c_false(...) - -#define declare_rc(C, KEY) declare_arc(C, KEY) -#define declare_rc2(SELF, VAL) declare_arc2(SELF, VAL) -#define declare_list(C, KEY) _declare_list(C, KEY,) -#define declare_stack(C, KEY) _declare_stack(C, KEY,) -#define declare_vec(C, KEY) _declare_stack(C, KEY,) -#define declare_pqueue(C, KEY) _declare_stack(C, KEY,) -#define declare_queue(C, KEY) _declare_queue(C, KEY,) -#define declare_deque(C, KEY) _declare_queue(C, KEY,) -#define declare_hashmap(C, KEY, VAL) _declare_htable(C, c_true, c_false, KEY, VAL,) -#define declare_hashset(C, KEY) _declare_htable(C, c_false, c_true, KEY, KEY,) -#define declare_sortedmap(C, KEY, VAL) _declare_aatree(C, c_true, c_false, KEY, VAL,) -#define declare_sortedset(C, KEY) _declare_aatree(C, c_false, c_true, KEY, KEY,) - -#define declare_list_aux(C, KEY, AUX) _declare_list(C, KEY, AUX aux;) -#define declare_stack_aux(C, KEY, AUX) _declare_stack(C, KEY, AUX aux;) -#define declare_vec_aux(C, KEY, AUX) _declare_stack(C, KEY, AUX aux;) -#define declare_pqueue_aux(C, KEY, AUX) _declare_stack(C, KEY, AUX aux;) -#define declare_queue_aux(C, KEY, AUX) _declare_queue(C, KEY, AUX aux;) -#define declare_deque_aux(C, KEY, AUX) _declare_queue(C, KEY, AUX aux;) -#define declare_hashmap_aux(C, KEY, VAL) _declare_htable(C, c_true, c_false, KEY, VAL, AUX aux;) -#define declare_hashset_aux(C, KEY) _declare_htable(C, c_false, c_true, KEY, KEY, AUX aux;) -#define declare_sortedmap_aux(C, KEY, VAL) _declare_aatree(C, c_true, c_false, KEY, VAL, AUX aux;) -#define declare_sortedset_aux(C, KEY) _declare_aatree(C, c_false, c_true, KEY, KEY, AUX aux;) - -typedef struct { uint32_t state, codep; } cutf8_decode_t; - -// csview : non-null terminated string view -typedef const char csview_value; -typedef struct csview { - csview_value* buf; - ptrdiff_t size; -} csview; - -typedef union { - struct { csview chr; csview_value* end; cutf8_decode_t dec; } u8; - csview chr; - csview_value* ref; -} csview_iter; - -#define c_sv(...) c_MACRO_OVERLOAD(c_sv, __VA_ARGS__) -#define c_sv_1(STRLIT) c_sv_2(STRLIT, c_litstrlen(STRLIT)) -#define c_sv_2(str, n) (c_literal(csview){str, n}) -#define c_svfmt "%.*s" -#define c_svarg(sv) (int)(sv).size, (sv).buf // printf(c_svfmt "\n", c_svarg(sv)); - -// zsview : zero-terminated string view -typedef csview_value zsview_value; -typedef struct zsview { - zsview_value* str; - ptrdiff_t size; -} zsview; - -typedef union { - struct { csview chr; cutf8_decode_t dec; } u8; - csview chr; - zsview_value* ref; -} zsview_iter; - -#define c_zv(literal) (c_literal(zsview){literal, c_litstrlen(literal)}) - -// cstr : zero-terminated owning string (short string optimized - sso) -typedef char cstr_value; -typedef struct { cstr_value* data; intptr_t size, cap; } cstr_buf; -typedef union cstr { - struct { cstr_value data[ sizeof(cstr_buf) - 1 ]; uint8_t size; } sml; - struct { cstr_value* data; uintptr_t size; uintptr_t ncap; } lon; -} cstr; - -typedef union { - struct { csview chr; cutf8_decode_t dec; } u8; - csview chr; // utf8 character/codepoint - const cstr_value* ref; -} cstr_iter; - -// non-owning char pointer -typedef const char* cstr_raw; -#define cstr_raw_cmp(x, y) strcmp(*(x), *(y)) -#define cstr_raw_eq(x, y) (cstr_raw_cmp(x, y) == 0) -#define cstr_raw_hash(vp) c_hash_str(*(vp)) - - -#define declare_arc(SELF, VAL) \ - typedef VAL SELF##_value; \ - typedef struct SELF##_ctrl SELF##_ctrl; \ -\ - typedef union SELF { \ - SELF##_value* get; \ - SELF##_ctrl* ctrl; \ - } SELF - -#define declare_arc2(SELF, VAL) \ - typedef VAL SELF##_value; \ - typedef struct SELF##_ctrl SELF##_ctrl; \ -\ - typedef struct SELF { \ - SELF##_value* get; \ - SELF##_ctrl* ctrl2; \ - } SELF - -#define declare_box(SELF, VAL) \ - typedef VAL SELF##_value; \ -\ - typedef struct SELF { \ - SELF##_value* get; \ - } SELF - -#define _declare_queue(SELF, VAL, AUXDEF) \ - typedef VAL SELF##_value; \ -\ - typedef struct SELF { \ - SELF##_value *cbuf; \ - ptrdiff_t start, end, capmask; \ - AUXDEF \ - } SELF; \ -\ - typedef struct { \ - SELF##_value *ref; \ - ptrdiff_t pos; \ - const SELF* _s; \ - } SELF##_iter - -#define _declare_list(SELF, VAL, AUXDEF) \ - typedef VAL SELF##_value; \ - typedef struct SELF##_node SELF##_node; \ -\ - typedef struct { \ - SELF##_value *ref; \ - SELF##_node *const *_last, *prev; \ - } SELF##_iter; \ -\ - typedef struct SELF { \ - SELF##_node *last; \ - AUXDEF \ - } SELF - -#define _declare_htable(SELF, MAP_ONLY, SET_ONLY, KEY, VAL, AUXDEF) \ - typedef KEY SELF##_key; \ - typedef VAL SELF##_mapped; \ -\ - typedef SET_ONLY( SELF##_key ) \ - MAP_ONLY( struct SELF##_value ) \ - SELF##_value, SELF##_entry; \ -\ - typedef struct { \ - SELF##_value *ref; \ - size_t idx; \ - bool inserted; \ - uint8_t hashx; \ - uint16_t dist; \ - } SELF##_result; \ -\ - typedef struct { \ - SELF##_value *ref, *_end; \ - struct hmap_meta *_mref; \ - } SELF##_iter; \ -\ - typedef struct SELF { \ - SELF##_value* table; \ - struct hmap_meta* meta; \ - ptrdiff_t size, bucket_count; \ - AUXDEF \ - } SELF - -#define _declare_aatree(SELF, MAP_ONLY, SET_ONLY, KEY, VAL, AUXDEF) \ - typedef KEY SELF##_key; \ - typedef VAL SELF##_mapped; \ - typedef struct SELF##_node SELF##_node; \ -\ - typedef SET_ONLY( SELF##_key ) \ - MAP_ONLY( struct SELF##_value ) \ - SELF##_value, SELF##_entry; \ -\ - typedef struct { \ - SELF##_value *ref; \ - bool inserted; \ - } SELF##_result; \ -\ - typedef struct { \ - SELF##_value *ref; \ - SELF##_node *_d; \ - int _top; \ - int32_t _tn, _st[36]; \ - } SELF##_iter; \ -\ - typedef struct SELF { \ - SELF##_node *nodes; \ - int32_t root, disp, head, size, capacity; \ - AUXDEF \ - } SELF - -#define _declare_inplace_stack(SELF, VAL, CAP, AUXDEF) \ - typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref, *end; } SELF##_iter; \ - typedef struct SELF { ptrdiff_t size; SELF##_value data[CAP]; AUXDEF } SELF - -#define _declare_stack(SELF, VAL, AUXDEF) \ - typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref, *end; } SELF##_iter; \ - typedef struct SELF { SELF##_value *data; ptrdiff_t size, capacity; AUXDEF } SELF - -#endif // STC_TYPES_H_INCLUDED
D vendor/stc/include/stc/vec.h

@@ -1,403 +0,0 @@

-/* MIT License - * - * Copyright (c) 2026 Tyge Løvset - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* -#define i_implement -#include <stc/cstr.h> -#include <stc/types.h> - -declare_vec(vec_i32, int); - -typedef struct MyStruct { - vec_i32 int_vec; - cstr name; -} MyStruct; - -#define i_key float -#include <stc/vec.h> - -#define i_pro_key cstr // cstr is a "pro"-type -#include <stc/vec.h> - -#define T vec_i32, int32_t, (c_declared) -#include <stc/vec.h> - -int main(void) { - vec_i32 vec = {0}; - vec_i32_push(&vec, 123); - vec_i32_drop(&vec); - - vec_float fvec = {0}; - vec_float_push(&fvec, 123.3); - vec_float_drop(&fvec); - - vec_cstr svec = {0}; - vec_cstr_emplace(&svec, "Hello, friend"); - vec_cstr_drop(&svec); -} -*/ -#include "priv/linkage.h" -#include "types.h" - -#ifndef STC_VEC_H_INCLUDED -#define STC_VEC_H_INCLUDED -#include "common.h" -#include <stdlib.h> - -#define _it2_ptr(it1, it2) (it1.ref && !it2.ref ? it1.end : it2.ref) -#define _it_ptr(it) (it.ref ? it.ref : it.end) -#endif // STC_VEC_H_INCLUDED - -#ifndef _i_prefix - #define _i_prefix vec_ -#endif -#include "priv/template.h" - -#ifndef i_declared - _c_DEFTYPES(_declare_stack, Self, i_key, _i_aux_def); -#endif -typedef i_keyraw _m_raw; -STC_API void _c_MEMB(_drop)(const Self* cself); -STC_API void _c_MEMB(_clear)(Self* self); -STC_API bool _c_MEMB(_reserve)(Self* self, isize_t cap); -STC_API bool _c_MEMB(_resize)(Self* self, isize_t size, _m_value null); -STC_API _m_iter _c_MEMB(_erase_n)(Self* self, isize_t idx, isize_t n); -STC_API _m_iter _c_MEMB(_insert_uninit)(Self* self, isize_t idx, isize_t n); -#if defined _i_has_eq -STC_API _m_iter _c_MEMB(_find_in)(const Self* self, _m_iter it1, _m_iter it2, _m_raw raw); -#endif // _i_has_eq - -STC_INLINE void _c_MEMB(_value_drop)(const Self* self, _m_value* val) - { (void)self; i_keydrop(val); } - -STC_INLINE Self _c_MEMB(_move)(Self *self) { - Self m = *self; - self->capacity = self->size = 0; - self->data = NULL; - return m; -} - -STC_INLINE void _c_MEMB(_take)(Self *self, Self unowned) { - _c_MEMB(_drop)(self); - *self = unowned; -} - -STC_INLINE _m_value* _c_MEMB(_push)(Self* self, _m_value value) { - if (self->size == self->capacity) - if (!_c_MEMB(_reserve)(self, self->size*2 + 4)) - return NULL; - _m_value *v = self->data + self->size++; - *v = value; - return v; -} - -#ifndef _i_no_put -STC_INLINE void _c_MEMB(_put_n)(Self* self, const _m_raw* raw, isize_t n) - { while (n--) _c_MEMB(_push)(self, i_keyfrom((*raw))), ++raw; } -#endif - -#ifndef _i_no_emplace -STC_API _m_iter _c_MEMB(_emplace_n)(Self* self, isize_t idx, const _m_raw raw[], isize_t n); - -STC_INLINE _m_value* _c_MEMB(_emplace)(Self* self, _m_raw raw) - { return _c_MEMB(_push)(self, i_keyfrom(raw)); } - -STC_INLINE _m_value* _c_MEMB(_emplace_back)(Self* self, _m_raw raw) - { return _c_MEMB(_push)(self, i_keyfrom(raw)); } - -STC_INLINE _m_iter _c_MEMB(_emplace_at)(Self* self, _m_iter it, _m_raw raw) - { return _c_MEMB(_emplace_n)(self, _it_ptr(it) - self->data, &raw, 1); } -#endif // !_i_no_emplace - -#ifndef i_no_clone -STC_API void _c_MEMB(_copy)(Self* self, const Self* other); -STC_API _m_iter _c_MEMB(_copy_to)(Self* self, isize_t idx, const _m_value arr[], isize_t n); -STC_API Self _c_MEMB(_clone)(Self vec); -STC_INLINE _m_value _c_MEMB(_value_clone)(const Self* self, _m_value val) - { (void)self; return i_keyclone(val); } -#endif // !i_no_clone - -STC_INLINE isize_t _c_MEMB(_size)(const Self* self) { return self->size; } -STC_INLINE isize_t _c_MEMB(_capacity)(const Self* self) { return self->capacity; } -STC_INLINE bool _c_MEMB(_is_empty)(const Self* self) { return !self->size; } -STC_INLINE _m_raw _c_MEMB(_value_toraw)(const _m_value* val) { return i_keytoraw(val); } -STC_INLINE const _m_value* _c_MEMB(_front)(const Self* self) { return self->data; } -STC_INLINE _m_value* _c_MEMB(_front_mut)(Self* self) { return self->data; } -STC_INLINE const _m_value* _c_MEMB(_back)(const Self* self) { return &self->data[self->size - 1]; } -STC_INLINE _m_value* _c_MEMB(_back_mut)(Self* self) { return &self->data[self->size - 1]; } - -STC_INLINE void _c_MEMB(_pop)(Self* self) - { c_assert(self->size); _m_value* p = &self->data[--self->size]; i_keydrop(p); } -STC_INLINE _m_value _c_MEMB(_pull)(Self* self) - { c_assert(self->size); return self->data[--self->size]; } -STC_INLINE _m_value* _c_MEMB(_push_back)(Self* self, _m_value value) - { return _c_MEMB(_push)(self, value); } -STC_INLINE void _c_MEMB(_pop_back)(Self* self) { _c_MEMB(_pop)(self); } - -#ifndef _i_aux_alloc - STC_INLINE Self _c_MEMB(_init)(void) - { return c_literal(Self){0}; } - - STC_INLINE Self _c_MEMB(_with_capacity)(isize_t cap) - { Self out = {_i_new_n(_m_value, cap), 0, cap}; return out; } - - STC_INLINE Self _c_MEMB(_with_size_uninit)(isize_t size) - { Self out = {_i_new_n(_m_value, size), size, size}; return out; } - - STC_INLINE Self _c_MEMB(_with_size)(isize_t size, _m_raw default_raw) { - Self out = {_i_new_n(_m_value, size), size, size}; - while (size) out.data[--size] = i_keyfrom(default_raw); - return out; - } - - #ifndef _i_no_put - STC_INLINE Self _c_MEMB(_from_n)(const _m_raw* raw, isize_t n) { - Self out = _c_MEMB(_with_capacity)(n); - _c_MEMB(_put_n)(&out, raw, n); return out; - } - #endif -#endif - -STC_INLINE void _c_MEMB(_shrink_to_fit)(Self* self) - { _c_MEMB(_reserve)(self, c_NPOS); } - -STC_INLINE _m_iter -_c_MEMB(_insert_n)(Self* self, const isize_t idx, const _m_value arr[], const isize_t n) { - _m_iter it = _c_MEMB(_insert_uninit)(self, idx, n); - if (it.ref) - c_memcpy(it.ref, arr, n*c_sizeof *arr); - return it; -} - -STC_INLINE _m_iter _c_MEMB(_insert_at)(Self* self, _m_iter it, const _m_value value) { - return _c_MEMB(_insert_n)(self, _it_ptr(it) - self->data, &value, 1); -} - -STC_INLINE _m_iter _c_MEMB(_erase_at)(Self* self, _m_iter it) { - return _c_MEMB(_erase_n)(self, it.ref - self->data, 1); -} - -STC_INLINE _m_iter _c_MEMB(_erase_range)(Self* self, _m_iter i1, _m_iter i2) { - return _c_MEMB(_erase_n)(self, i1.ref - self->data, _it2_ptr(i1, i2) - i1.ref); -} - -STC_INLINE const _m_value* _c_MEMB(_at)(const Self* self, const isize_t idx) { - c_assert(c_uless(idx, self->size)); return self->data + idx; -} - -STC_INLINE _m_value* _c_MEMB(_at_mut)(Self* self, const isize_t idx) { - c_assert(c_uless(idx, self->size)); return self->data + idx; -} - -// iteration - -STC_INLINE _m_iter _c_MEMB(_begin)(const Self* self) { - _m_iter it = {(_m_value*)self->data, (_m_value*)self->data}; - if (self->size) it.end += self->size; - else it.ref = NULL; - return it; -} - -STC_INLINE _m_iter _c_MEMB(_rbegin)(const Self* self) { - _m_iter it = {(_m_value*)self->data, (_m_value*)self->data}; - if (self->size) { it.ref += self->size - 1; it.end -= 1; } - else it.ref = NULL; - return it; -} - -STC_INLINE _m_iter _c_MEMB(_end)(const Self* self) - { (void)self; _m_iter it = {0}; return it; } - -STC_INLINE _m_iter _c_MEMB(_rend)(const Self* self) - { (void)self; _m_iter it = {0}; return it; } - -STC_INLINE void _c_MEMB(_next)(_m_iter* it) - { if (++it->ref == it->end) it->ref = NULL; } - -STC_INLINE void _c_MEMB(_rnext)(_m_iter* it) - { if (--it->ref == it->end) it->ref = NULL; } - -STC_INLINE _m_iter _c_MEMB(_advance)(_m_iter it, size_t n) { - if ((it.ref += n) >= it.end) it.ref = NULL; - return it; -} - -STC_INLINE isize_t _c_MEMB(_index)(const Self* self, _m_iter it) - { return (it.ref - self->data); } - -STC_INLINE void _c_MEMB(_adjust_end_)(Self* self, isize_t n) - { self->size += n; } - -#if defined _i_has_eq -STC_INLINE _m_iter _c_MEMB(_find)(const Self* self, _m_raw raw) - { return _c_MEMB(_find_in)(self, _c_MEMB(_begin)(self), _c_MEMB(_end)(self), raw); } - -STC_INLINE bool _c_MEMB(_contains)(const Self* self, _m_raw raw) - { return _c_MEMB(_find)(self, raw).ref != NULL; } - -STC_INLINE bool _c_MEMB(_eq)(const Self* self, const Self* other) { -#ifdef _i_has_default_eq - return c_memcmp(self->data, other->data, self->size*c_sizeof(_m_value)) == 0; -#else - if (self->size != other->size) return false; - for (isize_t i = 0; i < self->size; ++i) { - const _m_raw _rx = i_keytoraw((self->data+i)), _ry = i_keytoraw((other->data+i)); - if (!(i_eq((&_rx), (&_ry)))) return false; - } - return true; -#endif -} -#endif // _i_has_eq - -#if defined _i_has_cmp -#include "priv/sort_prv.h" -#endif // _i_has_cmp - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined i_implement - -STC_DEF void -_c_MEMB(_clear)(Self* self) { - if (self->size == 0) return; - _m_value *p = self->data + self->size; - while (p-- != self->data) { i_keydrop(p); } - self->size = 0; -} - -STC_DEF void -_c_MEMB(_drop)(const Self* cself) { - Self* self = (Self*)cself; - if (self->capacity == 0) - return; - _c_MEMB(_clear)(self); - _i_free_n(self->data, self->capacity); -} - -STC_DEF bool -_c_MEMB(_reserve)(Self* self, const isize_t cap) { - isize_t n = cap == c_NPOS ? self->size : cap; - if ((cap > self->capacity) & (n != self->capacity)) { - _m_value* d = (_m_value*)_i_realloc_n(self->data, self->capacity, n); - if (d == NULL) return false; - self->data = d; - self->capacity = n; - } - return self->data != NULL; -} - -STC_DEF bool -_c_MEMB(_resize)(Self* self, const isize_t len, _m_value null) { - if (!_c_MEMB(_reserve)(self, len)) - return false; - const isize_t n = self->size; - for (isize_t i = len; i < n; ++i) - { i_keydrop((self->data + i)); } - for (isize_t i = n; i < len; ++i) - self->data[i] = null; - self->size = len; - return true; -} - -STC_DEF _m_iter -_c_MEMB(_insert_uninit)(Self* self, const isize_t idx, const isize_t n) { - if (self->size + n >= self->capacity) - if (!_c_MEMB(_reserve)(self, self->size*3/2 + n)) - return _c_MEMB(_end)(self); - - _m_value *pos = self->data + idx; - c_memmove(pos + n, pos, (self->size - idx)*c_sizeof *pos); - self->size += n; - return c_literal(_m_iter){pos, self->data + self->size}; -} - -STC_DEF _m_iter -_c_MEMB(_erase_n)(Self* self, const isize_t idx, const isize_t len) { - c_assert(idx + len <= self->size); - _m_value* d = self->data + idx, *p = d, *end = self->data + self->size; - for (isize_t i = 0; i < len; ++i, ++p) - { i_keydrop(p); } - memmove(d, p, (size_t)(end - p)*sizeof *d); - self->size -= len; - return c_literal(_m_iter){p == end ? NULL : d, end - len}; -} - -#ifndef i_no_clone -STC_DEF void -_c_MEMB(_copy)(Self* self, const Self* other) { - if (self == other) return; - _c_MEMB(_clear)(self); - _c_MEMB(_reserve)(self, other->size); - self->size = other->size; - for (c_range(i, other->size)) - self->data[i] = i_keyclone((other->data[i])); -} - -STC_DEF Self -_c_MEMB(_clone)(Self vec) { - Self out = vec, *self = &out; (void)self; - out.data = NULL; out.size = out.capacity = 0; - _c_MEMB(_reserve)(&out, vec.size); - out.size = vec.size; - for (c_range(i, vec.size)) - out.data[i] = i_keyclone(vec.data[i]); - return out; -} - -STC_DEF _m_iter -_c_MEMB(_copy_to)(Self* self, const isize_t idx, - const _m_value arr[], const isize_t n) { - _m_iter it = _c_MEMB(_insert_uninit)(self, idx, n); - if (it.ref) - for (_m_value* p = it.ref, *q = p + n; p != q; ++arr) - *p++ = i_keyclone((*arr)); - return it; -} -#endif // !i_no_clone - -#ifndef _i_no_emplace -STC_DEF _m_iter -_c_MEMB(_emplace_n)(Self* self, const isize_t idx, const _m_raw raw[], isize_t n) { - _m_iter it = _c_MEMB(_insert_uninit)(self, idx, n); - if (it.ref) - for (_m_value* p = it.ref; n--; ++raw, ++p) - *p = i_keyfrom((*raw)); - return it; -} -#endif // !_i_no_emplace - -#if defined _i_has_eq -STC_DEF _m_iter -_c_MEMB(_find_in)(const Self* self, _m_iter i1, _m_iter i2, _m_raw raw) { - (void)self; - const _m_value* p2 = _it2_ptr(i1, i2); - for (; i1.ref != p2; ++i1.ref) { - const _m_raw r = i_keytoraw(i1.ref); - if (i_eq((&raw), (&r))) - return i1; - } - i2.ref = NULL; - return i2; -} -#endif // _i_has_eq -#endif // i_implement -#include "sys/finalize.h"
D vendor/stc/src/cstr_core.c

@@ -1,2 +0,0 @@

-#define STC_CSTR_CORE -#include "../include/stc/cstr.h"
D vendor/stc/src/cstr_io.c

@@ -1,2 +0,0 @@

-#define STC_CSTR_IO -#include "../include/stc/cstr.h"
D vendor/stc/src/cstr_misc.c

@@ -1,2 +0,0 @@

-#define STC_CSTR_MISC -#include "../include/stc/cstr.h"
D vendor/stc/stc.c

@@ -1,4 +0,0 @@

-// Selectively including some files out of STC v6.0 RC4 -// Commit 6574a39b26cf24c32fc58ed585209b35c34c7998 -#include "src/cstr_core.c" -#include "src/cstr_misc.c"