Replace char * with Str8 in cpath dirup

This commit is contained in:
2025-02-22 22:09:04 +00:00
parent d9314fb41e
commit dbedcb3100
3 changed files with 149 additions and 121 deletions

View File

@@ -1,5 +1,8 @@
#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>
@@ -59,56 +62,76 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
return CPATH_JOIN_SUCCESS;
}
void dirup(char *dst, u64 levels, const char *path) {
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) {
return;
output = wapp_str8_alloc_str8(allocator, path);
goto RETURN_DIRUP;
}
u64 copy_count = 0;
u64 sep_count = 0;
u64 full_length;
u64 length;
length = full_length = strlen(path);
if (length > 1 && path[length - 1] == PATH_SEP) {
--length;
Allocator tmp_arena = wapp_mem_arena_allocator_init(MB(8));
if (wapp_mem_allocator_invalid(&tmp_arena)) {
goto RETURN_DIRUP;
}
for (i64 i = length - 1; i >= 0; --i) {
if (path[i] == PATH_SEP) {
++sep_count;
copy_count = i + 1;
Str8List *parts = wapp_str8_split(&tmp_arena, path, &separator);
if (!parts) {
goto RETURN_DIRUP;
}
if (sep_count == levels) {
break;
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);
}
}
}
char tmp[256];
snprintf(tmp, 2, "%c", PATH_SEP);
// NOTE (Abdelrahman): Conditions stored in variables to silence MSVC warning C5045
bool insufficient_levels = sep_count < levels;
bool path_to_copy_is_separator = strncmp(path, tmp, copy_count) != 0;
if (insufficient_levels && path_to_copy_is_separator) {
copy_count = 0;
}
LIST_CLEANUP_DIRUP:
wapp_mem_arena_allocator_destroy(&tmp_arena);
if (dst == path) {
memset(&dst[copy_count], 0, full_length - copy_count);
} else {
u64 dst_length = strlen(dst);
memset(dst, 0, dst_length);
strncpy(dst, path, copy_count);
}
u64 final_length = strlen(dst);
if (final_length > 1) {
dst[final_length - 1] = '\0';
} else if (final_length == 0) {
dst[0] = '.';
}
RETURN_DIRUP:
return output;
}
void join_root_and_leaf(const char *root, const char *leaf, char *dst) {

View File

@@ -2,6 +2,7 @@
#define CPATH_H
#include "aliases.h"
#include "mem_allocator.h"
#include "platform.h"
#include "str8.h"
@@ -17,8 +18,8 @@ BEGIN_C_LINKAGE
#error "Unrecognised platform"
#endif
#define wapp_cpath_dirname(DST, PATH) dirup(DST, 1, PATH)
#define wapp_cpath_dirup(DST, COUNT, PATH) dirup(DST, COUNT, PATH)
#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,
@@ -28,7 +29,7 @@ enum {
};
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts);
void dirup(char *dst, u64 levels, const char *path);
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels);
#ifdef __cplusplus
END_C_LINKAGE