gout

A static git page generator
git clone https://git.bracken.jp/gout.git
Log | Files | Refs | README | LICENSE

commit 6b8fbb84cba77dc80811dad051b1c4c810ae1406
parent 6d1e33e1549fcdcdbb03c956cd566e35aaaef2bd
Author: Chris Bracken <chris@bracken.jp>
Date:   Thu, 19 Feb 2026 14:26:16 +0900

utils: better path_concat

Diffstat:
Msrc/utils.c | 37++++++++++++++++++++++++++-----------
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; }