Replace char * with Str8 in cpath dirup
This commit is contained in:
parent
d9314fb41e
commit
dbedcb3100
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "test_cpath.h"
|
||||
#include "cpath.h"
|
||||
#include "mem_allocator.h"
|
||||
#include "mem_arena_allocator.h"
|
||||
#include "misc_utils.h"
|
||||
#include "str8.h"
|
||||
#include "tester.h"
|
||||
#include <string.h>
|
||||
@ -84,100 +87,101 @@ TestFuncResult test_cpath_join_path(void) {
|
||||
}
|
||||
|
||||
TestFuncResult test_cpath_dirname(void) {
|
||||
char dst[MAIN_BUF_SIZE] = {0};
|
||||
char expected[MAIN_BUF_SIZE] = {0};
|
||||
char tmp[TMP_BUF_SIZE] = {0};
|
||||
|
||||
snprintf(tmp, 2, "%c", PATH_SEP);
|
||||
wapp_cpath_dirname(dst, tmp);
|
||||
bool result = strcmp(dst, tmp) == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRNAME_EXIT;
|
||||
Allocator arena = wapp_mem_arena_allocator_init(MB(8));
|
||||
if (wapp_mem_allocator_invalid(&arena)) {
|
||||
return wapp_tester_result(false);
|
||||
}
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
wapp_cpath_dirname(dst, "home");
|
||||
result = strcmp(dst, ".") == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRNAME_EXIT;
|
||||
}
|
||||
bool result;
|
||||
Str8 *output = NULL;
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
wapp_cpath_dirname(dst, "");
|
||||
result = strcmp(dst, ".") == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRNAME_EXIT;
|
||||
}
|
||||
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
|
||||
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
snprintf(tmp, TMP_BUF_SIZE, "%chome%ctest", PATH_SEP, PATH_SEP);
|
||||
snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
|
||||
wapp_cpath_dirname(dst, tmp);
|
||||
result = strcmp(dst, expected) == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRNAME_EXIT;
|
||||
}
|
||||
// CASE 1
|
||||
wapp_str8_format(&tmp, "%c", PATH_SEP);
|
||||
wapp_str8_format(&expected, "%c", PATH_SEP);
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
memset(tmp, 0, strlen(tmp));
|
||||
memset(expected, 0, strlen(expected));
|
||||
snprintf(tmp, TMP_BUF_SIZE, "%chome%ctest%c", PATH_SEP, PATH_SEP, PATH_SEP);
|
||||
snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
|
||||
wapp_cpath_dirname(dst, tmp);
|
||||
result = strcmp(dst, expected) == 0;
|
||||
output = wapp_cpath_dirname(&arena, &tmp);
|
||||
result = output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 2
|
||||
wapp_str8_format(&expected, "%s", ".");
|
||||
|
||||
output = wapp_cpath_dirname(&arena, &wapp_str8_lit("home"));
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 3
|
||||
output = wapp_cpath_dirname(&arena, &wapp_str8_lit(""));
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 4
|
||||
wapp_str8_format(&tmp, "%chome%ctest", PATH_SEP, PATH_SEP);
|
||||
wapp_str8_format(&expected, "%chome", PATH_SEP);
|
||||
|
||||
output = wapp_cpath_dirname(&arena, &tmp);
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 5
|
||||
wapp_str8_format(&tmp, "%chome%ctest%c", PATH_SEP, PATH_SEP, PATH_SEP);
|
||||
wapp_str8_format(&expected, "%chome", PATH_SEP);
|
||||
|
||||
output = wapp_cpath_dirname(&arena, &tmp);
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
wapp_mem_arena_allocator_destroy(&arena);
|
||||
|
||||
TEST_DIRNAME_EXIT:
|
||||
return wapp_tester_result(result);
|
||||
}
|
||||
|
||||
TestFuncResult test_cpath_dirup(void) {
|
||||
char dst[MAIN_BUF_SIZE] = {0};
|
||||
char expected[MAIN_BUF_SIZE] = {0};
|
||||
char tmp[TMP_BUF_SIZE] = {0};
|
||||
|
||||
snprintf(tmp, 2, "%c", PATH_SEP);
|
||||
wapp_cpath_dirup(dst, 3, tmp);
|
||||
bool result = strcmp(dst, tmp) == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRUP_EXIT;
|
||||
Allocator arena = wapp_mem_arena_allocator_init(MB(8));
|
||||
if (wapp_mem_allocator_invalid(&arena)) {
|
||||
return wapp_tester_result(false);
|
||||
}
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
memset(tmp, 0, strlen(tmp));
|
||||
snprintf(tmp, TMP_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
|
||||
snprintf(expected, MAIN_BUF_SIZE, "%c", PATH_SEP);
|
||||
wapp_cpath_dirup(dst, 3, tmp);
|
||||
result = strcmp(dst, expected) == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRUP_EXIT;
|
||||
}
|
||||
bool result;
|
||||
Str8 *output = NULL;
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
memset(tmp, 0, strlen(tmp));
|
||||
snprintf(tmp, TMP_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
|
||||
wapp_cpath_dirup(dst, 3, tmp);
|
||||
result = strcmp(dst, ".") == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRUP_EXIT;
|
||||
}
|
||||
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
|
||||
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
memset(tmp, 0, strlen(tmp));
|
||||
memset(expected, 0, strlen(expected));
|
||||
snprintf(tmp, TMP_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
|
||||
snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
|
||||
wapp_cpath_dirup(dst, 2, tmp);
|
||||
result = strcmp(dst, expected) == 0;
|
||||
if (!result) {
|
||||
goto TEST_DIRUP_EXIT;
|
||||
}
|
||||
// CASE 1
|
||||
wapp_str8_format(&tmp, "%c", PATH_SEP);
|
||||
wapp_str8_format(&expected, "%c", PATH_SEP);
|
||||
|
||||
memset(dst, 0, strlen(dst));
|
||||
memset(tmp, 0, strlen(tmp));
|
||||
snprintf(tmp, TMP_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
|
||||
wapp_cpath_dirup(dst, 2, tmp);
|
||||
result = strcmp(dst, "home") == 0;
|
||||
output = wapp_cpath_dirup(&arena, &tmp, 3);
|
||||
result = output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 2
|
||||
wapp_str8_format(&tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
|
||||
wapp_str8_format(&expected, "%c", PATH_SEP);
|
||||
|
||||
output = wapp_cpath_dirup(&arena, &tmp, 3);
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 3
|
||||
wapp_str8_format(&tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
|
||||
wapp_str8_copy_cstr_capped(&expected, ".");
|
||||
|
||||
output = wapp_cpath_dirup(&arena, &tmp, 3);
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 4
|
||||
wapp_str8_format(&tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
|
||||
wapp_str8_format(&expected, "%chome", PATH_SEP);
|
||||
|
||||
output = wapp_cpath_dirup(&arena, &tmp, 2);
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
// CASE 5
|
||||
wapp_str8_format(&tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
|
||||
wapp_str8_copy_cstr_capped(&expected, "home");
|
||||
|
||||
output = wapp_cpath_dirup(&arena, &tmp, 2);
|
||||
result = result && output != NULL && wapp_str8_equal(output, &expected);
|
||||
|
||||
wapp_mem_arena_allocator_destroy(&arena);
|
||||
|
||||
TEST_DIRUP_EXIT:
|
||||
return wapp_tester_result(result);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user