feat: some nix shit
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
{ stdenv, gcc, lib, bash }:
|
{ stdenv, gcc, lib, bash, inotify-tools }:
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
pname = "hectic";
|
pname = "hectic";
|
||||||
@@ -6,7 +6,7 @@ stdenv.mkDerivation {
|
|||||||
src = ./.;
|
src = ./.;
|
||||||
doCheck = true;
|
doCheck = true;
|
||||||
|
|
||||||
nativeBuildInputs = [ gcc ];
|
nativeBuildInputs = [ gcc inotify-tools ];
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
ls
|
ls
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ void init_logger(void) {
|
|||||||
current_log_level = log_level_from_string(getenv("LOG_LEVEL"));
|
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) {
|
if (level < current_log_level) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -82,69 +83,69 @@ char* raise_message(LogLevel level, const char *file, int line, const char *form
|
|||||||
// -- arena --
|
// -- 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 arena;
|
||||||
arena.begin = malloc(size);
|
arena.begin = malloc(size);
|
||||||
memset(arena.begin, 0, size);
|
memset(arena.begin, 0, size);
|
||||||
arena.current = arena.begin;
|
arena.current = arena.begin;
|
||||||
arena.capacity = size;
|
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);
|
"Initialized arena at %p with capacity %zu", arena.begin, size);
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
raise_message(LOG_LEVEL_TRACE, file, line, "arena_alloc_or_null(%p, %zu)", arena, size);
|
raise_message(LOG_LEVEL_TRACE, file, func, line, "arena_alloc_or_null(%p, %zu)", arena, size);
|
||||||
void *mem = NULL;
|
void *mem = NULL;
|
||||||
if (arena->begin == 0) {
|
if (arena->begin == 0) {
|
||||||
*arena = arena_init__(file, line, 1024); // ARENA_DEFAULT_SIZE assumed as 1024
|
*arena = arena_init__(file, line, 1024); // ARENA_DEFAULT_SIZE assumed as 1024
|
||||||
}
|
}
|
||||||
size_t current = (size_t)arena->current - (size_t)arena->begin;
|
size_t current = (size_t)arena->current - (size_t)arena->begin;
|
||||||
if (arena->capacity <= current || arena->capacity - current < size) {
|
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 %p (capacity %zu) used %zu cannot allocate %zu bytes",
|
||||||
arena->begin, arena->capacity, current, size);
|
arena->begin, arena->capacity, current, size);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} 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 %p (capacity %zu) used %zu will allocate %zu bytes",
|
||||||
arena->begin, arena->capacity, current, size);
|
arena->begin, arena->capacity, current, size);
|
||||||
mem = arena->current;
|
mem = arena->current;
|
||||||
arena->current = (char*)arena->current + size;
|
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;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *mem = arena_alloc_or_null__(file, line, arena, size);
|
void *mem = arena_alloc_or_null__(file, func, line, arena, size);
|
||||||
if (!mem) {
|
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);
|
"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");
|
"Arena out of memory");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
return mem;
|
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;
|
arena->current = arena->begin;
|
||||||
raise_message(LOG_LEVEL_DEBUG, file, line,
|
raise_message(LOG_LEVEL_DEBUG, file, func, line,
|
||||||
"Arena %p reset", arena->begin);
|
"Arena %p reset", arena->begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arena_free__(const char *file, int line, Arena *arena) {
|
void arena_free__(const char *file, const char *func, int line, Arena *arena) {
|
||||||
raise_message(LOG_LEVEL_DEBUG, file, line,
|
raise_message(LOG_LEVEL_DEBUG, file, func, line,
|
||||||
"Freeing arena at %p", arena->begin);
|
"Freeing arena at %p", arena->begin);
|
||||||
free(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;
|
char *result;
|
||||||
if (s) {
|
if (s) {
|
||||||
size_t len = strlen(s) + 1;
|
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);
|
memcpy(result, s, len);
|
||||||
} else {
|
} else {
|
||||||
result = NULL;
|
result = NULL;
|
||||||
@@ -152,28 +153,28 @@ char* arena_strdup__(const char *file, int line, Arena *arena, const char *s) {
|
|||||||
return result;
|
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) {
|
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 src_len = strlen(src);
|
||||||
int rep_len = strlen(rep);
|
int rep_len = strlen(rep);
|
||||||
int new_len = src_len - (int)len + rep_len;
|
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, src, start);
|
||||||
memcpy(new_str + start, rep, rep_len);
|
memcpy(new_str + start, rep, rep_len);
|
||||||
strcpy(new_str + start + rep_len, src + start + len);
|
strcpy(new_str + start + rep_len, src + start + len);
|
||||||
return new_str;
|
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 *old_ptr, size_t old_size, size_t new_size) {
|
||||||
void *new_ptr = NULL;
|
void *new_ptr = NULL;
|
||||||
if (old_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) {
|
} else if (new_size <= old_size) {
|
||||||
new_ptr = old_ptr;
|
new_ptr = old_ptr;
|
||||||
} else {
|
} 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)
|
if (new_ptr)
|
||||||
memcpy(new_ptr, old_ptr, old_size);
|
memcpy(new_ptr, old_ptr, old_size);
|
||||||
}
|
}
|
||||||
@@ -184,16 +185,16 @@ void* arena_realloc_copy__(const char *file, int line, Arena *arena,
|
|||||||
// -- misc --
|
// -- 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.
|
// 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)",
|
"substr_cloning(src=\"%s\", src_ptr=%p, dest=%p, from=%zu, len=%zu)",
|
||||||
src, src, dest, from, len);
|
src, src, dest, from, len);
|
||||||
|
|
||||||
size_t srclen = strlen(src);
|
size_t srclen = strlen(src);
|
||||||
if (from >= srclen) {
|
if (from >= srclen) {
|
||||||
// Log warning with context when 'from' is out of range.
|
// 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)",
|
"Invalid 'from' index (%zu): exceeds source length (%zu)",
|
||||||
from, srclen);
|
from, srclen);
|
||||||
dest[0] = '\0';
|
dest[0] = '\0';
|
||||||
@@ -206,7 +207,7 @@ void substr_clone__(const char *file, int line, const char * const src, char *de
|
|||||||
dest[len] = '\0';
|
dest[len] = '\0';
|
||||||
|
|
||||||
// Log success message with result.
|
// 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",
|
"Completed substr_cloning: result=\"%s\", copied_length=%zu",
|
||||||
dest, len);
|
dest, len);
|
||||||
}
|
}
|
||||||
@@ -537,4 +538,4 @@ int* arena_slice_copy__(const char *file, int line, Arena *arena, Slice s) {
|
|||||||
if (copy)
|
if (copy)
|
||||||
memcpy(copy, s.data, s.len * s.isize);
|
memcpy(copy, s.data, s.len * s.isize);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ void logger_level(LogLevel level);
|
|||||||
|
|
||||||
LogLevel log_level_from_string(const char *level_str);
|
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
|
#ifndef PRECOMPILED_LOG_LEVEL
|
||||||
#define PRECOMPILED_LOG_LEVEL LOG_LEVEL_TRACE // default 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
|
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_TRACE
|
||||||
#define raise_trace(...) ((void)0) // log removed at compile time
|
#define raise_trace(...) ((void)0) // log removed at compile time
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_DEBUG
|
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_DEBUG
|
||||||
#define raise_debug(...) ((void)0)
|
#define raise_debug(...) ((void)0)
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_LOG
|
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_LOG
|
||||||
#define raise_log(...) ((void)0)
|
#define raise_log(...) ((void)0)
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_INFO
|
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_INFO
|
||||||
#define raise_info(...) ((void)0)
|
#define raise_info(...) ((void)0)
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_NOTICE
|
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_NOTICE
|
||||||
#define raise_notice(...) ((void)0)
|
#define raise_notice(...) ((void)0)
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_WARN
|
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_WARN
|
||||||
#define raise_warn(...) ((void)0)
|
#define raise_warn(...) ((void)0)
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_EXCEPTION
|
#if PRECOMPILED_LOG_LEVEL > LOG_LEVEL_EXCEPTION
|
||||||
#define raise_exception(...) ((void)0)
|
#define raise_exception(...) ((void)0)
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
// -----------
|
// -----------
|
||||||
@@ -142,49 +142,49 @@ typedef struct {
|
|||||||
size_t capacity;
|
size_t capacity;
|
||||||
} Arena;
|
} 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);
|
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);
|
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__`
|
// 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.
|
// in `raise_debug` reflect the location where the macro is called, not where it's defined.
|
||||||
#define arena_alloc_or_null(arena, size) \
|
#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) \
|
#define arena_init(size) \
|
||||||
arena_init__(__FILE__, __LINE__, size)
|
arena_init__(__FILE__, __func__, __LINE__, size)
|
||||||
|
|
||||||
#define arena_reset(arena) \
|
#define arena_reset(arena) \
|
||||||
arena_reset__(__FILE__, __LINE__, arena)
|
arena_reset__(__FILE__, __func__, __LINE__, arena)
|
||||||
|
|
||||||
#define arena_free(arena) \
|
#define arena_free(arena) \
|
||||||
arena_free__(__FILE__, __LINE__, arena)
|
arena_free__(__FILE__, __func__, __LINE__, arena)
|
||||||
|
|
||||||
#define arena_alloc(arena, size) \
|
#define arena_alloc(arena, size) \
|
||||||
arena_alloc__(__FILE__, __LINE__, arena, size)
|
arena_alloc__(__FILE__, __func__, __LINE__, arena, size)
|
||||||
|
|
||||||
#define arena_strdup(arena, s) \
|
#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) \
|
#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) \
|
#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 --
|
// -- 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) */
|
/* Retrieve an object item by key (case-sensitive) */
|
||||||
Json *json_get_object_item(const Json * const object, const char * const key);
|
Json *json_get_object_item(const Json * const object, const char * const key);
|
||||||
|
|
||||||
#endif // EPRINTF_H
|
|
||||||
|
|
||||||
// -----------
|
// -----------
|
||||||
// -- Slice --
|
// -- 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);
|
int* arena_slice_copy__(const char *file, int line, Arena *arena, Slice s);
|
||||||
|
|
||||||
#define slice_create(type, array, array_len, start, len) \
|
#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) \
|
#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) \
|
#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__ ({ \
|
#define SLICE_TO_STRING(type, slice, fmt) __extension__ ({ \
|
||||||
size_t count = (slice).len / (slice).isize; \
|
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; \
|
buf; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#endif // EPRINTF_H
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
# Usage: make.sh [build|check] [--norun] [--debug] [--color]
|
# Usage: make.sh [build|check] [--norun] [--debug] [--color]
|
||||||
# Options:
|
# Options:
|
||||||
# build Build the library and app (default if no mode is provided).
|
# 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.
|
# check Build tests; runs them unless --norun is specified.
|
||||||
# --norun (check only) Build tests but do not run them.
|
# --norun (check only) Build tests but do not run them.
|
||||||
# --debug Build with -O0 (debug mode).
|
# --debug Build with -O0 (debug mode).
|
||||||
@@ -15,6 +16,14 @@ check_dependencies() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
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
|
check_dependencies
|
||||||
|
|
||||||
@@ -22,6 +31,7 @@ print_help() {
|
|||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $0 [build|check] [--norun] [--debug] [--color]
|
Usage: $0 [build|check] [--norun] [--debug] [--color]
|
||||||
build Build the library and app (default).
|
build Build the library and app (default).
|
||||||
|
watch Build the library and app and watch for changes.
|
||||||
check Build tests; runs them unless --norun is specified.
|
check Build tests; runs them unless --norun is specified.
|
||||||
--norun (check only) Build tests but do not run them.
|
--norun (check only) Build tests but do not run them.
|
||||||
--debug Build with debug flags (-O0).
|
--debug Build with debug flags (-O0).
|
||||||
@@ -66,6 +76,7 @@ while [ $# -gt 0 ]; do
|
|||||||
;;
|
;;
|
||||||
--color)
|
--color)
|
||||||
COLOR_FLAG="-fdiagnostics-color=always"
|
COLOR_FLAG="-fdiagnostics-color=always"
|
||||||
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown option: $1"
|
echo "Unknown option: $1"
|
||||||
@@ -81,6 +92,9 @@ if [ -n "$COLOR_FLAG" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
case "$MODE" in
|
case "$MODE" in
|
||||||
|
watch)
|
||||||
|
find . -type d | nix run .#watch -- 'sh ./make.sh build' -p '*.c' -p '*.h' 2>&1
|
||||||
|
;;
|
||||||
build)
|
build)
|
||||||
mkdir -p target
|
mkdir -p target
|
||||||
echo "# Build library"
|
echo "# Build library"
|
||||||
|
|||||||
30
package/c/watch/default.nix
Normal file
30
package/c/watch/default.nix
Normal file
@@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user