8 Commits
map ... master

Author SHA1 Message Date
ea9d45625d Added ev_log
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-07-07 16:36:29 +03:00
2dcc69e692 Updated meson native files
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-07-07 16:36:20 +03:00
eb271ae2a8 Added .gitignore file
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-07-07 16:35:57 +03:00
d3bbc155af [ev_vec] Added ev_vec_dup
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-07-07 10:46:20 +03:00
77a594b36b [ev_types] Temporarily removed EV_CATN usage to fix TYPEDATA_GEN issues
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-07-07 10:46:00 +03:00
8410e66eb5 [ev_str] Added COPY and FREE to type data
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-07-07 10:45:09 +03:00
2daeb8652c Fixed compilation on linux
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-07-07 10:44:29 +03:00
fe5b9a131f Fixed warnings + add vec magic number
Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
2025-01-27 14:46:36 +02:00
13 changed files with 394 additions and 63 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.cache
build

View File

@@ -0,0 +1,11 @@
[binaries]
c = 'clang-19'
c_ld = 'lld-19'
cpp = 'clang++-19'
cpp_ld = 'lld-19'
[properties]
c_args = ['-DEV_CC_CLANG=1','-fcolor-diagnostics', '-fansi-escape-codes', '-fms-extensions']
[cmake]
CMAKE_C_COMPILER = 'clang-19'

View File

@@ -0,0 +1,11 @@
[binaries]
c = 'clang.exe'
c_ld = 'lld'
cpp = 'clang++.exe'
cpp_ld = 'lld'
[properties]
c_args = ['-DEV_CC_CLANG=1','-fcolor-diagnostics', '-fansi-escape-codes']
[cmake]
CMAKE_C_COMPILER = 'clang.exe'

2
buildfiles/ev_log.c Normal file
View File

@@ -0,0 +1,2 @@
#define EV_LOG_IMPLEMENTATION
#include "../ev_log.h"

View File

@@ -23,12 +23,17 @@ evstring_readFile(
#ifdef EV_HELPERS_IMPLEMENTATION #ifdef EV_HELPERS_IMPLEMENTATION
#undef EV_HELPERS_IMPLEMENTATION #undef EV_HELPERS_IMPLEMENTATION
evstring evstring
evstring_readFile( evstring_readFile(
evstring filePath) evstring filePath)
{ {
FILE* f = fopen(filePath, "rb"); FILE* f = NULL;
if(f == NULL) return EV_INVALID(evstring); #if EV_OS_WINDOWS
if(fopen_s(&f,filePath,"rb")) return EV_INVALID(evstring);
#else
f = fopen(filePath, "rb");
#endif
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
u32 buflen = ftell(f); u32 buflen = ftell(f);

202
ev_log.h Normal file
View File

@@ -0,0 +1,202 @@
#ifndef EV_HEADERS_LOG_H
#define EV_HEADERS_LOG_H
#define EV_LOG_USE_COLOR
#include "ev_internal.h"
#include "stdarg.h"
#include "stdbool.h"
#include "stdio.h"
#include "time.h"
typedef struct {
va_list ap;
const char* fmt;
const char* file;
struct tm* time;
void* udata;
int line;
int level;
} ev_log_event_t;
typedef void (*ev_log_log_fn)(ev_log_event_t* ev);
typedef void (*ev_log_lock_fn)(bool lock, void* udata);
typedef enum {
EV_LOG_TRACE,
EV_LOG_DEBUG,
EV_LOG_INFO ,
EV_LOG_WARN ,
EV_LOG_ERROR,
EV_LOG_FATAL,
} ev_log_level;
#define ev_log_trace(...) ev_log(EV_LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
#define ev_log_debug(...) ev_log(EV_LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define ev_log_info(...) ev_log(EV_LOG_INFO , __FILE__, __LINE__, __VA_ARGS__)
#define ev_log_warn(...) ev_log(EV_LOG_WARN , __FILE__, __LINE__, __VA_ARGS__)
#define ev_log_error(...) ev_log(EV_LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define ev_log_fatal(...) ev_log(EV_LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
const char* ev_log_level_string(ev_log_level level);
void ev_log_set_lock(ev_log_lock_fn fn, void* udata);
void ev_log_set_level(ev_log_level level);
void ev_log_set_quiet(bool enable);
i32 ev_log_add_callback(ev_log_log_fn fn, void* udata, ev_log_level level);
i32 ev_log_add_fp(FILE *fp, ev_log_level level);
void ev_log(ev_log_level level, const char* file, u32 line, const char* fmt, ...);
#ifdef EV_LOG_IMPLEMENTATION
#undef EV_LOG_IMPLEMENTATION
#define MAX_CALLBACKS 32
typedef struct {
ev_log_log_fn fn;
void* udata;
ev_log_level level;
} ev_log_callback_t;
struct {
void* udata;
ev_log_lock_fn lock;
ev_log_level level;
bool quiet;
ev_log_callback_t callbacks[MAX_CALLBACKS];
} G;
static const char* level_strings[] = {
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};
static const char* level_colors[] = {
"\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"
};
static void ev_log_stdout_callback(ev_log_event_t* ev)
{
char buf[16];
buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0';
#ifdef EV_LOG_USE_COLOR
fprintf(
ev->udata, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m ",
buf, level_colors[ev->level], level_strings[ev->level],
ev->file, ev->line);
#else
fprintf(
ev->udata, "%s %-5s %s:%d: ",
buf, level_strings[ev->level], ev->file, ev->line);
#endif
vfprintf(ev->udata, ev->fmt, ev->ap);
fprintf(ev->udata, "\n");
fflush(ev->udata);
}
static void ev_log_file_callback(ev_log_event_t* ev)
{
char buf[64];
buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
fprintf(
ev->udata, "%s %-5s %s:%d: ",
buf, level_strings[ev->level], ev->file, ev->line);
vfprintf(ev->udata, ev->fmt, ev->ap);
fprintf(ev->udata, "\n");
fflush(ev->udata);
}
static void lock(void)
{
if(G.lock)
G.lock(true, G.udata);
}
static void unlock(void)
{
if(G.lock)
G.lock(false, G.udata);
}
const char* ev_log_level_string(ev_log_level level)
{
return level_strings[level];
}
void ev_log_set_lock(ev_log_lock_fn fn, void* udata)
{
G.lock = fn;
G.udata = udata;
}
void ev_log_set_level(ev_log_level level)
{
G.level = level;
}
void ev_log_set_quiet(bool enable)
{
G.quiet = enable;
}
i32 ev_log_add_callback(ev_log_log_fn fn, void* udata, ev_log_level level)
{
for (i32 i = 0; i < MAX_CALLBACKS; i++) {
if (!G.callbacks[i].fn) {
G.callbacks[i] = (ev_log_callback_t) { fn, udata, level };
return 0;
}
}
return -1;
}
i32 log_add_fp(FILE *fp, ev_log_level level)
{
return ev_log_add_callback(ev_log_file_callback, fp, level);
}
static void init_event(ev_log_event_t* ev, void* udata)
{
if (!ev->time) {
time_t t = time(NULL);
ev->time = localtime(&t);
}
ev->udata = udata;
}
void ev_log(ev_log_level level, const char* file, u32 line, const char* fmt, ...)
{
ev_log_event_t ev = {
.fmt = fmt,
.file = file,
.line = line,
.level = level,
};
lock();
if (!G.quiet && level >= G.level) {
init_event(&ev, stderr);
va_start(ev.ap, fmt);
ev_log_stdout_callback(&ev);
va_end(ev.ap);
}
for (i32 i = 0; i < MAX_CALLBACKS && G.callbacks[i].fn; i++) {
ev_log_callback_t* cb = &G.callbacks[i];
if (level >= cb->level) {
init_event(&ev, cb->udata);
va_start(ev.ap, fmt);
cb->fn(&ev);
va_end(ev.ap);
}
}
unlock();
}
#endif
#endif

View File

@@ -97,4 +97,15 @@ static const struct Float64Data Float64 =
.EPS = 2.2204460492503131e-016 .EPS = 2.2204460492503131e-016
}; };
#if !EV_OS_WINDOWS
#define max(a,b) \
({ __typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; })
#define min(a,b) \
({ __typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; })
#endif
#endif // EV_HEADERS_NUMERIC_H #endif // EV_HEADERS_NUMERIC_H

View File

@@ -197,8 +197,20 @@ DEFINE_EQUAL_FUNCTION(evstring, Default)
return evstring_cmp(*(evstring*)self, *(evstring*)other) == 0; return evstring_cmp(*(evstring*)self, *(evstring*)other) == 0;
} }
DEFINE_COPY_FUNCTION(evstring, Default)
{
*(evstring*)dst = evstring_newFromStr(*src);
}
DEFINE_FREE_FUNCTION(evstring, Default)
{
evstring_free(*self);
}
TYPEDATA_GEN(evstring, TYPEDATA_GEN(evstring,
EQUAL(Default) EQUAL(Default),
COPY(Default),
FREE(Default)
); );

View File

@@ -30,12 +30,12 @@ typedef struct {
void *invalid_val; void *invalid_val;
} EvTypeData; } EvTypeData;
#define COPY_FUNCTION(T,name) EV_CATN(EV_COPY_FUNCTION_,T,_,name) #define COPY_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_COPY_FUNCTION_ ,T),_),name)
#define FREE_FUNCTION(T,name) EV_CATN(EV_FREE_FUNCTION_,T,_,name) #define FREE_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_FREE_FUNCTION_ ,T),_),name)
#define HASH_FUNCTION(T,name) EV_CATN(EV_HASH_FUNCTION_,T,_,name) #define HASH_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_HASH_FUNCTION_ ,T),_),name)
#define EQUAL_FUNCTION(T,name) EV_CATN(EV_EQUAL_FUNCTION_,T,_,name) #define EQUAL_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_EQUAL_FUNCTION_ ,T),_),name)
#define TOSTR_FUNCTION(T,name) EV_CATN(EV_TOSTR_FUNCTION_,T,_,name) #define TOSTR_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_TOSTR_FUNCTION_ ,T),_),name)
#define TOSTRLEN_FUNCTION(T,name) EV_CATN(EV_TOSTRLEN_FUNCTION_,T,_,name) #define TOSTRLEN_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_TOSTRLEN_FUNCTION_,T),_),name)
#define DEFINE_COPY_FUNCTION(T,name) static inline void COPY_FUNCTION(T,name)(T *dst, T *src) #define DEFINE_COPY_FUNCTION(T,name) static inline void COPY_FUNCTION(T,name)(T *dst, T *src)
#define DEFINE_DEFAULT_COPY_FUNCTION(T) \ #define DEFINE_DEFAULT_COPY_FUNCTION(T) \
@@ -94,7 +94,7 @@ typedef struct {
EV_WARNING_POP(); \ EV_WARNING_POP(); \
EV_UNUSED static T EV_OVERRIDE_VAR(T) EV_UNUSED static T EV_OVERRIDE_VAR(T)
#define __EV_STRUCT_METHOD_DEF(T, ...) EV_CATN(__EV_,EV_HEAD __VA_ARGS__,_FN)(T, EV_TAIL __VA_ARGS__) #define __EV_STRUCT_METHOD_DEF(T, ...) EV_CAT(EV_CAT(__EV_,EV_HEAD __VA_ARGS__),_FN)(T, EV_TAIL __VA_ARGS__)
#define COPY(...) (COPY , __VA_ARGS__) #define COPY(...) (COPY , __VA_ARGS__)
#define FREE(...) (FREE , __VA_ARGS__) #define FREE(...) (FREE , __VA_ARGS__)

162
ev_vec.h
View File

@@ -6,6 +6,10 @@
#include "ev_types.h" #include "ev_types.h"
#include "ev_numeric.h" #include "ev_numeric.h"
#if !EV_OS_WINDOWS
#include <string.h>
#endif
#if defined(EV_VEC_SHARED) #if defined(EV_VEC_SHARED)
# if defined (EV_VEC_IMPL) # if defined (EV_VEC_IMPL)
# define EV_VEC_API EV_EXPORT # define EV_VEC_API EV_EXPORT
@@ -99,8 +103,12 @@ TYPEDATA_GEN(ev_vec_overrides_t);
*/ */
#define ev_svec(T) T* #define ev_svec(T) T*
#define EV_VEC_MAGIC (0x65765F7665635F74)
//! Metadata that is stored with a vector. Unique to each vector. //! Metadata that is stored with a vector. Unique to each vector.
struct ev_vec_meta_t { struct ev_vec_meta_t {
u64 _magic;
//! The number of elements in the vector. //! The number of elements in the vector.
u64 length; u64 length;
//! The maximum length of the vector before it needs to be resized. //! The maximum length of the vector before it needs to be resized.
@@ -140,15 +148,19 @@ ev_vec_init_impl(
static struct ev_vec_meta_t *__svec_interm_md; static struct ev_vec_meta_t *__svec_interm_md;
#define __ev_svec_init_impl(T, len, cap, ...) ( \ #define __ev_svec_init_impl(T, len, cap, ...) ( \
__svec_interm_md = (u8[sizeof(T)*cap + sizeof(struct ev_vec_meta_t)]){}, \ EV_WARNING_PUSH() \
EV_WARNING_DISABLE_CLANG("unsequenced") \
__svec_interm_md = (void*)(u8[sizeof(T)*cap + sizeof(struct ev_vec_meta_t)]){}, \
*__svec_interm_md = (struct ev_vec_meta_t){ \ *__svec_interm_md = (struct ev_vec_meta_t){ \
._magic = EV_VEC_MAGIC, \
.length = len, \ .length = len, \
.capacity = cap, \ .capacity = cap, \
.typeData = TypeData(T), \ .typeData = TypeData(T), \
.allocationType = EV_VEC_ALLOCATION_TYPE_STACK, \ .allocationType = EV_VEC_ALLOCATION_TYPE_STACK, \
}, \ }, \
EV_VA_OPT(__VA_ARGS__)(memcpy(&__svec_interm_md[1], (T[])__VA_ARGS__, sizeof((T[])__VA_ARGS__)),) \ EV_VA_OPT(__VA_ARGS__)(memcpy(&__svec_interm_md[1], (T[])__VA_ARGS__, sizeof((T[])__VA_ARGS__)),) \
&(__svec_interm_md[1]) \ (void*)&(__svec_interm_md[1]) \
EV_WARNING_POP() \
) )
/*! /*!
@@ -169,46 +181,46 @@ static struct ev_vec_meta_t *__svec_interm_md;
#define __ev_vec_internal_push(v, var) ev_vec_push_impl((ev_vec_t*)v, var); #define __ev_vec_internal_push(v, var) ev_vec_push_impl((ev_vec_t*)v, var);
/*! /*!
* \param v A pointer to the vector that we want an iterator for * \param vec_p A pointer to the vector that we want an iterator for
* *
* \returns A pointer to the first element in a vector * \returns A pointer to the first element in a vector
*/ */
EV_VEC_API void * EV_VEC_API void *
ev_vec_iter_begin( ev_vec_iter_begin(
const ev_vec_t* v); const void* vec_p);
/*! /*!
* \param v A pointer to the vector that we want an iterator for * \param vec_p A pointer to the vector that we want an iterator for
* *
* \returns A pointer to the memory block right after the last element in the vector * \returns A pointer to the memory block right after the last element in the vector
*/ */
EV_VEC_API void * EV_VEC_API void *
ev_vec_iter_end( ev_vec_iter_end(
const ev_vec_t* v); const void* vec_p);
/*! /*!
* \brief A function that increments an iterator to make it point to the next * \brief A function that increments an iterator to make it point to the next
* element in the vector * element in the vector
* *
* \param v A pointer to the vector that is being iterated over * \param vec_p A pointer to the vector that is being iterated over
* \param iter Reference to the iterator that is being incremented * \param iter Reference to the iterator that is being incremented
*/ */
EV_VEC_API void EV_VEC_API void
ev_vec_iter_next( ev_vec_iter_next(
const ev_vec_t* v, const void* vec_p,
void **iter); void **iter);
/*! /*!
* \brief A function that looks for the index of `val` in `v` * \brief A function that looks for the index of `val` in `v`
* *
* \param v A pointer to the vector that is being iterated over * \param vec_p A pointer to the vector that is being iterated over
* \param val A pointer to the object that will be compared with vector elements * \param val A pointer to the object that will be compared with vector elements
* *
* \returns If found, index of element in vector. Otherwise, -1. * \returns If found, index of element in vector. Otherwise, -1.
*/ */
EV_VEC_API i32 EV_VEC_API i32
ev_vec_find( ev_vec_find(
const ev_vec_t* v, const void* vec_p,
void* val); void* val);
/*! /*!
@@ -219,11 +231,11 @@ ev_vec_find(
* *Note*: For stack-allocated vectors (`svec`), destructors are called for * *Note*: For stack-allocated vectors (`svec`), destructors are called for
* elements but no memory is freed. * elements but no memory is freed.
* *
* \param v A pointer to the vector that is being destroyed * \param vec_p A pointer to the vector that is being destroyed
*/ */
EV_VEC_API void EV_VEC_API void
ev_vec_fini( ev_vec_fini(
ev_vec_t* v); void* vec_p);
/*! /*!
* \brief A function that copies a value to the end of a vector. If the element * \brief A function that copies a value to the end of a vector. If the element
@@ -235,7 +247,7 @@ ev_vec_fini(
* For `svec`, as long as the capacity is more than the current size, a push * For `svec`, as long as the capacity is more than the current size, a push
* operation is permitted. Otherwise, the operation is treated as an OOM. * operation is permitted. Otherwise, the operation is treated as an OOM.
* *
* \param v Reference to the vector object * \param vec_p Reference to the vector object
* \param val A pointer to the element that is to be copied to the end of the * \param val A pointer to the element that is to be copied to the end of the
* vector * vector
* *
@@ -244,7 +256,7 @@ ev_vec_fini(
*/ */
EV_VEC_API int EV_VEC_API int
ev_vec_push_impl( ev_vec_push_impl(
ev_vec_t *v, void* vec_p,
void *val); void *val);
/*! /*!
@@ -260,7 +272,7 @@ ev_vec_push_impl(
* operation. If a deep copy is needed, individually pushing the elements of * operation. If a deep copy is needed, individually pushing the elements of
* the array is the way to go. * the array is the way to go.
* *
* \param v Reference to the vector object * \param vec_p Reference to the vector object
* \param arr A pointer to the array that is to be copied to the end of the * \param arr A pointer to the array that is to be copied to the end of the
* vector * vector
* \param size Number of elements in the array * \param size Number of elements in the array
@@ -270,17 +282,28 @@ ev_vec_push_impl(
*/ */
EV_VEC_API u32 EV_VEC_API u32
ev_vec_append( ev_vec_append(
ev_vec_t *v, void* vec_p,
void **arr, void **arr,
u64 size); u64 size);
/*!
* \brief A function that duplicates the passed vector into a new one and returns it.
*
* \param vec_p Reference to the vector object
*
* \returns The newly created vector.
*/
EV_VEC_API ev_vec_t
ev_vec_dup(
const void* vec_p);
/*! /*!
* \brief A function that copies the value at the end of a vector and removes * \brief A function that copies the value at the end of a vector and removes
* it from the vector. If a copy function was passed while initializing the * it from the vector. If a copy function was passed while initializing the
* vector, then this function is used. Otherwise, memcpy is used with a length * vector, then this function is used. Otherwise, memcpy is used with a length
* of `vec_meta.elemsize` * of `vec_meta.elemsize`
* *
* \param v Reference to the vector object * \param vec_p Reference to the vector object
* \param out A pointer to the memory block at which the popped element will be * \param out A pointer to the memory block at which the popped element will be
* copied. If NULL is passed, then the element is destructed. Otherwise, the * copied. If NULL is passed, then the element is destructed. Otherwise, the
* element is copied to `out` and the receiving code is responsible for its * element is copied to `out` and the receiving code is responsible for its
@@ -291,54 +314,54 @@ ev_vec_append(
*/ */
EV_VEC_API ev_vec_error_t EV_VEC_API ev_vec_error_t
ev_vec_pop( ev_vec_pop(
ev_vec_t *v, void* vec_p,
void *out); void *out);
/*! /*!
* \brief A function that returns the last element in the vector. * \brief A function that returns the last element in the vector.
* *
* \param v A pointer to the vector object * \param vec_p A pointer to the vector object
* *
* \returns Pointer to the last element in the vector. NULL if the vector is * \returns Pointer to the last element in the vector. NULL if the vector is
* empty. * empty.
*/ */
EV_VEC_API void * EV_VEC_API void *
ev_vec_last( ev_vec_last(
const ev_vec_t* v); const void* v);
/*! /*!
* \brief A function that returns the length of a vector * \brief A function that returns the length of a vector
* *
* \param v A pointer to the vector object * \param vec_p A pointer to the vector object
* *
* \returns Current length of the vector * \returns Current length of the vector
*/ */
EV_VEC_API u64 EV_VEC_API u64
ev_vec_len( ev_vec_len(
const ev_vec_t* v); void* vec_p);
/*! /*!
* \brief A function that returns the capacity of a vector * \brief A function that returns the capacity of a vector
* *
* \param v A pointer to the vector object * \param vec_p A pointer to the vector object
* *
* \returns Current capacity of the vector * \returns Current capacity of the vector
*/ */
EV_VEC_API u64 EV_VEC_API u64
ev_vec_capacity( ev_vec_capacity(
const ev_vec_t* v); const void* vec_p);
/*! /*!
* \brief Calls the free operation (if exists) on every element, then sets * \brief Calls the free operation (if exists) on every element, then sets
* the length to 0. * the length to 0.
* *
* \param v A pointer to the vector object * \param vec_p A pointer to the vector object
* *
* \returns 0 on success * \returns 0 on success
*/ */
EV_VEC_API u32 EV_VEC_API u32
ev_vec_clear( ev_vec_clear(
const ev_vec_t* v); const void* vec_p);
/*! /*!
* \brief Sets the length of the vector to `len`. * \brief Sets the length of the vector to `len`.
@@ -350,20 +373,20 @@ ev_vec_clear(
* For `svec`, if the `len` is more than the already allocated capacity, it is * For `svec`, if the `len` is more than the already allocated capacity, it is
* treated as an OOM. * treated as an OOM.
* *
* \param v Reference to the vector object * \param vec_p Reference to the vector object
* \param len The desired new length * \param len The desired new length
* *
* \returns `VEC_ERR_NONE` on success * \returns `VEC_ERR_NONE` on success
*/ */
EV_VEC_API ev_vec_error_t EV_VEC_API ev_vec_error_t
ev_vec_setlen( ev_vec_setlen(
ev_vec_t *v, void* vec_p,
u64 len); u64 len);
/*! /*!
* \brief Sets the capacity of the vector to `cap`. * \brief Sets the capacity of the vector to `cap`.
* *
* \param v Reference to the vector object * \param vec_p Reference to the vector object
* \param cap The desired new capacity * \param cap The desired new capacity
* *
* For stack-allocated vectors, `VEC_ERR_OOM` is returned * For stack-allocated vectors, `VEC_ERR_OOM` is returned
@@ -372,25 +395,26 @@ ev_vec_setlen(
*/ */
EV_VEC_API ev_vec_error_t EV_VEC_API ev_vec_error_t
ev_vec_setcapacity( ev_vec_setcapacity(
ev_vec_t *v, void* vec_p,
u64 cap); u64 cap);
/*! /*!
* \brief Grows the vector's capacity by a factor of `VEC_GROWTH_RATE` * \brief Grows the vector's capacity by a factor of `VEC_GROWTH_RATE`
* *
* \param Reference to the vector object * \param vec_p Reference to the vector object
* *
* \returns `VEC_ERR_NONE` on success * \returns `VEC_ERR_NONE` on success
*/ */
EV_VEC_API ev_vec_error_t EV_VEC_API ev_vec_error_t
ev_vec_grow( ev_vec_grow(
ev_vec_t *v); void* vec_p);
static const ev_vec_t EV_VEC_EMPTY = static const ev_vec_t EV_VEC_EMPTY =
(ev_vec(i32))&((struct { (ev_vec(i32))&((struct {
struct ev_vec_meta_t meta; struct ev_vec_meta_t meta;
EV_ALIGNAS(EV_ALIGNOF(i32)) i32 data[0]; EV_ALIGNAS(EV_ALIGNOF(i32)) i32 data[0];
}) { }) {
.meta._magic = EV_VEC_MAGIC,
.meta.length = 0, .meta.length = 0,
.meta.capacity = 0, .meta.capacity = 0,
.meta.typeData = TypeData(i32), .meta.typeData = TypeData(i32),
@@ -412,6 +436,7 @@ TYPEDATA_GEN(
#ifdef EV_VEC_IMPLEMENTATION #ifdef EV_VEC_IMPLEMENTATION
#undef EV_VEC_IMPLEMENTATION #undef EV_VEC_IMPLEMENTATION
#ifdef EV_VEC_API_CHECK #ifdef EV_VEC_API_CHECK
#define EV_VEC_CHECK(x) do { x; } while (0) #define EV_VEC_CHECK(x) do { x; } while (0)
#else #else
@@ -425,7 +450,8 @@ TYPEDATA_GEN(
((struct ev_vec_meta_t *)v) - 1 ((struct ev_vec_meta_t *)v) - 1
#define __ev_vec_getmeta(v) \ #define __ev_vec_getmeta(v) \
struct ev_vec_meta_t *metadata = ((struct ev_vec_meta_t *)(v)) - 1; struct ev_vec_meta_t *metadata = ((struct ev_vec_meta_t *)(v)) - 1; \
assert(metadata->_magic == EV_VEC_MAGIC);
#define __ev_vec_syncmeta(v) \ #define __ev_vec_syncmeta(v) \
metadata = ((struct ev_vec_meta_t *)(v)) - 1; metadata = ((struct ev_vec_meta_t *)(v)) - 1;
@@ -450,6 +476,7 @@ ev_vec_init_impl(
struct ev_vec_meta_t *metadata = (struct ev_vec_meta_t *)v; struct ev_vec_meta_t *metadata = (struct ev_vec_meta_t *)v;
*metadata = (struct ev_vec_meta_t){ *metadata = (struct ev_vec_meta_t){
._magic = EV_VEC_MAGIC,
.length = 0, .length = 0,
.capacity = EV_VEC_INIT_CAP, .capacity = EV_VEC_INIT_CAP,
.allocationType = EV_VEC_ALLOCATION_TYPE_HEAP, .allocationType = EV_VEC_ALLOCATION_TYPE_HEAP,
@@ -461,9 +488,10 @@ ev_vec_init_impl(
i32 i32
ev_vec_find( ev_vec_find(
const ev_vec_t* v, const void* vec_p,
void *val) void *val)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
if(metadata->typeData.equal_fn) { if(metadata->typeData.equal_fn) {
for (void *elem = ev_vec_iter_begin(v); elem != ev_vec_iter_end(v); ev_vec_iter_next(v, &elem)) { for (void *elem = ev_vec_iter_begin(v); elem != ev_vec_iter_end(v); ev_vec_iter_next(v, &elem)) {
@@ -486,8 +514,9 @@ ev_vec_find(
void void
ev_vec_fini( ev_vec_fini(
ev_vec_t* v) void* vec_p)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
if (metadata->typeData.free_fn) { if (metadata->typeData.free_fn) {
@@ -505,9 +534,10 @@ ev_vec_fini(
int int
ev_vec_push_impl( ev_vec_push_impl(
ev_vec_t *v, void* vec_p,
void *val) void *val)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
if (metadata->length == metadata->capacity) { if (metadata->length == metadata->capacity) {
@@ -531,15 +561,16 @@ ev_vec_push_impl(
void * void *
ev_vec_iter_begin( ev_vec_iter_begin(
const ev_vec_t* v) const void* vec_p)
{ {
return *v; return *(void**)vec_p;
} }
void * void *
ev_vec_iter_end( ev_vec_iter_end(
const ev_vec_t* v) const void* vec_p)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
return ((char *)*v) + (metadata->typeData.size * metadata->length); return ((char *)*v) + (metadata->typeData.size * metadata->length);
@@ -547,19 +578,21 @@ ev_vec_iter_end(
void void
ev_vec_iter_next( ev_vec_iter_next(
const ev_vec_t* v, const void* vec_p,
void **iter) void **iter)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
*iter = ((char*)*iter) + metadata->typeData.size; *iter = ((char*)*iter) + metadata->typeData.size;
} }
EV_VEC_API u32 EV_VEC_API u32
ev_vec_append( ev_vec_append(
ev_vec_t *v, void* vec_p,
void **arr, void **arr,
u64 size) u64 size)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
size_t old_len = metadata->length; size_t old_len = metadata->length;
size_t req_len = old_len + size; size_t req_len = old_len + size;
@@ -576,11 +609,35 @@ ev_vec_append(
return (int)old_len; return (int)old_len;
} }
EV_VEC_API ev_vec_t
ev_vec_dup(
const void* vec_p)
{
ev_vec_t v_orig = *(ev_vec_t*)vec_p;
__ev_vec_getmeta(v_orig)
ev_vec_t v_new = ev_vec_init_impl(metadata->typeData, (ev_vec_overrides_t){0});
ev_vec_setcapacity(&v_new, metadata->length);
if(metadata->typeData.copy_fn)
{
for(int i = 0; i < metadata->length; i++)
ev_vec_push_impl(&v_new, (u8*)v_orig + (metadata->typeData.size * i));
}
else
{
ev_vec_setlen(&v_new, metadata->length);
memcpy(v_new, v_orig, metadata->length * metadata->typeData.size);
}
return v_new;
}
ev_vec_error_t ev_vec_error_t
ev_vec_pop( ev_vec_pop(
ev_vec_t *v, void* vec_p,
void *out) void *out)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
if(out != NULL) { if(out != NULL) {
@@ -604,8 +661,9 @@ ev_vec_pop(
void * void *
ev_vec_last( ev_vec_last(
const ev_vec_t* v) const void* vec_p)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
if(metadata->length == 0) { if(metadata->length == 0) {
@@ -617,24 +675,27 @@ ev_vec_last(
u64 u64
ev_vec_len( ev_vec_len(
const ev_vec_t* v) void* vec_p)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
return metadata->length; return metadata->length;
} }
u64 u64
ev_vec_capacity( ev_vec_capacity(
const ev_vec_t* v) const void* vec_p)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
return metadata->capacity; return metadata->capacity;
} }
u32 u32
ev_vec_clear( ev_vec_clear(
const ev_vec_t* v) const void* vec_p)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
if (metadata->typeData.free_fn) { if (metadata->typeData.free_fn) {
@@ -650,9 +711,10 @@ ev_vec_clear(
ev_vec_error_t ev_vec_error_t
ev_vec_setlen( ev_vec_setlen(
ev_vec_t *v, void* vec_p,
u64 len) u64 len)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
while(len > metadata->capacity) { while(len > metadata->capacity) {
@@ -669,9 +731,10 @@ ev_vec_setlen(
ev_vec_error_t ev_vec_error_t
ev_vec_setcapacity( ev_vec_setcapacity(
ev_vec_t *v, void* vec_p,
u64 cap) u64 cap)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
if(metadata->allocationType == EV_VEC_ALLOCATION_TYPE_STACK) { if(metadata->allocationType == EV_VEC_ALLOCATION_TYPE_STACK) {
@@ -701,8 +764,9 @@ ev_vec_setcapacity(
ev_vec_error_t ev_vec_error_t
ev_vec_grow( ev_vec_grow(
ev_vec_t *v) void* vec_p)
{ {
ev_vec_t* v = (ev_vec_t*)vec_p;
__ev_vec_getmeta(*v) __ev_vec_getmeta(*v)
return ev_vec_setcapacity(v, metadata->capacity * EV_VEC_GROWTH_RATE); return ev_vec_setcapacity(v, metadata->capacity * EV_VEC_GROWTH_RATE);
} }

9
log_test.c Normal file
View File

@@ -0,0 +1,9 @@
#define EV_LOG_IMPLEMENTATION
#include "ev_log.h"
int main()
{
ev_log_trace("Trace Log");
return 0;
}

View File

@@ -1,4 +0,0 @@
[binaries]
c = 'clang.exe'
c_ld = 'lld'
cpp = 'clang++.exe'

View File

@@ -24,26 +24,32 @@ endif
str_lib = static_library('ev_str', files('buildfiles/ev_str.c'), c_args: evh_c_args) str_lib = static_library('ev_str', files('buildfiles/ev_str.c'), c_args: evh_c_args)
vec_lib = static_library('ev_vec', files('buildfiles/ev_vec.c'), c_args: evh_c_args) vec_lib = static_library('ev_vec', files('buildfiles/ev_vec.c'), c_args: evh_c_args)
helpers_lib = static_library('ev_helpers', files('buildfiles/ev_helpers.c'), c_args: evh_c_args) helpers_lib = static_library('ev_helpers', files('buildfiles/ev_helpers.c'), c_args: evh_c_args)
log_lib = static_library('ev_log', files('buildfiles/ev_log.c'), c_args: evh_c_args)
str_dep = declare_dependency(link_with: str_lib, include_directories: headers_include) str_dep = declare_dependency(link_with: str_lib, include_directories: headers_include)
vec_dep = declare_dependency(link_with: vec_lib, include_directories: headers_include) vec_dep = declare_dependency(link_with: vec_lib, include_directories: headers_include)
helpers_dep = declare_dependency(link_with: helpers_lib, include_directories: headers_include) helpers_dep = declare_dependency(link_with: helpers_lib, include_directories: headers_include)
log_dep = declare_dependency(link_with: log_lib, include_directories: headers_include)
headers_dep = declare_dependency( headers_dep = declare_dependency(
dependencies: [ dependencies: [
str_dep, str_dep,
vec_dep, vec_dep,
helpers_dep, helpers_dep,
log_dep
] ]
) )
# Tests # Tests
str_test = executable('str_test', 'str_test.c', dependencies: [str_dep], c_args: evh_c_args) str_test = executable('str_test', 'str_test.c', dependencies: [str_dep], c_args: evh_c_args)
test('evstr', str_test) test('evstr', str_test)
log_test = executable('log_test', 'log_test.c', dependencies: [log_dep], c_args: evh_c_args)
test('evlog', log_test)
if meson.version().version_compare('>= 0.54.0') if meson.version().version_compare('>= 0.54.0')
meson.override_dependency('ev_vec', vec_dep) meson.override_dependency('ev_vec', vec_dep)
meson.override_dependency('ev_str', str_dep) meson.override_dependency('ev_str', str_dep)
meson.override_dependency('ev_helpers', helpers_dep) meson.override_dependency('ev_helpers', helpers_dep)
meson.override_dependency('ev_log', log_dep)
meson.override_dependency('evol-headers', headers_dep) meson.override_dependency('evol-headers', headers_dep)
endif endif