cgit

commit 3d8a6507ca542881a5e8b30ad6b7068a9c4fdeea

Author: John Keeping <john@keeping.me.uk>

filter: pass extra arguments via cgit_open_filter

This avoids poking into the filter data structure at various points in
the code.  We rely on the fact that the number of arguments is fixed
based on the filter type (set in cgit_new_filter) and that the call
sites all know which filter type they're using.

Signed-off-by: John Keeping <john@keeping.me.uk>

 cgit.h | 3 ++-
 filter.c | 35 ++++++++++++++++++++++++-----------
 ui-repolist.c | 10 +++-------
 ui-summary.c | 13 ++++++-------
 ui-tree.c | 7 +++----


diff --git a/cgit.h b/cgit.h
index a72c503d84c35dec4ff9709a4b81f4da854a6c2f..e6e7715bbaa8c146676005428250a6dc4a8687a4 100644
--- a/cgit.h
+++ b/cgit.h
@@ -59,6 +59,7 @@
 struct cgit_filter {
 	char *cmd;
 	char **argv;
+	int extra_args;
 	int old_stdout;
 	int pipe_fh[2];
 	int pid;
@@ -342,7 +343,7 @@ extern const char *cgit_repobasename(const char *reponame);
 
 extern int cgit_parse_snapshots_mask(const char *str);
 
-extern int cgit_open_filter(struct cgit_filter *filter);
+extern int cgit_open_filter(struct cgit_filter *filter, ...);
 extern int cgit_close_filter(struct cgit_filter *filter);
 extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype);
 




diff --git a/filter.c b/filter.c
index f4ee9ac2167eee92c3dc0ba8719421d7d701c45c..d8c0116df39bd20a96f183b4e992b969afdb7623 100644
--- a/filter.c
+++ b/filter.c
@@ -13,8 +13,16 @@ #include 
 #include <string.h>
 #include <stdlib.h>
 
-int cgit_open_filter(struct cgit_filter *filter)
+int cgit_open_filter(struct cgit_filter *filter, ...)
 {
+	int i;
+	va_list ap;
+
+	va_start(ap, filter);
+	for (i = 0; i < filter->extra_args; i++)
+		filter->argv[i+1] = va_arg(ap, char *);
+	va_end(ap);
+
 	filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
 		"Unable to duplicate STDOUT");
 	chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
@@ -36,45 +44,50 @@
 
 int cgit_close_filter(struct cgit_filter *filter)
 {
-	int exit_status;
+	int i, exit_status;
 
 	chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
 		"Unable to restore STDOUT");
 	close(filter->old_stdout);
 	if (filter->pid < 0)
-		return 0;
+		goto done;
 	waitpid(filter->pid, &exit_status, 0);
 	if (WIFEXITED(exit_status) && !WEXITSTATUS(exit_status))
-		return 0;
+		goto done;
 	die("Subprocess %s exited abnormally", filter->cmd);
+
+done:
+	for (i = 0; i < filter->extra_args; i++)
+		filter->argv[i+1] = NULL;
+	return 0;
+
 }
 
 struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 {
 	struct cgit_filter *f;
 	int args_size = 0;
-	int extra_args;
 
 	if (!cmd || !cmd[0])
 		return NULL;
 
+	f = xmalloc(sizeof(struct cgit_filter));
+	memset(f, 0, sizeof(struct cgit_filter));
+
 	switch (filtertype) {
 		case SOURCE:
 		case ABOUT:
-			extra_args = 1;
+			f->extra_args = 1;
 			break;
 
 		case COMMIT:
 		default:
-			extra_args = 0;
+			f->extra_args = 0;
 			break;
 	}
-	
-	f = xmalloc(sizeof(struct cgit_filter));
-	memset(f, 0, sizeof(struct cgit_filter));
 
 	f->cmd = xstrdup(cmd);
-	args_size = (2 + extra_args) * sizeof(char *);
+	args_size = (2 + f->extra_args) * sizeof(char *);
 	f->argv = xmalloc(args_size);
 	memset(f->argv, 0, args_size);
 	f->argv[0] = f->cmd;




diff --git a/ui-repolist.c b/ui-repolist.c
index d4ee2798c0d9be1ec02a308b4072ac97b0889c42..f622a0130184843206932969a84d5587352c8f4a 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -331,13 +331,9 @@ void cgit_print_site_readme()
 {
 	if (!ctx.cfg.root_readme)
 		return;
-	if (ctx.cfg.about_filter) {
-		ctx.cfg.about_filter->argv[1] = ctx.cfg.root_readme;
-		cgit_open_filter(ctx.cfg.about_filter);
-	}
+	if (ctx.cfg.about_filter)
+		cgit_open_filter(ctx.cfg.about_filter, ctx.cfg.root_readme);
 	html_include(ctx.cfg.root_readme);
-	if (ctx.cfg.about_filter) {
+	if (ctx.cfg.about_filter)
 		cgit_close_filter(ctx.cfg.about_filter);
-		ctx.cfg.about_filter->argv[1] = NULL;
-	}
 }




diff --git a/ui-summary.c b/ui-summary.c
index 63a5a754ba0297e8775c666495a885d942cf1b0e..725f3ab4a98c01bac83bcfe43cdfd559c53914ca 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -151,18 +151,17 @@ 	/* Print the calculated readme, either from the git repo or from the
 	 * filesystem, while applying the about-filter.
 	 */
 	html("<div id='summary'>");
-	if (ctx.repo->about_filter) {
-		ctx.repo->about_filter->argv[1] = filename;
-		cgit_open_filter(ctx.repo->about_filter);
-	}
+	if (ctx.repo->about_filter)
+		cgit_open_filter(ctx.repo->about_filter, filename);
+
 	if (ref)
 		cgit_print_file(filename, ref, 1);
 	else
 		html_include(filename);
-	if (ctx.repo->about_filter) {
+
+	if (ctx.repo->about_filter)
 		cgit_close_filter(ctx.repo->about_filter);
-		ctx.repo->about_filter->argv[1] = NULL;
-	}
+
 	html("</div>");
 	if (free_filename)
 		free(filename);




diff --git a/ui-tree.c b/ui-tree.c
index 5ae39269cc7278d6cbaa41df5ee35b032be1e0cc..e4c3d2263cb3b85e84066ed4f0bfb6640bdcbe0a 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -45,13 +45,12 @@ 		html("\n");
 	}
 
 	if (ctx.repo->source_filter) {
+		char *filter_arg = xstrdup(name);
 		html("<td class='lines'><pre><code>");
-		ctx.repo->source_filter->argv[1] = xstrdup(name);
-		cgit_open_filter(ctx.repo->source_filter);
+		cgit_open_filter(ctx.repo->source_filter, filter_arg);
 		html_raw(buf, size);
 		cgit_close_filter(ctx.repo->source_filter);
-		free(ctx.repo->source_filter->argv[1]);
-		ctx.repo->source_filter->argv[1] = NULL;
+		free(filter_arg);
 		html("</code></pre></td></tr></table>\n");
 		return;
 	}