From 0b9cfab8ffc31d1ed34616a7d13ea410cf2c0699 Mon Sep 17 00:00:00 2001 From: Aaro Saila Date: Sun, 28 Jun 2026 23:00:17 +0300 Subject: [PATCH] progress --- meson.build | 1 + src/DynArray.c | 2 +- src/DynArray.h | 130 +++++++++++++++++++++++++++++++++--------------- src/DynString.c | 48 +++++++++++++++--- src/DynString.h | 8 ++- src/log.h | 4 ++ src/main.c | 97 +++++++++++++++++++++--------------- 7 files changed, 199 insertions(+), 91 deletions(-) diff --git a/meson.build b/meson.build index 37c2772..2147058 100644 --- a/meson.build +++ b/meson.build @@ -4,6 +4,7 @@ cargs = [ '-std=c99', '-Og', '-g', + '-DBOUNDS_CHECK' ] dependencies = [] diff --git a/src/DynArray.c b/src/DynArray.c index 51a9474..ab6e798 100644 --- a/src/DynArray.c +++ b/src/DynArray.c @@ -1,3 +1,3 @@ #include "DynArray.h" -DYN_ARRAY_IMPL(DynString); +DYN_ARRAY_IMPL(DynString, DynString); diff --git a/src/DynArray.h b/src/DynArray.h index f02169e..16a2ea9 100644 --- a/src/DynArray.h +++ b/src/DynArray.h @@ -7,57 +7,105 @@ #include "DynString.h" -#define DYN_ARRAY_EXPANDER(macro, args) macro args +#ifdef BOUNDS_CHECK -#define DYN_ARRAY_IMPL(type) \ -DYN_ARRAY_ALLOC(type, DynArray_##type, DynArray_##type##_alloc) \ -DYN_ARRAY_PUSH_BACK(type, DynArray_##type, DynArray_##type##_push_back) \ +#include "log.h" -#define DYN_ARRAY_SIGS(type) \ -DYN_ARRAY_ALLOC_SIG(DynArray_##type, DynArray_##type##_alloc); \ -DYN_ARRAY_PUSH_BACK_SIG(type, DynArray_##type, DynArray_##type##_push_back); \ +#endif // BOUNDS_CHECK -#define DYN_ARRAY_STRUCT(type) \ -typedef struct { \ - type* data; \ - size_t count; \ - size_t capacity; \ -} DynArray_##type +#define DYN_ARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, DynArray_##type_name, DynArray_##type_name##_##func_name); -// DYN_ARRAY_STRUCT(DynString); +#define DYN_ARRAY_IMPL(type, type_name) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC, type, type_name, alloc) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL, type, type_name, is_null) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK, type, type_name, push_back) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_AT, type, type_name, at) -#define DYN_ARRAY_ALLOC_SIG(type_name, func_name) int func_name(type_name* darr, const size_t capacity) +#define DYN_ARRAY_HEADER(type, type_name) \ + DYN_ARRAY_STRUCT(type, type_name) \ + DYN_ARRAY_SIGS(type, type_name) -#define DYN_ARRAY_ALLOC(type, type_name, func_name) \ -DYN_ARRAY_ALLOC_SIG(type_name, func_name) { \ - darr->data = (type*) calloc(capacity, sizeof(type)); \ - if (darr->data == NULL) { \ - return -1; \ - } \ - darr->count = 0; \ - darr->capacity = capacity; \ - return 1; \ -} +#define DYN_ARRAY_SIGS(type, type_name) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC_SIG, type, type_name, alloc) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL_SIG, type, type_name, is_null) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK_SIG, type, type_name, push_back) \ + DYN_ARRAY_EXPANDER(DYN_ARRAY_AT_SIG, type, type_name, at) + +// DYN_ARRAY_ALLOC_SIG(type, DynArray_##type_name, DynArray_##type_name##_alloc); \ +// DYN_ARRAY_PUSH_BACK_SIG(type, DynArray_##type_name, DynArray_##type_name##_push_back); + +#define DYN_ARRAY_STRUCT(type, type_name) \ + typedef struct { \ + type* data; \ + size_t len; \ + size_t capacity; \ + } DynArray_##type_name; + +// DYN_ARRAY_STRUCT(int); + +#define DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) int func_name(type_name* darr) + +#define DYN_ARRAY_ALLOC(type, type_name, func_name) \ + DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) { \ + darr->data = (type*) calloc(1, sizeof(type)); \ + if (darr->data == NULL) { \ + return -1; \ + } \ + darr->len = 0; \ + darr->capacity = 1; \ + return 1; \ + } + +#define DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) bool func_name(const type_name* darr) + +#define DYN_ARRAY_IS_NULL(type, type_name, func_name) \ + DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) { \ + return darr->data == NULL; \ + } + +// DYN_ARRAY_ALLOC(int, DynArray_int, DynArray_int_alloc); #define DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem) -#define DYN_ARRAY_PUSH_BACK(type, type_name, func_name) \ -DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) { \ - if (darr->count + 1 > darr->capacity) { \ - darr->capacity *= 2; \ - darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \ - if (darr->data == NULL) { \ - return -1; \ - } \ - } \ - memcpy(darr->data + darr->count, new_elem, sizeof(type)); \ - darr->count++; \ - return 1; \ -} +#define DYN_ARRAY_PUSH_BACK(type, type_name, func_name) \ + DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) { \ + if (darr->len + 1 > darr->capacity) { \ + darr->capacity *= 2; \ + darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \ + if (darr->data == NULL) { \ + return -1; \ + } \ + } \ + memcpy(darr->data + darr->len, new_elem, sizeof(type)); \ + darr->len++; \ + return 1; \ + } -// DYN_ARRAY_PUSH_BACK(DynString, DynArray_DynString, DynArray_DynString_push_back); +#define DYN_ARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i) -DYN_ARRAY_STRUCT(DynString); -DYN_ARRAY_SIGS(DynString); +#ifdef BOUNDS_CHECK + +#define DYN_ARRAY_AT(type, type_name, func_name) \ + DYN_ARRAY_AT_SIG(type, type_name, func_name) { \ + if (i < 0 || i > darr->len) { \ + LOG_FATALF(#func_name " exceeded bounds! i: %zu, len: %zu", i, darr->len); \ + } \ + \ + return &darr->data[i]; \ + } + +#else + +#define DYN_ARRAY_AT(type, type_name, func_name) \ + DYN_ARRAY_AT_SIG(type, type_name, func_name) { \ + return darr->data[i]; \ + } + +#endif // BOUNDS_CHECK + +// DYN_ARRAY_PUSH_BACK(int, DynArray_int, DynArray_int_push_back); + +DYN_ARRAY_HEADER(DynString, DynString); +DYN_ARRAY_HEADER(char*, charp); #endif // DYN_ARRAY_H_ diff --git a/src/DynString.c b/src/DynString.c index 5b99d7c..85f6f0c 100644 --- a/src/DynString.c +++ b/src/DynString.c @@ -1,17 +1,49 @@ #include #include +#include #include "DynString.h" +#include "log.h" -short DynString_alloc(DynString* dstr, const char* str, const size_t len) { - dstr->data = (char*) malloc(sizeof(char) * len + 1); - if (dstr->data == NULL) { - return -1; +DynString DynString_alloc(const char* str, const size_t len) { + DynString dstr = { + .data = (char*) malloc(sizeof(char) * len), + .len = len + }; + if (dstr.data == NULL) { + LOG_FATAL("Ran out of memory"); } - dstr->data = memcpy(dstr->data, str, len); - dstr->data[len] = '\0'; - dstr->len = len; + dstr.data = memcpy(dstr.data, str, len); - return 1; + return dstr; +} + +void DynString_free(DynString* dstr) { + if (dstr->data != NULL) { + free(dstr->data); + } + dstr->len = 0; +} + +bool DynString_is_null(const DynString* dstr) { + return dstr->data == NULL; +} + +bool DynString_equal(const DynString* s1, const DynString* s2) { + if (s1->len != s2->len) { + return false; + } + + if (s1->data == NULL || s2->data == NULL) { + return false; + } + + for (size_t i = 0; i < s1->len; i++) { + if (s1->data[i] != s2->data[i]) { + return false; + } + } + + return true; } diff --git a/src/DynString.h b/src/DynString.h index 746dcf7..b31c2e5 100644 --- a/src/DynString.h +++ b/src/DynString.h @@ -2,12 +2,18 @@ #define DYN_STRING_H_ #include +#include + +#define DYN_STRING_FMT(dstr) (int) (dstr).len, (dstr).data typedef struct { char* data; size_t len; } DynString; -short DynString_alloc(DynString* dstr, const char* str, const size_t len); +DynString DynString_alloc(const char* str, const size_t len); +void DynString_free(DynString* dstr); +bool DynString_is_null(const DynString* dstr); +bool DynString_equal(const DynString* s1, const DynString* s2); #endif // DYN_STRING_H_ diff --git a/src/log.h b/src/log.h index 29ba6a6..6bd126f 100644 --- a/src/log.h +++ b/src/log.h @@ -2,10 +2,14 @@ #define LOG_H_ #include +#include #define LOG_ERROR(str) log_error(__FILE__, __LINE__, (str)) #define LOG_ERRORF(fmt, ...) log_errorf(__FILE__, __LINE__, (fmt), __VA_ARGS__) +#define LOG_FATAL(str) LOG_ERROR(str); exit(-1); +#define LOG_FATALF(fmt, ...) LOG_ERRORF(fmt, __VA_ARGS__); exit(-1); + void log_error(char* file, size_t line, char* str); void log_errorf(char* file, size_t line, char* fmt, ...); diff --git a/src/main.c b/src/main.c index 3f97263..f06ae90 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,9 @@ #include "DynString.h" #include "log.h" +#include +#include + HMODULE opengl_module = NULL; // int _main() { @@ -22,6 +25,8 @@ HMODULE opengl_module = NULL; // #ifdef __MINGW32__ +DynArray_DynString wgl_extensions = { 0 }; + typedef struct { const char* msg; int num; @@ -44,6 +49,34 @@ void* gl_function_load(const char* name) { return gl_func; } +bool has_wgl_extension(const DynString* name) { + assert(!DynString_is_null(name)); + assert(!DynArray_DynString_is_null(&wgl_extensions)); + + for (size_t i = 0; i < wgl_extensions.len; i++) { + if (DynString_equal(name, DynArray_DynString_at(&wgl_extensions, i))) { + return true; + } + } + + return false; +} + +bool has_wgl_extension_c_str(const char* name) { + DynString name_dstr = DynString_alloc(name, strlen(name)); + const bool res = has_wgl_extension(&name_dstr); + DynString_free(&name_dstr); + return res; +} + +struct timespec thread_time_get() { + struct timespec t = { 0 }; + if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t) == -1) { + LOG_FATALF("Failed to get thread time. errno: %d", errno); + } + return t; +} + void OnSize(HWND hwnd, UINT flag, int width, int height) { printf("Window resize: flag: %d, width: %d, height: %d\n", flag, width, height); } @@ -149,63 +182,47 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 1; } - // const char* wgl_extensions = wglGetExtensionsStringARB(hdc); - char* wgl_extensions = (char*) wglGetExtensionsStringARB(hdc); - printf("wgl extensions: %s\n", wgl_extensions); + char* wgl_extensions_str = (char*) wglGetExtensionsStringARB(hdc); + printf("wgl extensions: %s\n", wgl_extensions_str); - DynArray_DynString extensions_arr = { 0 }; - if (!DynArray_DynString_alloc(&extensions_arr, 1)) { - LOG_ERROR("Failed to allocate"); + char* wgl_extensions_str_copy = strdup(wgl_extensions_str); + + if (!DynArray_DynString_alloc(&wgl_extensions)) { + LOG_ERROR("Failed to allocate wgl_extensions"); + return 1; } - char* wgl_extensions_copy = strdup(wgl_extensions); - - char* ext = strtok(wgl_extensions_copy, " "); + char* ext = strtok(wgl_extensions_str_copy, " "); if (ext == NULL) { - LOG_ERROR("wgl_extensions was empty"); - return 1; - } - DynString ext_dstr = { 0 }; - if (!DynString_alloc(&ext_dstr, ext, strlen(ext))) { - LOG_ERROR("Failed to allocate extension string"); + LOG_ERROR("wgl_extensions_str was empty"); return 1; } + while (ext != NULL) { + DynString ext_dstr = DynString_alloc(ext, strlen(ext)); + + if (!DynArray_DynString_push_back(&wgl_extensions, &ext_dstr)) { + LOG_ERROR("Failed to push back extension string"); + return 1; + } - if (!DynArray_DynString_push_back(&extensions_arr, &ext_dstr)) { - LOG_ERROR("Failed to push back extension string"); - return 1; - } - // printf("ext: %s\n", ext); - while (true) { ext = strtok(NULL, " "); - // printf("ext: %s\n", ext); if (ext == NULL) { break; } - DynString ext_dstr = { 0 }; - if (!DynString_alloc(&ext_dstr, ext, strlen(ext))) { - LOG_ERROR("Failed to allocate extension string"); - return 1; - } - - if (!DynArray_DynString_push_back(&extensions_arr, &ext_dstr)) { - LOG_ERROR("Failed to push back extension string"); - return 1; - } } - free(wgl_extensions_copy); + free(wgl_extensions_str_copy); - printf("count: %zu\n", extensions_arr.count); - for (size_t i = 0; i < extensions_arr.count; i++) { - printf("%s\n", extensions_arr.data[i].data); + for (size_t i = 0; i < wgl_extensions.len; i++) { + const DynString* ext = DynArray_DynString_at(&wgl_extensions, i); + printf("%.*s\n", DYN_STRING_FMT(*ext)); } - // glClearColor(1.0, 1.0, 0.0, 1.0); - // glClear(GL_COLOR_BUFFER_BIT); - // const unsigned char* version = glGetString(GL_VERSION); - // printf("OpenGL version %s\n", version); + const struct timespec b = thread_time_get(); + has_wgl_extension_c_str("WGL_ARB_create_context"); + const struct timespec a = thread_time_get(); + printf("time: %ld\n", a.tv_nsec - b.tv_nsec); return 0; }