Compare commits

..

No commits in common. "main" and "memory" have entirely different histories.
main ... memory

369
slibs.h
View file

@ -7,13 +7,93 @@
#include <stdlib.h>
#include <string.h>
// Miscellaneous
#pragma region Memory
typedef struct sl_metadata
{
uint8_t magic;
uint32_t size;
} sl_metadata;
#define MD_SZ sizeof(sl_metadata)
#define MD_MAGIC 0xDE
typedef void *sl_mem;
void *sl_get_memory(sl_metadata *m);
sl_metadata *sl_get_metadata(sl_mem ptr);
void *sl_malloc(uint32_t size);
void *sl_realloc(sl_mem ptr, uint32_t size);
sl_mem __sl_serialize_struct(void *struc, size_t size);
#define sl_serialize_struct(struc) __sl_serialize_struct((void *)&struc, sizeof(struc))
#ifdef SL_IMPLEMENTATION
sl_mem sl_get_memory(sl_metadata *md)
{
return (sl_mem)((uintptr_t)md + MD_SZ);
}
sl_metadata *sl_get_metadata(sl_mem ptr)
{
sl_metadata *md = (sl_metadata *)((uintptr_t)ptr - MD_SZ);
assert(md->magic == MD_MAGIC && "Metadata magic does not match.");
return md;
}
sl_mem sl_malloc(uint32_t size)
{
sl_metadata *md = (sl_metadata *)malloc(size + MD_SZ);
md->magic = MD_MAGIC;
md->size = size;
return sl_get_memory(md);
}
void *sl_realloc(sl_mem ptr, uint32_t size)
{
sl_metadata *md = (sl_metadata *)realloc(sl_get_metadata(ptr), size);
md->size = size;
return sl_get_memory(md);
}
sl_mem __sl_serialize_struct(sl_mem struc, size_t size)
{
sl_mem mem = NULL;
size_t offset = 0;
for (int i = 0; i < size / sizeof(uintptr_t); i++)
{
sl_mem ptr = *(sl_mem *)(struc + i * sizeof(void *));
sl_metadata *md = sl_get_metadata(ptr);
size_t full_size = md->size + MD_SZ;
if (mem == NULL)
{
mem = sl_malloc(full_size);
}
else
{
sl_metadata *mem_md = sl_get_metadata(mem);
mem = sl_realloc(mem, mem_md->size + full_size);
}
memcpy(mem + offset, md, MD_SZ);
offset += MD_SZ;
memcpy(mem + offset, ptr, md->size);
offset += md->size;
}
return mem;
}
#endif
#pragma endregion
#pragma region Miscellaneous
#define sl_auto(name, x) typeof(x) name = x
#define sl_new(type, ...) \
({ \
type *ptr = malloc(sizeof(type)); \
type *ptr = sl_malloc(sizeof(type)); \
*ptr = (type){__VA_ARGS__}; \
ptr; \
})
@ -42,10 +122,12 @@
#define sl_stringify(x) #x
// Vector
#pragma endregion
#pragma region Vector
#define sl_vec(type) \
struct { \
struct \
{ \
type *data; \
size_t size; \
size_t capacity; \
@ -54,8 +136,12 @@
#define sl_vec_grow(vec) \
{ \
(vec).capacity = (vec).capacity * 2 + 1; \
void *ptr = realloc((vec).data, (vec).capacity * sizeof(*(vec).data)); \
if (ptr) \
void *ptr; \
if ((vec).data == NULL) \
ptr = sl_malloc((vec).capacity * sizeof(*(vec).data)); \
else \
ptr = sl_realloc((vec).data, (vec).capacity * sizeof(*(vec).data)); \
assert(ptr != NULL); \
(vec).data = ptr; \
}
@ -66,14 +152,7 @@
(vec).data[(vec).size++] = (element); \
}
#define sl_vec_from_arr(vec, arr) \
{ \
for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { \
sl_vec_push(vec, arr[i]); \
} \
}
#define sl_vec_unshift(vec, element) \
#define sl_vec_shift(vec, element) \
{ \
if ((vec).size >= (vec).capacity) \
sl_vec_grow(vec); \
@ -82,21 +161,10 @@
(vec).size++; \
}
#define sl_vec_shift(vec) \
{ \
memmove((vec).data, (vec).data + 1, (vec).size * sizeof(*(vec).data)); \
(vec).size--; \
}
#define sl_vec_forward(vec) \
{ (vec).data++; }
#define sl_vec_backward(vec) \
{ (vec).data--; }
#define sl_vec_pop(vec) \
{ \
if ((vec).size > 0) { \
if ((vec).size > 0) \
{ \
(vec).size--; \
} \
}
@ -118,97 +186,8 @@
(name) != sl_vec_end(vec); \
++(name)
// TODO: Linked List
// #define sl_list(name, type) \
// struct name \
// { \
// type *data; \
// struct name *next; \
// }
// #define sl_list_append(list, value) \
// { \
// sl_auto(curr, list);\
// } \
// Hashmap
#define SL_MAX_HASH_ENTRIES 512
int sl_hash(const char *str);
#define sl_map(name, valuetype) \
typedef valuetype sl_##name##_type; \
\
typedef struct sl_##name##_entry { \
const char *key; \
sl_##name##_type value; \
} sl_##name##_entry; \
\
typedef sl_vec(sl_##name##_entry) sl_##name##_entry_vec; \
\
typedef struct sl_##name##_map { \
sl_##name##_entry_vec *entries[SL_MAX_HASH_ENTRIES]; \
} sl_##name##_map; \
\
sl_##name##_map name = {0};
#define sl_map_set(map, key_, val) \
{ \
int hash = sl_hash(key_); \
sl_##map##_entry_vec *entry = map.entries[hash]; \
if (!entry) { \
entry = calloc(1, sizeof(sl_##map##_entry_vec)); \
map.entries[hash] = entry; \
} \
int found = 0; \
for (sl_vec_it(el, *entry)) { \
if (strcmp(el->key, key_) == 0) { \
el->value = val; \
found = 1; \
break; \
} \
} \
if (!found) { \
sl_##map##_entry new_entry = {key_, val}; \
sl_vec_push(*entry, new_entry) \
} \
}
#define sl_map_get(map, key_) \
({ \
sl_##map##_entry_vec *entry = map.entries[sl_hash(key_)]; \
sl_##map##_type *value = NULL; \
\
if (entry) { \
for (sl_vec_it(el, *entry)) { \
if (strcmp(el->key, key_) == 0) { \
value = &el->value; \
break; \
} \
} \
} \
\
value; \
})
#ifdef SL_IMPLEMENTATION
int sl_hash(const char *str) {
uint32_t seed = 0;
size_t len = strlen(str);
for (size_t i = 0; i < len && i < sizeof(uint32_t); i++) {
seed <<= 8;
seed |= str[i];
}
srand(seed);
return rand() % SL_MAX_HASH_ENTRIES;
}
#endif
// String
#pragma endregion
#pragma region String
typedef sl_vec(char) sl_string;
@ -223,7 +202,7 @@ typedef sl_vec(char) sl_string;
#define sl_tostring(val) \
({ \
sl_auto(len, snprintf(NULL, 0, sl_fmt_spec(val), val) + 1); \
sl_auto(buf, (char *)malloc(len)); \
sl_auto(buf, (char *)sl_malloc(len)); \
snprintf(buf, len, sl_fmt_spec(val), val); \
sl_auto(str, sl_string(buf)); \
free(buf); \
@ -232,39 +211,33 @@ typedef sl_vec(char) sl_string;
#define sl_str_free(str) sl_vec_free(str)
char *sl_c_str(sl_string str);
#define sl_c_str(str) \
({ \
sl_vec_push((str), '\0'); \
(str).size--; \
(str).data; \
})
#ifdef SL_IMPLEMENTATION
char *sl_c_str(sl_string str) {
sl_vec_push(str, '\0');
return str.data;
}
#endif
void sl_append_c_str(sl_string *sl_str, const char *c_str);
#ifdef SL_IMPLEMENTATION
void sl_append_c_str(sl_string *sl_str, const char *c_str) {
for (int i = 0; i < strlen(c_str); i++) {
sl_vec_push(*sl_str, c_str[i]);
}
}
#endif
// Pointers
#pragma endregion
#pragma region Pointers
#define sl_ptr(type) \
struct { \
struct \
{ \
type *ptr; \
int ref_count; \
}
#define sl_ptr_make(raw_ptr) {raw_ptr, 1}
#define sl_ptr_make(raw_ptr) \
{ \
raw_ptr, 1 \
}
#define sl_ptr_release(smart_ptr) \
({ \
smart_ptr.ref_count--; \
if (smart_ptr.ref_count <= 0) { \
if (smart_ptr.ref_count <= 0) \
{ \
free(smart_ptr.ptr); \
} \
})
@ -284,43 +257,119 @@ void sl_append_c_str(sl_string *sl_str, const char *c_str) {
sl_ptr_release(smart_ptr); \
});
FILE *sl_open_file(const char *filename, const char *mode);
sl_string *sl_read_file(const char *filename);
void sl_write_file(const char *filename, const sl_string buffer);
void sl_read_file(const char *filename, sl_string *buffer);
void sl_write_file(const char *filename, const sl_string *buffer);
void sl_write_bytes(const char *filename, const uint8_t *data, size_t length);
uint8_t *sl_read_bytes(const char *filename, size_t *length);
void sl_write_metadata(const char *filename, sl_metadata *m);
void sl_write_memory(const char *filename, void *ptr);
#ifdef SL_IMPLEMENTATION
FILE *sl_open_file(const char *filename, const char *mode) {
FILE *file = fopen(filename, mode);
return file;
}
sl_string *sl_read_file(const char *filename) {
FILE *file = sl_open_file(filename, "r");
void sl_read_file(const char *filename, sl_string *buffer)
{
FILE *file = fopen(filename, "r");
if (!file)
return NULL;
{
fprintf(stderr, "Error: could not open file %s\n", filename);
exit(1);
}
fseek(file, 0, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0, SEEK_SET);
sl_string *buffer = sl_new(sl_string, 0);
for (size_t i = 0; i < file_size; i++) {
for (size_t i = 0; i < file_size; i++)
{
sl_vec_push(*buffer, fgetc(file));
}
fclose(file);
return buffer;
}
void sl_write_file(const char *filename, sl_string buffer) {
FILE *file = sl_open_file(filename, "w");
void sl_write_file(const char *filename, const sl_string *buffer)
{
FILE *file = fopen(filename, "w");
if (!file)
return;
{
fprintf(stderr, "Error: could not open file %s\n", filename);
exit(1);
}
for (size_t i = 0; i < buffer->size; i++)
{
fputc(buffer->data[i], file);
}
fputs(sl_c_str(buffer), file);
fclose(file);
}
void sl_write_bytes(const char *filename, const uint8_t *data, size_t length)
{
FILE *file = fopen(filename, "wb");
if (!file)
{
fprintf(stderr, "Error: could not open file %s\n", filename);
exit(1);
}
size_t written = fwrite(data, sizeof(uint8_t), length, file);
if (written != length)
{
fprintf(stderr, "Error: could not write all data to file %s\n", filename);
fclose(file);
exit(1);
}
fclose(file);
}
uint8_t *sl_read_bytes(const char *filename, size_t *length)
{
FILE *file = fopen(filename, "rb");
if (!file)
{
fprintf(stderr, "Error: could not open file %s\n", filename);
exit(1);
}
fseek(file, 0, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0, SEEK_SET);
uint8_t *data = (uint8_t *)sl_malloc(file_size);
if (!data)
{
fprintf(stderr, "Error: could not allocate memory\n");
fclose(file);
exit(1);
}
size_t read = fread(data, sizeof(uint8_t), file_size, file);
if (read != file_size)
{
fprintf(stderr, "Error: could not read all data from file %s\n", filename);
free(data);
fclose(file);
exit(1);
}
fclose(file);
if (length != NULL)
*length = file_size;
return data;
}
void sl_write_metadata(const char *filename, sl_metadata *m)
{
sl_write_bytes(filename, sl_get_memory(m), m->size);
}
void sl_write_memory(const char *filename, void *ptr)
{
sl_write_metadata(filename, sl_get_metadata(ptr));
}
#endif
#pragma endregion
#endif // SLIBS_H