file system rewrite + more

This commit is contained in:
Abdulmujeeb Raji 2025-02-18 09:36:53 +00:00
parent 19c45cca31
commit 1b1af5ff85
Signed by: midnadimple
GPG key ID: EB02C582F8C3962B
8 changed files with 192 additions and 120 deletions

View file

@ -11,68 +11,34 @@ struct Buffer {
#define BUFFER(raw, cap) ((Buffer){raw, cap, 0, FALSE})
typedef enum BufferOutputType BufferOutputType;
enum BufferOutputType {
BufferOutputType_string = 0,
BufferOutputType_file,
};
typedef struct BufferOutput BufferOutput;
struct BufferOutput {
BufferOutputType type;
union {
S8 str;
int fd;
} data;
};
FUNCTION void
Buffer_flush(Buffer *b, BufferOutput out)
{
switch (out.type) {
case BufferOutputType_string: {
b->error |= out.data.str.len < b->len;
m_memoryCopy(out.data.str.raw, b->raw, out.data.str.len);
} break;
case BufferOutputType_file: {
b->error |= out.data.fd < 0;
b->error |= !os_write(out.data.fd, b->raw, b->len);
} break;
}
b->len = 0;
}
// Utility
FUNCTION S8
Buffer_buildS8(Buffer *b, m_Allocator *perm)
{
S8 res = S8_alloc(b->len, perm);
BufferOutput out = {0};
out.type = BufferOutputType_string;
out.data.str = res;
b->error |= res.len < b->len;
m_memoryCopy(res.raw, b->raw, res.len);
Buffer_flush(b, out);
b->len = 0;
return res;
}
FUNCTION void
Buffer_standardOutput(Buffer *b)
{
BufferOutput output = {0};
output.type = BufferOutputType_file;
output.data.fd = 1;
Buffer_flush(b, output);
os_File stdout = os_getStdout();
b->error |= !os_writeFile(stdout, b->raw, b->len);
b->len = 0;
}
FUNCTION void
Buffer_fileOutput(Buffer *b, S8 filename)
{
BufferOutput output = {0};
output.type = BufferOutputType_file;
output.data.fd = os_openFile(filename.raw, TRUE);
Buffer_flush(b, output);
os_closeFile(output.data.fd);
os_File file = os_openFile(filename.raw);
b->error |= !os_writeFile(file, b->raw, b->len);
os_closeFile(file);
b->len = 0;
}
FUNCTION void
@ -115,6 +81,26 @@ Buffer_appendI64(Buffer *b, I64 x)
Buffer_append(b, beg, end-beg);
}
FUNCTION void
Buffer_appendU64Hex(Buffer *b, U64 x)
{
U8 tmp[64];
U8 *end = tmp + sizeof(tmp);
U8 *beg = end;
do {
char remainder = x % 16;
char c = 0;
if (remainder > 9) {
c = remainder +55;
} else {
c = remainder + '0';
}
*--beg = c;
} while (x /= 16);
Buffer_appendS8(b, S8("0x"));
Buffer_append(b, beg, end-beg);
}
FUNCTION void
Buffer_appendPtr(Buffer *b, void *p)
{
@ -155,25 +141,26 @@ Buffer_appendF64(Buffer *b, F64 x, U64 num_decimals)
FUNCTION void
Buffer_appendFile(Buffer *b, S8 filename, m_Allocator *perm)
{
int fd = os_openFile(filename.raw, FALSE);
U32 file_size = (U32)os_getFileSize(fd);
os_File file = os_openFile(filename.raw);
U8 *data = m_MAKE(U8, file_size, perm);
b->error |= os_read(fd, data, (int)file_size, &file_size);
Buffer_append(b, data, file_size);
U8 *data = m_MAKE(U8, file.size, perm);
b->error |= os_readFile(file, data, (int)file.size, &file.size);
Buffer_append(b, data, file.size);
os_closeFile(fd);
m_RELEASE(data, file_size, perm);
os_closeFile(file);
if (!file.already_exists) {
os_deleteFile(file);
}
m_RELEASE(data, file.size, perm);
}
FUNCTION void
Buffer_appendStandardInput(Buffer *b, U64 max_read_size, m_Allocator *perm)
{
int stdin_fd = 0;
U32 len = 0;
int len = 0;
U8 *data = m_MAKE(U8, max_read_size, perm);
b->error |= os_read(stdin_fd, data, (int)max_read_size, &len);
os_File stdin = os_getStdin();
b->error |= os_readFile(stdin, data, (int)max_read_size, &len);
Buffer_append(b, data, len);
// NOTE maybe we should switch to sl_U8 so theres no max length for stdin

View file

@ -3,11 +3,19 @@
FUNCTION void os_abort(char *msg);
FUNCTION void *os_alloc(U64 cap);
FUNCTION B8 os_write(int fd, U8 *buf, int len);
FUNCTION B8 os_read(int fd, U8 *buf, int len, U32 *bytes_read);
FUNCTION U64 os_getFileSize(int fd);
FUNCTION int os_openFile(U8 *filename, B8 always_create);
FUNCTION B8 os_closeFile(int fd);
typedef struct os_File os_File;
struct os_File; // Depends on the OS. Always tells you if the file existed before being opened
FUNCTION os_File os_openFile(U8 *filename);
FUNCTION os_File os_getStdout(void);
FUNCTION os_File os_getStdin(void);
FUNCTION B8 os_deleteFile(os_File file);
FUNCTION B8 os_closeFile(os_File file);
FUNCTION B8 os_readFile(os_File file, U8 *buf, int len, U32 *bytes_read);
FUNCTION B8 os_writeFile(os_File file, U8 *buf, int len);
typedef struct os_Thread os_Thread;
struct os_Thread; // Depends on the OS
@ -36,7 +44,8 @@ enum {
};
CALLBACK_EXPORT os_ErrorCode os_entry(void);
FUNCTION U64 os_rdtsc(void);
// Handle microseconds using U64
FUNCTION U64 os_wallclock(void);
#if defined(OS_WINDOWS)

View file

@ -25,66 +25,83 @@ os_alloc(U64 cap)
return VirtualAlloc(NIL, cap, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}
FUNCTION B8
os_write(int fd, U8 *buf, int len)
{
HANDLE h = GetStdHandle(-10 - fd);
if (h == INVALID_HANDLE_VALUE) {
h = (HANDLE)_get_osfhandle(fd);
}
if (h == INVALID_HANDLE_VALUE) {
return FALSE;
}
U32 dummy;
return WriteFile(h, buf, len, &dummy, 0);
}
struct os_File {
U8 *name;
HANDLE raw;
U64 size;
B8 already_exists;
};
FUNCTION B8
os_read(int fd, U8 *buf, int len, U32 *bytes_read)
FUNCTION os_File
os_openFile(U8 *filename)
{
HANDLE h = GetStdHandle(-10 - fd);
if (h != INVALID_HANDLE_VALUE) {
// This *should be* stdin
ASSERT(fd == 0, "fd is 0 for stdin");
os_File res = {0};
B8 res = ReadConsole(h, buf, len, bytes_read, NIL);
return res;
} else {
h = (HANDLE)_get_osfhandle(fd);
return ReadFile(h, buf, len, bytes_read, 0);
}
}
res.name = filename;
FUNCTION U64
os_getFileSize(int fd)
{
HANDLE h = GetStdHandle(-10 - fd);
if (h == INVALID_HANDLE_VALUE) {
// This is a real file
h = (HANDLE)_get_osfhandle(fd);
U32 attribs = GetFileAttributes(res.name);
res.already_exists = (attribs != INVALID_FILE_ATTRIBUTES &&
!(attribs & FILE_ATTRIBUTE_DIRECTORY));
DWORD open_style = CREATE_NEW;
if (res.already_exists) {
open_style = OPEN_EXISTING;
}
res.raw = CreateFileA(res.name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, 0, open_style, FILE_ATTRIBUTE_NORMAL, 0);
LARGE_INTEGER file_size;
GetFileSizeEx(h, &file_size);
return (U64)file_size.QuadPart;
GetFileSizeEx(res.raw, &file_size);
res.size = (U64)file_size.QuadPart;
return res;
}
FUNCTION int
os_openFile(U8 *filename, B8 always_create)
FUNCTION os_File
os_getStdout(void)
{
U32 open_style = OPEN_EXISTING;
if (always_create) {
open_style = CREATE_ALWAYS;
os_File res = {0};
res.already_exists = TRUE;
res.name = "stdout";
res.size = KILO(1);
res.raw = GetStdHandle((U32)(-11));
return res;
}
HANDLE file = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, 0, open_style, 0, 0);
return _open_osfhandle((intptr_t)file, 0);
FUNCTION os_File
os_getStdin(void)
{
os_File res = {0};
res.already_exists = TRUE;
res.name = "stdin";
res.size = KILO(1);
res.raw = GetStdHandle((U32)(-10));
return res;
}
FUNCTION B8
os_closeFile(int fd)
os_deleteFile(os_File file)
{
return _close(fd);
return DeleteFileA(file.name);
}
FUNCTION B8
os_closeFile(os_File file)
{
return CloseHandle(file.raw);
}
FUNCTION B8
os_writeFile(os_File file, U8 *buf, int len)
{
U32 dummy;
return WriteFile(file.raw, buf, len, &dummy, 0);
}
FUNCTION B8
os_readFile(os_File file, U8 *buf, int len, U32 *bytes_read)
{
return ReadFile(file.raw, buf, len, bytes_read, 0);
}
FUNCTION char **
@ -181,9 +198,14 @@ os_Semaphore_wait(os_Semaphore semaphore)
}
FUNCTION U64
os_rdtsc(void)
os_wallclock(void)
{
return __rdtsc();
LARGE_INTEGER count, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&count);
U64 res = (count.QuadPart * 1000000) / freq.QuadPart;
return res;
}
#if defined(BASTD_CLI)

View file

@ -24,10 +24,10 @@ rand_generateSeed(U64 x)
FUNCTION U64
rand_next(void)
{
U64 rdtscp_val = os_rdtsc();
U64 wallclock = os_wallclock();
for (int i = 0; i < COUNT_OF(rand_seed); i++) {
if (rand_seed[i] == 0) {
rand_seed[i] = rand_generateSeed(rdtscp_val);
rand_seed[i] = rand_generateSeed(wallclock);
}
}

View file

@ -1,10 +1,25 @@
// GENERIC FILE, REDEFINED ON EVERY INCLUDE
// Shared by all generic types
#ifndef BASTD_SLICE_C
#defien BASTD_SLICE_C
typedef enum slice_CompareResult slice_CompareResult;
enum slice_CompareResult {
slice_CompareResult_first_elem_less = -1,
slice_CompareResult_equal = 0,
slice_CompareResult_first_elem_greater = 1,
};
#endif//BASTD_SLICE_C
// GENERIC SECTION, REDEFINED ON EVERY INCLUDE
#ifndef sl_TYPE
#error "No sl_TYPE given"
#endif
#define sl_NAME CONCAT(sl_, sl_TYPE)
#include "rand.c"
typedef struct sl_NAME sl_NAME;
struct sl_NAME {
sl_TYPE *elems;
@ -45,5 +60,39 @@ CONCAT(sl_NAME, _pop) (sl_NAME *slice)
return *(slice->elems + --slice->len);
}
FUNCTION sl_TYPE*
CONCAT(sl_NAME, _get) (sl_NAME slice, U64 idx)
{
if (idx >= slice.len) {
// TODO not sure what the appropriate error handling is here
return NIL;
}
return slice.elems + idx;
}
typedef slice_CompareResult (* CONCAT(sl_NAME, _CompareProc))(sl_TYPE, sl_TYPE);
FUNCTION void
CONCAT(sl_NAME, _sort) (sl_NAME *slice, CONCAT(sl_NAME, _CompareProc) compare_proc)
{
// QuickSort
if (slice->len < 2) {
return;
}
U64 pivot_idx = rand_next() % slice->len;
sl_NAME
for (int i = 0; i < slice->len; i++) {
sl_TYPE val = slice->elems[i];
slice_CompareResult cmp = compare_proc(val, slice->elems[pivot_idx]);
if (cmp == slice_CompareResult_first_elem_less) {
} else {
}
}
}
#undef sl_NAME
#undef sl_TYPE

View file

@ -6,12 +6,11 @@ struct S8 {
U64 len;
U8 *raw;
};
#define S8(s) (S8){.len = LENGTH_OF(s), .raw = (U8 *)s}
#define sl_TYPE S8
#include "slice.c"
#define S8(s) (S8){.len = LENGTH_OF(s), .raw = (U8 *)s}
FUNCTION S8
S8_alloc(U64 len, m_Allocator *perm)
{
@ -107,6 +106,12 @@ S8_equal(S8 a, S8 b)
return m_memoryDifference(a.raw, b.raw, a.len) == 0;
}
FUNCTION B8
S8_empty(S8 s)
{
return S8_equal(s, (S8){.len = 0, .raw = NIL});
}
FUNCTION S8
S8_view(S8 s, U64 start, U64 end)
{

View file

@ -13,6 +13,6 @@ REM cl ..\bastd\examples\buffer.c %debugflags%
REM cl ..\bastd\examples\job_random.c %debugflags%
REM This builds your application with debug symbols.
cl ..\main.c %debugflags%
REM cl ..\main.c %debugflags%
popd