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 | } |
