List for cgit developers and users
 help / color / mirror / Atom feed
From: john at keeping.me.uk (John Keeping)
Subject: [PATCH 3/6] filter: pass extra arguments via cgit_open_filter
Date: Sun, 12 Jan 2014 17:13:50 +0000	[thread overview]
Message-ID: <974633e1762a414cd7d25b84823a441c82e34ab2.1389546691.git.john@keeping.me.uk> (raw)
In-Reply-To: <cover.1389546691.git.john@keeping.me.uk>

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 at keeping.me.uk>
---
 cgit.h        |  3 ++-
 filter.c      | 35 ++++++++++++++++++++++++-----------
 ui-repolist.c | 10 +++-------
 ui-summary.c  | 13 ++++++-------
 ui-tree.c     |  7 +++----
 5 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/cgit.h b/cgit.h
index a72c503..e6e7715 100644
--- a/cgit.h
+++ b/cgit.h
@@ -59,6 +59,7 @@ typedef enum {
 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 f4ee9ac..d8c0116 100644
--- a/filter.c
+++ b/filter.c
@@ -13,8 +13,16 @@
 #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_open_filter(struct cgit_filter *filter)
 
 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 d4ee279..f622a01 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 63a5a75..725f3ab 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -151,18 +151,17 @@ void cgit_print_repo_readme(char *path)
 	 * 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 5ae3926..e4c3d22 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -45,13 +45,12 @@ static void print_text_buffer(const char *name, char *buf, unsigned long size)
 	}
 
 	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;
 	}
-- 
1.8.5.226.g0d60d77



  parent reply	other threads:[~2014-01-12 17:13 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-12 17:13 [RFC/PATCH 0/6] Preparation for more filter types john
2014-01-12 17:13 ` [PATCH 1/6] html: remove redundant htmlfd variable john
2014-01-12 19:11   ` Jason
2014-01-12 17:13 ` [PATCH 2/6] ui-snapshot: set unused cgit_filter fields to zero john
2014-01-12 17:13 ` john [this message]
2014-01-12 19:20   ` [PATCH 3/6] filter: pass extra arguments via cgit_open_filter Jason
2014-01-12 17:13 ` [PATCH 4/6] filter: add fprintf_filter function john
2014-01-12 19:23   ` Jason
2014-01-12 19:35     ` john
2014-01-12 19:40       ` Jason
2014-01-12 17:13 ` [PATCH 5/6] filter: add interface layer john
2014-01-12 17:13 ` [PATCH 6/6] filter: introduce "filter type" prefix john

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=974633e1762a414cd7d25b84823a441c82e34ab2.1389546691.git.john@keeping.me.uk \
    --to=cgit@lists.zx2c4.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).