Add path utilities
This commit is contained in:
parent
226d6f9359
commit
362b1b33d5
18
include/path_utils.h
Normal file
18
include/path_utils.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef PATH_UTILS_H
|
||||||
|
#define PATH_UTILS_H
|
||||||
|
|
||||||
|
#include "aliases.h"
|
||||||
|
|
||||||
|
#define NUMPARTS(...) \
|
||||||
|
(sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1)
|
||||||
|
|
||||||
|
#define JOIN_PATH(DST, ...) join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__)
|
||||||
|
|
||||||
|
void join_path(char *dst, u64 count, ...);
|
||||||
|
|
||||||
|
#define DIRNAME(DST, PATH) dirup(DST, 1, PATH)
|
||||||
|
#define DIRUP(DST, COUNT, PATH) dirup(DST, COUNT, PATH)
|
||||||
|
|
||||||
|
void dirup(char *dst, u64 levels, const char *path);
|
||||||
|
|
||||||
|
#endif // !PATH_UTILS_H
|
76
src/path_utils.c
Normal file
76
src/path_utils.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include "path_utils.h"
|
||||||
|
#include "aliases.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(__APPLE__) || defined(__ANDROID__)
|
||||||
|
INTERNAL char path_sep = '/';
|
||||||
|
#elif defined(_WIN32) || defined(_WIN64)
|
||||||
|
INTERNAL char path_sep = '\';
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void join_root_and_leaf(const char *root, const char *leaf, char *dst);
|
||||||
|
|
||||||
|
void join_path(char *dst, u64 count, ...) {
|
||||||
|
va_list 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dirup(char *dst, u64 levels, const char *path) {
|
||||||
|
if (levels < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 end_index = 0;
|
||||||
|
u64 sep_count = 0;
|
||||||
|
|
||||||
|
u64 length = strlen(path);
|
||||||
|
if (path[length - 1] == path_sep) {
|
||||||
|
--length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u64 i = length - 1; i >= 0; --i) {
|
||||||
|
if (path[i] == path_sep) {
|
||||||
|
++sep_count;
|
||||||
|
end_index = i;
|
||||||
|
|
||||||
|
if (sep_count == levels) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sep_count < levels) {
|
||||||
|
end_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(dst, path, end_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leaf[leaf_start] == path_sep) {
|
||||||
|
++leaf_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(dst, root, ++root_end);
|
||||||
|
dst[root_end] = path_sep;
|
||||||
|
strncpy(&(dst[++root_end]), &(leaf[leaf_start]), leaf_length - leaf_start);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user