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);