diff --git a/include/option-parser.h b/include/option-parser.h index d63f5a8..098e2ee 100644 --- a/include/option-parser.h +++ b/include/option-parser.h @@ -33,7 +33,10 @@ struct option_parser { int n_opts; }; -void option_parser_init(struct option_parser* self, const struct wv_option* options); +#define OPTION_PARSER_CHECK_ALL_ARGUMENTS 0 +#define OPTION_PARSER_STOP_ON_FIRST_NONOPTION 1 -void option_parser_print_usage(struct option_parser* self, FILE* stream); +void option_parser_init(struct option_parser* self, const struct wv_option* options, unsigned flags); + +void option_parser_print_options(struct option_parser* self, FILE* stream); int option_parser_getopt(struct option_parser* self, int argc, char* argv[]); diff --git a/meson.build b/meson.build index 46f8d25..cd226f6 100644 --- a/meson.build +++ b/meson.build @@ -120,6 +120,7 @@ ctlsources = [ 'src/json-ipc.c', 'src/ctl-client.c', 'src/strlcpy.c', + 'src/option-parser.c', ] ctldependencies = [ diff --git a/src/main.c b/src/main.c index dc71b29..45b45dd 100644 --- a/src/main.c +++ b/src/main.c @@ -909,7 +909,7 @@ void on_capture_done(struct screencopy* sc) int wayvnc_usage(struct option_parser* parser, FILE* stream, int rc) { fprintf(stream, "Usage: wayvnc [options] [address [port]]\n\n"); - option_parser_print_usage(parser, stream); + option_parser_print_options(parser, stream); fprintf(stream, "\n"); return rc; } @@ -1297,7 +1297,8 @@ int main(int argc, char* argv[]) }; struct option_parser option_parser; - option_parser_init(&option_parser, opts); + option_parser_init(&option_parser, opts, + OPTION_PARSER_CHECK_ALL_ARGUMENTS); while (1) { int c = option_parser_getopt(&option_parser, argc, argv); diff --git a/src/option-parser.c b/src/option-parser.c index 9f3abba..78d2a04 100644 --- a/src/option-parser.c +++ b/src/option-parser.c @@ -30,7 +30,8 @@ static int count_options(const struct wv_option* opts) } void option_parser_init(struct option_parser* self, - const struct wv_option* options) + const struct wv_option* options, + unsigned flags) { memset(self, 0, sizeof(*self)); @@ -40,6 +41,9 @@ void option_parser_init(struct option_parser* self, int short_opt_index = 0; int long_opt_index = 0; + if (flags && OPTION_PARSER_STOP_ON_FIRST_NONOPTION) + self->short_opts[short_opt_index++] = '+'; + for (int i = 0; i < self->n_opts; ++i) { assert(options[i].short_opt); // TODO: Make this optional? @@ -157,8 +161,9 @@ static void format_option(const struct wv_option* opt, int left_col_width, } } -void option_parser_print_usage(struct option_parser* self, FILE* stream) +void option_parser_print_options(struct option_parser* self, FILE* stream) { + fprintf(stream, "Options:\n"); int left_col_width = get_left_col_width(self->options, self->n_opts); for (int i = 0; i < self->n_opts; ++i) { diff --git a/src/wayvncctl.c b/src/wayvncctl.c index 38cfeae..5504bb0 100644 --- a/src/wayvncctl.c +++ b/src/wayvncctl.c @@ -32,6 +32,7 @@ #include "util.h" #include "ctl-client.h" +#include "option-parser.h" #define MAYBE_UNUSED __attribute__((unused)) @@ -41,30 +42,16 @@ struct wayvncctl { struct ctl_client* ctl; }; -static int wayvncctl_usage(FILE* stream, int rc) +static int wayvncctl_usage(FILE* stream, struct option_parser* options, int rc) { static const char* usage = "Usage: wayvncctl [options] [command [--param1=value1 ...]]\n" "\n" "Connects to and interacts with a running wayvnc instance." "\n" -"Try 'wayvncctl help' for a list of available commands.\n" -"\n" -"Options:\n" -" -S,--socket= Wayvnc control socket path.\n" -" Default: $XDG_RUNTIME_DIR/wayvncctl\n" -" -w,--wait Wait for wayvnc to start up if it's\n" -" not already running.\n" -" -r,--reconnect If disconnected while waiting for\n" -" events, wait for wayvnc to restart.\n" -" -j,--json Output json on stdout.\n" -" -V,--version Show version info.\n" -" -v,--verbose Be more verbose.\n" -" -h,--help Get help (this text).\n" -"\n"; - - fprintf(stream, "%s", usage); - +"Try 'wayvncctl help' for a list of available commands."; + fprintf(stream, "%s\n\n", usage); + option_parser_print_options(options, stream); return rc; } @@ -78,27 +65,36 @@ int main(int argc, char* argv[]) { struct wayvncctl self = { 0 }; - static const char* shortopts = "+S:hVvjwr"; - bool verbose = false; const char* socket_path = NULL; int wait_for_socket = 0; unsigned flags = 0; - static const struct option longopts[] = { - { "socket", required_argument, NULL, 'S' }, - { "wait", no_argument, NULL, 'w' }, - { "reconnect", no_argument, NULL, 'r' }, - { "json", no_argument, NULL, 'j' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'V' }, - { "verbose", no_argument, NULL, 'v' }, - { NULL, 0, NULL, 0 } + static const struct wv_option opts[] = { + { 'S', "socket", "", + "Control socket path." }, + { 'w', "wait", NULL, + "Wait for wayvnc to start up if it's not already running." }, + { 'r', "reconnect", NULL, + "If disconnected while waiting for events, wait for wayvnc to restart." }, + { 'j', "json", NULL, + "Output json on stdout." }, + { 'V', "version", NULL, + "Show version info." }, + { 'v', "verbose", NULL, + "Be more verbose." }, + { 'h', "help", NULL, + "Get help (this text)." }, + { '\0', NULL, NULL, NULL } }; + struct option_parser option_parser; + option_parser_init(&option_parser, opts, + OPTION_PARSER_STOP_ON_FIRST_NONOPTION); + while (1) { - int c = getopt_long(argc, argv, shortopts, longopts, NULL); + int c = option_parser_getopt(&option_parser, argc, argv); if (c < 0) break; @@ -121,14 +117,14 @@ int main(int argc, char* argv[]) case 'V': return show_version(); case 'h': - return wayvncctl_usage(stdout, 0); + return wayvncctl_usage(stdout, &option_parser, 0); default: - return wayvncctl_usage(stderr, 1); + return wayvncctl_usage(stderr, &option_parser, 1); } } argc -= optind; if (argc <= 0) - return wayvncctl_usage(stderr, 1); + return wayvncctl_usage(stderr, &option_parser, 1); argv = &argv[optind]; ctl_client_debug_log(verbose);