commit 6b8fbb84cba77dc80811dad051b1c4c810ae1406
parent 6d1e33e1549fcdcdbb03c956cd566e35aaaef2bd
Author: Chris Bracken <chris@bracken.jp>
Date: Thu, 19 Feb 2026 14:26:16 +0900
utils: better path_concat
Diffstat:
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/src/utils.c b/src/utils.c
@@ -12,20 +12,35 @@
#include "third_party/openbsd/strlcpy.h"
char* path_concat(const char* p1, const char* p2) {
- size_t p1_len = strlen(p1);
- size_t p2_len = strlen(p2);
- // +1 for '/', +1 for null terminator
- size_t total_len = p1_len + p2_len + 2;
- char* out = ecalloc(total_len, sizeof(char));
-
- if (p1_len == 0) {
- estrlcpy(out, p2, total_len);
- } else if (p2_len == 0) {
- estrlcpy(out, p1, total_len);
- } else {
+ size_t p1_len = p1 ? strlen(p1) : 0;
+ size_t p2_len = p2 ? strlen(p2) : 0;
+
+ if (p1_len == 0) return estrdup(p2 ? p2 : "");
+ if (p2_len == 0) return estrdup(p1);
+
+ bool p1_slash = p1[p1_len - 1] == '/';
+ bool p2_slash = p2[0] == '/';
+
+ char* out;
+ size_t total_len;
+ if (p1_slash && p2_slash) {
+ total_len = p1_len + p2_len;
+ out = ecalloc(total_len, sizeof(char));
+ if (snprintf(out, total_len, "%s%s", p1, p2 + 1) < 0) {
+ err(1, "snprintf");
+ }
+ } else if (!p1_slash && !p2_slash) {
+ total_len = p1_len + p2_len + 2;
+ out = ecalloc(total_len, sizeof(char));
if (snprintf(out, total_len, "%s/%s", p1, p2) < 0) {
err(1, "snprintf");
}
+ } else {
+ total_len = p1_len + p2_len + 1;
+ out = ecalloc(total_len, sizeof(char));
+ if (snprintf(out, total_len, "%s%s", p1, p2) < 0) {
+ err(1, "snprintf");
+ }
}
return out;
}