diff --git a/src/core/cpath/cpath.c b/src/core/cpath/cpath.c index cf66c4f..35b3829 100644 --- a/src/core/cpath/cpath.c +++ b/src/core/cpath/cpath.c @@ -1,18 +1,9 @@ #include "cpath.h" #include "aliases.h" -#include "platform.h" #include #include #include -#ifdef WAPP_PLATFORM_POSIX -internal char path_sep = '/'; -#elif defined(WAPP_PLATFORM_WINDOWS) -internal char path_sep = '\\'; -#else -#error "Unrecognised platform" -#endif - void join_root_and_leaf(const char *root, const char *leaf, char *dst); void join_path(char *dst, u64 count, ...) { @@ -32,21 +23,21 @@ void dirup(char *dst, u64 levels, const char *path) { return; } - u64 end_index = 0; + u64 copy_count = 0; u64 sep_count = 0; u64 full_length; u64 length; length = full_length = strlen(path); - if (path[length - 1] == path_sep) { + if (length > 1 && path[length - 1] == PATH_SEP) { --length; } for (i64 i = length - 1; i >= 0; --i) { - if (path[i] == path_sep) { + if (path[i] == PATH_SEP) { ++sep_count; - end_index = i; + copy_count = i + 1; if (sep_count == levels) { break; @@ -54,37 +45,44 @@ void dirup(char *dst, u64 levels, const char *path) { } } - if (sep_count < levels) { - end_index = 0; + char tmp[256]; + sprintf(tmp, "%c", PATH_SEP); + if (sep_count < levels && strncmp(path, tmp, copy_count) != 0) { + copy_count = 0; } if (dst == path) { - memset(&dst[end_index], 0, full_length - end_index); + memset(&dst[copy_count], 0, full_length - copy_count); } else { u64 dst_length = strlen(dst); memset(dst, 0, dst_length); - strncpy(dst, path, end_index); + 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] = '.'; } } void join_root_and_leaf(const char *root, const char *leaf, char *dst) { u64 root_length = strlen(root); - u64 root_end = root_length - 1; - u64 leaf_length = strlen(leaf); - u64 leaf_start = 0; - if (root[root_end] == path_sep) { - --root_end; + memcpy(dst, root, root_length); + + if (leaf_length == 0) { + return; } - if (leaf[leaf_start] == path_sep) { - ++leaf_start; + u64 copy_start = root_length; + + if (root_length > 0 && root[root_length - 1] != PATH_SEP && leaf[0] != PATH_SEP) { + dst[root_length] = PATH_SEP; + ++copy_start; } - memcpy(dst, root, ++root_end); - - dst[root_end] = path_sep; - - memcpy(&(dst[++root_end]), &(leaf[leaf_start]), leaf_length - leaf_start); + memcpy(&(dst[copy_start]), leaf, leaf_length); } diff --git a/src/core/cpath/cpath.h b/src/core/cpath/cpath.h index ed16c90..64243b2 100644 --- a/src/core/cpath/cpath.h +++ b/src/core/cpath/cpath.h @@ -1,12 +1,21 @@ -#ifndef PATH_UTILS_H -#define PATH_UTILS_H +#ifndef CPATH_H +#define CPATH_H #include "aliases.h" +#include "platform.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 NUMPARTS(...) (sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1) #define wapp_cpath_join_path(DST, ...) join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__) diff --git a/tests/cpath/test_cpath.c b/tests/cpath/test_cpath.c new file mode 100644 index 0000000..61b4d00 --- /dev/null +++ b/tests/cpath/test_cpath.c @@ -0,0 +1,165 @@ +#include "test_cpath.h" +#include "cpath.h" +#include "tester.h" +#include +#include +#include + +TestFuncResult test_cpath_join_path(void) { + char expected[4096] = {0}; + char out[4096] = {0}; + char tmp[1024] = {0}; + + sprintf(expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); + sprintf(tmp, "%c", PATH_SEP); + wapp_cpath_join_path(out, tmp, "home", "abdelrahman", "Documents"); + + bool result = strcmp(out, expected) == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(out, 0, strlen(out)); + sprintf(expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); + wapp_cpath_join_path(out, "home", "abdelrahman", "Documents"); + + result = result && strcmp(out, expected) == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(out, 0, strlen(out)); + memset(tmp, 0, strlen(tmp)); + sprintf(expected, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); + sprintf(tmp, "%chome", PATH_SEP); + wapp_cpath_join_path(out, tmp, "abdelrahman", "Documents"); + + result = result && strcmp(out, expected) == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(out, 0, strlen(out)); + memset(tmp, 0, strlen(tmp)); + sprintf(expected, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); + sprintf(tmp, "home%c", PATH_SEP); + wapp_cpath_join_path(out, tmp, "abdelrahman", "Documents"); + + result = result && strcmp(out, expected) == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(out, 0, strlen(out)); + memset(tmp, 0, strlen(tmp)); + sprintf(expected, "%chome", PATH_SEP); + sprintf(tmp, "%chome", PATH_SEP); + wapp_cpath_join_path(out, tmp, ""); + + result = result && strcmp(out, expected) == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(out, 0, strlen(out)); + sprintf(expected, ""); + wapp_cpath_join_path(out, "", ""); + + result = result && strcmp(out, expected) == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(out, 0, strlen(out)); + sprintf(expected, "home"); + wapp_cpath_join_path(out, "", "home"); + + result = result && strcmp(out, expected) == 0; + + return wapp_tester_result(result); +} + +TestFuncResult test_cpath_dirname(void) { + char buf[4096] = {0}; + char tmp[4096] = {0}; + + wapp_cpath_dirname(buf, "/"); + bool result = strcmp(buf, "/") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + wapp_cpath_dirname(buf, "home"); + result = strcmp(buf, ".") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + wapp_cpath_dirname(buf, ""); + result = strcmp(buf, ".") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + sprintf(tmp, "%chome%ctest", PATH_SEP, PATH_SEP); + wapp_cpath_dirname(buf, tmp); + result = strcmp(buf, "/home") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + memset(tmp, 0, strlen(tmp)); + sprintf(tmp, "%chome%ctest%c", PATH_SEP, PATH_SEP, PATH_SEP); + wapp_cpath_dirname(buf, tmp); + result = strcmp(buf, "/home") == 0; + + return wapp_tester_result(result); +} + +TestFuncResult test_cpath_dirup(void) { + char buf[4096] = {0}; + char tmp[4096] = {0}; + + wapp_cpath_dirup(buf, 3, "/"); + bool result = strcmp(buf, "/") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + sprintf(tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); + wapp_cpath_dirup(buf, 3, tmp); + result = strcmp(buf, "/") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + memset(tmp, 0, strlen(tmp)); + sprintf(tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); + wapp_cpath_dirup(buf, 3, tmp); + result = strcmp(buf, ".") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + sprintf(tmp, "%chome%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP, PATH_SEP); + wapp_cpath_dirup(buf, 2, tmp); + result = strcmp(buf, "/home") == 0; + if (!result) { + return wapp_tester_result(result); + } + + memset(buf, 0, strlen(buf)); + memset(tmp, 0, strlen(tmp)); + sprintf(tmp, "home%cabdelrahman%cDocuments", PATH_SEP, PATH_SEP); + wapp_cpath_dirup(buf, 2, tmp); + result = strcmp(buf, "home") == 0; + + return wapp_tester_result(result); +} diff --git a/tests/cpath/test_cpath.h b/tests/cpath/test_cpath.h new file mode 100644 index 0000000..1584876 --- /dev/null +++ b/tests/cpath/test_cpath.h @@ -0,0 +1,18 @@ +#ifndef TEST_CPATH_H +#define TEST_CPATH_H + +#include "tester.h" + +#ifdef __cplusplus +BEGIN_C_LINKAGE +#endif // __cplusplus + +TestFuncResult test_cpath_join_path(void); +TestFuncResult test_cpath_dirname(void); +TestFuncResult test_cpath_dirup(void); + +#ifdef __cplusplus +END_C_LINKAGE +#endif // __cplusplus + +#endif // !TEST_CPATH_H diff --git a/tests/wapptest.c b/tests/wapptest.c index 04e6fbe..fba7127 100644 --- a/tests/wapptest.c +++ b/tests/wapptest.c @@ -1,15 +1,17 @@ #include "test_allocator.h" #include "test_arena.h" +#include "test_cpath.h" #include "test_shell_commander.h" #include "tester.h" #include int main(void) { wapp_tester_run_tests(test_libc_allocator, test_arena_allocator, test_arena_init, - test_arena_init_succeeds_when_reserving_very_large_size, - test_arena_alloc_succeeds_when_within_capacity, test_arena_alloc_fails_when_over_capacity, - test_arena_realloc_bigger_size, test_arena_realloc_smaller_size, test_arena_clear, - test_arena_destroy, test_commander_cmd_success, test_commander_cmd_failure, + test_arena_init_succeeds_when_reserving_very_large_size, test_cpath_join_path, + test_cpath_dirname, test_cpath_dirup, test_arena_alloc_succeeds_when_within_capacity, + test_arena_alloc_fails_when_over_capacity, test_arena_realloc_bigger_size, + test_arena_realloc_smaller_size, test_arena_clear, test_arena_destroy, + test_commander_cmd_success, test_commander_cmd_failure, test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_failure); return EXIT_SUCCESS;