diff --git a/README.md b/README.md index 2797847..7e62b27 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,8 @@ imgcli [-i INPUT]... [-vf GRAPH] [-q N] [-f FMT] [-y|-n] [--json] OUTPUT --json emit one machine-readable JSON result line (an array in batch) --quiet suppress the human-readable success line --dry-run validate the filtergraph + report output dims; write nothing - -filters list every filter (add --json for a machine-readable list) + -filters [NAME] list every filter, or just NAME's syntax (add --json for a + machine-readable list) -info print input dimensions and exit -V print version -h help diff --git a/man/imgcli.1 b/man/imgcli.1 index 6f7c828..19ecd90 100644 --- a/man/imgcli.1 +++ b/man/imgcli.1 @@ -94,8 +94,10 @@ Suppress the human-readable success line. .B \-\-dry\-run Validate the filtergraph and report the output dimensions; write nothing. .TP -.B \-filters -List every filter. Add +.BI \-filters " [NAME]" +List every filter, or with +.I NAME +just that one filter's syntax (exit status 1 if no filter has that name). Add .B \-\-json for a machine-readable list. .TP diff --git a/src/filters.c b/src/filters.c index 1b866b3..af81aad 100644 --- a/src/filters.c +++ b/src/filters.c @@ -762,6 +762,30 @@ void filters_print_json(void) { printf("]\n"); } +/* Print one filter's help, looked up by exact name (for `imgcli -filters NAME`). + * With json, emits the same [{name,syntax,description}] array shape as + * filters_print_json, filtered to the single match. Returns 1 if the filter was + * found, 0 otherwise (so the caller can set a non-zero exit code). */ +int filters_print_single(const char *name, int json) { + for (int i = 0; i < NFILTERS; i++) { + if (strcmp(FILTERS[i].name, name) != 0) continue; + if (json) { + char syntax[128]; + const char *desc; + split_usage(FILTERS[i].usage, syntax, sizeof syntax, &desc); + fputs("[\n {\"name\":", stdout); json_str(stdout, FILTERS[i].name); + fputs(",\"syntax\":", stdout); json_str(stdout, syntax); + fputs(",\"description\":", stdout); json_str(stdout, desc); + fputs("}\n]\n", stdout); + } else { + printf(" %s\n", FILTERS[i].usage); + } + return 1; + } + fprintf(stderr, "imgcli: no filter named '%s' (try -filters to list them)\n", name); + return 0; +} + /* trim leading/trailing ascii whitespace in place, returns start */ static char *trim(char *s) { while (*s && isspace((unsigned char)*s)) s++; diff --git a/src/filters.h b/src/filters.h index 93a2337..0e83de9 100644 --- a/src/filters.h +++ b/src/filters.h @@ -23,6 +23,10 @@ Image *run_filtergraph(const char *graph, Image *base, AppContext *app, char **e /* Print the filter catalogue to stdout (for `imgcli -filters`). */ void filters_print_list(void); +/* Print one filter's help by exact name (`imgcli -filters NAME`), honouring + * --json. Returns 1 if found, 0 if no filter has that name. */ +int filters_print_single(const char *name, int json); + /* Print the filter catalogue as a JSON array of {name, syntax, description} * to stdout (for `imgcli -filters --json`). */ void filters_print_json(void); diff --git a/src/main.c b/src/main.c index 2b9d76a..b7fc18f 100644 --- a/src/main.c +++ b/src/main.c @@ -55,7 +55,7 @@ static void usage(FILE *f) { " --json emit a single machine-readable JSON result line (array in batch)\n" " --quiet suppress the human-readable success line\n" " --dry-run validate the filtergraph and report output dims; write nothing\n" - " -filters list available filters and exit\n" + " -filters [NAME] list filters (or, with NAME, one filter's syntax) and exit\n" " -info print info about each input and exit\n" " -V, --version print version and exit\n" " -h, --help show this help\n" @@ -205,12 +205,17 @@ int main(int argc, char **argv) { int overwrite = -1; /* -1 ask/refuse, 1 = -y, 0 = -n */ int want_filters = 0, want_info = 0, json = 0, quiet = 0, dry_run = 0, fail_fast = 0; char msg[512]; + const char *filter_name = NULL; /* `-filters NAME` -> help for one filter */ for (int i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) { usage(stdout); return 0; } else if (!strcmp(arg, "-V") || !strcmp(arg, "--version")) { printf("imgcli %s\n", IMGCLI_VERSION); return 0; } - else if (!strcmp(arg, "-filters")) want_filters = 1; + else if (!strcmp(arg, "-filters")) { + want_filters = 1; + /* an optional non-flag token names a single filter to describe */ + if (i + 1 < argc && argv[i + 1][0] != '-') filter_name = argv[++i]; + } else if (!strcmp(arg, "-info")) want_info = 1; else if (!strcmp(arg, "--json")) json = 1; else if (!strcmp(arg, "--quiet")) quiet = 1; @@ -254,7 +259,12 @@ int main(int argc, char **argv) { } } - if (want_filters) { if (json) filters_print_json(); else filters_print_list(); return 0; } + if (want_filters) { + if (filter_name) return filters_print_single(filter_name, json) ? 0 : 1; + if (json) filters_print_json(); + else filters_print_list(); + return 0; + } if (ninputs == 0) { emit_error(json, "no input (use -i); try -h for help"); return 2; }