65422WRSAIL2WBOKQMPBVXF5LDEBCJW2ZJTJ6O7YWODJ7BP4GT6QC #include "main.h"#include "../testing/testing.h"#include <luajit-2.1/lauxlib.h>#include <luajit-2.1/lua.h>#include <luajit-2.1/lualib.h>#include <stdlib.h>#include <string.h>lua_State *L;#define lua_unreachable(...) \({ \luaL_error(L, __VA_ARGS__); \nullptr; \})static table_t new_table(size_t len) {return (table_t){malloc(len * sizeof(char *)) ?: lua_unreachable("allocation failure"),len,};}char const *basename(char const *path) {char const *last = strrchr(path, '/');return last ? last + 1 : path;}test_table(basename_test, basename, (char const *, char const *),{{ "main.c", "src/main.c"},{"init.lua", "$(HOME)/.config/nvim/init.lua"},})static bool ismatch(char const *target, char const *pattern) {for (; *target && *pattern; target++) pattern += *target == *pattern;return *pattern == '\0';}test_table(match_test, ismatch, (bool, char const *, char const *),{{ true, "aabbccdd", "abcd"},{ true, "src/main.zig", "s/mz"},{false, "hello", "world"},{false, "init.lua", "iin"},})static table_t fuzfilter(table_t tbl, char const *pat) {table_t ret = new_table(tbl.len);int id = 0;bool isfullpath = strchr(pat, '/');for (int i = 0; i < tbl.len; i++) {char const *target = isfullpath ? tbl.buf[i] : basename(tbl.buf[i]);if (ismatch(target, pat)) ret.buf[id++] = tbl.buf[i];}ret.len = id;return ret;}static int fuzpath(lua_State *arg) {L = arg;luaL_checktype(L, 1, LUA_TTABLE);luaL_checktype(L, 2, LUA_TSTRING);size_t tbl_len = lua_objlen(L, 1);table_t table droptbl = new_table(tbl_len);for (size_t i = 1; i <= tbl_len; i++) {lua_rawgeti(L, 1, i);table.buf[i - 1] = luaL_checkstring(L, -1);lua_pop(L, 1);}char const *pattern = luaL_checkstring(L, 2);table_t result droptbl = fuzfilter(table, pattern);lua_newtable(L);for (int i = 0; i < result.len; i++) {lua_pushstring(L, result.buf[i]);lua_rawseti(L, -2, i + 1);}return 1;}int luaopen_fuzpath(lua_State *L) {static luaL_Reg const funcs[] = {{"fuzpath", fuzpath},{ nullptr, nullptr}};luaL_newlib(L, funcs);return 1;}
/*** @file src/ansiesc.c* @brief Test escape sequence macros*/#include "ansiesc.h"#include "testing.h"test (ansi_escape_sequence) {expect(true);test_filter("all") {puts(ESCLR);#define PRINT_HELLO(x) puts(x "hello" ESCLR);MAP(PRINT_HELLO,ESBLD,ESTHN,ESITA,ESULN,ESBLN,ESFBLN,ESREV,ESHID,ESUDO,ESCRED,ESCGRN,ESCYEL,ESCBLU,ESCMGN,ESCCYN,ESCBLK,ESCBRED,ESCBGRN,ESCBYEL,ESCBBLU,ESCBMGN,ESCBCYN,ESCBBLK,ESCCODE(100),ESCCODE_RGB(100, 100, 100))}}
/*** @file include/ansiesc.h* @brief Define escape sequence macros*/#pragma once#define ESCSI "\033["#define ESCLR ESCSI "0m"#define ESBLD ESCSI "1m"#define ESTHN ESCSI "2m"#define ESITA ESCSI "3m"#define ESULN ESCSI "4m"#define ESBLN ESCSI "5m"#define ESFBLN ESCSI "6m"#define ESREV ESCSI "7m"#define ESHID ESCSI "8m"#define ESUDO ESCSI "9m"#define ESCBLK ESCSI "30m"#define ESCRED ESCSI "31m"#define ESCGRN ESCSI "32m"#define ESCYEL ESCSI "33m"#define ESCBLU ESCSI "34m"#define ESCMGN ESCSI "35m"#define ESCCYN ESCSI "36m"#define ESCWHT ESCSI "37m"#define ESCBBLK ESCSI "40m"#define ESCBRED ESCSI "41m"#define ESCBGRN ESCSI "42m"#define ESCBYEL ESCSI "43m"#define ESCBBLU ESCSI "44m"#define ESCBMGN ESCSI "45m"#define ESCBCYN ESCSI "46m"#define ESCBWHT ESCSI "47m"#define ESCCODE(code) ESCSI "38;5;" #code "m"#define ESCCODE_RGB(r, g, b) ESCSI "38;2;" #r ";" #g ";" #b "m"#define ESCUU(n) ESCSI #n "A"#define ESCUD(n) ESCSI #n "B"#define ESCUF(n) ESCSI #n "C"#define ESCUB(n) ESCSI #n "D"#define ESCNL(n) ESCSI #n "E"#define ESCPL(n) ESCSI #n "F"#define ESCHA(n) ESCSI #n "G"#define ESCUP(n, m) ESCSI #n ";" #m "H"#define ESED(n) ESCSI #n "J"#define ESEL(n) ESCSI #n "K"#define ESSU(n) ESCSI #n "S"#define ESSD(n) ESCSI #n "T"#define ESHVP(n, m) ESCSI #n ";" #m "f"#define ESSCP ESCSI "s"#define ESRCP ESCSI "u"
/*** @file src/chore.c* @brief Define util functions*/#include "chore.h"#include "exproriented.h"#include "mathdef.h"#include "testing.h"/*** @brief Check if the decimal part is 0* @param[in] arg Checked double number* @return Is decimal part 0*/inline bool isInt(double arg) {if (isinf(arg) || isnan(arg)) return false;if (arg < -__LONG_MAX__ - 1L || (double)__LONG_MAX__ < arg) return false;return arg == (double)(long)arg;}test_table(isint, isInt, (bool, double),{{ true, 5.0},{ true, 3.000},{ true, 100},{ true, -10},{false, 5.6},{false, 10.9},{false, 99.99999},{false, -10.4}})/*** @brief panic alloc* @param[in] sz Memory size* @warning Unrecoverable*/void *palloc(size_t sz) {return malloc(sz) ?: p$panic(ERR_ALLOCATION_FAILURE);}/*** @brief free for drop*/void freecl(void *p) {free(*bit_cast(void **, p));}void fclosecl(FILE **fp) {fclose(*fp);}void closedircl(DIR **fp) {closedir(*fp);}
/*** @file include/chore.h* @brief Define util macros*/#pragma once#include "def.h"#include <dirent.h>#include <stdio.h>#include <string.h>constexpr size_t alpha_n = 'z' - 'a' + 1;#define HERE __FILE__ ":" TOSTR(__LINE__)#define less(lhs, rhs) ((lhs) < (rhs) ? (lhs) : (rhs))#define more(lhs, rhs) ((lhs) > (rhs) ? (lhs) : (rhs))#define overloadable [[clang::overloadable]]#define ondrop(cl) [[gnu::cleanup(cl)]]#define drop ondrop(freecl)#define dropfile ondrop(fclosecl)#define dropdir ondrop(closedircl)#define __ CAT(_DISCARD_, __COUNTER__) [[gnu::unused]]#define _ auto __#define xalloc(T, size) ((T *)palloc(size * sizeof(T)))#define nfree(p) \do { \if (p == nullptr) break; \free(p); \p = nullptr; \} while (0)#define bit_cast(T, ...) \({ \auto src = __VA_ARGS__; \static_assert(sizeof(T) == sizeof(src)); \T dst; \memcpy(&dst, &src, sizeof(T)); \dst; \})[[gnu::const]] bool isInt(double);[[gnu::returns_nonnull, nodiscard("allocation")]] void *palloc(size_t);[[gnu::nonnull]] void freecl(void *);[[gnu::nonnull]] void fclosecl(FILE **);[[gnu::nonnull]] void closedircl(DIR **);
/*** @file include/def.h*/#pragma once#define _TOSTR(x) #x#define TOSTR(x) _TOSTR(x)#define EMP(...)#define EXPAND(...) __VA_ARGS__// max depth: 4 ^ 5 = 1024#define EVAL(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))#define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))#define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__))))#define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__))))#define EVAL4(...) EXPAND(EXPAND(EXPAND(EXPAND(__VA_ARGS__))))#define PRIM_CAT(a, b) a##b#define CAT(a, b) PRIM_CAT(a, b)#define PRIM_CAR(_1, ...) _1#define PRIM_CDR(_1, ...) __VA_ARGS__#define CAR(...) PRIM_CAR(__VA_ARGS__)#define CDR(...) PRIM_CDR(__VA_ARGS__)#define CHECK(x) CAR(CDR(x, 0))#define NOT(x) CHECK(PRIM_CAT(NOT_, x))#define NOT_0 _, 1#define BOOL(x) NOT(NOT(x))#define RECURSE(a, b) CAT EMP()(a, b)#define PRIM_MAP(M, _1, ...) \M(_1) __VA_OPT__(RECURSE(PRIM, _MAP)(M, __VA_ARGS__))#define MAP(...) EVAL(PRIM_MAP(__VA_ARGS__))#define PRIM_MAP_PAIR(M, _1, ...) \M _1 __VA_OPT__(RECURSE(PRIM, _MAP_PAIR)(M, __VA_ARGS__))#define MAP_PAIR(...) EVAL(PRIM_MAP_PAIR(__VA_ARGS__))
/*** @file src/gene.c* @brief Define generic functions*/#include "gene.h"#include "mathdef.h"#include "testing.h"constexpr double eps = 1e-5;static bool doubleEq(double a, double b) {if (fabs(b) < eps) return fabs(a) < eps; // prevent 0-div when b is near 0if (a < 0 != b < 0) return false; // mis signedreturn fabs(a / b - 1.0) < eps; // cmp based on ratios}static bool complexEq(comp a, comp b) {return doubleEq(creal(a), creal(b)) && doubleEq(cimag(a), cimag(b));}test_table(double_eq, doubleEq, (bool, double, double),{{ true, 1.0, 1.0},{ true, 1e-10, 0},{ true, 1e100, 1e100 + 1e10},{false, 0, 1},{false, NAN, NAN},{false, NAN, 1e10},{false, INFINITY, INFINITY},{false, INFINITY, 1e100},})test_table(complex_eq, complexEq, (bool, comp, comp),{{ true, 0, 0},{ true, 1 + 3i, 1.0 + 3.0i},{ true, 1.0 + 1e-10 + 3i, 1 + 3i},{false, 0, 1},{false, 3 + 5i, -1 + 3i},})#pragma clang attribute push(overloadable, apply_to = function)void printany(int x) {printf("%d", x);}void printany(size_t x) {printf("%zu", x);}void printany(double x) {printf("%lf", x);}void printany(char *x) {printf("%s", x);}void printany(char x) {printf("%c", x);}void printany(bool x) {printf(x ? "`true`" : "`false`");}void printany(long x) {printf("%ld", x);}void printany(long long x) {printf("%lld", x);}void printany(void *x) {if (x) printf("0x%p", x);else printf("`nullptr`");}void printanyf(int x) {PRINT(x);}void printanyf(size_t x) {PRINT(x, "LU");}void printanyf(double x) {PRINT(x);}void printanyf(char *x) {PRINT("\"", x, "\"");}void printanyf(char x) {PRINT("'", x, "'");}void printanyf(bool x) {PRINT(x);}void printanyf(long x) {PRINT(x, "L");}void printanyf(long long x) {PRINT(x, "LL");}void printanyf(void *x) {PRINT(x);}#define EQ_DIRECTLY(T) \bool eq(T x, T y) { \return x == y; \}MAP(EQ_DIRECTLY, int, size_t, char, bool, void *)bool eq(double x, double y) {return doubleEq(x, y);}bool eq(comp x, comp y) {return complexEq(x, y);}bool eq(char *x, char *y) {return !strcmp(x, y);}#pragma clang attribute pop
/*** @file include/gene.h* @brief Define macros for generic programming*/#pragma once#include "def.h"#include <stddef.h>#define overloadable [[clang::overloadable]]#define DEF_PRIM(T) \overloadable void printany(T); \overloadable void printanyf(T); \overloadable bool eq(T, T);#define DEF_GEN(T) DEF_PRIM(T) DEF_PRIM(T *)#define TYPES bool, char, int, size_t, long, long long, double#define PRIM_TYPES void *#define APPLY_ADDSUB(M) M(Add, +) M(Sub, -)#define APPLY_ARTHM(M) APPLY_ADDSUB(M) M(Mul, *) M(Div, /)#define APPLY_LTGT(M) M(Lt, <) M(Gt, >)MAP(DEF_GEN, TYPES)MAP(DEF_PRIM, PRIM_TYPES)#define _PRINTREC(first, ...) \printany(first); \__VA_OPT__(RECURSE(_PRINT, REC)(__VA_ARGS__))#define PRINT(...) \do { EVAL(_PRINTREC(__VA_ARGS__)) } while (0)
/*** @file src/testing.c*/#include "testing.h"#undef main#ifdef TEST_MODEint test__success;int test__count;int main() {PRINT("\n" ESCBLU "Passed" ESCLR ": ", test__success, "/", test__count, "\n");// pre-commit: make test || exit 1return test__count - test__success;}test (testing_test) {expect(1 + 1 == 2);expecteq(3, 3);expectneq(1, 10);test_filter("testing test") {expect(false);expect(1 + 1 == 1);expecteq(5, 3);expecteq(3, 3 + 3);expectneq(3 + 7, 50 / 5 + 6 * 0);expect(false);}}#endif
/*** @file include/testing.h* @brief Define macros for testing* @note Tests not in the test_filter block are always executed*/#pragma once#include "chore.h"#ifdef TEST_MODE#include "ansiesc.h"#include "gene.h"extern int test__success;extern int test__count;#define TEST_HEADER " ■ " ESCBLU "Testing " ESCLR#define ALIGN_COL(name) \do { \int col = 6 - ((int)strlen(TEST_HEADER #name) - 3) / 8; \for (int i = 0; i < col; i++) putchar('\t'); \} while (0)#define PRINT_FAILED(cnt) PRINT("\n └" ESCRED ESBLD "[NG:", cnt, "]\n" ESCLR)#define PRINT_SUCCESS puts("=> " ESCGRN "[OK]" ESCLR)// zig style testing syntax#define test(name) \static void test__test##name(int *); \[[gnu::constructor]] static void test__run##name() { \test__count++; \printf(TEST_HEADER ESBLD #name ESCLR); \int failed = 0; \test__test##name(&failed); \if (failed) { \PRINT_FAILED(failed); \return; \} \ALIGN_COL(name); \PRINT_SUCCESS; \test__success++; \} \static void test__test##name(int *test__failed)#ifdef TEST_FILTER#define test_filter(filter) if (strstr(filter, TEST_FILTER))#else#define test_filter(_) if (0)#endif// generate function parameter#define PMAP(tok, _, ...) \t->tok __VA_OPT__(, RECURSE(PM, AP)(tok##p, __VA_ARGS__))// generate struct member// e.g.) T1 p /* expected */; T2 pp /* arg1 */; T3 ppp /* arg2 */; ...#define SMAP(tok, T1, ...) \T1 tok; \__VA_OPT__(RECURSE(SM, AP)(tok##p, __VA_ARGS__))#define CALL(fn, ...) fn(EVAL(PMAP(pp, __VA_ARGS__)))#define STDEF(...) \struct { \EVAL(SMAP(p, __VA_ARGS__)) \}// if {a, b, c} is passed as a macro parameter, it becomes "{a", "b", "c}", so// it must be received as a variable length argument.#define test_table(name, fn, signature, ...) \test_table_with_cleanup(name, fn, EMP, signature, __VA_ARGS__)#define test_table_with_cleanup(name, fn, cl, signature, ...) \[[gnu::constructor]] static void test__tabletest##name() { \test__count++; \printf(TEST_HEADER ESBLD #name ESCLR); \int failed = 0; \typedef STDEF signature S; \S data[] = __VA_ARGS__; \for (size_t i = 0; i < sizeof data / sizeof(S); i++) { \S *t = data + i; \int *test__failed /* for expecteq */ = &failed; \int pre = failed; \auto result = CALL(fn, CDR signature); \expecteq(t->p, result); \cl(result); \if (pre != failed) PRINT(" at test case ", i); \} \if (failed) { \PRINT_FAILED(failed); \return; \} \ALIGN_COL(name); \PRINT_SUCCESS; \test__success++; \}// disable main function somewhere#define main test__dummymain#define expect(cond) \do { \if (cond) break; \puts("\n ├┬ Unexpected result at " HERE); \printf(" │└─ `" #cond "` " ESCRED ESBLD " [NG]" ESCLR); \(*test__failed)++; \} while (0)#define expecteq(expected, actual) \do { \typeof(actual) const lhs = expected; \auto const rhs = actual; \if (eq(lhs, rhs)) break; \puts("\n ├┬ Expected equal at " HERE); \printf(" │├─ " ESCGRN "Expected" ESCLR ": "); \printanyf(lhs); \printf("\n │└─ " ESCRED "Actual" ESCLR ": "); \printanyf(rhs); \printf(ESCRED ESBLD " [NG]" ESCLR); \(*test__failed)++; \} while (0)#define expectneq(unexpected, actual) \do { \typeof(actual) const lhs = unexpected; \auto const rhs = actual; \if (!eq(lhs, rhs)) break; \int __llen = (int)strlen(#unexpected); \int __rlen = (int)strlen(#actual); \int __lpad = more(0, __rlen - __llen); \int __rpad = more(0, __llen - __rlen); \puts("\n ├┬ Unexpected equality at " HERE); \printf(" │├─ Left side: `" #unexpected "` ─"); \for (int __i = 0; __i < __lpad; __i++) printf("─"); \puts("┐"); \printf(" │└─ Right side: `" #actual "` ─"); \for (int __i = 0; __i < __rpad; __i++) printf("─"); \printf("┴─➤ "); \printanyf(lhs); \printf(ESCRED ESBLD " [NG]" ESCLR); \(*test__failed)++; \} while (0)#else// --gc-sections#define test(name) \[[gnu::unused]] static void test__dum##name(int *test__failed)#define test_table(...)#define test_filter(filter)#define expect(cond) \do { \_ = cond; \_ = test__failed; \} while (0)#define expecteq(lhs, rhs) \do { \_ = lhs; \_ = rhs; \_ = test__failed; \} while (0)#define expectneq(lhs, rhs) \do { \_ = lhs; \_ = rhs; \_ = test__failed; \} while (0)#endif
.PHONY: lib-build lib-clean plug-install plug-sync plug-gc plug-clean setupPREFIX = $(HOME)/.cache/nvimCC = ccache clangSRCDIRS = $(filter-out src/testing, $(wildcard src/*))TARGETS = $(patsubst src/%, lib/%.so, $(SRCDIRS))CFLAGS := -std=c2y -Wtautological-compare -Wsign-compare -Wall -Wextra -O3 \-fforce-emit-vtables -ffunction-sections -fdata-sections -fPIC \-faddrsig -march=native -mtune=native -funroll-loops -fomit-frame-pointerLDFLAGS = -flto=full -fwhole-program-vtables -funroll-loops -fomit-frame-pointer \-O3 -shared -lmTESTFLAGS := -std=c2y -DTEST_MODE -gfull $(shell pkg-config --cflags luajit)TESTLDFLAGS := -lm $(shell pkg-config --libs luajit)TESTTARGETS := $(addsuffix /test, $(PREFIX))lib-build: $(TARGETS)$(TARGETS): lib/%.so: src/%$(CC) $</*.c $(CFLAGS) $(LDFLAGS) -o $@lib-test: $(TESTTARGETS)$(TESTTARGETS): %/test: %$(CC) $</*.c $(wildcard src/testing/*.c) $(TESTFLAGS) $(TESTLDFLAGS) -o $@./$@lib-clean:rm $(TARGETS)LLMFILE ?= llmfile.txtFILES_IN_DIRS := $(wildcard $(addsuffix /*.*, $(DIRS)))LIST_FILES ?= $(FILES) $(FILES_IN_DIRS)$(LLMFILE): $(LIST_FILES) # for the LLM to readecho $^ | sed 's/ /\n/g' > $@echo >> $@ # newline# `head` automatically inserts the file name at the start of the filehead -n 9999 $^ >> $@llmfile: $(LLMFILE)%/: ; mkdir -p $@FILES ?= init.luaDIRS ?= lua lua/ftplugin