aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar John Keeping <john@keeping.me.uk>2014-01-13 02:13:52 (JST)
committerGravatar Jason A. Donenfeld <Jason@zx2c4.com>2014-01-14 10:00:07 (JST)
commit7bd90b8048fd6937766dff7474947dd80205ea7e (patch)
tree63f9ba4eac9892a843338400042194b3bf115216
parent632efb25c07c1b014a4e8cfbbea759f517c2aaf6 (diff)
downloadcgit-7bd90b8048fd6937766dff7474947dd80205ea7e.zip
cgit-7bd90b8048fd6937766dff7474947dd80205ea7e.tar.gz
filter: add interface layer
Change the existing cgit_{open,close,fprintf}_filter functions to delegate to filter-specific implementations accessed via function pointers on the cgit_filter object. We treat the "exec" filter type slightly specially here by putting its structure definition in the header file and providing an "init" function to set up the function pointers. This is required so that the ui-snapshot.c code that applies a compression filter can continue to use the filter interface to do so. Signed-off-by: John Keeping <john@keeping.me.uk>
-rw-r--r--cgit.h8
-rw-r--r--filter.c66
-rw-r--r--ui-snapshot.c11
3 files changed, 63 insertions, 22 deletions
diff --git a/cgit.h b/cgit.h
index 9b4be26..92e8c55 100644
--- a/cgit.h
+++ b/cgit.h
@@ -57,6 +57,13 @@ typedef enum {
57} filter_type; 57} filter_type;
58 58
59struct cgit_filter { 59struct cgit_filter {
60 int (*open)(struct cgit_filter *, va_list ap);
61 int (*close)(struct cgit_filter *);
62 void (*fprintf)(struct cgit_filter *, FILE *, const char *prefix);
63};
64
65struct cgit_exec_filter {
66 struct cgit_filter base;
60 char *cmd; 67 char *cmd;
61 char **argv; 68 char **argv;
62 int extra_args; 69 int extra_args;
@@ -346,6 +353,7 @@ extern int cgit_parse_snapshots_mask(const char *str);
346extern int cgit_open_filter(struct cgit_filter *filter, ...); 353extern int cgit_open_filter(struct cgit_filter *filter, ...);
347extern int cgit_close_filter(struct cgit_filter *filter); 354extern int cgit_close_filter(struct cgit_filter *filter);
348extern void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix); 355extern void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix);
356extern void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, char **argv);
349extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype); 357extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype);
350 358
351extern void cgit_prepare_repo_env(struct cgit_repo * repo); 359extern void cgit_prepare_repo_env(struct cgit_repo * repo);
diff --git a/filter.c b/filter.c
index 80cf689..0f3edb0 100644
--- a/filter.c
+++ b/filter.c
@@ -13,15 +13,13 @@
13#include <string.h> 13#include <string.h>
14#include <stdlib.h> 14#include <stdlib.h>
15 15
16int cgit_open_filter(struct cgit_filter *filter, ...) 16static int open_exec_filter(struct cgit_filter *base, va_list ap)
17{ 17{
18 struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base;
18 int i; 19 int i;
19 va_list ap;
20 20
21 va_start(ap, filter);
22 for (i = 0; i < filter->extra_args; i++) 21 for (i = 0; i < filter->extra_args; i++)
23 filter->argv[i+1] = va_arg(ap, char *); 22 filter->argv[i+1] = va_arg(ap, char *);
24 va_end(ap);
25 23
26 filter->old_stdout = chk_positive(dup(STDOUT_FILENO), 24 filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
27 "Unable to duplicate STDOUT"); 25 "Unable to duplicate STDOUT");
@@ -41,9 +39,9 @@ int cgit_open_filter(struct cgit_filter *filter, ...)
41 return 0; 39 return 0;
42} 40}
43 41
44 42static int close_exec_filter(struct cgit_filter *base)
45int cgit_close_filter(struct cgit_filter *filter)
46{ 43{
44 struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base;
47 int i, exit_status; 45 int i, exit_status;
48 46
49 chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), 47 chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
@@ -63,21 +61,50 @@ done:
63 61
64} 62}
65 63
66void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix) 64static void fprintf_exec_filter(struct cgit_filter *base, FILE *f, const char *prefix)
67{ 65{
66 struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base;
68 fprintf(f, "%s%s\n", prefix, filter->cmd); 67 fprintf(f, "%s%s\n", prefix, filter->cmd);
69} 68}
70 69
71struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype) 70int cgit_open_filter(struct cgit_filter *filter, ...)
72{ 71{
73 struct cgit_filter *f; 72 int result;
74 int args_size = 0; 73 va_list ap;
74 va_start(ap, filter);
75 result = filter->open(filter, ap);
76 va_end(ap);
77 return result;
78}
75 79
76 if (!cmd || !cmd[0]) 80int cgit_close_filter(struct cgit_filter *filter)
77 return NULL; 81{
82 return filter->close(filter);
83}
84
85void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix)
86{
87 filter->fprintf(filter, f, prefix);
88}
89
90void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, char **argv)
91{
92 memset(filter, 0, sizeof(*filter));
93 filter->base.open = open_exec_filter;
94 filter->base.close = close_exec_filter;
95 filter->base.fprintf = fprintf_exec_filter;
96 filter->cmd = cmd;
97 filter->argv = argv;
98}
99
100static struct cgit_filter *new_exec_filter(const char *cmd, filter_type filtertype)
101{
102 struct cgit_exec_filter *f;
103 int args_size = 0;
78 104
79 f = xmalloc(sizeof(struct cgit_filter)); 105 f = xmalloc(sizeof(*f));
80 memset(f, 0, sizeof(struct cgit_filter)); 106 /* We leave argv for now and assign it below. */
107 cgit_exec_filter_init(f, xstrdup(cmd), NULL);
81 108
82 switch (filtertype) { 109 switch (filtertype) {
83 case SOURCE: 110 case SOURCE:
@@ -91,10 +118,17 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
91 break; 118 break;
92 } 119 }
93 120
94 f->cmd = xstrdup(cmd);
95 args_size = (2 + f->extra_args) * sizeof(char *); 121 args_size = (2 + f->extra_args) * sizeof(char *);
96 f->argv = xmalloc(args_size); 122 f->argv = xmalloc(args_size);
97 memset(f->argv, 0, args_size); 123 memset(f->argv, 0, args_size);
98 f->argv[0] = f->cmd; 124 f->argv[0] = f->cmd;
99 return f; 125 return &f->base;
126}
127
128struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
129{
130 if (!cmd || !cmd[0])
131 return NULL;
132
133 return new_exec_filter(cmd, filtertype);
100} 134}
diff --git a/ui-snapshot.c b/ui-snapshot.c
index 5136c49..7115ec4 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -58,13 +58,12 @@ static int write_compressed_tar_archive(const char *hex,
58 char *filter_argv[]) 58 char *filter_argv[])
59{ 59{
60 int rv; 60 int rv;
61 struct cgit_filter f = { 61 struct cgit_exec_filter f;
62 .cmd = filter_argv[0], 62 cgit_exec_filter_init(&f, filter_argv[0], filter_argv);
63 .argv = filter_argv, 63
64 }; 64 cgit_open_filter(&f.base);
65 cgit_open_filter(&f);
66 rv = write_tar_archive(hex, prefix); 65 rv = write_tar_archive(hex, prefix);
67 cgit_close_filter(&f); 66 cgit_close_filter(&f.base);
68 return rv; 67 return rv;
69} 68}
70 69