Move os layer to be part of the core
This commit is contained in:
133
src/core/os/cpath/cpath.c
Normal file
133
src/core/os/cpath/cpath.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#include "cpath.h"
|
||||
#include "aliases.h"
|
||||
#include "mem_allocator.h"
|
||||
#include "mem_arena_allocator.h"
|
||||
#include "misc_utils.h"
|
||||
#include "str8.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
|
||||
if (!dst || !parts) {
|
||||
return CPATH_JOIN_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (parts->node_count == 0) {
|
||||
return CPATH_JOIN_EMPTY_PARTS;
|
||||
}
|
||||
|
||||
Str8 separator = wapp_str8_buf(4);
|
||||
wapp_str8_push_back(&separator, PATH_SEP);
|
||||
|
||||
u64 required_capacity = parts->node_count * separator.size + parts->total_size;
|
||||
if (dst->capacity < required_capacity) {
|
||||
return CPATH_JOIN_INSUFFICIENT_DST_CAPACITY;
|
||||
}
|
||||
|
||||
// Handle first node
|
||||
const Str8Node *first_node = wapp_str8_list_get(parts, 0);
|
||||
wapp_str8_copy_str8_capped(dst, first_node->string);
|
||||
|
||||
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
||||
// MSVC Spectre mitigation warnings
|
||||
const Str8Node *node = first_node;
|
||||
u64 node_index = 1;
|
||||
bool running = true;
|
||||
while (running && node->next) {
|
||||
node = node->next;
|
||||
if (node->string->size == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dst->size > 0) {
|
||||
char dst_last = wapp_str8_get(dst, dst->size - 1);
|
||||
char node_start = wapp_str8_get(node->string, 0);
|
||||
bool add_path_sep = dst_last != PATH_SEP && node_start != PATH_SEP;
|
||||
|
||||
if (add_path_sep) {
|
||||
wapp_str8_concat_capped(dst, &separator);
|
||||
}
|
||||
}
|
||||
|
||||
wapp_str8_concat_capped(dst, node->string);
|
||||
|
||||
++node_index;
|
||||
running = node_index < parts->node_count;
|
||||
}
|
||||
|
||||
return CPATH_JOIN_SUCCESS;
|
||||
}
|
||||
|
||||
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
|
||||
Str8 *output = NULL;
|
||||
if (!allocator || !path) {
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
bool absolute = wapp_str8_get(path, 0) == PATH_SEP;
|
||||
Str8 separator = wapp_str8_buf(4);
|
||||
wapp_str8_push_back(&separator, PATH_SEP);
|
||||
|
||||
if (path->size == 0) {
|
||||
output = wapp_str8_alloc_buf(allocator, 16);
|
||||
if (!output) {
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
if (levels < 1) {
|
||||
output = wapp_str8_alloc_str8(allocator, path);
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
Allocator tmp_arena = wapp_mem_arena_allocator_init(MB(8));
|
||||
if (wapp_mem_allocator_invalid(&tmp_arena)) {
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
Str8List *parts = wapp_str8_split(&tmp_arena, path, &separator);
|
||||
if (!parts) {
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
if (levels >= parts->node_count) {
|
||||
output = wapp_str8_alloc_buf(allocator, 16);
|
||||
if (!output) {
|
||||
goto LIST_CLEANUP_DIRUP;
|
||||
}
|
||||
|
||||
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
|
||||
} else {
|
||||
for (u64 i = 0; i < levels; ++i) {
|
||||
wapp_str8_list_pop_back(parts);
|
||||
}
|
||||
|
||||
u64 alignment = sizeof(void *) * 2;
|
||||
u64 alloc_size = parts->total_size + parts->node_count * separator.size;
|
||||
u64 modulo = alloc_size & (alignment - 1);
|
||||
alloc_size += alignment - modulo;
|
||||
|
||||
output = wapp_str8_alloc_buf(allocator, alloc_size);
|
||||
if (output) {
|
||||
if (absolute) {
|
||||
wapp_str8_push_back(output, PATH_SEP);
|
||||
}
|
||||
|
||||
Str8 *joined = wapp_str8_join(&tmp_arena, parts, &separator);
|
||||
if (joined) {
|
||||
wapp_str8_concat_capped(output, joined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LIST_CLEANUP_DIRUP:
|
||||
wapp_mem_arena_allocator_destroy(&tmp_arena);
|
||||
|
||||
RETURN_DIRUP:
|
||||
return output;
|
||||
}
|
38
src/core/os/cpath/cpath.h
Normal file
38
src/core/os/cpath/cpath.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef CPATH_H
|
||||
#define CPATH_H
|
||||
|
||||
#include "aliases.h"
|
||||
#include "mem_allocator.h"
|
||||
#include "platform.h"
|
||||
#include "str8.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
BEGIN_C_LINKAGE
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef WAPP_PLATFORM_POSIX
|
||||
#define PATH_SEP '/'
|
||||
#elif defined(WAPP_PLATFORM_WINDOWS)
|
||||
#define PATH_SEP '\\'
|
||||
#else
|
||||
#error "Unrecognised platform"
|
||||
#endif
|
||||
|
||||
#define wapp_cpath_dirname(ALLOCATOR, PATH) dirup(ALLOCATOR, PATH, 1)
|
||||
#define wapp_cpath_dirup(ALLOCATOR, PATH, COUNT) dirup(ALLOCATOR, PATH, COUNT)
|
||||
|
||||
enum {
|
||||
CPATH_JOIN_SUCCESS = 0,
|
||||
CPATH_JOIN_INVALID_ARGS,
|
||||
CPATH_JOIN_EMPTY_PARTS,
|
||||
CPATH_JOIN_INSUFFICIENT_DST_CAPACITY,
|
||||
};
|
||||
|
||||
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts);
|
||||
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels);
|
||||
|
||||
#ifdef __cplusplus
|
||||
END_C_LINKAGE
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // !CPATH_H
|
Reference in New Issue
Block a user