summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2026-03-23 23:30:18 +0800
committerSadeep Madurange <sadeep@asciimx.com>2026-03-23 23:31:55 +0800
commitc54970aed7e1ecbec194863dc42484075a77bcbe (patch)
tree21dd3e959bda79a21b67115b8088c8c3d7aa98f1
parente8f2f497caffed1daa9c2e5125216d7f6d0430ce (diff)
downloadcvn-c54970aed7e1ecbec194863dc42484075a77bcbe.tar.gz
Remove concat function and use snprintf wrapper.
-rw-r--r--main.c144
1 files changed, 59 insertions, 85 deletions
diff --git a/main.c b/main.c
index 2b724c4..5202715 100644
--- a/main.c
+++ b/main.c
@@ -3,6 +3,7 @@
#include <fcntl.h>
#include <fnmatch.h>
#include <ftw.h>
+#include <limits.h>
#include <sha1.h>
#include <stdarg.h>
#include <stdio.h>
@@ -18,10 +19,10 @@
#define EXCLUDE_PATHS ".vcxignore"
-#define BUF_LEN 8192
-#define MAX_DEPTH 256
-#define MAX_PATH_LEN 4096
-#define HASH_LEN SHA1_DIGEST_STRING_LENGTH
+#define MAX_DEPTH 256
+#define BUF_LEN 8192
+#define PATH_LEN PATH_MAX
+#define HASH_LEN SHA1_DIGEST_STRING_LENGTH
#define KIND_DEL 'D'
#define KIND_MOD 'M'
@@ -44,15 +45,15 @@ static inline void print_status(const char *file, char kind, int islnk);
static inline int scan_head(const char * path, const struct stat *st, int flag, struct FTW *ftwbuf);
static inline int scan_tree(const char * path, const struct stat *st, int flag, struct FTW *ftwbuf);
-static inline void mkcopy(const char *path, char dst[HASH_LEN]);
-static inline void mklink(const char *src, const char obj[HASH_LEN]);
+static inline void mkcopy(const char *path, char *dst);
+static inline void mklink(const char *src, const char *obj);
static inline void mkdirs(const char *path);
static inline void copy_link(const char *src);
static inline void copy_file(const char *src, const char *dst);
static inline int lnklen(const char *lnk);
-static inline void concat(char *dst, size_t n, const char *arg1, ...);
+static inline char *format_path(const char *fmt, ...);
static inline void *_xmalloc(size_t s, const char *file, int line);
static inline void *_xrealloc(void *ptr, size_t s, const char *file, int line);
@@ -120,7 +121,7 @@ static inline void add(int argc, char *argv[])
{
size_t i;
struct stat st;
- char *wt_path;
+ char *wt_path, *hd_path;
if (argc < 2)
errx(1, "Usage: %s [<files>]", argv[0]);
@@ -133,14 +134,8 @@ static inline void add(int argc, char *argv[])
if (lstat(wt_path, &st) == -1)
err(1, "%s", wt_path);
- size_t hd_sz = strlen(HEAD) + strlen(wt_path) + 2;
- char hd_path[hd_sz];
- concat(hd_path, hd_sz, HEAD, "/", wt_path, NULL);
+ hd_path = format_path("%s/%s", HEAD, wt_path);
- size_t tmp_sz = strlen(TMP_DIR) + strlen(wt_path) + 2;
- char tmp_path[tmp_sz];
- concat(tmp_path, tmp_sz, TMP_DIR, "/", wt_path, NULL);
-
if (nftw(hd_path, scan_head, MAX_DEPTH, FTW_PHYS) == -1)
err(1, "Failed to scan head");
@@ -152,14 +147,12 @@ static inline void add(int argc, char *argv[])
int scan_head(const char * path, const struct stat *sb, int flag,
struct FTW *ftwbuf)
{
+ char *wt_path;
struct stat wt_stat;
if (flag == FTW_F) {
const char *filename = path + ftwbuf->base;
-
- size_t wt_sz = strlen(filename) + 3;
- char wt_path[wt_sz];
- concat(wt_path, wt_sz, ".", "/", filename, NULL);
+ wt_path = format_path("./%s", filename);
if (lstat(wt_path, &wt_stat) == -1) {
if (errno == ENOENT) {
@@ -190,16 +183,14 @@ int scan_head(const char * path, const struct stat *sb, int flag,
static inline int scan_tree(const char * path, const struct stat *st,
int flag, struct FTW *ftwbuf)
{
+ char *hd_path;
+
if (fnmatch("./.vcx/*", path, 0) == 0)
return 0;
if (flag == FTW_F) {
const char *filename = path + ftwbuf->base;
-
- size_t hd_sz = strlen(HEAD) + strlen(filename) + 2;
- char hd_path[hd_sz];
- concat(hd_path, hd_sz, HEAD, "/", filename, NULL);
-
+ hd_path = format_path("%s/%s", HEAD, filename);
if (access(hd_path, F_OK) != 0)
scan_res_cb(path, KIND_NEW, S_ISLNK(st->st_mode) != 0);
}
@@ -304,36 +295,31 @@ static inline void stage_entry(const char *path, char kind, int islnk)
}
}
-static inline void mkcopy(const char *path, char dst[HASH_LEN])
+static inline void mkcopy(const char *path, char *dst)
{
- int len, obj_len;
- char obj_name[HASH_LEN];
+ int len;
+ char *obj_path;
len = strlen(path);
- obj_len = HASH_LEN - 1;
- if (SHA1Data((const uint8_t *)path, len, obj_name) == NULL)
+
+ if (SHA1Data((const uint8_t *)path, len, dst) == NULL)
err(1, "Failed to compute hash for %s", path);
- size_t obj_sz = strlen(OBJ_DIR) + obj_len + 6;
- char obj_path[obj_sz];
- concat(obj_path, obj_sz, OBJ_DIR, "/", obj_name, ".tmp", NULL);
+ obj_path = format_path("%s/%s.tmp", OBJ_DIR, dst);
copy_file(path, obj_path);
}
-static inline void mklink(const char *src, const char obj[HASH_LEN])
+static inline void mklink(const char *src, const char *obj)
{
- // HASH_LEN includes null byte
- size_t lnkt_sz = strlen("../obj/") + HASH_LEN + 4;
- char lnk_target[lnkt_sz];
- concat(lnk_target, lnkt_sz, "../obj/", obj, ".tmp", NULL);
-
- size_t lnkp_sz = strlen(TMP_DIR) + strlen(src) + 2;
- char lnk_path[lnkp_sz];
- concat(lnk_path, lnkp_sz, TMP_DIR, "/", src, NULL);
-
- mkdirs(lnk_path);
- if (symlink(lnk_target, lnk_path) != 0)
- err(1, "symlink error on %s", src);
+ char *lnk, *dst;
+
+ lnk = format_path("../obj/%s.tmp", obj);
+ dst = format_path("%s/%s", TMP_DIR, src);
+
+ mkdirs(dst);
+
+ if (symlink(lnk, dst) != 0)
+ err(1, "symlink %s", src);
}
static inline void print_status(const char *file, char kind, int islnk)
@@ -350,46 +336,12 @@ static inline int lnklen(const char *lnk)
err(1, "lstat %s", lnk);
len = st.st_size + 1;
- if (MAX_PATH_LEN < len)
+ if (PATH_LEN < len)
errx(1, "Link too long: %s", lnk);
return len;
}
-static inline void concat(char *dst, size_t n, const char *arg1, ...)
-{
- va_list ap;
- const char *part;
- int curlen, partlen;
-
- if (!dst || n == 0)
- return;
-
- dst[0] = '\0';
- curlen = 0;
-
- if (!arg1)
- return;
-
- va_start(ap, arg1);
- part = arg1;
-
- while (part) {
- partlen = strlen(part);
- if (curlen + partlen + 1 > n) {
- dst[curlen] = '\0';
- va_end(ap);
- errx(1, "Path too long: %s%s", dst, part);
- }
- memcpy(dst + curlen, part, partlen);
- curlen += partlen;
- part = va_arg(ap, const char *);
- }
-
- dst[curlen] = '\0';
- va_end(ap);
-}
-
static inline int diff(const char *file1, const char *file2)
{
pid_t pid;
@@ -469,7 +421,9 @@ static inline void copy_link(const char *src)
{
int len;
ssize_t n;
+ char *dst;
+ // todo: use path_buf
len = lnklen(src);
char target[len];
n = readlink(src, target, len);
@@ -478,9 +432,7 @@ static inline void copy_link(const char *src)
target[n] = '\0';
- size_t dst_sz = strlen(TMP_DIR) + strlen(src) + 2;
- char dst[dst_sz];
- concat(dst, dst_sz, TMP_DIR, src, NULL);
+ dst = format_path("%s/%s", TMP_DIR, src);
mkdirs(dst);
if (symlink(target, dst) != 0)
@@ -492,10 +444,10 @@ static inline void mkdirs(const char *path)
char *p;
int pathlen;
- static char buf[MAX_PATH_LEN];
+ static char buf[PATH_LEN];
pathlen = strlen(path);
- if (MAX_PATH_LEN < pathlen + 1)
+ if (PATH_LEN < pathlen + 1)
errx(1, "Path too long: %s", path);
buf[0] = '\0';
@@ -513,6 +465,28 @@ static inline void mkdirs(const char *path)
}
}
+static char *path_buf[2][PATH_LEN];
+
+static inline char *format_path(const char *fmt, ...)
+{
+ int rc;
+ va_list args;
+ static uint8_t i = 1;
+
+ i ^= 1;
+ va_start(args, fmt);
+ rc = vsnprintf((char *)path_buf[i], PATH_LEN, fmt, args);
+ va_end(args);
+
+ if (rc < 0)
+ err(1, "vsnprintf");
+
+ if (rc >= PATH_LEN)
+ errx(1, "Path too long");
+
+ return (char *)path_buf[i];
+}
+
static inline void *_xmalloc(size_t s, const char *file, int line)
{
void *p;