summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rwxr-xr-xsource/base/base.h37
-rwxr-xr-xsource/base/base_arena.c3
-rwxr-xr-xsource/base/base_arena.h5
-rw-r--r--source/base/base_error.h89
-rw-r--r--source/base/base_hash.c12
-rwxr-xr-xsource/base/base_include.h22
-rw-r--r--source/base/base_io.h60
-rw-r--r--source/base/base_os.h96
-rw-r--r--source/base/base_platform.h6
-rw-r--r--source/base/base_rand.h28
-rwxr-xr-xsource/base/base_stack.c187
-rwxr-xr-xsource/base/base_stack.h188
-rw-r--r--source/base/base_string.c30
-rw-r--r--source/base/base_string.h79
-rw-r--r--source/base/base_test.h46
-rw-r--r--source/base/bash_hash.h19
-rw-r--r--source/tb_db/tb_ml.c9
-rw-r--r--source/tb_ml/tb_ml.c20
18 files changed, 512 insertions, 424 deletions
diff --git a/source/base/base.h b/source/base/base.h
index b9e317a..3fe9dca 100755
--- a/source/base/base.h
+++ b/source/base/base.h
@@ -2,28 +2,11 @@
2#define BASE_H 2#define BASE_H
3 3
4/* assert an expression and output the file and the line */ 4/* assert an expression and output the file and the line */
5 5#define internal static
6#define internal static
7#define global_variable static 6#define global_variable static
8#define local_persist static 7#define local_persist static
9
10#define ERR_OK 0
11#define ERR_IO 1
12#define ERR_PARSE 2
13#define ERR_PERM 3
14#define ERR_INVALID 4
15
16#define KiB(n) (((u64)(n)) << 10)
17#define MiB(n) (((u64)(n)) << 20)
18#define GiB(n) (((u64)(n)) << 30)
19 8
20#define unused(x) (void)(x) 9#define unused(x) (void)(x)
21
22#define PATH_MAX_LEN 128
23#define BUFF_SMALL 128
24#define BUFF_DEFAULT 256
25#define BUFF_LARGE 512
26
27#define NIL 0 10#define NIL 0
28 11
29#define DEPRECATED __attribute__((__deprecated__)) 12#define DEPRECATED __attribute__((__deprecated__))
@@ -67,15 +50,15 @@ typedef s8 b8;
67typedef uintptr_t umm; 50typedef uintptr_t umm;
68typedef intptr_t smm; 51typedef intptr_t smm;
69 52
70#define TRUE (1 == 1) 53#define True (1 == 1)
71#define FALSE (1 != 1) 54#define False (1 != 1)
72 55
73#define RED "\x1b[31m" 56#define Red "\x1b[31m"
74#define GREEN "\x1b[32m" 57#define Green "\x1b[32m"
75#define RESET "\x1b[0m" 58#define Reset "\x1b[0m"
76#define BLUE "\x1b[34m" 59#define Blue "\x1b[34m"
77#define YELLOW "\x1b[33m" 60#define Yellow "\x1b[33m"
78 61
79#define LEN(s) (sizeof(s) - 1) 62#define Len(s) (sizeof(s) - 1)
80 63
81#endif 64#endif
diff --git a/source/base/base_arena.c b/source/base/base_arena.c
index 7e9c44b..8fc8c13 100755
--- a/source/base/base_arena.c
+++ b/source/base/base_arena.c
@@ -110,8 +110,9 @@ arena_resize_align(mem_arena *arena, void *old_memory, u64 new_size, u64 old_siz
110 } 110 }
111 else 111 else
112 { 112 {
113 verify(0); 113 // warn(0);
114 } 114 }
115
115 return NULL; 116 return NULL;
116} 117}
117 118
diff --git a/source/base/base_arena.h b/source/base/base_arena.h
index 2818ae4..dc6dd73 100755
--- a/source/base/base_arena.h
+++ b/source/base/base_arena.h
@@ -7,6 +7,11 @@
7#define PushArray(arena, type, len) (type *)arena_alloc((arena), sizeof(type) * (len), 0) 7#define PushArray(arena, type, len) (type *)arena_alloc((arena), sizeof(type) * (len), 0)
8#define PushArrayZero(arena, type, len) (type *)arena_alloc((arena), sizeof(type) * (len), 1) 8#define PushArrayZero(arena, type, len) (type *)arena_alloc((arena), sizeof(type) * (len), 1)
9 9
10#define KiB(n) (((u64)(n)) << 10)
11#define MiB(n) (((u64)(n)) << 20)
12#define GiB(n) (((u64)(n)) << 30)
13
14
10typedef struct mem_arena mem_arena; 15typedef struct mem_arena mem_arena;
11struct mem_arena 16struct mem_arena
12{ 17{
diff --git a/source/base/base_error.h b/source/base/base_error.h
index b2bb4c0..e9f52b7 100644
--- a/source/base/base_error.h
+++ b/source/base/base_error.h
@@ -1,47 +1,66 @@
1/* base library internal logging system */ 1/* base library internal error checking system */
2#ifndef BASE_ERROR_H 2#ifndef BASE_ERROR_H
3#define BASE_ERROR_H 3#define BASE_ERROR_H
4 4
5#define error_at(msg) \ 5#define error_at(msg) \
6 do \ 6 do { \
7 { \ 7 write_string(STDERR_FD, Red "[ERROR] " __FILE__ ":"); \
8 os_write(STDERR_FD, RED "[ERROR] ", LEN(RED "[ERROR] ")); \ 8 write_int(STDERR_FD, __LINE__); \
9 write_string(STDERR_FD, __FILE__); \ 9 write_string(STDERR_FD, ":" __func__ ": " Reset); \
10 write_string(STDERR_FD, ":"); \ 10 write_string(STDERR_FD, (msg)); \
11 write_int(__LINE__); \ 11 write_string(STDERR_FD, "\n"); \
12 write_string(STDERR_FD, " in "); \
13 write_string(STDERR_FD, __func__); \
14 write_string(STDERR_FD, ": "); \
15 write_string(STDERR_FD, (msg)); \
16 os_write(STDERR_FD, RESET "\n", LEN(RESET "\n")); \
17 } while (0) 12 } while (0)
18 13
19#define fatal(msg) \ 14#define warn(msg) \
20 do \ 15 do { \
21 { \ 16 write_string(STDERR_FD, Yellow "[WARN] " __FILE__ ":"); \
22 error_at(msg); \ 17 write_int(STDERR_FD, __LINE__); \
23 _exit(1); \ 18 write_string(STDERR_FD, ":" __func__ ": " Reset); \
19 write_string(STDERR_FD, (msg)); \
20 write_string(STDERR_FD, "\n"); \
24 } while (0) 21 } while (0)
25 22
26#define assert_msg(expr, msg) \ 23#define assert_msg(expr, msg) \
27 do \ 24 do { \
28 { \ 25 if (!(expr)) { \
29 if (!(expr)) \ 26 write_string(STDERR_FD, Red "[ERROR] " __FILE__ ":"); \
30 { \ 27 write_int(STDERR_FD, __LINE__); \
31 fatal(msg); \ 28 write_string(STDERR_FD, ":" __func__ ": " Reset); \
32 } \ 29 write_string(STDERR_FD, (msg)); \
30 write_string(STDERR_FD, "\n"); \
31 _exit(1); \
32 } \
33 } while (0) 33 } while (0)
34 34
35#define warn(msg) \ 35#define show \
36 do \ 36 do { \
37 { \ 37 write_string(STDOUT_FD, __FILE__ ":"); \
38 os_write(STDERR_FD, YELLOW "[WARN] ", LEN(YELLOW "[WARN] ")); \ 38 write_int(STDOUT_FD, __LINE__); \
39 write_string(STDERR_FD, __FILE__); \ 39 write_string(STDOUT_FD, ":" __func__ "\n"); \
40 write_string(STDERR_FD, ":"); \ 40 } while (0)
41 write_int(__LINE__); \ 41
42 write_string(STDERR_FD, ": "); \ 42#define test(expr) \
43 write_string(STDERR_FD, (msg)); \ 43 do { \
44 os_write(STDERR_FD, RESET "\n", LEN(RESET "\n")); \ 44 if ((expr) != 0) { \
45 write_string(STDERR_FD, "[FAILED] " __FILE__ ":"); \
46 write_int(STDERR_FD, __LINE__); \
47 write_string(STDERR_FD, ":" __func__ "\n"); \
48 _exit(1); \
49 } \
50 } while (0)
51
52#define verify(expr) \
53 do { \
54 if ((expr) != 0) { \
55 write_string(STDERR_FD, Red "[ERROR] " __FILE__ ":"); \
56 write_int(STDERR_FD, __LINE__); \
57 write_string(STDERR_FD, ":" __func__ "\n" Reset); \
58 _exit(1); \
59 } else { \
60 write_string(STDERR_FD, Green "[OK] " __FILE__ ":"); \
61 write_int(STDERR_FD, __LINE__); \
62 write_string(STDERR_FD, ":" __func__ "\n" Reset); \
63 } \
45 } while (0) 64 } while (0)
46 65
47#endif /* BASE_ERROR_H */ 66#endif /* BASE_ERROR_H */
diff --git a/source/base/base_hash.c b/source/base/base_hash.c
deleted file mode 100644
index 1964441..0000000
--- a/source/base/base_hash.c
+++ /dev/null
@@ -1,12 +0,0 @@
1
2internal u64
3generate_hash()
4{
5
6
7
8}
9
10internal hash_map
11make_hash_map
12
diff --git a/source/base/base_include.h b/source/base/base_include.h
index c8eec41..a376f29 100755
--- a/source/base/base_include.h
+++ b/source/base/base_include.h
@@ -9,26 +9,30 @@
9#include <stdint.h> 9#include <stdint.h>
10#include <stddef.h> 10#include <stddef.h>
11#include <string.h> 11#include <string.h>
12#include <math.h>
12#include <unistd.h> 13#include <unistd.h>
14#include <time.h>
15#include <stdarg.h>
13 16
14#include "base.h" 17#include "base.h"
15#include "base_mem.h" 18#include "base_mem.h"
19
16#include "base_arena.h" 20#include "base_arena.h"
17#include "base_stack.h" 21#include "base_stack.h"
18#include "base_string.h"
19
20#include "base_io.h"
21#include "base_error.h"
22#include "base_test.h"
23
24#ifdef BASE_UNITY
25 22
23#ifdef BASE_IMPLEMENTATION
26#include "base_arena.c" 24#include "base_arena.c"
27#include "base_stack.c"
28
29#endif 25#endif
30 26
27
28#include "base_string.h"
29#include "base_string.c"
30
31#include "base_os.h" 31#include "base_os.h"
32#include "base_error.h"
33
34#include "base_rand.h"
35
32 36
33 37
34#endif 38#endif
diff --git a/source/base/base_io.h b/source/base/base_io.h
deleted file mode 100644
index ac55737..0000000
--- a/source/base/base_io.h
+++ /dev/null
@@ -1,60 +0,0 @@
1#ifndef BASE_IO_H
2#define BASE_IO_H
3
4#define STDIN_FD 0
5#define STDOUT_FD 1
6#define STDERR_FD 2
7
8internal s64
9os_write(s32 fd, void const *buf, u64 count)
10{
11 return syscall(SYS_write, fd, buf, count);
12}
13
14internal s64
15os_read(s32 fd, void *buf, u64 count)
16{
17 return syscall(SYS_read, fd, buf, count);
18}
19
20internal void
21print_s8(string8 s)
22{
23 os_write(STDOUT_FILENO, s.data, s.size);
24}
25
26internal void
27print(const char *str)
28{
29 s32 len = 0;
30 while (str[len]) len++;
31 os_write(STDOUT_FILENO, str, len);
32
33}
34
35internal void
36write_int(s32 num)
37{
38
39 if (num < 0)
40 {
41 write(STDERR_FILENO, "-", 1);
42 num = -num;
43 }
44 if (num >= 10)
45 write_int(num / 10);
46 char digit = '0' + (num % 10);
47
48 write(STDERR_FILENO, &digit, 1);
49}
50
51internal void
52write_string(s32 fd, const char *str)
53{
54 s32 len = 0;
55 while (str[len]) len++;
56 os_write(fd, str, len);
57}
58
59
60#endif /* BASE_IO_H */
diff --git a/source/base/base_os.h b/source/base/base_os.h
index 388f665..82aa70d 100644
--- a/source/base/base_os.h
+++ b/source/base/base_os.h
@@ -1,28 +1,35 @@
1#ifndef BASE_OS_H 1#ifndef BASE_OS_H
2#define BASE_OS_H 2#define BASE_OS_H
3 3
4#define STDIN_FD 0
5#define STDOUT_FD 1
6#define STDERR_FD 2
7
8#endif /* BASE_OS_H */
9
10#ifdef BASE_IMPLEMENTATION
11
4internal string8 12internal string8
5load_file(mem_arena *arena, const char *path) 13load_file(mem_arena *arena, const char *path)
6{ 14{
7 string8 result = {0}; 15 string8 result = {0};
8 struct stat sbuf = {0}; 16 struct stat sbuf = {0};
9 17
18 // TODO(nasr): abstract this to a platform layer
10 s32 file = open(path, O_RDONLY); 19 s32 file = open(path, O_RDONLY);
11 if(file == -1) 20 if(file == -1)
12 { 21 {
13 warn("fialed to open file. path could be invalid");
14 return (string8){0}; 22 return (string8){0};
15 } 23 }
16 24
17 if(fstat(file, &sbuf) == -1) 25 if(fstat(file, &sbuf) == -1)
18 { 26 {
19 warn("error: fstat failed");
20 close(file); 27 close(file);
21 return (string8){0}; 28 return (string8){0};
22 } 29 }
23 30
24 31
25 result = PushString(arena, sbuf.st_size); 32 result = PushString8(arena, sbuf.st_size);
26 33
27 result.size = (u64)sbuf.st_size; 34 result.size = (u64)sbuf.st_size;
28 if(result.size != 0) 35 if(result.size != 0)
@@ -37,31 +44,102 @@ load_file(mem_arena *arena, const char *path)
37internal string8 44internal string8
38write_file(const char *path, string8 data) 45write_file(const char *path, string8 data)
39{ 46{
40
41 string8 result = {0}; 47 string8 result = {0};
42 s32 file = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 48 s32 file = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
43 if(file == -1) 49 if(file == -1)
44 { 50 {
45 warn("failed to open file for writing. path could be invalid");
46 return (string8){0}; 51 return (string8){0};
47 } 52 }
48 53
49 u64 written = 0; 54 u64 written = 0;
50 while(written < data.size) 55 while(written < data.size)
51 { 56 {
52 s64 err = write(file, data.data + written, data.size - written); 57 s64 err = write(file, data.data + written, data.size - written);
53 if(err == -1) 58 if(err == -1)
54 { 59 {
55 warn("write syscall failed");
56 close(file); 60 close(file);
57 return (string8){0}; 61 return (string8){0};
58 } 62 }
59 written += err; 63 written += err;
60 } 64 }
61 65
62 close(file); 66 close(file);
63 result = data; 67 result = data;
64 return result; 68 return result;
65} 69}
66 70
67#endif /* BASE_OS_H */ 71#define os_write(buf, count) _os_write(STDIN_FD, buf, count)
72#define os_read(buf, count) _os_read(STDIN_FD, buf, count)
73
74internal s64
75_os_write(s32 fd, void const *buf, u64 count)
76{
77 return syscall(SYS_write, fd, buf, count);
78}
79
80internal s64
81_os_read(s32 fd, void *buf, u64 count)
82{
83 return syscall(SYS_read, fd, buf, count);
84}
85
86internal void
87log_s8(string8 s)
88{
89 os_write(s.data, s.size);
90}
91
92#if 1
93internal void
94_log(const char *str)
95{
96#ifdef BASE_LOGGING
97 s32 len = 0;
98 while (str[len]) len++;
99 os_write(str, len);
100#else
101 unused(str);
102#endif
103
104}
105#endif
106
107internal void
108write_string(const char *str)
109{
110 s32 len = 0;
111 while (str[len]) len++;
112 os_write(str, len);
113}
114
115internal void
116write_int(s32 num)
117{
118
119 if (num < 0)
120 {
121 write(STDERR_FILENO, "-", 1);
122 num = -num;
123 }
124 if (num >= 10) write_int(num / 10);
125
126 char digit = '0' + (num % 10);
127
128 write(STDERR_FILENO, &digit, 1);
129}
130
131internal inline void
132sleep_ms(long ms)
133{
134 struct timespec ts;
135 ts.tv_sec = ms / 1000;
136 ts.tv_nsec = (ms % 1000) * 1000000L;
137
138 while (nanosleep(&ts, &ts))
139 {
140 NULL;
141 }
142}
143
144
145#endif
diff --git a/source/base/base_platform.h b/source/base/base_platform.h
new file mode 100644
index 0000000..b34a7d0
--- /dev/null
+++ b/source/base/base_platform.h
@@ -0,0 +1,6 @@
1#ifndef BASE_PLATFORM_H
2#define BASE_PLATFORM_H
3
4#ifdef BASE_PLATFORM_IMPLEMENTATION
5#endif /* BASE_PLATFORM_IMPLEMENTATION */
6#endif /* BASE_PLATFORM_H */
diff --git a/source/base/base_rand.h b/source/base/base_rand.h
new file mode 100644
index 0000000..bfdab0f
--- /dev/null
+++ b/source/base/base_rand.h
@@ -0,0 +1,28 @@
1#ifndef BASE_RAND_H
2#define BASE_RAND_H
3
4// source: https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64
5
6#define RAND_CONSTANT 6364136223846793005
7#define GEN_RAND() _generate_random_u64(RAND_CONSTANT)
8
9#endif /* BASE_RAND_H */
10
11#ifdef BASE_RAND_IMPLEMENTATION
12internal u64
13generate_random_u64(u64 constant)
14{
15 time_t current_time = time(0);
16 constant = current_time ^ constant;
17
18 constant += 0x9e3779b97f4a7c15;
19
20 u64 z = constant;
21 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
22 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
23 z = z ^ (z >> 31);
24
25 return z;
26}
27
28#endif
diff --git a/source/base/base_stack.c b/source/base/base_stack.c
deleted file mode 100755
index 9c1218a..0000000
--- a/source/base/base_stack.c
+++ /dev/null
@@ -1,187 +0,0 @@
1internal mem_stack *
2stack_create(u64 capacity)
3{
4 mem_stack *stack = (mem_stack *)mmap(
5 0,
6 capacity + sizeof(mem_stack),
7 PROT_READ | PROT_WRITE,
8 MAP_SHARED | MAP_ANONYMOUS,
9 -1,
10 0);
11
12 if (stack == MAP_FAILED)
13 {
14 return NULL;
15 }
16
17 stack->capacity = capacity;
18 stack->base_position = (u8 *)stack + sizeof(mem_stack);
19 stack->current_offset = 0;
20
21 return stack;
22}
23
24internal u8
25calculate_padding(u64 pointer, u8 alignment, u64 header_size)
26{
27 u8 modulo, padding;
28
29 if (!is_pow(alignment))
30 {
31 return 0;
32 }
33
34 modulo = pointer & (u8)(alignment - 1);
35
36 padding = 0;
37
38 if (0 == modulo)
39 {
40 padding = alignment - modulo;
41 }
42
43 if (padding < header_size)
44 {
45 header_size -= padding;
46
47 if ((header_size & (alignment - 1)) != 0)
48 {
49 padding += alignment * (1 + (header_size / alignment));
50 }
51 else
52 {
53 padding += alignment * (header_size / alignment);
54 }
55 }
56
57 return padding;
58}
59
60internal mem_stack *
61stack_push_align(mem_stack *stack, u64 size, u8 alignment)
62{
63 u8 padding = 0;
64
65 if (!is_pow(alignment))
66 {
67 return (0);
68 }
69
70 if (alignment > 128)
71 {
72 alignment = 128;
73 }
74
75 u64 current_address = (u64)stack->base_position + stack->current_offset;
76 padding = calculate_padding(current_address, alignment, sizeof(mem_stack_header));
77
78 if (stack->current_offset + padding + size > stack->capacity)
79 {
80 return 0;
81 }
82
83 stack->current_offset += padding;
84
85 u64 next_address = current_address + (u64)padding;
86 mem_stack_header *header = (mem_stack_header *)(next_address - sizeof(mem_stack_header));
87 header->padding = padding;
88
89 stack->current_offset += size;
90
91 return MemSet((void *)next_address, size);
92}
93internal void *
94stack_push(mem_stack *stack, u64 size)
95{
96 return stack_push_align(stack, size, ARENA_ALIGN);
97}
98
99internal void
100stack_pop(mem_stack *stack, void *pointer)
101{
102 if (pointer != NULL)
103 {
104 u64 start, end, current_address;
105 mem_stack_header *header;
106 u64 prev_offset;
107
108 start = (u64)stack->base_position;
109 end = start + (u64)stack->capacity;
110 current_address = (u64)pointer;
111
112 if (!(start <= current_address && current_address < end))
113 {
114 if (0 && "Out of bounds memory address passed to stack allocator (free)")
115 {
116 return;
117 }
118 return;
119 }
120
121 if (current_address >= start + (u64)stack->base_position)
122 {
123 return;
124 }
125
126 header = (mem_stack_header *)(current_address - sizeof(mem_stack_header));
127 prev_offset = (size_t)(current_address - (u64)header->padding - start);
128 stack->current_offset = prev_offset;
129 }
130}
131
132internal mem_stack *
133stack_resize_align(mem_stack *stack, void *pointer, u64 old_size, u64 new_size, u8 alignment)
134{
135 if (pointer == NULL)
136 {
137 return stack_push_align(stack, new_size, alignment);
138 }
139 else if (new_size == 0)
140 {
141 stack_pop(stack, pointer);
142 return NULL;
143 }
144
145 u64 start, end, current_address;
146 u64 min_size = old_size < new_size ? old_size : new_size;
147 void *new_pointer;
148
149 start = (u64)stack->base_position;
150 end = start + (u64)stack->capacity;
151 current_address = (u64)pointer;
152 if (!(start <= current_address && current_address < end))
153 {
154 return NULL;
155 }
156
157 if (current_address >= start + (u64)stack->current_offset)
158 {
159 return NULL;
160 }
161
162 if (old_size == new_size)
163 {
164 return pointer;
165 }
166
167 new_pointer = stack_push_align(stack, new_size, alignment);
168 memmove(new_pointer, pointer, min_size);
169 return new_pointer;
170}
171
172internal void
173stack_pop_all(mem_stack *stack)
174{
175 stack->current_offset = 0;
176}
177
178internal void
179stack_destroy(mem_stack *stack)
180{
181 if (!stack)
182 {
183 return;
184 }
185
186 munmap(stack, stack->capacity + sizeof(mem_stack));
187}
diff --git a/source/base/base_stack.h b/source/base/base_stack.h
index 54d61d3..43a7230 100755
--- a/source/base/base_stack.h
+++ b/source/base/base_stack.h
@@ -19,4 +19,192 @@ struct mem_stack
19 u8 *base_position; 19 u8 *base_position;
20}; 20};
21 21
22internal mem_stack *
23stack_create(u64 capacity)
24{
25 mem_stack *stack = (mem_stack *)mmap(
26 0,
27 capacity + sizeof(mem_stack),
28 PROT_READ | PROT_WRITE,
29 MAP_SHARED | MAP_ANONYMOUS,
30 -1,
31 0);
32
33 if (stack == MAP_FAILED)
34 {
35 return NULL;
36 }
37
38 stack->capacity = capacity;
39 stack->base_position = (u8 *)stack + sizeof(mem_stack);
40 stack->current_offset = 0;
41
42 return stack;
43}
44
45internal u8
46calculate_padding(u64 pointer, u8 alignment, u64 header_size)
47{
48 u8 modulo, padding;
49
50 if (!is_pow(alignment))
51 {
52 return 0;
53 }
54
55 modulo = pointer & (u8)(alignment - 1);
56
57 padding = 0;
58
59 if (0 == modulo)
60 {
61 padding = alignment - modulo;
62 }
63
64 if (padding < header_size)
65 {
66 header_size -= padding;
67
68 if ((header_size & (alignment - 1)) != 0)
69 {
70 padding += alignment * (1 + (header_size / alignment));
71 }
72 else
73 {
74 padding += alignment * (header_size / alignment);
75 }
76 }
77
78 return padding;
79}
80
81internal mem_stack *
82stack_push_align(mem_stack *stack, u64 size, u8 alignment)
83{
84 u8 padding = 0;
85
86 if (!is_pow(alignment))
87 {
88 return (0);
89 }
90
91 if (alignment > 128)
92 {
93 alignment = 128;
94 }
95
96 u64 current_address = (u64)stack->base_position + stack->current_offset;
97 padding = calculate_padding(current_address, alignment, sizeof(mem_stack_header));
98
99 if (stack->current_offset + padding + size > stack->capacity)
100 {
101 return 0;
102 }
103
104 stack->current_offset += padding;
105
106 u64 next_address = current_address + (u64)padding;
107 mem_stack_header *header = (mem_stack_header *)(next_address - sizeof(mem_stack_header));
108 header->padding = padding;
109
110 stack->current_offset += size;
111
112 return MemSet((void *)next_address, size);
113}
114internal void *
115stack_push(mem_stack *stack, u64 size)
116{
117 return stack_push_align(stack, size, ARENA_ALIGN);
118}
119
120internal void
121stack_pop(mem_stack *stack, void *pointer)
122{
123 if (pointer != NULL)
124 {
125 u64 start, end, current_address;
126 mem_stack_header *header;
127 u64 prev_offset;
128
129 start = (u64)stack->base_position;
130 end = start + (u64)stack->capacity;
131 current_address = (u64)pointer;
132
133 if (!(start <= current_address && current_address < end))
134 {
135 if (0 && "Out of bounds memory address passed to stack allocator (free)")
136 {
137 return;
138 }
139 return;
140 }
141
142 if (current_address >= start + (u64)stack->base_position)
143 {
144 return;
145 }
146
147 header = (mem_stack_header *)(current_address - sizeof(mem_stack_header));
148 prev_offset = (size_t)(current_address - (u64)header->padding - start);
149 stack->current_offset = prev_offset;
150 }
151}
152
153internal mem_stack *
154stack_resize_align(mem_stack *stack, void *pointer, u64 old_size, u64 new_size, u8 alignment)
155{
156 if (pointer == NULL)
157 {
158 return stack_push_align(stack, new_size, alignment);
159 }
160 else if (new_size == 0)
161 {
162 stack_pop(stack, pointer);
163 return NULL;
164 }
165
166 u64 start, end, current_address;
167 u64 min_size = old_size < new_size ? old_size : new_size;
168 void *new_pointer;
169
170 start = (u64)stack->base_position;
171 end = start + (u64)stack->capacity;
172 current_address = (u64)pointer;
173 if (!(start <= current_address && current_address < end))
174 {
175 return NULL;
176 }
177
178 if (current_address >= start + (u64)stack->current_offset)
179 {
180 return NULL;
181 }
182
183 if (old_size == new_size)
184 {
185 return pointer;
186 }
187
188 new_pointer = stack_push_align(stack, new_size, alignment);
189 memmove(new_pointer, pointer, min_size);
190 return new_pointer;
191}
192
193internal void
194stack_pop_all(mem_stack *stack)
195{
196 stack->current_offset = 0;
197}
198
199internal void
200stack_destroy(mem_stack *stack)
201{
202 if (!stack)
203 {
204 return;
205 }
206
207 munmap(stack, stack->capacity + sizeof(mem_stack));
208}
209
22#endif 210#endif
diff --git a/source/base/base_string.c b/source/base/base_string.c
new file mode 100644
index 0000000..986fde5
--- /dev/null
+++ b/source/base/base_string.c
@@ -0,0 +1,30 @@
1internal b32
2is_alpha(u8 point)
3{
4 return ((point >= 'a' && point <= 'z') || (point >= 'A' && point <= 'Z') || (point == '_'));
5}
6
7internal b32
8is_digit(u8 point)
9{
10 return (point >= '0' && point <= '9');
11}
12
13internal b32
14is_alpha_num(u8 point)
15{
16 return (is_alpha(point) || is_digit(point));
17}
18
19internal b32 is_whitespace(u8 point)
20{
21 return (point == '\n' || point == '\r' || point == ' ' || point == '\t');
22}
23
24internal b32
25is_slash(u8 point)
26{
27 return (point == '/' || point == '\\');
28}
29
30
diff --git a/source/base/base_string.h b/source/base/base_string.h
index 29ccf1e..eb51e65 100644
--- a/source/base/base_string.h
+++ b/source/base/base_string.h
@@ -1,9 +1,15 @@
1#ifndef BASE_STRING_H 1#ifndef BASE_STRING_H
2#define BASE_STRING_H 2#define BASE_STRING_H
3 3
4#define PushString(arena, count) (string8){ .data = (PushArrayZero(arena, u8, (count))), .size = (count) } 4#define PushString8(arena, count) (string8){ .data = (PushArrayZero(arena, u8, (count))), .size = (count) }
5#define StringCast(data, size) (string8){(u8 *)(data), (u64)(size) } 5#define PushString16(arena, count) (string16){ .data = (PushArrayZero(arena, u16, (count))), .size = (count) }
6#define StringPCast(data, size) (string8 *){(u8 *)(data), (u64)(size) } 6#define PushString32(arena, count) (string32){ .data = (PushArrayZero(arena, u32, (count))), .size = (count) }
7
8#define String8(data, size) (string8){(u8 *)(data), (u64)(size) }
9#define String16(data, size) (string16){(u16 *)(data), (u64)(size) }
10#define String32(data, size) (string32){(u32 *)(data), (u64)(size) }
11
12
7 13
8#define StringFmt "%.*s" 14#define StringFmt "%.*s"
9#define ULongFmt "%lu" 15#define ULongFmt "%lu"
@@ -16,6 +22,51 @@ struct string8
16 u64 size; 22 u64 size;
17}; 23};
18 24
25typedef struct string16 string16;
26struct string16
27{
28 u16 *data;
29 u64 size;
30};
31
32typedef struct string32 string32;
33struct string32
34{
35 u32 *data;
36 u64 size;
37};
38
39//- string linked list implementation
40typedef struct string8_node string8_node;
41struct string8_node
42{
43 string8 *next;
44 string8 string;
45};
46
47typedef struct string8_list string8_list;
48struct string8_list
49{
50 string8 *first;
51 string8 *last;
52 u64 count;
53};
54
55typedef struct string16_list string16_list;
56struct string16_list
57{
58 string16 *next;
59 string16 string;
60};
61
62typedef struct string32_list string32_list;
63struct string32_list
64{
65 string32 *first;
66 string32 *last;
67 u64 count;
68};
69
19internal b8 70internal b8
20string8_cmp(string8 a, string8 b) 71string8_cmp(string8 a, string8 b)
21{ 72{
@@ -23,31 +74,11 @@ string8_cmp(string8 a, string8 b)
23 return (b8)(memcmp(a.data, b.data, a.size) == 0); 74 return (b8)(memcmp(a.data, b.data, a.size) == 0);
24} 75}
25 76
26internal u64
27string8_to_u64(u8 *buf, umm len)
28{
29 u64 value = 0;
30 for (umm i = 0; i < len; ++i)
31 {
32 u8 c = buf[i];
33 if (c < '0' || c > '9') break;
34 value = value * 10 + (c - '0');
35 }
36 return value;
37}
38
39internal void 77internal void
40string8_append_char(string8 *buf, u8 c) 78string8_appendc(string8 *buf, u8 c)
41{ 79{
42 buf->data[buf->size] = c; 80 buf->data[buf->size] = c;
43 buf->size += 1; 81 buf->size += 1;
44} 82}
45 83
46read_only global_variable
47string8 nil_string =
48{
49 .data = NULL,
50 .size = 0,
51};
52
53#endif /* BASE_STRING_H */ 84#endif /* BASE_STRING_H */
diff --git a/source/base/base_test.h b/source/base/base_test.h
deleted file mode 100644
index fd47abc..0000000
--- a/source/base/base_test.h
+++ /dev/null
@@ -1,46 +0,0 @@
1// TODO(nasr): metaprogram that takes an expected output and generates a test for that specified
2// function
3/* base library testing framework */
4#ifndef BASE_TEST_H
5#define BASE_TEST_H
6
7// helper macro
8#define show \
9 do \
10 { \
11 write(STDOUT_FILENO, __FILE__, sizeof(__FILE__) - 1); \
12 write(STDOUT_FILENO, ":", 1); \
13 write(STDOUT_FILENO, __func__, sizeof(__func__) - 1); \
14 write(STDOUT_FILENO, ":", 1); \
15 write_int(__LINE__); \
16 write(STDOUT_FILENO, "\n", 1); \
17 } while (0)
18
19#define test(expr) \
20 { \
21 if ((expr) != 0) \
22 { \
23 write(STDERR_FILENO, "[FAILED] ", LEN("[FAILED] ")); \
24 show; \
25 _exit(1); \
26 } \
27 }
28
29#define verify(expr) \
30 { \
31 if ((expr) != 0) \
32 { \
33 write(STDERR_FILENO, RED "[ERROR] ", LEN(RED "[ERROR] ")); \
34 show; \
35 write(STDERR_FILENO, RESET, LEN(RESET)); \
36 _exit(1); \
37 } \
38 else \
39 { \
40 write(STDERR_FILENO, GREEN "[SUCCESS] ", LEN(GREEN "[SUCCESS] ")); \
41 show; \
42 write(STDERR_FILENO, RESET, LEN(RESET)); \
43 } \
44 }
45
46#endif /* BASE_TEST_H */
diff --git a/source/base/bash_hash.h b/source/base/bash_hash.h
index 2c286a2..758ef72 100644
--- a/source/base/bash_hash.h
+++ b/source/base/bash_hash.h
@@ -1,15 +1,24 @@
1##ifndef HEADER_H 1#ifndef BASH_HASH_H
2#define HEADER_H 2#define BASH_HASH_H
3 3
4typedef struct hash_map hash_map; 4typedef struct hash_map hash_map;
5typedef struct hash hash; 5typedef struct hash hash;
6 6
7 7struct map
8struct hash_map
9{ 8{
9 string8
10 u64 capacity
11};
10 12
11 13
14struct index
15{
16 string8 key;
17 string8 value;
12}; 18};
13 19
14 20
15#endif /* HEADER_H */ 21
22internal void
23
24#endif /* BASH_HASH_H */
diff --git a/source/tb_db/tb_ml.c b/source/tb_db/tb_ml.c
deleted file mode 100644
index a86303d..0000000
--- a/source/tb_db/tb_ml.c
+++ /dev/null
@@ -1,9 +0,0 @@
1#define BASE_UNITY
2#include "../base/base_include.h"
3
4int main(int c, char **v)
5{
6
7
8 return 0;
9}
diff --git a/source/tb_ml/tb_ml.c b/source/tb_ml/tb_ml.c
new file mode 100644
index 0000000..cf9625a
--- /dev/null
+++ b/source/tb_ml/tb_ml.c
@@ -0,0 +1,20 @@
1#define BASE_UNITY
2#include "../base/base_include.h"
3
4#if 0
5
6#include "../third_party/btree_impl.h"
7#endif
8
9
10
11//- dataset is an implementation of the btree
12
13int main(int c, char **v)
14{
15 unused(c);
16 unused(v);
17
18
19 return 0;
20}