summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/al/lib.h10
-rw-r--r--include/al/list.h41
-rw-r--r--include/al/random.h2
-rw-r--r--include/al/str.h27
-rw-r--r--include/al/test.h6
-rw-r--r--include/al/wstr.h8
-rw-r--r--src/array.c2
-rw-r--r--src/lib.c13
-rw-r--r--src/str.c51
-rw-r--r--tests/str.c22
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 { \
diff --git a/src/lib.c b/src/lib.c
index 2df40d3..64a60a3 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -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);
diff --git a/src/str.c b/src/str.c
index a3c0946..2bb7fa9 100644
--- a/src/str.c
+++ b/src/str.c
@@ -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();