shithub: libgit

Download patch

ref: 254e6855efd805fda2826f324169009c8b0a4105
parent: 3334f29a9e020b0447d81ac4afc8e1b31452276f
author: sirjofri <sirjofri@sirjofri.de>
date: Sun Jun 16 10:00:25 EDT 2024

adds ...l functions that accept arrays instead of va_lists

--- a/git.c
+++ b/git.c
@@ -5,7 +5,7 @@
 
 char *Enoinit = "not initialized";
 
-// #define DEBUG
+//#define DEBUG
 
 char *gitdir = "/mnt/git";
 int initialized = 0;
@@ -126,6 +126,7 @@
 		close(p[0]);
 		
 		exec(c, args);
+		free(args);
 		break;
 	case -1: /* error */
 		werrstr("unable to fork: %r");
@@ -132,6 +133,7 @@
 		return FAIL;
 		break;
 	default: /* parent */
+		free(args); // TODO crashes on gitlog
 		break;
 	}
 	
@@ -159,72 +161,127 @@
 }
 
 int
+gitcommitl(char *msg, char **files)
+{
+	char **args;
+	char **f;
+	int n, i;
+	
+	checkinitialized();
+	
+	for (f = files, n = 0; *f; f++)
+		n++;
+	
+	args = mallocz((n + 1 + 3) * sizeof(char*), 1);
+	
+	i = 0;
+	args[i++] = nil;
+	args[i++] = "-m";
+	args[i++] = msg;
+	
+	memcpy(&args[i], files, n * sizeof(char*));
+	
+	i = gitcmd(COMMIT, args, nil, nil);
+	
+	return i;
+}
+
+static void
+filllist(char ***list, int start, int len, va_list args)
+{
+	char *f;
+	
+	if (*list == nil) {
+		start = 0;
+		len = 32;
+		*list = mallocz(len * sizeof(char*), 1);
+		if (*list == nil)
+			sysfatal("%r");
+	}
+	
+	while (f = va_arg(args, char*)) {
+		if (start > (len - 2)) {
+			len += 32;
+			*list = realloc(*list, len * sizeof(char*));
+			if (*list == nil)
+				sysfatal("%r");
+			
+			(*list)[start++] = f;
+		}
+	}
+	(*list)[start] = nil;
+}
+
+int
 gitcommit(char *msg, char *file, ...)
 {
 	va_list args;
-	char *files[32];
-	char *f;
-	int nfile = 1;
+	char **files;
+	int n, l;
 
 	checkinitialized();
 	
-	files[nfile++] = "-m";
-	files[nfile++] = msg;
+	n = 0;
+	l = 32;
 	
-	files[nfile++] = file;
+	files = mallocz(l, 1);
+	files[n++] = file;
 	
 	va_start(args, file);
-	while (f = va_arg(args, char*)) {
-		files[nfile++] = f;
-		if (nfile >= sizeof(files)) {
-			files[nfile] = nil;
-			if (!gitcmd(COMMIT, files, nil, nil))
-				return FAIL;
-			nfile = 3;
-		}
-	}
+	filllist(&files, n, l, args);
 	va_end(args);
 	
-	if (nfile > 3) {
-		files[nfile] = nil;
-		if (!gitcmd(COMMIT, files, nil, nil))
-			return FAIL;
-	}
+	files[n] = nil;
 	
-	return SUCCESS;
+	return gitcommitl(msg, files);
 }
 
 static int
-gitaddrm(char *F, char *file, va_list args)
+gitaddrm(char *F, char **files)
 {
-	char *ofile;
+	char **f;
 	int fd;
 	
-	ofile = strdup(file);
-	file = cleanname(ofile);
-	
 	fd = open(indexfile, OWRITE);
 	if (fd < 0)
 		return FAIL;
 	seek(fd, 0, 2);
 	
-	fprint(fd, "%s NOQID 0 %s\n", F, file);
-	free(ofile);
-	
-	while ((ofile = va_arg(args, char*)) != nil) {
-		ofile = strdup(ofile);
-		file = cleanname(ofile);
-		
-		fprint(fd, "%s NOQID 0 %s\n", F, file);
-		free(ofile);
+	for (f = files; *f; f++) {
+		fprint(fd, "%s NOQID 0 %s\n", F, *f);
 	}
 	
-	va_end(args);
 	close(fd);
 	return SUCCESS;
 }
 
+static int
+gitaddrmargs(char *F, char *file, va_list args)
+{
+	char **files;
+	int i, l;
+	
+	l = 32;
+	i = 0;
+	files = mallocz(l * sizeof(char*), 1);
+	
+	files[i++] = file;
+	filllist(&files, i, l, args);
+	va_end(args);
+	
+	i = gitaddrm(F, files);
+	free(files);
+	return i;
+}
+
 int
+gitaddl(char **files)
+{
+	checkinitialized();
+	return gitaddrm("A", files);
+}
+
+int
 gitadd(char *file, ...)
 {
 	va_list args;
@@ -232,10 +289,17 @@
 	checkinitialized();
 	
 	va_start(args, file);
-	return gitaddrm("A", file, args);
+	return gitaddrmargs("A", file, args);
 }
 
 int
+gitrml(char **files)
+{
+	checkinitialized();
+	return gitaddrm("R", files);
+}
+
+int
 gitrm(char *file, ...)
 {
 	va_list args;
@@ -243,7 +307,7 @@
 	checkinitialized();
 	
 	va_start(args, file);
-	return gitaddrm("R", file, args);
+	return gitaddrmargs("R", file, args);
 }
 
 typedef struct Logparams Logparams;
@@ -310,16 +374,16 @@
 }
 
 int
-gitlog(Gitlog **logs, int n, char *commit, ...)
+gitlogl(Gitlog **logs, int n, char *commit, char **files)
 {
-	va_list args;
-	char *file;
-	char *files[64];
-	char num[5];
-	int ret;
-	int nfile;
 	Logparams p;
+	char num[5];
+	char **argv;
+	int nfiles;
+	int l, i;
 	
+	checkinitialized();
+	
 	if (n <= 0) {
 		sysfatal("gitlog: n <= 0");
 	}
@@ -337,38 +401,48 @@
 	p.n = n;
 	p.last = -1;
 	
-	nfile = 1;
+	for (argv = files, nfiles = 0; *argv; argv++)
+		nfiles++;
 	
+	l = nfiles;
+	l += 2; /* ending nil, starting argv0 */
+	l += 2; /* num args */
+	if (commit)
+		l += 2;
+	argv = mallocz(l * sizeof(char*), 1);
+	
+	i = 1; /* reserve [0] for argv0 */
+	
 	snprint(num, sizeof(num), "%d", n);
-	files[nfile++] = "-n";
-	files[nfile++] = num;
+	argv[i++] = "-n";
+	argv[i++] = num;
 	
 	if (commit) {
-		files[nfile++] = "-c";
-		files[nfile++] = commit;
+		argv[i++] = "-c";
+		argv[i++] = commit;
 	}
 	
+	memcpy(&argv[i], files, nfiles * sizeof(char*));
+	return gitcmd(LOG, argv, gitlogline, &p);
+}
+
+int
+gitlog(Gitlog **logs, int n, char *commit, ...)
+{
+	va_list args;
+	char **files = nil;
+	int ret;
+	
+	checkinitialized();
+	
 	va_start(args, commit);
-	while (file = va_arg(args, char*)) {
-		files[nfile++] = file;
-		if (nfile >= sizeof(files)) {
-			goto Toomanyfiles;
-		}
-	}
+	filllist(&files, 0, 0, args);
 	va_end(args);
 	
-	files[nfile] = nil;
-	ret = gitcmd(LOG, files, gitlogline, &p);
+	ret = gitlogl(logs, n, commit, files);
+	free(files);
 	
-	if (!ret)
-		return FAIL;
-	
 	return ret;
-
-Toomanyfiles:
-	va_end(args);
-	werrstr("too many files in log command");
-	return FAIL;
 }
 
 int
--- a/git.h
+++ b/git.h
@@ -16,6 +16,10 @@
 /* git commands. files must be relative within repository. The last
    name must be nil. */
 int gitcommit(char *msg, char *file, ...);
+int gitcommitl(char *msg, char **files);
 int gitadd(char *file, ...);
+int gitaddl(char **files);
 int gitrm(char *file, ...);
+int gitrml(char **files);
 int gitlog(Gitlog **logs, int n, char *commit, ...);
+int gitlogl(Gitlog **logs, int n, char *commit, char **files);