filter: pass extra arguments via cgit_open_filter
This avoids poking into the filter data structure at various points in the code. We rely on the fact that the number of arguments is fixed based on the filter type (set in cgit_new_filter) and that the call sites all know which filter type they're using. Signed-off-by: John Keeping <john@keeping.me.uk>
This commit is contained in:
parent
da218fcd9e
commit
3d8a6507ca
3
cgit.h
3
cgit.h
@ -59,6 +59,7 @@ typedef enum {
|
|||||||
struct cgit_filter {
|
struct cgit_filter {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char **argv;
|
char **argv;
|
||||||
|
int extra_args;
|
||||||
int old_stdout;
|
int old_stdout;
|
||||||
int pipe_fh[2];
|
int pipe_fh[2];
|
||||||
int pid;
|
int pid;
|
||||||
@ -342,7 +343,7 @@ extern const char *cgit_repobasename(const char *reponame);
|
|||||||
|
|
||||||
extern int cgit_parse_snapshots_mask(const char *str);
|
extern int cgit_parse_snapshots_mask(const char *str);
|
||||||
|
|
||||||
extern int cgit_open_filter(struct cgit_filter *filter);
|
extern int cgit_open_filter(struct cgit_filter *filter, ...);
|
||||||
extern int cgit_close_filter(struct cgit_filter *filter);
|
extern int cgit_close_filter(struct cgit_filter *filter);
|
||||||
extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype);
|
extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype);
|
||||||
|
|
||||||
|
35
filter.c
35
filter.c
@ -13,8 +13,16 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int cgit_open_filter(struct cgit_filter *filter)
|
int cgit_open_filter(struct cgit_filter *filter, ...)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, filter);
|
||||||
|
for (i = 0; i < filter->extra_args; i++)
|
||||||
|
filter->argv[i+1] = va_arg(ap, char *);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
|
filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
|
||||||
"Unable to duplicate STDOUT");
|
"Unable to duplicate STDOUT");
|
||||||
chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
|
chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
|
||||||
@ -36,45 +44,50 @@ int cgit_open_filter(struct cgit_filter *filter)
|
|||||||
|
|
||||||
int cgit_close_filter(struct cgit_filter *filter)
|
int cgit_close_filter(struct cgit_filter *filter)
|
||||||
{
|
{
|
||||||
int exit_status;
|
int i, exit_status;
|
||||||
|
|
||||||
chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
|
chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
|
||||||
"Unable to restore STDOUT");
|
"Unable to restore STDOUT");
|
||||||
close(filter->old_stdout);
|
close(filter->old_stdout);
|
||||||
if (filter->pid < 0)
|
if (filter->pid < 0)
|
||||||
return 0;
|
goto done;
|
||||||
waitpid(filter->pid, &exit_status, 0);
|
waitpid(filter->pid, &exit_status, 0);
|
||||||
if (WIFEXITED(exit_status) && !WEXITSTATUS(exit_status))
|
if (WIFEXITED(exit_status) && !WEXITSTATUS(exit_status))
|
||||||
return 0;
|
goto done;
|
||||||
die("Subprocess %s exited abnormally", filter->cmd);
|
die("Subprocess %s exited abnormally", filter->cmd);
|
||||||
|
|
||||||
|
done:
|
||||||
|
for (i = 0; i < filter->extra_args; i++)
|
||||||
|
filter->argv[i+1] = NULL;
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
|
struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
|
||||||
{
|
{
|
||||||
struct cgit_filter *f;
|
struct cgit_filter *f;
|
||||||
int args_size = 0;
|
int args_size = 0;
|
||||||
int extra_args;
|
|
||||||
|
|
||||||
if (!cmd || !cmd[0])
|
if (!cmd || !cmd[0])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
f = xmalloc(sizeof(struct cgit_filter));
|
||||||
|
memset(f, 0, sizeof(struct cgit_filter));
|
||||||
|
|
||||||
switch (filtertype) {
|
switch (filtertype) {
|
||||||
case SOURCE:
|
case SOURCE:
|
||||||
case ABOUT:
|
case ABOUT:
|
||||||
extra_args = 1;
|
f->extra_args = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMMIT:
|
case COMMIT:
|
||||||
default:
|
default:
|
||||||
extra_args = 0;
|
f->extra_args = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = xmalloc(sizeof(struct cgit_filter));
|
|
||||||
memset(f, 0, sizeof(struct cgit_filter));
|
|
||||||
|
|
||||||
f->cmd = xstrdup(cmd);
|
f->cmd = xstrdup(cmd);
|
||||||
args_size = (2 + extra_args) * sizeof(char *);
|
args_size = (2 + f->extra_args) * sizeof(char *);
|
||||||
f->argv = xmalloc(args_size);
|
f->argv = xmalloc(args_size);
|
||||||
memset(f->argv, 0, args_size);
|
memset(f->argv, 0, args_size);
|
||||||
f->argv[0] = f->cmd;
|
f->argv[0] = f->cmd;
|
||||||
|
@ -331,13 +331,9 @@ void cgit_print_site_readme()
|
|||||||
{
|
{
|
||||||
if (!ctx.cfg.root_readme)
|
if (!ctx.cfg.root_readme)
|
||||||
return;
|
return;
|
||||||
if (ctx.cfg.about_filter) {
|
if (ctx.cfg.about_filter)
|
||||||
ctx.cfg.about_filter->argv[1] = ctx.cfg.root_readme;
|
cgit_open_filter(ctx.cfg.about_filter, ctx.cfg.root_readme);
|
||||||
cgit_open_filter(ctx.cfg.about_filter);
|
|
||||||
}
|
|
||||||
html_include(ctx.cfg.root_readme);
|
html_include(ctx.cfg.root_readme);
|
||||||
if (ctx.cfg.about_filter) {
|
if (ctx.cfg.about_filter)
|
||||||
cgit_close_filter(ctx.cfg.about_filter);
|
cgit_close_filter(ctx.cfg.about_filter);
|
||||||
ctx.cfg.about_filter->argv[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
13
ui-summary.c
13
ui-summary.c
@ -151,18 +151,17 @@ void cgit_print_repo_readme(char *path)
|
|||||||
* filesystem, while applying the about-filter.
|
* filesystem, while applying the about-filter.
|
||||||
*/
|
*/
|
||||||
html("<div id='summary'>");
|
html("<div id='summary'>");
|
||||||
if (ctx.repo->about_filter) {
|
if (ctx.repo->about_filter)
|
||||||
ctx.repo->about_filter->argv[1] = filename;
|
cgit_open_filter(ctx.repo->about_filter, filename);
|
||||||
cgit_open_filter(ctx.repo->about_filter);
|
|
||||||
}
|
|
||||||
if (ref)
|
if (ref)
|
||||||
cgit_print_file(filename, ref, 1);
|
cgit_print_file(filename, ref, 1);
|
||||||
else
|
else
|
||||||
html_include(filename);
|
html_include(filename);
|
||||||
if (ctx.repo->about_filter) {
|
|
||||||
|
if (ctx.repo->about_filter)
|
||||||
cgit_close_filter(ctx.repo->about_filter);
|
cgit_close_filter(ctx.repo->about_filter);
|
||||||
ctx.repo->about_filter->argv[1] = NULL;
|
|
||||||
}
|
|
||||||
html("</div>");
|
html("</div>");
|
||||||
if (free_filename)
|
if (free_filename)
|
||||||
free(filename);
|
free(filename);
|
||||||
|
@ -45,13 +45,12 @@ static void print_text_buffer(const char *name, char *buf, unsigned long size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.repo->source_filter) {
|
if (ctx.repo->source_filter) {
|
||||||
|
char *filter_arg = xstrdup(name);
|
||||||
html("<td class='lines'><pre><code>");
|
html("<td class='lines'><pre><code>");
|
||||||
ctx.repo->source_filter->argv[1] = xstrdup(name);
|
cgit_open_filter(ctx.repo->source_filter, filter_arg);
|
||||||
cgit_open_filter(ctx.repo->source_filter);
|
|
||||||
html_raw(buf, size);
|
html_raw(buf, size);
|
||||||
cgit_close_filter(ctx.repo->source_filter);
|
cgit_close_filter(ctx.repo->source_filter);
|
||||||
free(ctx.repo->source_filter->argv[1]);
|
free(filter_arg);
|
||||||
ctx.repo->source_filter->argv[1] = NULL;
|
|
||||||
html("</code></pre></td></tr></table>\n");
|
html("</code></pre></td></tr></table>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user