From d800266fe04119aa2b1e20cc4989090befd8201a Mon Sep 17 00:00:00 2001 From: yukkop Date: Fri, 4 Apr 2025 01:59:57 +0000 Subject: [PATCH] feat: some nix shit --- package/c/hectic/default.nix | 4 +-- package/c/hectic/hectic.c | 59 ++++++++++++++++++------------------ package/c/hectic/hectic.h | 58 +++++++++++++++++------------------ package/c/hectic/make.sh | 14 +++++++++ package/c/watch/default.nix | 30 ++++++++++++++++++ 5 files changed, 105 insertions(+), 60 deletions(-) create mode 100644 package/c/watch/default.nix diff --git a/package/c/hectic/default.nix b/package/c/hectic/default.nix index f73ddfb..58941ad 100644 --- a/package/c/hectic/default.nix +++ b/package/c/hectic/default.nix @@ -1,4 +1,4 @@ -{ stdenv, gcc, lib, bash }: +{ stdenv, gcc, lib, bash, inotify-tools }: stdenv.mkDerivation { pname = "hectic"; @@ -6,7 +6,7 @@ stdenv.mkDerivation { src = ./.; doCheck = true; - nativeBuildInputs = [ gcc ]; + nativeBuildInputs = [ gcc inotify-tools ]; buildPhase = '' ls diff --git a/package/c/hectic/hectic.c b/package/c/hectic/hectic.c index f93f094..3bbfb28 100644 --- a/package/c/hectic/hectic.c +++ b/package/c/hectic/hectic.c @@ -55,7 +55,8 @@ void init_logger(void) { current_log_level = log_level_from_string(getenv("LOG_LEVEL")); } -char* raise_message(LogLevel level, const char *file, int line, const char *format, ...) { +char* raise_message(LogLevel level, const char *file, const char *func, int line, const char *format, ...) { + (void)func; if (level < current_log_level) { return NULL; } @@ -82,69 +83,69 @@ char* raise_message(LogLevel level, const char *file, int line, const char *form // -- arena -- // ----------- -Arena arena_init__(const char *file, int line, size_t size) { +Arena arena_init__(const char *file, const char *func, int line, size_t size) { Arena arena; arena.begin = malloc(size); memset(arena.begin, 0, size); arena.current = arena.begin; arena.capacity = size; - raise_message(LOG_LEVEL_DEBUG, file, line, + raise_message(LOG_LEVEL_DEBUG, file, func, line, "Initialized arena at %p with capacity %zu", arena.begin, size); return arena; } -void* arena_alloc_or_null__(const char *file, int line, Arena *arena, size_t size) { - raise_message(LOG_LEVEL_TRACE, file, line, "arena_alloc_or_null(%p, %zu)", arena, size); +void* arena_alloc_or_null__(const char *file, const char *func, int line, Arena *arena, size_t size) { + raise_message(LOG_LEVEL_TRACE, file, func, line, "arena_alloc_or_null(%p, %zu)", arena, size); void *mem = NULL; if (arena->begin == 0) { *arena = arena_init__(file, line, 1024); // ARENA_DEFAULT_SIZE assumed as 1024 } size_t current = (size_t)arena->current - (size_t)arena->begin; if (arena->capacity <= current || arena->capacity - current < size) { - raise_message(LOG_LEVEL_DEBUG, file, line, + raise_message(LOG_LEVEL_DEBUG, file, func, line, "Arena %p (capacity %zu) used %zu cannot allocate %zu bytes", arena->begin, arena->capacity, current, size); return NULL; } else { - raise_message(LOG_LEVEL_DEBUG, file, line, + raise_message(LOG_LEVEL_DEBUG, file, func, line, "Arena %p (capacity %zu) used %zu will allocate %zu bytes", arena->begin, arena->capacity, current, size); mem = arena->current; arena->current = (char*)arena->current + size; } - raise_message(LOG_LEVEL_DEBUG, file, line, "Allocated at %p", mem); + raise_message(LOG_LEVEL_DEBUG, file, func, line, "Allocated at %p", mem); return mem; } -void* arena_alloc__(const char *file, int line, Arena *arena, size_t size) { - void *mem = arena_alloc_or_null__(file, line, arena, size); +void* arena_alloc__(const char *file, const char *func, int line, Arena *arena, size_t size) { + void *mem = arena_alloc_or_null__(file, func, line, arena, size); if (!mem) { - raise_message(LOG_LEVEL_DEBUG, file, line, + raise_message(LOG_LEVEL_DEBUG, file, func, line, "Arena out of memory when trying to allocate %zu bytes", size); - raise_message(LOG_LEVEL_EXCEPTION, file, line, + raise_message(LOG_LEVEL_EXCEPTION, file, func, line, "Arena out of memory"); exit(1); } return mem; } -void arena_reset__(const char *file, int line, Arena *arena) { +void arena_reset__(const char *file, const char *func, int line, Arena *arena) { arena->current = arena->begin; - raise_message(LOG_LEVEL_DEBUG, file, line, + raise_message(LOG_LEVEL_DEBUG, file, func, line, "Arena %p reset", arena->begin); } -void arena_free__(const char *file, int line, Arena *arena) { - raise_message(LOG_LEVEL_DEBUG, file, line, +void arena_free__(const char *file, const char *func, int line, Arena *arena) { + raise_message(LOG_LEVEL_DEBUG, file, func, line, "Freeing arena at %p", arena->begin); free(arena->begin); } -char* arena_strdup__(const char *file, int line, Arena *arena, const char *s) { +char* arena_strdup__(const char *file, const char *func, int line, Arena *arena, const char *s) { char *result; if (s) { size_t len = strlen(s) + 1; - result = (char*)arena_alloc__(file, line, arena, len); + result = (char*)arena_alloc__(file, func, line, arena, len); memcpy(result, s, len); } else { result = NULL; @@ -152,28 +153,28 @@ char* arena_strdup__(const char *file, int line, Arena *arena, const char *s) { return result; } -char* arena_repstr__(const char *file, int line, Arena *arena, +char* arena_repstr__(const char *file, const char *func, int line, Arena *arena, const char *src, size_t start, size_t len, const char *rep) { - raise_message(LOG_LEVEL_TRACE, file, line, "arena_repstr__(%p, %p, %zu, \"%s\")", src, start, len, rep); + raise_message(LOG_LEVEL_TRACE, file, func, line, "arena_repstr__(%p, %p, %zu, \"%s\")", src, start, len, rep); int src_len = strlen(src); int rep_len = strlen(rep); int new_len = src_len - (int)len + rep_len; - char *new_str = (char*)arena_alloc__(file, line, arena, new_len + 1); + char *new_str = (char*)arena_alloc__(file, func, line, arena, new_len + 1); memcpy(new_str, src, start); memcpy(new_str + start, rep, rep_len); strcpy(new_str + start + rep_len, src + start + len); return new_str; } -void* arena_realloc_copy__(const char *file, int line, Arena *arena, +void* arena_realloc_copy__(const char *file, const char *func, int line, Arena *arena, void *old_ptr, size_t old_size, size_t new_size) { void *new_ptr = NULL; if (old_ptr == NULL) { - new_ptr = arena_alloc__(file, line, arena, new_size); + new_ptr = arena_alloc__(file, func, line, arena, new_size); } else if (new_size <= old_size) { new_ptr = old_ptr; } else { - new_ptr = arena_alloc_or_null__(file, line, arena, new_size); + new_ptr = arena_alloc_or_null__(file, func, line, arena, new_size); if (new_ptr) memcpy(new_ptr, old_ptr, old_size); } @@ -184,16 +185,16 @@ void* arena_realloc_copy__(const char *file, int line, Arena *arena, // -- misc -- // ---------- -void substr_clone__(const char *file, int line, const char * const src, char *dest, size_t from, size_t len) { +void substr_clone__(const char *file, const char *func, int line, const char * const src, char *dest, size_t from, size_t len) { // Log function entry with all parameters. - raise_message(LOG_LEVEL_TRACE, file, line, + raise_message(LOG_LEVEL_TRACE, file, func, line, "substr_cloning(src=\"%s\", src_ptr=%p, dest=%p, from=%zu, len=%zu)", src, src, dest, from, len); size_t srclen = strlen(src); if (from >= srclen) { // Log warning with context when 'from' is out of range. - raise_message(LOG_LEVEL_WARN, file, line, + raise_message(LOG_LEVEL_WARN, file, func, line, "Invalid 'from' index (%zu): exceeds source length (%zu)", from, srclen); dest[0] = '\0'; @@ -206,7 +207,7 @@ void substr_clone__(const char *file, int line, const char * const src, char *de dest[len] = '\0'; // Log success message with result. - raise_message(LOG_LEVEL_TRACE, file, line, + raise_message(LOG_LEVEL_TRACE, file, func, line, "Completed substr_cloning: result=\"%s\", copied_length=%zu", dest, len); } @@ -537,4 +538,4 @@ int* arena_slice_copy__(const char *file, int line, Arena *arena, Slice s) { if (copy) memcpy(copy, s.data, s.len * s.isize); return copy; -} +} \ No newline at end of file diff --git a/package/c/hectic/hectic.h b/package/c/hectic/hectic.h index 5f8d3ac..ab04c78 100644 --- a/package/c/hectic/hectic.h +++ b/package/c/hectic/hectic.h @@ -82,7 +82,7 @@ void logger_level(LogLevel level); LogLevel log_level_from_string(const char *level_str); -char* raise_message(LogLevel level, const char *file, int line, const char *format, ...); +char* raise_message(LogLevel level, const char *file, const char *func, int line, const char *format, ...); #ifndef PRECOMPILED_LOG_LEVEL #define PRECOMPILED_LOG_LEVEL LOG_LEVEL_TRACE // default level @@ -91,43 +91,43 @@ char* raise_message(LogLevel level, const char *file, int line, const char *form #if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_TRACE #define raise_trace(...) ((void)0) // log removed at compile time #else -#define raise_trace(...) raise_message(LOG_LEVEL_TRACE, __FILE__, __LINE__, ##__VA_ARGS__) +#define raise_trace(...) raise_message(LOG_LEVEL_TRACE, __FILE__, __func__, __LINE__, ##__VA_ARGS__) #endif #if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_DEBUG #define raise_debug(...) ((void)0) #else -#define raise_debug(...) raise_message(LOG_LEVEL_DEBUG, __FILE__, __LINE__, ##__VA_ARGS__) +#define raise_debug(...) raise_message(LOG_LEVEL_DEBUG, __FILE__, __func__, __LINE__, ##__VA_ARGS__) #endif #if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_LOG #define raise_log(...) ((void)0) #else -#define raise_log(...) raise_message(LOG_LEVEL_LOG, __FILE__, __LINE__, ##__VA_ARGS__) +#define raise_log(...) raise_message(LOG_LEVEL_LOG, __FILE__, __func__, __LINE__, ##__VA_ARGS__) #endif #if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_INFO #define raise_info(...) ((void)0) #else -#define raise_info(...) raise_message(LOG_LEVEL_INFO, __FILE__, __LINE__, ##__VA_ARGS__) +#define raise_info(...) raise_message(LOG_LEVEL_INFO, __FILE__, __func__, __LINE__, ##__VA_ARGS__) #endif #if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_NOTICE #define raise_notice(...) ((void)0) #else -#define raise_notice(...) raise_message(LOG_LEVEL_NOTICE, __FILE__, __LINE__, ##__VA_ARGS__) +#define raise_notice(...) raise_message(LOG_LEVEL_NOTICE, __FILE__, __func__, __LINE__, ##__VA_ARGS__) #endif #if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_WARN #define raise_warn(...) ((void)0) #else -#define raise_warn(...) raise_message(LOG_LEVEL_WARN, __FILE__, __LINE__, ##__VA_ARGS__) +#define raise_warn(...) raise_message(LOG_LEVEL_WARN, __FILE__, __func__, __LINE__, ##__VA_ARGS__) #endif #if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_EXCEPTION #define raise_exception(...) ((void)0) #else -#define raise_exception(...) raise_message(LOG_LEVEL_EXCEPTION, __FILE__, __LINE__, ##__VA_ARGS__) +#define raise_exception(...) raise_message(LOG_LEVEL_EXCEPTION, __FILE__, __func__, __LINE__, ##__VA_ARGS__) #endif // ----------- @@ -142,49 +142,49 @@ typedef struct { size_t capacity; } Arena; -Arena arena_init__(const char *file, int line, size_t size); +Arena arena_init__(const char *file, const char *func, int line, size_t size); -void* arena_alloc_or_null__(const char *file, int line, Arena *arena, size_t size); +void* arena_alloc_or_null__(const char *file, const char *func, int line, Arena *arena, size_t size); -void* arena_alloc__(const char *file, int line, Arena *arena, size_t size); +void* arena_alloc__(const char *file, const char *func, int line, Arena *arena, size_t size); -void arena_reset__(const char *file, int line, Arena *arena); +void arena_reset__(const char *file, const char *func, int line, Arena *arena); -void arena_free__(const char *file, int line, Arena *arena); +void arena_free__(const char *file, const char *func, int line, Arena *arena); -char* arena_strdup__(const char *file, int line, Arena *arena, const char *s); +char* arena_strdup__(const char *file, const char *func, int line, Arena *arena, const char *s); -char* arena_repstr__(const char *file, int line, Arena *arena, +char* arena_repstr__(const char *file, const char *func, int line, Arena *arena, const char *src, size_t start, size_t len, const char *rep); -void* arena_realloc_copy__(const char *file, int line, Arena *arena, +void* arena_realloc_copy__(const char *file, const char *func, int line, Arena *arena, void *old_ptr, size_t old_size, size_t new_size); // NOTE(yukkop): This macro is used to define procedures so that `__LINE__` and `__FILE__` // in `raise_debug` reflect the location where the macro is called, not where it's defined. #define arena_alloc_or_null(arena, size) \ - arena_alloc_or_null__(__FILE__, __LINE__, arena, size) + arena_alloc_or_null__(__FILE__, __func__, __LINE__, arena, size) #define arena_init(size) \ - arena_init__(__FILE__, __LINE__, size) + arena_init__(__FILE__, __func__, __LINE__, size) #define arena_reset(arena) \ - arena_reset__(__FILE__, __LINE__, arena) + arena_reset__(__FILE__, __func__, __LINE__, arena) #define arena_free(arena) \ - arena_free__(__FILE__, __LINE__, arena) + arena_free__(__FILE__, __func__, __LINE__, arena) #define arena_alloc(arena, size) \ - arena_alloc__(__FILE__, __LINE__, arena, size) + arena_alloc__(__FILE__, __func__, __LINE__, arena, size) #define arena_strdup(arena, s) \ - arena_strdup__(__FILE__, __LINE__, arena, s) + arena_strdup__(__FILE__, __func__, __LINE__, arena, s) #define arena_repstr(arena, src, start, len, rep) \ - arena_repstr__(__FILE__, __LINE__, arena, src, start, len, rep) + arena_repstr__(__FILE__, __func__, __LINE__, arena, src, start, len, rep) #define arena_realloc_copy(arena, old_ptr, old_size, new_size) \ - arena_realloc_copy__(__FILE__, __LINE__, arena, old_ptr, old_size, new_size) + arena_realloc_copy__(__FILE__, __func__, __LINE__, arena, old_ptr, old_size, new_size) // ---------- // -- misc -- @@ -245,8 +245,6 @@ char *json_to_string_with_opts(Arena *arena, const Json * const item, JsonRawOpt /* Retrieve an object item by key (case-sensitive) */ Json *json_get_object_item(const Json * const object, const char * const key); -#endif // EPRINTF_H - // ----------- // -- Slice -- // ----------- @@ -269,13 +267,13 @@ Slice slice_subslice__(const char *file, int line, Slice s, size_t start, size_t int* arena_slice_copy__(const char *file, int line, Arena *arena, Slice s); #define slice_create(type, array, array_len, start, len) \ - slice_create__(__FILE__, __LINE__, sizeof(type), array, array_len, start, len) + slice_create__(__FILE__, __func__, __LINE__, sizeof(type), array, array_len, start, len) #define slice_subslice(s, start, len) \ - slice_subslice__(__FILE__, __LINE__, s, start, len) + slice_subslice__(__FILE__, __func__, __LINE__, s, start, len) #define arena_slice_copy(arena, s) \ - arena_slice_copy__(__FILE__, __LINE__, arena, s) + arena_slice_copy__(__FILE__, __func__, __LINE__, arena, s) #define SLICE_TO_STRING(type, slice, fmt) __extension__ ({ \ size_t count = (slice).len / (slice).isize; \ @@ -292,3 +290,5 @@ int* arena_slice_copy__(const char *file, int line, Arena *arena, Slice s); } \ buf; \ }) + +#endif // EPRINTF_H \ No newline at end of file diff --git a/package/c/hectic/make.sh b/package/c/hectic/make.sh index 2bb3d18..402f269 100644 --- a/package/c/hectic/make.sh +++ b/package/c/hectic/make.sh @@ -2,6 +2,7 @@ # Usage: make.sh [build|check] [--norun] [--debug] [--color] # Options: # build Build the library and app (default if no mode is provided). +# watch Build the library and app and watch for changes. # check Build tests; runs them unless --norun is specified. # --norun (check only) Build tests but do not run them. # --debug Build with -O0 (debug mode). @@ -15,6 +16,14 @@ check_dependencies() { exit 1 fi done + + # Check for either fswatch or inotifywait + if ! command -v fswatch >/dev/null 2>&1 && ! command -v inotifywait >/dev/null 2>&1; then + echo "Error: Neither fswatch nor inotifywait found. Please install one of them." >&2 + echo " On macOS: brew install fswatch" >&2 + echo " On Linux: sudo apt install inotify-tools" >&2 + exit 1 + fi } check_dependencies @@ -22,6 +31,7 @@ print_help() { cat <&1 + ;; build) mkdir -p target echo "# Build library" diff --git a/package/c/watch/default.nix b/package/c/watch/default.nix new file mode 100644 index 0000000..2cb8eb7 --- /dev/null +++ b/package/c/watch/default.nix @@ -0,0 +1,30 @@ +{ stdenv, gcc, lib, hectic, bash }: + +stdenv.mkDerivation { + pname = "watch"; + version = "1.0"; + src = ./.; + doCheck = true; + + nativeBuildInputs = [ gcc gdb ]; + + buildPhase = '' + ${bash}/bin/sh ./make.sh build + ''; + + checkPhase = '' + ${bash}/bin/sh ./make.sh check + ''; + + installPhase = '' + mkdir -p $out/bin $out/lib $out/include + cp target/hmpl $out/bin/hmpl + cp target/libhmpl.a $out/lib/ + cp hmpl.h $out/include/hmpl.h + ''; + + meta = { + description = "watch"; + license = lib.licenses.mit; + }; +} \ No newline at end of file