Commit f55d118

kravantokh <kravantokh@noreply.codeberg.org>
2026-08-01 22:10:57
Add basic file operations (and tests).
1 parent 4b7cfb8
fs/file.h
@@ -13,25 +13,25 @@ typedef struct _FileView FileView;
 
 enum FileOpenFlags {
 
-	FILE_ACCESS_READ   = (1 << 1),
-	FILE_ACCESS_WRITE  = (1 << 2),
-	FILE_ACCESS_APPEND = (1 << 3),
+	FILE_ACCESS_READ   = ((usize)1 << 1),
+	FILE_ACCESS_WRITE  = ((usize)1 << 2),
+	FILE_ACCESS_APPEND = ((usize)1 << 3),
 
 	FILE_ACCESS_MASK = (FILE_ACCESS_READ | FILE_ACCESS_WRITE | FILE_ACCESS_APPEND),
 
-	FILE_EXISTING_OPEN     = (1 << 4),
-	FILE_EXISTING_TRUNCATE = (1 << 5),
-	FILE_EXISTING_FAIL     = (1 << 6),
+	FILE_EXISTING_OPEN     = ((usize)1 << 4),
+	FILE_EXISTING_TRUNCATE = ((usize)1 << 5),
+	FILE_EXISTING_FAIL     = ((usize)1 << 6),
 
 	FILE_EXISTING_MASK = (FILE_EXISTING_OPEN | FILE_EXISTING_TRUNCATE | FILE_EXISTING_FAIL),
 
-	FILE_MISSING_CREATE = (1 << 7),
-	FILE_MISSING_FAIL   = (1 << 8),
+	FILE_MISSING_CREATE = ((usize)1 << 7),
+	FILE_MISSING_FAIL   = ((usize)1 << 8),
 
 	FILE_MISSING_MASK = (FILE_MISSING_CREATE | FILE_MISSING_FAIL),
 
-	FILE_LINK_FOLLOW = (1 << 9),
-	FILE_LINK_FAIL = (1 << 10), /* os-dependent option - whatever the os guarantees. O_NOFOLLOW on linux. */
+	FILE_LINK_FOLLOW = ((usize)1 << 9),
+	FILE_LINK_FAIL = ((usize)1 << 10), /* os-dependent option - whatever the os guarantees. O_NOFOLLOW on linux. */
 
 	FILE_LINK_MASK = (FILE_LINK_FOLLOW | FILE_LINK_FAIL),
 
@@ -40,24 +40,22 @@ enum FileOpenFlags {
 static inline Status File_open_validate_flags( usize flags, Status err_source ) {
 
 	usize existing_flags = flags & FILE_EXISTING_MASK;
-	u8 existing_flags_multiple_set = !usize_is_power_of_two( existing_flags );
+	usize existing_flags_multiple_set = !usize_is_power_of_two( existing_flags );
 
-	if( existing_flags_multiple_set ) {
-		DEBUG(breakpoint());
-		return S_FAILURE | ERR_INVALID_ARGUMENT | err_source;
-	}
+	usize missing_flags = flags & FILE_MISSING_MASK;
+	usize missing_flags_multiple_set = !usize_is_power_of_two( missing_flags );
 
-	if( !( !!(flags & FILE_MISSING_CREATE) ^ !!(flags & FILE_MISSING_FAIL) ) ) {
-		DEBUG(breakpoint());
-		return ERR_INVALID_ARGUMENT | err_source;
-	}
+	usize link_flags = flags & FILE_LINK_MASK;
+	usize link_flags_multiple_set = !usize_is_power_of_two( link_flags );
 
-	if( !( !!(flags & FILE_LINK_FOLLOW ) ^ !!(flags & FILE_LINK_FAIL) ) ) {
-		DEBUG(breakpoint());
-		return S_FAILURE | ERR_INVALID_ARGUMENT | err_source;
-	}
+	usize write_append_flags = flags & (FILE_ACCESS_WRITE | FILE_ACCESS_APPEND);
+	usize write_append_flags_multiple_set = !usize_is_power_of_two( write_append_flags );
 
-	if( !( !!(flags & FILE_ACCESS_WRITE ) ^ !!(flags & FILE_ACCESS_APPEND) ) ) {
+	if( existing_flags_multiple_set |
+	    missing_flags_multiple_set |
+	    link_flags_multiple_set |
+	    (write_append_flags && write_append_flags_multiple_set)
+	) {
 		DEBUG(breakpoint());
 		return S_FAILURE | ERR_INVALID_ARGUMENT | err_source;
 	}
@@ -68,10 +66,17 @@ static inline Status File_open_validate_flags( usize flags, Status err_source )
 Status File_open( const String *name, usize flags, File *out );
 Status File_close( File *f );
 
+Status File_read( const File *f, usize max_amount, usize *out_amount, u8 *out );
+Status File_write( const File *f, usize amount, usize *out_amount, const u8 *buf );
+
+Status File_seek( const File *f, usize position );
+
+Status File_delete( const String *name );
+
 
 enum FileViewFlags {
 	FILEVIEW_OWN_FILE = (1 << 1),
-	FILEVIEW_PAGE_ALIGNED_EXTEND = (1 << 2),
+/*	FILEVIEW_PAGE_ALIGNED_EXTEND = (1 << 2), */
 };
 
 Status FileView_from_file( File *file, usize claim_amount, usize flags, FileView *out ); /* if claim_amount == 0 => claims exact filesize */
memory/heap.h
@@ -17,7 +17,7 @@ STRUCT( Heap,
 
 Status Heap_create( Heap *out, usize size ); /* size - size of underlying arena. The heap will hold less, due to bookkeeping overhead for allocations. */
 
-Status Heap_take( usize amount, u8 **out );
-Status Heap_give( u8* ptr );
+Status Heap_take( Heap *h, usize amount, u8 **out );
+Status Heap_give( Heap *h, u8 *ptr );
 
 #endif
platform/linux/file.h
@@ -139,13 +139,86 @@ Status File_close( File *f ) {
 	} else {
 		switch( res ) {
 			case -EBADF:
-				return ERR_ARG_1 | ERR_INVALID_ARGUMENT;
+				return S_FAILURE | ERR_ARG_1 | ERR_INVALID_ARGUMENT;
 			default:
 				return S_FAILURE | ERR_PLATFORM | ERR_GENERIC;
 		}
 	}
 }
 
+
+Status File_read( const File *f, usize max_amount, usize *out_amount, u8 *out ) {
+	usize res = linux_read( f->fd, out, max_amount ); 
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		*out_amount = res;
+		return S_SUCCESS;
+	} else {
+		switch(res) {
+			case -EBADF:
+				return S_FAILURE | ERR_ARG_1 | ERR_INVALID_ARGUMENT;
+			case -EFAULT:
+				return S_FAILURE | ERR_ARG_3 | ERR_OUT_OF_BOUND;
+			default:
+				return S_FAILURE | ERR_PLATFORM | ERR_GENERIC;
+		}
+	}
+}
+
+Status File_write( const File *f, usize amount, usize *out_amount, const u8 *buf ) {
+	usize res = linux_write( f->fd, buf, amount ); 
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		*out_amount = res;
+		return S_SUCCESS;
+	} else {
+		switch(res) {
+			case -EBADF:
+				return S_FAILURE | ERR_ARG_1 | ERR_INVALID_ARGUMENT;
+			case -EFAULT:
+				return S_FAILURE | ERR_ARG_3 | ERR_OUT_OF_BOUND;
+			default:
+				return S_FAILURE | ERR_PLATFORM | ERR_GENERIC;
+		}
+	}
+}
+
+Status File_delete( const String *name ) {
+	usize res = linux_unlink( (const u8*)&name->data );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		switch( res ) {
+			case -EACCES:
+			case -EPERM:
+				return S_FAILURE | ERR_PLATFORM | ERR_PERMISSION_DENIED;
+			case -EFAULT:
+				return S_FAILURE | ERR_ARG_1 | ERR_OUT_OF_BOUND;
+			case -ENOENT:
+				return S_FAILURE | ERR_PLATFORM | ERR_FILE_DOESNT_EXIST;
+			default:
+				return S_FAILURE | ERR_PLATFORM | ERR_GENERIC;
+		}
+	}
+}
+
+Status File_seek( const File *f, usize position ) {
+	usize res = linux_lseek( f->fd, position, SEEK_SET );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		switch( res ) {
+			case -EBADF:
+				return S_FAILURE | ERR_ARG_1 | ERR_INVALID_ARGUMENT;
+			case -EOVERFLOW:
+				return S_FAILURE | ERR_OVERFLOW;
+			default:
+				return S_FAILURE | ERR_GENERIC;
+		}
+	}
+}
+
 Status FileView_from_file( File *file, usize claim_amount, usize flags, FileView *out ) {
 	DEBUG( assert( claim_amount%sizeof(Page) == 0 ) );
 
platform/linux/syscalls.h
@@ -198,6 +198,14 @@ static inline isize linux_close( u32 fd ) {
 	return linux_syscall1( 3, fd );
 }
 
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+static inline isize linux_lseek( u32 fd, usize offset, usize whence ) {
+	return linux_syscall3( 8, fd, offset, whence );
+}
+
 #if ARCH == ARCH_X86_64
 struct stat {
     u64 st_dev;
@@ -301,6 +309,11 @@ static inline isize linux_madvise( usize start, usize len, s32 behaviour ) {
 	return linux_syscall3( 11, start, len, (usize)(u32)behaviour );
 }
 
+
+static inline isize linux_unlink( const u8 *path ) {
+	return linux_syscall1( 87, (usize)path );
+}
+
 static inline isize linux_fallocate( s32 fd, s32 mode, usize offset, usize len ) {
 	return linux_syscall4(285, fd, mode, offset, len);
 }
testing/tests/020_file_basic.c
@@ -0,0 +1,228 @@
+#include "notlibc/core.h"
+
+void test_existing_open_missing_create(void);
+void test_existing_truncate_missing_create(void);
+void test_existing_fail_missing_create(void);
+
+void test_existing_open_missing_fail(void);
+void test_existing_truncate_missing_fail(void);
+void test_existing_fail_missing_fail(void);
+void test_invalid_combinations(void);
+
+void test_file_access(void);
+
+File f = {0};
+const STRING( filename, "test.txt" );
+const STRING( msg, "hello there!" );
+u8 buffer[sizeof(msg.data) - 1] = {0};
+usize read_amount = 0;
+usize written_amount = 0;
+
+void reset_state(void) {
+	mem_set( &f, sizeof(f), 0 );
+	mem_set( &buffer, sizeof(buffer), 0 );
+	read_amount = 0;
+	written_amount = 0;
+}
+
+void entry(void) {
+	test_existing_open_missing_create();
+	reset_state();
+	test_existing_truncate_missing_create();
+	reset_state();
+	test_existing_fail_missing_create();
+	reset_state();
+
+	test_existing_open_missing_fail();
+	reset_state();
+	test_existing_truncate_missing_fail();
+	reset_state();
+
+	test_file_access();
+	reset_state();
+
+	RELEASE(
+		test_existing_fail_missing_fail();
+		reset_state();
+		test_invalid_combinations();
+		reset_state();
+	)
+
+	terminate(0);
+}
+
+
+void test_existing_open_missing_create(void) {
+	usize flags = 
+		FILE_EXISTING_OPEN |
+		FILE_MISSING_CREATE |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE;
+
+	/* Create */
+	Status s = File_open( (String*)&filename, flags, &f); assert( S_SUCCESSFUL(s) );
+
+	s = File_write( &f, msg.len, &written_amount, (const u8*)&msg.data ); assert( S_SUCCESSFUL(s) );
+	assert( written_amount == msg.len );
+
+
+	s = File_seek( &f, 0 ); assert( S_SUCCESSFUL(s) );
+	s = File_read( &f, msg.len, &read_amount, (u8*)&buffer ); assert( S_SUCCESSFUL(s) );
+
+	for( usize i = 0; i < msg.len; ++i ) {
+		assert( buffer[i] == msg.data[i] );
+	}
+
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+
+	/* Open */
+	s = File_open( (String*)&filename, flags, &f); assert( S_SUCCESSFUL(s) );
+
+	s = File_read( &f, msg.len, &read_amount, (u8*)&buffer ); assert( S_SUCCESSFUL(s) );
+
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+	s = File_delete( (String*)&filename ); assert( S_SUCCESSFUL(s) );
+}
+
+
+void test_existing_truncate_missing_create(void) {
+	usize flags = 
+		FILE_EXISTING_TRUNCATE |
+		FILE_MISSING_CREATE |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE;
+	
+	/* Create */
+	Status s = File_open( (String*)&filename, flags, &f); assert( S_SUCCESSFUL(s) );
+	s = File_write( &f, msg.len, &written_amount, (const u8*)&msg.data ); assert( S_SUCCESSFUL(s) );
+	assert( written_amount == msg.len );
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+
+	/* Open (truncate) */
+	s = File_open( (String*)&filename, flags, &f); assert( S_SUCCESSFUL(s) );
+
+	s = File_read( &f, msg.len, &read_amount, (u8*)&buffer ); assert( S_SUCCESSFUL(s) );
+	assert( read_amount == 0 );
+
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+	s = File_delete( (String*)&filename ); assert( S_SUCCESSFUL(s) );
+}
+
+void test_existing_fail_missing_create(void) {
+	usize flags = 
+		FILE_EXISTING_FAIL |
+		FILE_MISSING_CREATE |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE;
+	
+	/* Create */
+	Status s = File_open( (String*)&filename, flags, &f); assert( S_SUCCESSFUL(s) );
+	s = File_write( &f, msg.len, &written_amount, (const u8*)&msg.data ); assert( S_SUCCESSFUL(s) );
+	assert( written_amount == msg.len );
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+
+	/* Open (fail) */
+	s = File_open( (String*)&filename, flags, &f); assert( S_FAILED(s) );
+
+	s = File_delete( (String*)&filename ); assert( S_SUCCESSFUL(s) );
+}
+
+void test_existing_open_missing_fail(void) {
+	usize flags = 
+		FILE_EXISTING_OPEN |
+		FILE_MISSING_FAIL |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE;
+	
+	/* Create */
+	Status s = File_open( (String*)&filename, flags, &f); assert( S_FAILED(s) );
+
+	/* actually create for open */
+	s = File_open( (String*)&filename,
+		FILE_EXISTING_FAIL |
+		FILE_MISSING_CREATE |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE,
+		&f
+	); assert( S_SUCCESSFUL(s) );
+
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+
+	/* Open */
+	s = File_open( (String*)&filename, flags, &f); assert( S_SUCCESSFUL(s) );
+
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+	s = File_delete( (String*)&filename ); assert( S_SUCCESSFUL(s) );
+}
+
+void test_existing_truncate_missing_fail(void) {
+	usize flags = 
+		FILE_EXISTING_TRUNCATE |
+		FILE_MISSING_FAIL |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE;
+	
+	/* Create */
+	Status s = File_open( (String*)&filename, flags, &f); assert( S_FAILED(s) );
+
+	/* actually create for open */
+	s = File_open( (String*)&filename,
+		FILE_EXISTING_FAIL |
+		FILE_MISSING_CREATE |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE,
+		&f
+	); assert( S_SUCCESSFUL(s) );
+	s = File_write( &f, msg.len, &written_amount, (const u8*)&msg.data ); assert( S_SUCCESSFUL(s) );
+	assert( written_amount == msg.len );
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+
+	/* Open (truncate) */
+	s = File_open( (String*)&filename, flags, &f); assert( S_SUCCESSFUL(s) );
+
+	s = File_read( &f, msg.len, &read_amount, (u8*)&buffer ); assert( S_SUCCESSFUL(s) );
+	assert( read_amount == 0 );
+
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+	s = File_delete( (String*)&filename ); assert( S_SUCCESSFUL(s) );
+}
+
+void test_file_access(void) {
+	usize flags = FILE_EXISTING_OPEN | FILE_MISSING_CREATE | FILE_LINK_FAIL;
+
+	Status s = File_open( (String*)&filename, flags | FILE_ACCESS_READ, &f); assert( S_SUCCESSFUL(s) );
+	s = File_write( &f, msg.len, &written_amount, (const u8*)&msg.data ); assert( S_FAILED(s) );
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+	
+	s = File_open( (String*)&filename, flags | FILE_ACCESS_WRITE, &f); assert( S_SUCCESSFUL(s) );
+	s = File_read( &f, msg.len, &read_amount, (u8*)&buffer ); assert( S_FAILED(s) );
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+
+	s = File_open( (String*)&filename, flags | FILE_ACCESS_APPEND, &f); assert( S_SUCCESSFUL(s) );
+	s = File_read( &f, msg.len, &read_amount, (u8*)&buffer ); assert( S_FAILED(s) );
+	s = File_close( &f ); assert( S_SUCCESSFUL(s) );
+}
+
+void test_existing_fail_missing_fail(void) {
+	usize flags = 
+		FILE_EXISTING_FAIL |
+		FILE_MISSING_FAIL |
+		FILE_LINK_FAIL |
+		FILE_ACCESS_READ | FILE_ACCESS_WRITE;
+
+	Status s = File_open( (String*)&filename, flags, &f); assert( S_FAILED(s) );
+}
+
+void test_invalid_combinations(void) {
+
+	usize flags = FILE_EXISTING_OPEN | FILE_MISSING_CREATE | FILE_LINK_FAIL | FILE_ACCESS_READ;
+
+	Status s = File_open( (String*)&filename, flags | FILE_ACCESS_APPEND | FILE_ACCESS_WRITE, &f); assert( S_FAILED(s) );
+	s = File_open( (String*)&filename, flags | FILE_EXISTING_FAIL, &f); assert( S_FAILED(s) );
+	s = File_open( (String*)&filename, flags | FILE_EXISTING_TRUNCATE, &f); assert( S_FAILED(s) );
+	s = File_open( (String*)&filename, flags | FILE_EXISTING_TRUNCATE | FILE_EXISTING_FAIL, &f); assert( S_FAILED(s) );
+
+	s = File_open( (String*)&filename, flags | FILE_MISSING_FAIL, &f); assert( S_FAILED(s) );
+	s = File_open( (String*)&filename, flags | FILE_LINK_FOLLOW, &f); assert( S_FAILED(s) );
+}
+
testing/tests/020_fileview.c → testing/tests/021_fileview.c
File renamed without changes
util/safemath_generic.h
@@ -7,7 +7,7 @@
 
 /* Unsigned addition */
 
-static inline Status u64_add( u64 n1, u64 n2, u64*out ) {
+static inline Status u64_add( u64 n1, u64 n2, u64 *out ) {
 	if( n1 > (u64_MAX) - n2 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -15,7 +15,7 @@ static inline Status u64_add( u64 n1, u64 n2, u64*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status u32_add( u32 n1, u32 n2, u32*out ) {
+static inline Status u32_add( u32 n1, u32 n2, u32 *out ) {
 	if( n1 > (u32_MAX) - n2 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -23,7 +23,7 @@ static inline Status u32_add( u32 n1, u32 n2, u32*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status u16_add( u16 n1, u16 n2, u16*out ) {
+static inline Status u16_add( u16 n1, u16 n2, u16 *out ) {
 	if( n1 > (u16_MAX) - n2 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -31,7 +31,7 @@ static inline Status u16_add( u16 n1, u16 n2, u16*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status u8_add( u8 n1, u8 n2, u8*out ) {
+static inline Status u8_add( u8 n1, u8 n2, u8 *out ) {
 	if( n1 > (u8_MAX) - n2 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -41,7 +41,7 @@ static inline Status u8_add( u8 n1, u8 n2, u8*out ) {
 
 /* Signed addition */
 
-static inline Status s64_add( s64 n1, s64 n2, s64*out ) {
+static inline Status s64_add( s64 n1, s64 n2, s64 *out ) {
 	if( (n1 >= 0 && n2 > s64_MAX - n1) || (n1 < 0 && n2 < s64_MIN - n1) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -49,7 +49,7 @@ static inline Status s64_add( s64 n1, s64 n2, s64*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status s32_add( s32 n1, s32 n2, s32*out ) {
+static inline Status s32_add( s32 n1, s32 n2, s32 *out ) {
 	if( (n1 >= 0 && n2 > s32_MAX - n1) || (n1 < 0 && n2 < s32_MIN - n1) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -57,7 +57,7 @@ static inline Status s32_add( s32 n1, s32 n2, s32*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status s16_add( s16 n1, s16 n2, s16*out ) {
+static inline Status s16_add( s16 n1, s16 n2, s16 *out ) {
 	if( (n1 >= 0 && n2 > s16_MAX - n1) || (n1 < 0 && n2 < s16_MIN - n1) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -65,7 +65,7 @@ static inline Status s16_add( s16 n1, s16 n2, s16*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status s8_add( s8 n1, s8 n2, s8*out ) {
+static inline Status s8_add( s8 n1, s8 n2, s8 *out ) {
 	if( (n1 >= 0 && n2 > s8_MAX - n1) || (n1 < 0 && n2 < s8_MIN - n1) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -75,7 +75,7 @@ static inline Status s8_add( s8 n1, s8 n2, s8*out ) {
 
 /* Unsigned subtraction */
 
-static inline Status u64_sub( u64 n1, u64 n2, u64*out ) {
+static inline Status u64_sub( u64 n1, u64 n2, u64 *out ) {
 	if( n2 > n1 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -83,7 +83,7 @@ static inline Status u64_sub( u64 n1, u64 n2, u64*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status u32_sub( u32 n1, u32 n2, u32*out ) {
+static inline Status u32_sub( u32 n1, u32 n2, u32 *out ) {
 	if( n2 > n1 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -91,7 +91,7 @@ static inline Status u32_sub( u32 n1, u32 n2, u32*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status u16_sub( u16 n1, u16 n2, u16*out ) {
+static inline Status u16_sub( u16 n1, u16 n2, u16 *out ) {
 	if( n2 > n1 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -99,7 +99,7 @@ static inline Status u16_sub( u16 n1, u16 n2, u16*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status u8_sub( u8 n1, u8 n2, u8*out ) {
+static inline Status u8_sub( u8 n1, u8 n2, u8 *out ) {
 	if( n2 > n1 ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -109,7 +109,7 @@ static inline Status u8_sub( u8 n1, u8 n2, u8*out ) {
 
 /* Signed Subtraction */
 
-static inline Status s64_sub( s64 n1, s64 n2, s64*out ) {
+static inline Status s64_sub( s64 n1, s64 n2, s64 *out ) {
 	if( (n2 > 0 && n1 < s64_MIN + n2) || (n2 < 0 && n1 > s64_MAX + n2) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -117,7 +117,7 @@ static inline Status s64_sub( s64 n1, s64 n2, s64*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status s32_sub( s32 n1, s32 n2, s32*out ) {
+static inline Status s32_sub( s32 n1, s32 n2, s32 *out ) {
 	if( (n2 > 0 && n1 < s32_MIN + n2) || (n2 < 0 && n1 > s32_MAX + n2) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -125,7 +125,7 @@ static inline Status s32_sub( s32 n1, s32 n2, s32*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status s16_sub( s16 n1, s16 n2, s16*out ) {
+static inline Status s16_sub( s16 n1, s16 n2, s16 *out ) {
 	if( (n2 > 0 && n1 < s16_MIN + n2) || (n2 < 0 && n1 > s16_MAX + n2) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
@@ -133,7 +133,7 @@ static inline Status s16_sub( s16 n1, s16 n2, s16*out ) {
 	return S_SUCCESS;
 }
 
-static inline Status s8_sub( s8 n1, s8 n2, s8*out ) {
+static inline Status s8_sub( s8 n1, s8 n2, s8 *out ) {
 	if( (n2 > 0 && n1 < s8_MIN + n2) || (n2 < 0 && n1 > s8_MAX + n2) ) {
 		return S_FAILURE | ERR_OVERFLOW;
 	}
.gitignore
@@ -3,3 +3,4 @@ Session.vim
 main.c
 compile_flags.txt
 build
+test.txt
test.txt
@@ -1,1 +0,0 @@
-hello
\ No newline at end of file