diff options
author | John Keeping | 2014-01-12 17:13:52 +0000 |
---|---|---|
committer | Jason A. Donenfeld | 2014-01-14 02:00:07 +0100 |
commit | 7bd90b8048fd6937766dff7474947dd80205ea7e (patch) | |
tree | 63f9ba4eac9892a843338400042194b3bf115216 /filter.c | |
parent | 632efb25c07c1b014a4e8cfbbea759f517c2aaf6 (diff) | |
download | cgit-7bd90b8048fd6937766dff7474947dd80205ea7e.tar.gz cgit-7bd90b8048fd6937766dff7474947dd80205ea7e.tar.bz2 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.c | 66 |
1 files changed, 50 insertions, 16 deletions
@@ -13,15 +13,13 @@ | |||
13 | #include <string.h> | 13 | #include <string.h> |
14 | #include <stdlib.h> | 14 | #include <stdlib.h> |
15 | 15 | ||
16 | int cgit_open_filter(struct cgit_filter *filter, ...) | 16 | static 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 | 42 | static int close_exec_filter(struct cgit_filter *base) | |
45 | int 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 | ||
66 | void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix) | 64 | static 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 | ||
71 | struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype) | 70 | int 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]) | 80 | int cgit_close_filter(struct cgit_filter *filter) |
77 | return NULL; | 81 | { |
82 | return filter->close(filter); | ||
83 | } | ||
84 | |||
85 | void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix) | ||
86 | { | ||
87 | filter->fprintf(filter, f, prefix); | ||
88 | } | ||
89 | |||
90 | void 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 | |||
100 | static 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 | |||
128 | struct 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 | } |