about summary refs log tree commit diff stats
path: root/filter.c
diff options
context:
space:
mode:
authorJohn Keeping2014-01-12 17:13:52 +0000
committerJason A. Donenfeld2014-01-14 02:00:07 +0100
commit7bd90b8048fd6937766dff7474947dd80205ea7e (patch)
tree63f9ba4eac9892a843338400042194b3bf115216 /filter.c
parentfilter: add fprintf_filter function (diff)
downloadcgit-7bd90b8048fd6937766dff7474947dd80205ea7e.tar.gz
cgit-7bd90b8048fd6937766dff7474947dd80205ea7e.zip
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>
Diffstat (limited to 'filter.c')
-rw-r--r--filter.c66
1 files changed, 50 insertions, 16 deletions
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}