diff options
| -rw-r--r-- | include/al/lib.h | 10 | ||||
| -rw-r--r-- | include/al/list.h | 41 | ||||
| -rw-r--r-- | include/al/random.h | 2 | ||||
| -rw-r--r-- | include/al/str.h | 27 | ||||
| -rw-r--r-- | include/al/test.h | 6 | ||||
| -rw-r--r-- | include/al/wstr.h | 8 | ||||
| -rw-r--r-- | src/array.c | 2 | ||||
| -rw-r--r-- | src/lib.c | 13 | ||||
| -rw-r--r-- | src/str.c | 51 | ||||
| -rw-r--r-- | tests/str.c | 22 |
10 files changed, 84 insertions, 98 deletions
diff --git a/include/al/lib.h b/include/al/lib.h index 360ba38..81f6978 100644 --- a/include/al/lib.h +++ b/include/al/lib.h @@ -3,6 +3,9 @@ #include "types.h" +#define AL_USE_STDLIB 1 +#define AL_FORCE_DISABLE_OUTPUT 0 + #if defined(__clang__) || defined(__GNUC__) #define AL_UNUSED_FUNCTION_PUSH \ _Pragma("GCC diagnostic push") \ @@ -14,8 +17,6 @@ #define AL_UNUSED_FUNCTION_POP #endif -#define AL_USE_STDLIB 1 - #if AL_USE_STDLIB #include <stdlib.h> #include <string.h> @@ -24,6 +25,7 @@ #include <assert.h> void al_malloc_init(void); +void al_malloc_close(void); void *al_malloc(size_t n); void *al_calloc(size_t n, size_t size); void *al_realloc(void *ptr, size_t n); @@ -31,7 +33,7 @@ void al_free(void *ptr); #ifdef HAVE_POSIX_MEMALIGN int al_posix_memalign(void **ptr, size_t alignment, size_t n); #endif -void al_malloc_stats(u32 *current, u32 *max, u32 *total); +void al_malloc_stats(u32 *current, u32 *peak, u32 *total); void al_set_alloc(void *(*malloc_func)(size_t), void *(*calloc_func)(size_t, size_t), void *(*realloc_func)(void *, size_t), void (*free_func)(void *)); @@ -52,8 +54,6 @@ void al_set_alloc(void *(*malloc_func)(size_t), void *(*calloc_func)(size_t, siz AL_UNUSED_FUNCTION_PUSH -#define AL_FORCE_DISABLE_OUTPUT 0 - static inline s32 al_printf(const char *fmt, ...) { #if AL_FORCE_DISABLE_OUTPUT diff --git a/include/al/list.h b/include/al/list.h index 6e1ba29..41b1b2b 100644 --- a/include/al/list.h +++ b/include/al/list.h @@ -49,39 +49,39 @@ if (l) l->prev = node; \ return node; \ } \ - static inline list_##name *list_insert_before_##name(list_##name *l, list_##name *s, type value) { \ + static inline list_##name *list_insert_after_##name(list_##name *l, list_##name *s, type value) { \ if (!l) { \ list_##name *node = list_new_node_##name(value); \ node->next = NULL; \ node->prev = NULL; \ return node; \ - } else if (!s) { \ + } else if (!s || !s->next) { \ return list_append_##name(l, value); \ - } else if (s == l) { \ - return list_prepend_##name(l, value); \ } else { \ list_##name *node = list_new_node_##name(value); \ - s->prev->next = node; \ - node->prev = s->prev; \ - node->next = s; \ - s->prev = node; \ + s->next->prev = node; \ + node->next = s->next; \ + node->prev = s; \ + s->next = node; \ return l; \ } \ } \ - static inline list_##name *list_insert_after_##name(list_##name *l, list_##name *s, type value) { \ + static inline list_##name *list_insert_before_##name(list_##name *l, list_##name *s, type value) { \ if (!l) { \ list_##name *node = list_new_node_##name(value); \ node->next = NULL; \ node->prev = NULL; \ return node; \ - } else if (!s || !s->next) { \ + } else if (!s) { \ return list_append_##name(l, value); \ + } else if (s == l) { \ + return list_prepend_##name(l, value); \ } else { \ list_##name *node = list_new_node_##name(value); \ - s->next->prev = node; \ - node->next = s->next; \ - node->prev = s; \ - s->next = node; \ + s->prev->next = node; \ + node->prev = s->prev; \ + node->next = s; \ + s->prev = node; \ return l; \ } \ } \ @@ -106,23 +106,16 @@ #define list(name) list_##name -// Get element at nth position. #define al_list_nth(name, list, n) list_nth_##name(list, n) -// Get the last element in the list. #define al_list_last(name, list) list_last_##name(list) -// Append value to the end of the list. -// If list is NULL, create new list. +// If `list` is `NULL`, a new list is created. #define al_list_append(name, list, value) list_append_##name(list, value) -// Prepend value to the front of the list. -// If list is NULL, create new list. #define al_list_prepend(name, list, value) list_prepend_##name(list, value) -// Insert value before/after sibling. -// If list is NULL, create and return new list. -// If sibiling is NULL (or sibiling->next in after case) append the value to the end of the list. -#define al_list_insert_before(name, list, sibling, value) list_insert_before_##name(list, sibling, value) +// If `sibiling->next` is `NULL` (or just `sibiling` for before) append the value to the end of the list. #define al_list_insert_after(name, list, sibling, value) list_insert_after_##name(list, sibling, value) +#define al_list_insert_before(name, list, sibling, value) list_insert_before_##name(list, sibling, value) #define al_list_remove(name, list, node) list_remove_##name(list, node) diff --git a/include/al/random.h b/include/al/random.h index f5210b6..f4da0ba 100644 --- a/include/al/random.h +++ b/include/al/random.h @@ -16,7 +16,7 @@ static void al_rand_init(void) srand((u32)time(NULL)); } -// TEMP: "Random" that guarantees we wont get collisions for the current use-case. +// TEMP: "Random" that guarantees we won't get collisions for the current use-case. static u16 al_rand_u16(void) { if (_al_rand_value == UINT16_MAX) _al_rand_value = 1; diff --git a/include/al/str.h b/include/al/str.h index a43d4ba..9ede09a 100644 --- a/include/al/str.h +++ b/include/al/str.h @@ -4,23 +4,23 @@ #include "lib.h" typedef struct { - char *data; u32 len; u32 alloc; + char *data; } str; -#define AL_STR_EMPTY (str){ NULL, 0, 0 } +#define AL_STR_EMPTY (str){ 0, 0, NULL } #define al_str_at(s, i) (s)->data[i] #define al_str_atr(s, i) (s)->data[(s)->len + i] #ifndef __cplusplus -#define al_str_c(s) (&((str){ ((char *)s), (u32)al_strlen(s), 0 })) -#define al_str_w(s, i, n) (&((str){ &(s)[i], ((u32)n), 0 })) +#define al_str_c(s) (&((str){ (u32)al_strlen(s), 0, ((char *)s) })) +#define al_str_w(s, i, n) (&((str){ ((u32)n), 0, &(s)[i] })) #define al_str_substr(s, start, end) al_str_w((s)->data, start, ((end) - (start))) #else -#define al_str_cc(s) (((str){ ((char *)s), (u32)al_strlen(s), 0 })) -#define al_str_ww(s, i, n) (((str){ &(s)[i], ((u32)n), 0 })) +#define al_str_cc(s) (((str){ (u32)al_strlen(s), 0, ((char *)s) })) +#define al_str_ww(s, i, n) (((str){ ((u32)n), 0, &(s)[i] })) #define al_str_substr(s, start, end) al_str_ww((s)->data, start, ((end) - (start))) #endif @@ -94,9 +94,9 @@ static inline void al_str_cat(str *s, str *c) static inline void al_str_insert(str *s, str *c, u32 i) { s->alloc = al_str_reserve(s, s->len + c->len); - char *_i = s->data + i; - al_memmove(_i + c->len, _i, s->len - i); - al_memcpy(_i, c->data, c->len); + char *data = s->data + i; + al_memmove(data + c->len, data, s->len - i); + al_memcpy(data, c->data, c->len); s->len += c->len; } @@ -115,7 +115,7 @@ static inline s32 al_str_cmp(str *s, str *c, u32 start, u32 len) static inline bool al_str_eq(str *s, str *c) { - return al_str_cmp(s, c, 0, s->len > c->len ? s->len : c->len) == 0; + return al_str_cmp(s, c, 0, AL_MAX(s->len, c->len)) == 0; } static inline s32 al_str_find(str *s, char c) @@ -137,7 +137,7 @@ static inline s32 al_str_find_str(str *s, str *c) { if (c->len > s->len) return -1; for (u32 i = 0; i < s->len - c->len; i++) { - if (s->data[i] != c->data[0]) continue; + if (al_str_at(s, i) != al_str_at(c, 0)) continue; if (al_str_cmp(s, c, i, c->len) == 0) { return i; } @@ -149,13 +149,12 @@ static inline u32 al_str_hash(str *s) { u32 hash = 5381; for (u32 i = 0; i < s->len; i++) { - hash = ((hash << 5) + hash) + s->data[i]; /* hash * 33 + c */ + hash = ((hash << 5) + hash) + al_str_at(s, i); /* hash * 33 + c */ } return hash; } s64 al_str_to_long(str *s, s32 base); -bool al_str_tok(str *s, char sep, str *tok); -bool al_str_get_line(str *buffer, str *line); +bool al_str_get_line(str *buffer, char sep, str *line); #endif // _AL_STR_H diff --git a/include/al/test.h b/include/al/test.h index 41395ce..43f6770 100644 --- a/include/al/test.h +++ b/include/al/test.h @@ -84,7 +84,7 @@ static inline s32 al_test_u32_cmp(u32 a, u32 b) #define AL_TEST_CMP_u32 al_test_u32_cmp #define AL_TEST_TYPE_u32 u32 -#define AL_TEST_FMT_u32 "%d" +#define AL_TEST_FMT_u32 "%u" #define AL_TEST_PRINTF_u32(i) i static inline s32 al_test_s32_cmp(s32 a, s32 b) @@ -97,7 +97,7 @@ static inline s32 al_test_s32_cmp(s32 a, s32 b) #define AL_TEST_CMP_s32 al_test_s32_cmp #define AL_TEST_TYPE_s32 s32 -#define AL_TEST_FMT_s32 "%i" +#define AL_TEST_FMT_s32 "%d" #define AL_TEST_PRINTF_s32(i) i static inline s32 al_test_size_t_cmp(size_t a, size_t b) @@ -110,7 +110,7 @@ static inline s32 al_test_size_t_cmp(size_t a, size_t b) #define AL_TEST_CMP_s64 al_test_s64_cmp #define AL_TEST_TYPE_s64 s64 -#define AL_TEST_FMT_s64 "%li" +#define AL_TEST_FMT_s64 "%ld" #define AL_TEST_PRINTF_s64(i) i static inline s32 al_test_s64_cmp(s64 a, s64 b) diff --git a/include/al/wstr.h b/include/al/wstr.h index c2e8a07..97568db 100644 --- a/include/al/wstr.h +++ b/include/al/wstr.h @@ -8,11 +8,13 @@ #include <wchar.h> typedef struct { - wchar_t *data; u32 len; u32 alloc; + wchar_t *data; } wstr; +#define AL_WSTR_EMPTY (wstr){ 0, 0, NULL } + #define al_wstr_at(w, i) (w)->data[i] #define al_wstr_atr(w, i) (w)->data[(w)->len + i] @@ -47,9 +49,7 @@ static inline u32 al_wstr_reserve(wstr *w, u32 size) static inline void al_wstr_sized(wstr *w, u32 size) { - w->len = 0; - w->alloc = 0; - w->data = NULL; + *w = AL_WSTR_EMPTY; w->alloc = al_wstr_reserve(w, size * sizeof(wchar_t)); al_memset(w->data, 0, w->alloc); } diff --git a/src/array.c b/src/array.c index ffdc36b..c843ff6 100644 --- a/src/array.c +++ b/src/array.c @@ -1,7 +1,7 @@ #include "../include/al/lib.h" #include "../include/al/array_sort.h" -// based on: https://github.com/lifthrasiir/angolmois/blob/master/angolmois.c#L79 +// https://github.com/lifthrasiir/angolmois/blob/master/angolmois.c#L79 #define array(type) \ struct { \ @@ -1,4 +1,4 @@ -// Testing allocation tracking stuff. (Very scuffed) +// Testing allocation tracking stuff. (Very scuffed, not thread-safe!) #include "../include/al/lib.h" @@ -20,7 +20,7 @@ struct alloc_t { }; // Use stdlib allocation for the allocation tracking array. -// This avoids a circular loop and also keeps allocations +// This avoids a circular dependency and also keeps allocations // from the memory tracking code out of the stats. #include "../include/al/types.h" #define AL_ARRAY_MALLOC malloc @@ -29,9 +29,9 @@ struct alloc_t { #include "array.c" static array(struct alloc_t) allocations; -static u32 total_allocated = 0; static u32 currently_allocated = 0; static u32 peak_allocated = 0; +static u32 total_allocated = 0; #endif void al_malloc_init(void) @@ -41,6 +41,13 @@ void al_malloc_init(void) #endif } +void al_malloc_close(void) +{ +#if MEMORY_TRACKING + al_array_free(allocations); +#endif +} + void *al_malloc(size_t n) { void *ptr = _al_malloc(n); @@ -60,54 +60,25 @@ s64 al_str_to_long(str *s, s32 base) return ret; } -bool al_str_tok(str *s, char sep, str *tok) +bool al_str_get_line(str *buffer, char sep, str *line) { - if (tok->alloc == s->len + 1) { - return false; - } - u32 r = s->len - tok->alloc; -#ifndef __cplusplus - s32 i = al_str_find(al_str_w(s->data, tok->alloc, r), sep); -#else - str w = al_str_ww(s->data, tok->alloc, r); - s32 i = al_str_find(&w, sep); -#endif - if (i == -1) i = r; - tok->data = s->data + tok->alloc; - tok->len = (u32)i; - tok->alloc += tok->len + 1; - return true; -} - -bool al_str_get_line(str *buffer, str *line) -{ - s32 bytes_processed = 0; + u32 bytes = 0; if (line->data == NULL) { *line = *buffer; - } else { - // Move to the end of the current line. - line->data += line->len; - - bytes_processed = (s32)((line->data - buffer->data) + 1); - - // If line->ptr is at the last character, we are done. - // Also, if bytes_processed <= 0 buffer is empty or invalid, so return. - if (bytes_processed >= (s32)buffer->len || bytes_processed <= 0) { - return false; - } - - // Else, move line->ptr to the first character on the next line. - line->data++; + } else if ((bytes = (u32)((line->data += line->len + 1) - buffer->data)) >= buffer->len) { + // Move to the start of the assumed next line. If `bytes >= buffer->len`, + // there is no next line. + return false; } - // Find the next newline character. - char *nl = (char *)memchr(line->data, '\n', buffer->len - bytes_processed); + // Remaining bytes. + bytes = buffer->len - bytes; - // If there is no newline character move to the end of the buffer. - if (!nl) nl = buffer->data + buffer->len; + char *nl = (char *)al_memchr(line->data, sep, bytes); - line->len = (u32)(nl - line->data); + // If `!nl`, move to the end of the buffer. + line->len = !nl ? bytes : (u32)(nl - line->data); return true; } diff --git a/tests/str.c b/tests/str.c index 0dcd896..ce1c3b5 100644 --- a/tests/str.c +++ b/tests/str.c @@ -124,10 +124,26 @@ static bool str_test_get_line(void) str *lines = al_str_c("test\nasdf\ntest2\na\n"); str *lines_array[] = { al_str_c("test"), al_str_c("asdf"), al_str_c("test2"), al_str_c("a") }; - u32 count = 0; + str line; + al_memset(&line, 0, sizeof(str)); + u32 c = 0; - for (str line = { 0 }; al_str_get_line(lines, &line); ) { - AL_TEST_TRUE(al_str_eq(&line, lines_array[count++])); + for (; al_str_get_line(lines, '\n', &line); ) { + AL_TEST_LT(c, (u32)AL_ARRAY_SIZE(lines_array), u32); + AL_TEST_TRUE(al_str_eq(&line, lines_array[c++])); + } + + AL_TEST_EQ(c, (u32)AL_ARRAY_SIZE(lines_array), u32); + + lines = al_str_c(""); + + al_memset(&line, 0, sizeof(str)); + c = 0; + + for (; al_str_get_line(lines, '\n', &line); ) { + AL_TEST_LT(c, 1, u32); + AL_TEST_EQ(line.len, 0, u32); + c++; } AL_TEST_END(); |