Switch wapp_cpath_join_path to use Str8

This commit is contained in:
Abdelrahman Said 2025-02-22 17:48:25 +00:00
parent ba5e902a1d
commit ed4ec54c7a
4 changed files with 107 additions and 68 deletions

View File

@ -1,5 +1,6 @@
#include "cpath.h" #include "cpath.h"
#include "aliases.h" #include "aliases.h"
#include "str8.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
@ -7,16 +8,48 @@
void join_root_and_leaf(const char *root, const char *leaf, char *dst); void join_root_and_leaf(const char *root, const char *leaf, char *dst);
void join_path(char *dst, u64 count, ...) { u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
va_list args; if (!dst || !parts) {
return CPATH_JOIN_INVALID_ARGS;
va_start(args, count);
for (u64 i = 0; i < count; ++i) {
join_root_and_leaf(dst, va_arg(args, const char *), dst);
} }
va_end(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);
const Str8Node *node = first_node;
for (u64 i = 1; i < parts->node_count; ++i) {
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);
}
return CPATH_JOIN_SUCCESS;
} }
void dirup(char *dst, u64 levels, const char *path) { void dirup(char *dst, u64 levels, const char *path) {

View File

@ -3,6 +3,7 @@
#include "aliases.h" #include "aliases.h"
#include "platform.h" #include "platform.h"
#include "str8.h"
#ifdef __cplusplus #ifdef __cplusplus
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
@ -16,13 +17,17 @@ BEGIN_C_LINKAGE
#error "Unrecognised platform" #error "Unrecognised platform"
#endif #endif
#define NUMPARTS(...) (sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1)
#define wapp_cpath_join_path(DST, ...) join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__)
#define wapp_cpath_dirname(DST, PATH) dirup(DST, 1, PATH) #define wapp_cpath_dirname(DST, PATH) dirup(DST, 1, PATH)
#define wapp_cpath_dirup(DST, COUNT, PATH) dirup(DST, COUNT, PATH) #define wapp_cpath_dirup(DST, COUNT, PATH) dirup(DST, COUNT, PATH)
void join_path(char *dst, u64 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);
void dirup(char *dst, u64 levels, const char *path); void dirup(char *dst, u64 levels, const char *path);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,5 +1,6 @@
#include "test_cpath.h" #include "test_cpath.h"
#include "cpath.h" #include "cpath.h"
#include "str8.h"
#include "tester.h" #include "tester.h"
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -9,77 +10,76 @@
#define TMP_BUF_SIZE 1024 #define TMP_BUF_SIZE 1024
TestFuncResult test_cpath_join_path(void) { TestFuncResult test_cpath_join_path(void) {
char expected[MAIN_BUF_SIZE] = {0}; bool result;
char out[MAIN_BUF_SIZE] = {0};
char tmp[TMP_BUF_SIZE] = {0};
snprintf(expected, MAIN_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
snprintf(tmp, 2, "%c", PATH_SEP); Str8 out = wapp_str8_buf(MAIN_BUF_SIZE);
wapp_cpath_join_path(out, tmp, "home", "abdelrahman", "Documents"); Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
bool result = strcmp(out, expected) == 0; wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
if (!result) { wapp_str8_format(&tmp, "%c", PATH_SEP);
goto TEST_JOIN_PATH_EXIT;
}
memset(out, 0, strlen(out)); Str8List parts = {0};
snprintf(expected, MAIN_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); wapp_str8_list_push_back(&parts, &wapp_str8_node_from_str8(tmp));
wapp_cpath_join_path(out, "home", "abdelrahman", "Documents"); wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("home"));
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("abdelrahman"));
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("Documents"));
result = result && strcmp(out, expected) == 0; wapp_cpath_join_path(&out, &parts);
if (!result) { result = wapp_str8_equal(&out, &expected);
goto TEST_JOIN_PATH_EXIT;
}
memset(out, 0, strlen(out)); wapp_str8_list_pop_front(&parts);
memset(tmp, 0, strlen(tmp));
snprintf(expected, MAIN_BUF_SIZE, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
snprintf(tmp, TMP_BUF_SIZE, "%chome", PATH_SEP);
wapp_cpath_join_path(out, tmp, "abdelrahman", "Documents");
result = result && strcmp(out, expected) == 0; wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
if (!result) {
goto TEST_JOIN_PATH_EXIT;
}
memset(out, 0, strlen(out)); wapp_cpath_join_path(&out, &parts);
memset(tmp, 0, strlen(tmp)); result = result && wapp_str8_equal(&out, &expected);
snprintf(expected, MAIN_BUF_SIZE, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
snprintf(tmp, TMP_BUF_SIZE, "home%c", PATH_SEP);
wapp_cpath_join_path(out, tmp, "abdelrahman", "Documents");
result = result && strcmp(out, expected) == 0; wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("home"));
if (!result) { wapp_str8_list_pop_front(&parts);
goto TEST_JOIN_PATH_EXIT; wapp_str8_list_push_front(&parts, &wapp_str8_node_from_str8(tmp));
}
memset(out, 0, strlen(out)); wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP);
memset(tmp, 0, strlen(tmp));
snprintf(expected, MAIN_BUF_SIZE, "%chome", PATH_SEP);
snprintf(tmp, TMP_BUF_SIZE, "%chome", PATH_SEP);
wapp_cpath_join_path(out, tmp, "");
result = result && strcmp(out, expected) == 0; wapp_cpath_join_path(&out, &parts);
if (!result) { result = result && wapp_str8_equal(&out, &expected);
goto TEST_JOIN_PATH_EXIT;
}
memset(out, 0, strlen(out)); wapp_str8_format(&tmp, "home%c", PATH_SEP);
snprintf(expected, 1, "%s", ""); wapp_str8_list_pop_front(&parts);
wapp_cpath_join_path(out, "", ""); wapp_str8_list_push_front(&parts, &wapp_str8_node_from_cstr("home"));
result = result && strcmp(out, expected) == 0; wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP);
if (!result) {
goto TEST_JOIN_PATH_EXIT;
}
memset(out, 0, strlen(out)); wapp_cpath_join_path(&out, &parts);
snprintf(expected, MAIN_BUF_SIZE, "home"); result = result && wapp_str8_equal(&out, &expected);
wapp_cpath_join_path(out, "", "home");
result = result && strcmp(out, expected) == 0; wapp_str8_list_empty(&parts);
wapp_str8_format(&tmp, "%chome", PATH_SEP);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_str8(tmp));
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr(""));
wapp_str8_format(&expected, "%chome", PATH_SEP);
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_front(&parts);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr(""));
wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
wapp_str8_list_pop_back(&parts);
wapp_str8_list_push_back(&parts, &wapp_str8_node_from_cstr("home"));
wapp_str8_copy_cstr_capped(&expected, "home");
wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected);
TEST_JOIN_PATH_EXIT:
return wapp_tester_result(result); return wapp_tester_result(result);
} }

View File

@ -44,6 +44,7 @@ int main(void) {
test_str8_list_pop_front, test_str8_list_pop_front,
test_str8_list_pop_back, test_str8_list_pop_back,
test_str8_list_remove, test_str8_list_remove,
test_str8_list_empty,
test_cpath_join_path, test_cpath_join_path,
test_cpath_dirname, test_cpath_dirname,
test_cpath_dirup, test_cpath_dirup,