diff options
-rw-r--r-- | cgitrc.5.txt | 9 | ||||
-rw-r--r-- | filter.c | 33 |
2 files changed, 40 insertions, 2 deletions
diff --git a/cgitrc.5.txt b/cgitrc.5.txt index 52caed0..60159f6 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt | |||
@@ -557,6 +557,15 @@ config files, e.g. "repo.desc" becomes "desc". | |||
557 | 557 | ||
558 | FILTER API | 558 | FILTER API |
559 | ---------- | 559 | ---------- |
560 | By default, filters are separate processes that are executed each time they | ||
561 | are needed. Alternative technologies may be used by prefixing the filter | ||
562 | specification with the relevant string; available values are: | ||
563 | |||
564 | 'exec:':: | ||
565 | The default "one process per filter" mode. | ||
566 | |||
567 | Parameters are provided to filters as follows. | ||
568 | |||
560 | about filter:: | 569 | about filter:: |
561 | This filter is given a single parameter: the filename of the source | 570 | This filter is given a single parameter: the filename of the source |
562 | file to filter. The filter can use the filename to determine (for | 571 | file to filter. The filter can use the filename to determine (for |
@@ -64,7 +64,7 @@ done: | |||
64 | static void fprintf_exec_filter(struct cgit_filter *base, FILE *f, const char *prefix) | 64 | static void fprintf_exec_filter(struct cgit_filter *base, FILE *f, const char *prefix) |
65 | { | 65 | { |
66 | struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base; | 66 | struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base; |
67 | fprintf(f, "%s%s\n", prefix, filter->cmd); | 67 | fprintf(f, "%sexec:%s\n", prefix, filter->cmd); |
68 | } | 68 | } |
69 | 69 | ||
70 | int cgit_open_filter(struct cgit_filter *filter, ...) | 70 | int cgit_open_filter(struct cgit_filter *filter, ...) |
@@ -125,10 +125,39 @@ static struct cgit_filter *new_exec_filter(const char *cmd, filter_type filterty | |||
125 | return &f->base; | 125 | return &f->base; |
126 | } | 126 | } |
127 | 127 | ||
128 | static const struct { | ||
129 | const char *prefix; | ||
130 | struct cgit_filter *(*ctor)(const char *cmd, filter_type filtertype); | ||
131 | } filter_specs[] = { | ||
132 | { "exec", new_exec_filter }, | ||
133 | }; | ||
134 | |||
128 | struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype) | 135 | struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype) |
129 | { | 136 | { |
137 | char *colon; | ||
138 | int i; | ||
139 | size_t len; | ||
130 | if (!cmd || !cmd[0]) | 140 | if (!cmd || !cmd[0]) |
131 | return NULL; | 141 | return NULL; |
132 | 142 | ||
133 | return new_exec_filter(cmd, filtertype); | 143 | colon = strchr(cmd, ':'); |
144 | len = colon - cmd; | ||
145 | /* | ||
146 | * In case we're running on Windows, don't allow a single letter before | ||
147 | * the colon. | ||
148 | */ | ||
149 | if (len == 1) | ||
150 | colon = NULL; | ||
151 | |||
152 | /* If no prefix is given, exec filter is the default. */ | ||
153 | if (!colon) | ||
154 | return new_exec_filter(cmd, filtertype); | ||
155 | |||
156 | for (i = 0; i < ARRAY_SIZE(filter_specs); i++) { | ||
157 | if (len == strlen(filter_specs[i].prefix) && | ||
158 | !strncmp(filter_specs[i].prefix, cmd, len)) | ||
159 | return filter_specs[i].ctor(colon + 1, filtertype); | ||
160 | } | ||
161 | |||
162 | die("Invalid filter type: %.*s", (int) len, cmd); | ||
134 | } | 163 | } |