Aaro Saila 4 сар өмнө
parent
commit
0b9cfab8ff
7 өөрчлөгдсөн 207 нэмэгдсэн , 99 устгасан
  1. 1 0
      meson.build
  2. 1 1
      src/DynArray.c
  3. 97 49
      src/DynArray.h
  4. 40 8
      src/DynString.c
  5. 7 1
      src/DynString.h
  6. 4 0
      src/log.h
  7. 57 40
      src/main.c

+ 1 - 0
meson.build

@@ -4,6 +4,7 @@ cargs = [
   '-std=c99',
   '-Og',
   '-g',
+  '-DBOUNDS_CHECK'
   ]
 
 dependencies = []

+ 1 - 1
src/DynArray.c

@@ -1,3 +1,3 @@
 #include "DynArray.h"
 
-DYN_ARRAY_IMPL(DynString);
+DYN_ARRAY_IMPL(DynString, DynString);

+ 97 - 49
src/DynArray.h

@@ -7,57 +7,105 @@
 
 #include "DynString.h"
 
-#define DYN_ARRAY_EXPANDER(macro, args) macro args
-
-#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) \
-
-#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); \
-
-#define DYN_ARRAY_STRUCT(type) \
-typedef struct { \
-    type* data; \
-    size_t count; \
-    size_t capacity; \
-} DynArray_##type
-
-// DYN_ARRAY_STRUCT(DynString);
-
-#define DYN_ARRAY_ALLOC_SIG(type_name, func_name) int func_name(type_name* darr, const size_t capacity)
-
-#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; \
-}
+#ifdef BOUNDS_CHECK
+
+#include "log.h"
+
+#endif // BOUNDS_CHECK
+
+#define DYN_ARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, DynArray_##type_name, DynArray_##type_name##_##func_name);
+
+#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_HEADER(type, type_name) \
+    DYN_ARRAY_STRUCT(type, type_name)     \
+    DYN_ARRAY_SIGS(type, type_name)
+
+#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; \
-}
-
-// DYN_ARRAY_PUSH_BACK(DynString, DynArray_DynString, DynArray_DynString_push_back);
-
-DYN_ARRAY_STRUCT(DynString);
-DYN_ARRAY_SIGS(DynString);
+#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;                                                                    \
+    }
+
+#define DYN_ARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i)
+
+#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_

+ 40 - 8
src/DynString.c

@@ -1,17 +1,49 @@
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 #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;
 }
 

+ 7 - 1
src/DynString.h

@@ -2,12 +2,18 @@
 #define DYN_STRING_H_
 
 #include <stddef.h>
+#include <stdbool.h>
+
+#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_

+ 4 - 0
src/log.h

@@ -2,10 +2,14 @@
 #define LOG_H_
 
 #include <stddef.h>
+#include <stdlib.h>
 
 #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, ...);
 

+ 57 - 40
src/main.c

@@ -14,6 +14,9 @@
 #include "DynString.h"
 #include "log.h"
 
+#include <time.h>
+#include <sys/time.h>
+
 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);
-
-        DynArray_DynString extensions_arr = { 0 };
-        if (!DynArray_DynString_alloc(&extensions_arr, 1)) {
-            LOG_ERROR("Failed to allocate");
-        }
+        char* wgl_extensions_str = (char*) wglGetExtensionsStringARB(hdc);
+        printf("wgl extensions: %s\n", wgl_extensions_str);
 
-        char* wgl_extensions_copy = strdup(wgl_extensions);
+        char* wgl_extensions_str_copy = strdup(wgl_extensions_str);
 
-        char* ext = strtok(wgl_extensions_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");
+        if (!DynArray_DynString_alloc(&wgl_extensions)) {
+            LOG_ERROR("Failed to allocate wgl_extensions");
             return 1;
         }
 
-        if (!DynArray_DynString_push_back(&extensions_arr, &ext_dstr)) {
-            LOG_ERROR("Failed to push back extension string");
+        char* ext = strtok(wgl_extensions_str_copy, " ");
+        if (ext == NULL) {
+            LOG_ERROR("wgl_extensions_str was empty");
             return 1;
         }
-        // printf("ext: %s\n", ext);
-        while (true) {
-            ext = strtok(NULL, " ");
-            // printf("ext: %s\n", ext);
-            if (ext == NULL) {
-                break;
-            }
+        while (ext != NULL) {
+            DynString ext_dstr = DynString_alloc(ext, strlen(ext));
 
-            DynString ext_dstr = { 0 };
-            if (!DynString_alloc(&ext_dstr, ext, strlen(ext))) {
-                LOG_ERROR("Failed to allocate extension string");
+            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;
+            ext = strtok(NULL, " ");
+            if (ext == NULL) {
+                break;
             }
+
         }
 
-        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;
     }