summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornasr <nsrddyn@gmail.com>2026-04-14 23:11:49 +0200
committernasr <nsrddyn@gmail.com>2026-04-14 23:11:49 +0200
commit154bf6f53529e88dfa03d6ff5034b575f92cdbb5 (patch)
tree04acbc1039719c610f11712b57e1786092f89242
parent4d2a2af0c7d4eec9a9e43e0ba08813fdebaf8f9c (diff)
feature(setup): base implementation
-rw-r--r--.gitignore12
-rwxr-xr-x[-rw-r--r--]build.sh11
-rwxr-xr-xsource/base/base.h64
-rwxr-xr-xsource/base/base_arena.c138
-rwxr-xr-xsource/base/base_arena.h31
-rw-r--r--source/base/base_error.h43
-rwxr-xr-xsource/base/base_include.h36
-rw-r--r--source/base/base_io.h60
-rw-r--r--source/base/base_mem.h26
-rw-r--r--source/base/base_os.h68
-rw-r--r--source/base/base_rand.h4
-rwxr-xr-xsource/base/base_stack.h210
-rw-r--r--source/base/base_string.c30
-rw-r--r--source/base/base_string.h78
-rw-r--r--source/base/base_test.h46
-rw-r--r--source/base/bash_hash.h24
16 files changed, 881 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..05a7b85
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
1idea/
2idea
3idea/*
4.idea
5/build
6/notes.txt
7/test
8/tags
9/helper.sh
10/tests
11/tags
12/.cache/clangd/index
diff --git a/build.sh b/build.sh
index e69de29..29b4092 100644..100755
--- a/build.sh
+++ b/build.sh
@@ -0,0 +1,11 @@
1#!/bin/sh
2
3CC=cc
4SRC=./source/scb/scb.c
5OUT=./build/scb
6
7CFLAGS="-Wall -Wextra -Werror -Wpedantic -O0 -g -Wno-unused-function"
8
9mkdir -p ./build
10
11$CC $CFLAGS "$SRC" -o "$OUT"
diff --git a/source/base/base.h b/source/base/base.h
new file mode 100755
index 0000000..3fe9dca
--- /dev/null
+++ b/source/base/base.h
@@ -0,0 +1,64 @@
1#ifndef BASE_H
2#define BASE_H
3
4/* assert an expression and output the file and the line */
5#define internal static
6#define global_variable static
7#define local_persist static
8
9#define unused(x) (void)(x)
10#define NIL 0
11
12#define DEPRECATED __attribute__((__deprecated__))
13
14#if defined(__arm__) || defined(__aarch64__)
15#define breakpoint __asm__ volatile("brk #0");
16#define temp_breakpoint __asm__ volatile("udf #0");
17#elif defined(__i386__) || defined(__x86_64__)
18#define breakpoint __asm__ volatile("int3");
19#endif
20
21#define MemCpy(dest, src, len) memcpy((dest), (src), (len))
22#define MemSet(dest, len) memset((dest), (0), (len))
23
24#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS)
25#pragma section(".rdata$", read)
26#define read_only __declspec(allocate(".rdata$"))
27#elif (COMPILER_CLANG && OS_LINUX)
28#define read_only __attribute__((section(".rodata")))
29#else
30#define read_only
31#endif
32
33typedef uint64_t u64;
34typedef uint32_t u32;
35typedef uint16_t u16;
36typedef uint8_t u8;
37
38typedef int8_t s8;
39typedef int16_t s16;
40typedef int32_t s32;
41typedef int64_t s64;
42
43typedef float f32;
44typedef double f64;
45
46typedef s32 b32;
47typedef s16 b16;
48typedef s8 b8;
49
50typedef uintptr_t umm;
51typedef intptr_t smm;
52
53#define True (1 == 1)
54#define False (1 != 1)
55
56#define Red "\x1b[31m"
57#define Green "\x1b[32m"
58#define Reset "\x1b[0m"
59#define Blue "\x1b[34m"
60#define Yellow "\x1b[33m"
61
62#define Len(s) (sizeof(s) - 1)
63
64#endif
diff --git a/source/base/base_arena.c b/source/base/base_arena.c
new file mode 100755
index 0000000..7e9c44b
--- /dev/null
+++ b/source/base/base_arena.c
@@ -0,0 +1,138 @@
1internal mem_arena *
2arena_create(u64 capacity)
3{
4 mem_arena *arena = (mem_arena *)mmap(
5 /* kernel decides where to throw the arena */
6 NULL,
7 capacity + sizeof(mem_arena),
8 PROT_READ | PROT_WRITE,
9 MAP_SHARED | MAP_ANONYMOUS,
10 -1,
11 0);
12
13 if (arena == MAP_FAILED)
14 {
15 return NULL;
16 }
17
18 arena->capacity = capacity;
19 arena->base_position = (u8 *)arena + sizeof(mem_arena);
20 arena->current_position = 0;
21 arena->previous_position = 0;
22
23 return arena;
24}
25
26internal void
27arena_destroy(mem_arena *arena)
28{
29 if (!arena)
30 {
31 return;
32 }
33 munmap(arena, arena->capacity + sizeof(mem_arena));
34}
35internal void *
36arena_alloc(mem_arena *arena, u64 size, b32 zero)
37{
38 if (!arena)
39 {
40 return NULL;
41 }
42 u64 aligned = Align(arena->current_position, ARENA_ALIGN);
43 u64 new_pos = aligned + size;
44 if (new_pos > arena->capacity)
45 {
46 return NULL;
47 }
48
49 void *out = arena->base_position + aligned;
50
51 arena->previous_position = arena->current_position;
52 arena->current_position = aligned + size;
53
54 if (zero) MemSet(out, size);
55
56 return out;
57}
58
59internal void
60arena_pop(mem_arena *arena, u64 size)
61{
62 size = MIN(size, arena->current_position);
63 arena->current_position -= size;
64}
65
66internal void
67arena_pop_to(mem_arena *arena, u64 pos)
68{
69 u64 size = pos < arena->current_position ? arena->current_position - pos : 0;
70 arena_pop(arena, size);
71}
72
73internal void
74arena_clear(mem_arena *arena)
75{
76 arena->current_position = 0;
77}
78
79internal mem_arena *
80arena_resize_align(mem_arena *arena, void *old_memory, u64 new_size, u64 old_size, umm alignment)
81{
82 u8 *old_mem = (u8 *)old_memory;
83
84 if (!is_pow(alignment))
85 {
86 Align(arena->current_position, alignment);
87 }
88
89 if (old_memory == NULL || old_size == 0)
90 {
91 return (mem_arena *)arena_alloc(arena, new_size, 0);
92 }
93 else if ((old_mem >= arena->base_position && old_mem < arena->base_position + arena->capacity))
94 {
95 if ((arena->base_position + arena->previous_position) == old_memory)
96 {
97 arena->current_position = arena->previous_position + new_size;
98 if (new_size > old_size)
99 {
100 MemSet(&arena->current_position, new_size - old_size);
101 }
102 return (mem_arena *)old_memory;
103 }
104 else
105 {
106 void *new_memory = arena_alloc(arena, new_size, 0);
107 umm copy_size = old_size < new_size ? old_size : new_size;
108 memmove(new_memory, old_mem, copy_size);
109 }
110 }
111 else
112 {
113 verify(0);
114 }
115 return NULL;
116}
117
118internal mem_arena *
119arena_resize(mem_arena *arena, void *old_memory, u64 new_size, u64 old_size)
120{
121 return arena_resize_align(arena, old_memory, new_size, old_size, ARENA_ALIGN);
122}
123
124internal temp_arena
125temp_arena_begin(mem_arena *arena)
126{
127 temp_arena t;
128 t.arena = arena;
129 t.start_position = arena->current_position;
130
131 return t;
132}
133
134internal void
135temp_arena_end(temp_arena temp)
136{
137 temp.arena->current_position = temp.start_position;
138}
diff --git a/source/base/base_arena.h b/source/base/base_arena.h
new file mode 100755
index 0000000..dc6dd73
--- /dev/null
+++ b/source/base/base_arena.h
@@ -0,0 +1,31 @@
1#ifndef BASE_ARENA_H
2#define BASE_ARENA_H
3
4#define Align(pointer, alignment) align((u64)(pointer), (umm)(alignment))
5#define PushStruct(arena, type) (type *)arena_alloc((arena), sizeof(type), 0)
6#define PushStructZero(arena, type) (type *)arena_alloc((arena), sizeof(type), 1)
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)
9
10#define KiB(n) (((u64)(n)) << 10)
11#define MiB(n) (((u64)(n)) << 20)
12#define GiB(n) (((u64)(n)) << 30)
13
14
15typedef struct mem_arena mem_arena;
16struct mem_arena
17{
18 u64 current_position;
19 u64 previous_position;
20 u64 capacity;
21 u8 *base_position;
22};
23
24typedef struct temp_arena temp_arena;
25struct temp_arena
26{
27 mem_arena *arena;
28 u64 start_position;
29};
30
31#endif /* BASE_ARENA_H */
diff --git a/source/base/base_error.h b/source/base/base_error.h
new file mode 100644
index 0000000..4bf84fc
--- /dev/null
+++ b/source/base/base_error.h
@@ -0,0 +1,43 @@
1/* base library internal error checking system */
2#ifndef BASE_ERROR_H
3#define BASE_ERROR_H
4
5#define error_at(msg) \
6 do \
7 { \
8 os_write(STDERR_FD, Red "[ERROR] ", Len(Red "[ERROR] ")); \
9 write_string(STDERR_FD, __FILE__); \
10 write_string(STDERR_FD, ":"); \
11 write_int(__LINE__); \
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)
18
19#define _fatal(msg) \
20 do { \
21 error_at(msg); \
22 _exit(1); \
23 } while (0)
24
25#define assert_msg(expr, msg) \
26 do \
27 { \
28 if (!(expr)) _fatal(msg); \
29 } while (0)
30
31#define warn(msg) \
32 do \
33 { \
34 os_write(STDERR_FD, Yellow "[WARN] ", Len(Yellow "[WARN] ")); \
35 write_string(STDERR_FD, __FILE__); \
36 write_string(STDERR_FD, ":"); \
37 write_int(__LINE__); \
38 write_string(STDERR_FD, ": "); \
39 write_string(STDERR_FD, (msg)); \
40 os_write(STDERR_FD, Reset "\n", Len(Reset "\n")); \
41 } while (0)
42
43#endif /* BASE_ERROR_H */
diff --git a/source/base/base_include.h b/source/base/base_include.h
new file mode 100755
index 0000000..54844d4
--- /dev/null
+++ b/source/base/base_include.h
@@ -0,0 +1,36 @@
1#ifndef BASE_INCLUDE_H
2#define BASE_INCLUDE_H
3
4#include <dirent.h>
5#include <sys/mman.h>
6#include <sys/stat.h>
7#include <sys/syscall.h>
8#include <fcntl.h>
9#include <stdint.h>
10#include <stddef.h>
11#include <string.h>
12#include <unistd.h>
13
14#include "base.h"
15#include "base_mem.h"
16
17#include "base_arena.h"
18#include "base_stack.h"
19
20#include "base_string.h"
21#include "base_string.c"
22
23
24#ifdef BASE_MATH_IMPLEMENTATION
25#include <math.h>
26//- needs math.h
27#include "base_rand.h"
28#endif
29#include "base_io.h"
30#include "base_error.h"
31#include "base_test.h"
32#ifdef BASE_UNITY
33#include "base_arena.c"
34#endif
35#include "base_os.h"
36#endif
diff --git a/source/base/base_io.h b/source/base/base_io.h
new file mode 100644
index 0000000..ac55737
--- /dev/null
+++ b/source/base/base_io.h
@@ -0,0 +1,60 @@
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_mem.h b/source/base/base_mem.h
new file mode 100644
index 0000000..2778fce
--- /dev/null
+++ b/source/base/base_mem.h
@@ -0,0 +1,26 @@
1#ifndef BASE_MEM_H
2#define BASE_MEM_H
3
4#define ARENA_ALIGN (2 * sizeof(void *))
5#define MIN(a, b) (((a) < (b)) ? (a) : (b))
6#define MAX(a, b) (((a) > (b)) ? (a) : (b))
7
8internal inline b8
9is_pow(umm x)
10{
11 return (x & (x - 1)) == 0;
12}
13
14internal inline u64
15align(u64 pointer, umm alignment)
16{
17 if ((alignment & (alignment - 1)) == 0)
18 {
19 return pointer;
20 }
21
22 return (pointer + alignment - 1) & ~(alignment - 1);
23}
24
25
26#endif
diff --git a/source/base/base_os.h b/source/base/base_os.h
new file mode 100644
index 0000000..4f84d93
--- /dev/null
+++ b/source/base/base_os.h
@@ -0,0 +1,68 @@
1#ifndef BASE_OS_H
2#define BASE_OS_H
3
4internal string8
5load_file(mem_arena *arena, const char *path)
6{
7 string8 result = {0};
8 struct stat sbuf = {0};
9
10 // TODO(nasr): abstract this to a platform layer
11 s32 file = open(path, O_RDONLY);
12 if(file == -1)
13 {
14 warn("fialed to open file. path could be invalid");
15 return (string8){0};
16 }
17
18 if(fstat(file, &sbuf) == -1)
19 {
20 warn("error: fstat failed");
21 close(file);
22 return (string8){0};
23 }
24
25
26 result = PushString(arena, sbuf.st_size);
27
28 result.size = (u64)sbuf.st_size;
29 if(result.size != 0)
30 {
31 result.data = (u8 *)mmap(0, result.size, PROT_READ, MAP_PRIVATE, file, 0);
32 }
33
34 close(file);
35 return result;
36}
37
38internal string8
39write_file(const char *path, string8 data)
40{
41
42 string8 result = {0};
43 s32 file = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
44 if(file == -1)
45 {
46 warn("failed to open file for writing. path could be invalid");
47 return (string8){0};
48 }
49
50 u64 written = 0;
51 while(written < data.size)
52 {
53 s64 err = write(file, data.data + written, data.size - written);
54 if(err == -1)
55 {
56 warn("write syscall failed");
57 close(file);
58 return (string8){0};
59 }
60 written += err;
61 }
62
63 close(file);
64 result = data;
65 return result;
66}
67
68#endif /* BASE_OS_H */
diff --git a/source/base/base_rand.h b/source/base/base_rand.h
index e69de29..faa00e8 100644
--- a/source/base/base_rand.h
+++ b/source/base/base_rand.h
@@ -0,0 +1,4 @@
1#ifndef BASE_RAND_H
2#define BASE_RAND_H
3
4#endif /* BASE_RAND_H */
diff --git a/source/base/base_stack.h b/source/base/base_stack.h
new file mode 100755
index 0000000..43a7230
--- /dev/null
+++ b/source/base/base_stack.h
@@ -0,0 +1,210 @@
1#ifndef STACK_H
2#define STACK_H
3
4typedef struct mem_stack_header mem_stack_header;
5struct mem_stack_header
6{
7 u8 padding;
8 u8 previous_offset;
9};
10
11
12typedef struct mem_stack mem_stack;
13struct mem_stack
14{
15 mem_stack_header *header;
16
17 u64 current_offset;
18 u64 capacity;
19 u8 *base_position;
20};
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
210#endif
diff --git a/source/base/base_string.c b/source/base/base_string.c
index e69de29..986fde5 100644
--- a/source/base/base_string.c
+++ 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
new file mode 100644
index 0000000..c4b9f94
--- /dev/null
+++ b/source/base/base_string.h
@@ -0,0 +1,78 @@
1#ifndef BASE_STRING_H
2#define BASE_STRING_H
3
4#define PushString(arena, count) (string8){ .data = (PushArrayZero(arena, u8, (count))), .size = (count) }
5#define StringCast(data, size) (string8){(u8 *)(data), (u64)(size) }
6#define StringPCast(data, size) (string8 *){(u8 *)(data), (u64)(size) }
7
8#define StringFmt "%.*s"
9#define ULongFmt "%lu"
10#define ULLongFmt "%llu"
11
12typedef struct string8 string8;
13struct string8
14{
15 u8 *data;
16 u64 size;
17};
18
19typedef struct string16 string16;
20struct string16
21{
22 u16 *data;
23 u64 size;
24};
25
26typedef struct string32 string32;
27struct string32
28{
29 u32 *data;
30 u64 size;
31};
32
33//- string linked list implementation
34typedef struct string8_node string8_node;
35struct string8_node
36{
37 string8 *next;
38 string8 string;
39};
40
41typedef struct string8_list string8_list;
42struct string8_list
43{
44 string8 *first;
45 string8 *last;
46 u64 count;
47};
48
49typedef struct string16_list string16_list;
50struct string16_list
51{
52 string16 *next;
53 string16 string;
54};
55
56typedef struct string32_list string32_list;
57struct string32_list
58{
59 string32 *first;
60 string32 *last;
61 u64 count;
62};
63
64internal b8
65string8_cmp(string8 a, string8 b)
66{
67 if (a.size != b.size) return 0;
68 return (b8)(memcmp(a.data, b.data, a.size) == 0);
69}
70
71internal void
72string8_appendc(string8 *buf, u8 c)
73{
74 buf->data[buf->size] = c;
75 buf->size += 1;
76}
77
78#endif /* BASE_STRING_H */
diff --git a/source/base/base_test.h b/source/base/base_test.h
new file mode 100644
index 0000000..072bec3
--- /dev/null
+++ b/source/base/base_test.h
@@ -0,0 +1,46 @@
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
new file mode 100644
index 0000000..758ef72
--- /dev/null
+++ b/source/base/bash_hash.h
@@ -0,0 +1,24 @@
1#ifndef BASH_HASH_H
2#define BASH_HASH_H
3
4typedef struct hash_map hash_map;
5typedef struct hash hash;
6
7struct map
8{
9 string8
10 u64 capacity
11};
12
13
14struct index
15{
16 string8 key;
17 string8 value;
18};
19
20
21
22internal void
23
24#endif /* BASH_HASH_H */