Compare commits
5 Commits
ebe6e58ef3
...
ba7a81d205
| Author | SHA1 | Date | |
|---|---|---|---|
| ba7a81d205 | |||
| 8999fda11c | |||
| 7e5b1ea9bb | |||
| e16a0035a4 | |||
| be2c4e7792 |
@@ -7,14 +7,14 @@ typedef struct List {
|
|||||||
u32 allocated_size;
|
u32 allocated_size;
|
||||||
} List;
|
} List;
|
||||||
|
|
||||||
#define List_construct(L, T, OCCUPIED_COUNT, ALLOCATED_COUNT) \
|
#define List_construct(DATA_PTR, T, OCCUPIED_COUNT, ALLOCATED_COUNT) \
|
||||||
List_construct_size(L, (OCCUPIED_COUNT) * sizeof(T), (ALLOCATED_COUNT) * sizeof(T))
|
List_construct_size(DATA_PTR, (OCCUPIED_COUNT) * sizeof(T), (ALLOCATED_COUNT) * sizeof(T))
|
||||||
|
|
||||||
static inline List List_construct_size(void* data_ptr, u32 size, u32 allocated_size) {
|
static inline List List_construct_size(void* data_ptr, u32 occupied_size, u32 allocated_size) {
|
||||||
return (List){ .data = data_ptr, .size = size, .allocated_size = allocated_size };
|
return (List){ .data = data_ptr, .size = occupied_size, .allocated_size = allocated_size };
|
||||||
}
|
}
|
||||||
|
|
||||||
#define List_alloc(L, T, INITIAL_COUNT) List_alloc_size(L, (INITIAL_COUNT) * sizeof(T))
|
#define List_alloc(T, INITIAL_COUNT) List_alloc_size((INITIAL_COUNT) * sizeof(T))
|
||||||
List List_alloc_size(u32 initial_size);
|
List List_alloc_size(u32 initial_size);
|
||||||
|
|
||||||
void* List_expand(List* ptr, u32 expansion_size);
|
void* List_expand(List* ptr, u32 expansion_size);
|
||||||
61
include/tlibc/errors.h
Executable file
61
include/tlibc/errors.h
Executable file
@@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "std.h"
|
||||||
|
#include "string/str.h"
|
||||||
|
#include "collections/List.h"
|
||||||
|
|
||||||
|
typedef struct ErrorCallPos {
|
||||||
|
i32 line;
|
||||||
|
str file;
|
||||||
|
str func;
|
||||||
|
} ErrorCallPos;
|
||||||
|
#define ErrorCallPos_here() (ErrorCallPos){\
|
||||||
|
.line = __LINE__,\
|
||||||
|
.file = str_construct((char*)(void*)__FILE__, sizeof(__FILE__), true),\
|
||||||
|
.func = str_construct((char*)(void*)__func__, sizeof(__func__), true)\
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct Error {
|
||||||
|
str msg;
|
||||||
|
bool is_msg_on_heap;
|
||||||
|
/* List<ErrorCallPos> */
|
||||||
|
List call_stack;
|
||||||
|
} Error;
|
||||||
|
|
||||||
|
Error* Error_create(const char* msg, bool is_msg_on_heap, ErrorCallPos);
|
||||||
|
void Error_destroy(Error* e);
|
||||||
|
void Error_addCallPos(Error* e, ErrorCallPos p);
|
||||||
|
str Error_toStr(Error* e);
|
||||||
|
void Error_printAndExit(Error* e) __attribute__ ((__noreturn__));
|
||||||
|
|
||||||
|
typedef struct Result_ {
|
||||||
|
Error* error;
|
||||||
|
union {
|
||||||
|
u64 v_u64;
|
||||||
|
i64 v_i64;
|
||||||
|
f32 v_f32;
|
||||||
|
f64 v_f64;
|
||||||
|
void* v_ptr;
|
||||||
|
};
|
||||||
|
} Result_;
|
||||||
|
|
||||||
|
#define Result(T) Result_
|
||||||
|
|
||||||
|
|
||||||
|
#define RESULT_ERROR(MSG, IS_MSG_ON_HEAP) (Result_){ .error = Error_create(MSG, IS_MSG_ON_HEAP, ErrorCallPos_here()) }
|
||||||
|
#define RESULT_VOID (Result_){ .error = NULL }
|
||||||
|
#define RESULT_VALUE(TYPE, V) (Result_){ .error = NULL, .v_##TYPE = V }
|
||||||
|
|
||||||
|
#define try(VAR, RSLT_CALL, DEFER_CODE) \
|
||||||
|
Result_ VAR = RSLT_CALL;\
|
||||||
|
if(VAR.error){\
|
||||||
|
Error_addCallPos(VAR.error, ErrorCallPos_here());\
|
||||||
|
DEFER_CODE;\
|
||||||
|
return VAR;\
|
||||||
|
};
|
||||||
|
|
||||||
|
#define try_fatal(VAR, RSLT_CALL, DEFER_CODE) \
|
||||||
|
Result_ VAR = RSLT_CALL;\
|
||||||
|
if(VAR.error){\
|
||||||
|
DEFER_CODE;\
|
||||||
|
Error_printAndExit(VAR.error);\
|
||||||
|
};
|
||||||
@@ -20,6 +20,7 @@ typedef int64_t i64;
|
|||||||
typedef uint64_t u64;
|
typedef uint64_t u64;
|
||||||
typedef float f32;
|
typedef float f32;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
|
typedef void* ptr;
|
||||||
|
|
||||||
#if !__cplusplus
|
#if !__cplusplus
|
||||||
typedef u8 bool;
|
typedef u8 bool;
|
||||||
@@ -33,7 +34,7 @@ typedef const char* cstr;
|
|||||||
|
|
||||||
#define nameof(V) #V
|
#define nameof(V) #V
|
||||||
|
|
||||||
#define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
|
#define ARRAY_LEN(A) (sizeof(A)/sizeof(A[0]))
|
||||||
#define ALIGN_TO(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1))
|
#define ALIGN_TO(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1))
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
@@ -21,7 +21,7 @@ void StringBuilder_append_str(StringBuilder* b, str s);
|
|||||||
void StringBuilder_append_i64(StringBuilder* b, i64 a);
|
void StringBuilder_append_i64(StringBuilder* b, i64 a);
|
||||||
void StringBuilder_append_u64(StringBuilder* b, u64 a);
|
void StringBuilder_append_u64(StringBuilder* b, u64 a);
|
||||||
void StringBuilder_append_f64(StringBuilder* b, f64 a);
|
void StringBuilder_append_f64(StringBuilder* b, f64 a);
|
||||||
void StringBuilder_append_memory(StringBuilder* b, Array mem);
|
void StringBuilder_append_memory(StringBuilder* b, Array mem, bool uppercase);
|
||||||
|
|
||||||
// adds '\0' to the buffer and returns pointer to buffer content
|
// adds '\0' to the buffer and returns pointer to buffer content
|
||||||
str StringBuilder_getStr(StringBuilder* b);
|
str StringBuilder_getStr(StringBuilder* b);
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "../std.h"
|
#include "../std.h"
|
||||||
#include "char.h"
|
#include "char.h"
|
||||||
#include "cstr.h"
|
#include "cstr.h"
|
||||||
|
#include "../collections/Array.h"
|
||||||
|
|
||||||
typedef struct str {
|
typedef struct str {
|
||||||
char* data;
|
char* data;
|
||||||
@@ -11,7 +12,7 @@ typedef struct str {
|
|||||||
} str;
|
} str;
|
||||||
|
|
||||||
/// creates str from a string literal
|
/// creates str from a string literal
|
||||||
#define STR(LITERAL) str_construct(LITERAL, ARRAY_SIZE(LITERAL) - 1, true)
|
#define STR(LITERAL) str_construct(LITERAL, ARRAY_LEN(LITERAL) - 1, true)
|
||||||
|
|
||||||
#define str_construct(DATA, LEN, ZERO_TERMINATED) ((str){ .data = DATA, .size = LEN, .isZeroTerminated = ZERO_TERMINATED })
|
#define str_construct(DATA, LEN, ZERO_TERMINATED) ((str){ .data = DATA, .size = LEN, .isZeroTerminated = ZERO_TERMINATED })
|
||||||
|
|
||||||
@@ -41,3 +42,5 @@ u32 str_hash32(str s);
|
|||||||
|
|
||||||
str str_toUpper(str src);
|
str str_toUpper(str src);
|
||||||
str str_toLower(str src);
|
str str_toLower(str src);
|
||||||
|
|
||||||
|
str hex_to_str(Array buf, bool uppercase);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "collections/HashMap.h"
|
#include "tlibc/collections/HashMap.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
//TODO: sort bucket keys for binary search
|
//TODO: sort bucket keys for binary search
|
||||||
@@ -83,7 +83,7 @@ void* NULLABLE(HashMap_tryGetPtr)(HashMap* ptr, str key){
|
|||||||
|
|
||||||
static void __HashMap_expand(HashMap* ptr){
|
static void __HashMap_expand(HashMap* ptr){
|
||||||
u32 height_expanded_n = ptr->height_n + 1;
|
u32 height_expanded_n = ptr->height_n + 1;
|
||||||
assert(height_expanded_n >= Array_len(&__HashMap_heights, u32) && "HashMap IS FULL! Fix your code.");
|
assert(height_expanded_n < Array_len(&__HashMap_heights, u32) && "HashMap IS FULL! Fix your code.");
|
||||||
|
|
||||||
// alloc new HashMapBucket array
|
// alloc new HashMapBucket array
|
||||||
u32 height_expanded = ((u32*)__HashMap_heights.data)[height_expanded_n];
|
u32 height_expanded = ((u32*)__HashMap_heights.data)[height_expanded_n];
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "collections/List.h"
|
#include "tlibc/collections/List.h"
|
||||||
|
|
||||||
List List_alloc_size(u32 initial_size){
|
List List_alloc_size(u32 initial_size){
|
||||||
if(initial_size == 0)
|
if(initial_size == 0)
|
||||||
|
|||||||
53
src/errors.c
Executable file
53
src/errors.c
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#include "tlibc/errors.h"
|
||||||
|
#include "tlibc/string/StringBuilder.h"
|
||||||
|
|
||||||
|
#define ERRMSG_LENGTH 1024
|
||||||
|
|
||||||
|
Error* Error_create(const char* msg, bool is_msg_on_heap, ErrorCallPos){
|
||||||
|
Error* e = (Error*)malloc(sizeof(Error));
|
||||||
|
e->msg = str_construct((char*)(void*)msg, strlen(msg), true);
|
||||||
|
e->is_msg_on_heap = is_msg_on_heap;
|
||||||
|
e->call_stack = List_alloc(ErrorCallPos, 1);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Error_destroy(Error* e){
|
||||||
|
if(e->is_msg_on_heap)
|
||||||
|
free(e->msg.data);
|
||||||
|
free(e->call_stack.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Error_addCallPos(Error* e, ErrorCallPos p){
|
||||||
|
List_push(&e->call_stack, ErrorCallPos, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
str Error_toStr(Error* e){
|
||||||
|
u32 len = List_len(&e->call_stack, ErrorCallPos);
|
||||||
|
StringBuilder b = StringBuilder_alloc(e->msg.size + 80 * len);
|
||||||
|
|
||||||
|
StringBuilder_append_str(&b, STR("Error: "));
|
||||||
|
StringBuilder_append_str(&b, e->msg);
|
||||||
|
for(u32 i = 0; i < len; i++){
|
||||||
|
ErrorCallPos* ep = (ErrorCallPos*)e->call_stack.data + i;
|
||||||
|
StringBuilder_append_str(&b, STR("\n at "));
|
||||||
|
StringBuilder_append_str(&b, ep->file);
|
||||||
|
StringBuilder_append_char(&b, ':');
|
||||||
|
StringBuilder_append_i64(&b, ep->line);
|
||||||
|
StringBuilder_append_char(&b, ' ');
|
||||||
|
StringBuilder_append_str(&b, ep->func);
|
||||||
|
StringBuilder_append_str(&b, STR("()\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringBuilder_getStr(&b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Error_printAndExit(Error* e){
|
||||||
|
Error_addCallPos(e, ErrorCallPos_here());\
|
||||||
|
str e_str = Error_toStr(e);
|
||||||
|
printfe("%s\n", e_str.data);
|
||||||
|
free(e_str.data);
|
||||||
|
Error_destroy(e);
|
||||||
|
free(e);
|
||||||
|
exit(111);
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "string/StringBuilder.h"
|
#include "tlibc/string/StringBuilder.h"
|
||||||
|
|
||||||
void StringBuilder_destroy(StringBuilder* b){
|
void StringBuilder_destroy(StringBuilder* b){
|
||||||
free(b->buffer.data);
|
free(b->buffer.data);
|
||||||
@@ -55,13 +55,13 @@ void StringBuilder_append_f64(StringBuilder* b, f64 n){
|
|||||||
StringBuilder_append_cstr(b, buf);
|
StringBuilder_append_cstr(b, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringBuilder_append_memory(StringBuilder* b, Array mem) {
|
void StringBuilder_append_memory(StringBuilder* b, Array mem, bool uppercase) {
|
||||||
if(mem.data == NULL)
|
if(mem.data == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char buf[8];
|
char buf[8];
|
||||||
for (u32 i=0; i < mem.size; i++) {
|
for (u32 i=0; i < mem.size; i++) {
|
||||||
sprintf(buf, "%02x", ((u8*)mem.data)[i]);
|
sprintf(buf, uppercase ? "%02X" : "%02x", ((u8*)mem.data)[i]);
|
||||||
StringBuilder_append_str(b, str_construct(buf, 2, true));
|
StringBuilder_append_str(b, str_construct(buf, 2, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "string/cstr.h"
|
#include "tlibc/string/cstr.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
char* _strcat_malloc(size_t n, cstr str0, ...){
|
char* _strcat_malloc(size_t n, cstr str0, ...){
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "string/str.h"
|
#include "tlibc/string/str.h"
|
||||||
|
#include "tlibc/string/StringBuilder.h"
|
||||||
|
|
||||||
str str_copy(str src){
|
str str_copy(str src){
|
||||||
if(src.data == NULL || src.size == 0)
|
if(src.data == NULL || src.size == 0)
|
||||||
@@ -123,3 +124,9 @@ str str_toLower(str src){
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
str hex_to_str(Array buf, bool uppercase){
|
||||||
|
StringBuilder sb = StringBuilder_alloc(buf.size * 2 + 1);
|
||||||
|
StringBuilder_append_memory(&sb, buf, uppercase);
|
||||||
|
return StringBuilder_getStr(&sb);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user