diff options
author | John Hawthorn <john.hawthorn@gmail.com> | 2016-06-19 18:03:47 -0700 |
---|---|---|
committer | John Hawthorn <john.hawthorn@gmail.com> | 2016-06-19 18:03:47 -0700 |
commit | 45be23beb4f6b33f1764c64817062b213fd45e7d (patch) | |
tree | 2b736de10518d428a37a090fabad74c74cc10753 | |
parent | 26452f2efa488df369263d2a5ff661147ede5640 (diff) |
Extract option parsing to separate file
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/fzy.c | 133 | ||||
-rw-r--r-- | src/options.c | 104 | ||||
-rw-r--r-- | src/options.h | 12 |
4 files changed, 142 insertions, 109 deletions
@@ -11,7 +11,7 @@ INSTALL=install INSTALL_PROGRAM=$(INSTALL) INSTALL_DATA=${INSTALL} -m 644 -OBJECTS=src/fzy.o src/match.o src/tty.o src/choices.o +OBJECTS=src/fzy.o src/match.o src/tty.o src/choices.o src/options.o TESTOBJECTS=test/fzytest.c src/match.o src/choices.o all: fzy @@ -2,21 +2,16 @@ #include <string.h> #include <stdlib.h> #include <ctype.h> -#include <getopt.h> #include <limits.h> #include "match.h" #include "tty.h" #include "choices.h" +#include "options.h" #include "../config.h" -static int flag_show_scores = 0; - -static size_t num_lines = 10; -static size_t scrolloff = 1; - -static const char *prompt = "> "; +options_t options; #define SEARCH_SIZE_MAX 4096 static char search[SEARCH_SIZE_MAX + 1] = {0}; @@ -24,7 +19,7 @@ static char search[SEARCH_SIZE_MAX + 1] = {0}; static void clear(tty_t *tty) { tty_setcol(tty, 0); size_t line = 0; - while (line++ < num_lines) { + while (line++ < options.num_lines) { tty_newline(tty); } tty_clearline(tty); @@ -42,7 +37,7 @@ static void draw_match(tty_t *tty, const char *choice, int selected) { size_t maxwidth = tty_getwidth(tty); - if (flag_show_scores) + if (options.show_scores) tty_printf(tty, "(%5.2f) ", score); if (selected) @@ -66,16 +61,17 @@ static void draw_match(tty_t *tty, const char *choice, int selected) { } static void draw(tty_t *tty, choices_t *choices) { + unsigned int num_lines = options.num_lines; size_t start = 0; size_t current_selection = choices->selection; - if (current_selection + scrolloff >= num_lines) { - start = current_selection + scrolloff - num_lines + 1; + if (current_selection + options.scrolloff >= num_lines) { + start = current_selection + options.scrolloff - num_lines + 1; if (start + num_lines >= choices_available(choices)) { start = choices_available(choices) - num_lines; } } tty_setcol(tty, 0); - tty_printf(tty, "%s%s", prompt, search); + tty_printf(tty, "%s%s", options.prompt, search); tty_clearline(tty); for (size_t i = start; i < start + num_lines; i++) { tty_printf(tty, "\n"); @@ -86,7 +82,7 @@ static void draw(tty_t *tty, choices_t *choices) { } } tty_moveup(tty, num_lines); - tty_setcol(tty, strlen(prompt) + strlen(search)); + tty_setcol(tty, strlen(options.prompt) + strlen(search)); tty_flush(tty); } @@ -167,119 +163,40 @@ static void run(tty_t *tty, choices_t *choices) { } while (1); } -static const char *usage_str = - "" - "Usage: fzy [OPTION]...\n" - " -l, --lines=LINES Specify how many lines of results to show (default 10)\n" - " -p, --prompt=PROMPT Input prompt (default '> ')\n" - " -q, --query=QUERY Use QUERY as the initial search string\n" - " -e, --show-matches=QUERY Output the sorted matches of QUERY\n" - " -t, --tty=TTY Specify file to use as TTY device (default /dev/tty)\n" - " -s, --show-scores Show the scores of each match\n" - " -h, --help Display this help and exit\n" - " -v, --version Output version information and exit\n"; - -static void usage(const char *argv0) { - fprintf(stderr, usage_str, argv0); -} - -static struct option longopts[] = {{"show-matches", required_argument, NULL, 'e'}, - {"query", required_argument, NULL, 'q'}, - {"lines", required_argument, NULL, 'l'}, - {"tty", required_argument, NULL, 't'}, - {"prompt", required_argument, NULL, 'p'}, - {"show-scores", no_argument, NULL, 's'}, - {"version", no_argument, NULL, 'v'}, - {"benchmark", optional_argument, NULL, 'b'}, - {"help", no_argument, NULL, 'h'}, - {NULL, 0, NULL, 0}}; - int main(int argc, char *argv[]) { - int benchmark = 0; - const char *filter = NULL; - const char *tty_filename = "/dev/tty"; - char c; - while ((c = getopt_long(argc, argv, "vhse:q:l:t:p:", longopts, NULL)) != -1) { - switch (c) { - case 'v': - printf("%s " VERSION " (c) 2014 John Hawthorn\n", argv[0]); - exit(EXIT_SUCCESS); - case 's': - flag_show_scores = 1; - break; - case 'q': - strncpy(search, optarg, SEARCH_SIZE_MAX); - break; - case 'e': - filter = optarg; - break; - case 'b': - if (optarg) { - if (sscanf(optarg, "%d", &benchmark) != 1) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - } else { - benchmark = 100; - } - break; - case 't': - tty_filename = optarg; - break; - case 'p': - prompt = optarg; - break; - case 'l': { - int l; - if (!strcmp(optarg, "max")) { - l = INT_MAX; - } else if (sscanf(optarg, "%d", &l) != 1 || l < 3) { - fprintf(stderr, "Invalid format for --lines: %s\n", optarg); - fprintf(stderr, "Must be integer in range 3..\n"); - usage(argv[0]); - exit(EXIT_FAILURE); - } - num_lines = l; - } break; - case 'h': - default: - usage(argv[0]); - exit(EXIT_SUCCESS); - } - } - if (optind != argc) { - usage(argv[0]); - exit(EXIT_FAILURE); - } + options_parse(&options, argc, argv); choices_t choices; choices_init(&choices); choices_fread(&choices, stdin); - if (benchmark) { - if (!filter) { + if (options.benchmark) { + if (!options.filter) { fprintf(stderr, "Must specify -e/--show-matches with --benchmark\n"); exit(EXIT_FAILURE); } - for (int i = 0; i < benchmark; i++) - choices_search(&choices, filter); - } else if (filter) { - choices_search(&choices, filter); + for (int i = 0; i < options.benchmark; i++) + choices_search(&choices, options.filter); + } else if (options.filter) { + choices_search(&choices, options.filter); for (size_t i = 0; i < choices_available(&choices); i++) { - if (flag_show_scores) + if (options.show_scores) printf("%f\t", choices_getscore(&choices, i)); printf("%s\n", choices_get(&choices, i)); } } else { /* interactive */ tty_t tty; - tty_init(&tty, tty_filename); + tty_init(&tty, options.tty_filename); + + if (options.num_lines > choices.size) + options.num_lines = choices.size; - if (num_lines > choices.size) - num_lines = choices.size; + if (options.num_lines + 1 > tty_getheight(&tty)) + options.num_lines = tty_getheight(&tty) - 1; - if (num_lines + 1 > tty_getheight(&tty)) - num_lines = tty_getheight(&tty) - 1; + if (options.init_search) + strncpy(search, options.init_search, SEARCH_SIZE_MAX); run(&tty, &choices); } diff --git a/src/options.c b/src/options.c new file mode 100644 index 0000000..3150ead --- /dev/null +++ b/src/options.c @@ -0,0 +1,104 @@ +#include <getopt.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "options.h" + +static const char *usage_str = + "" + "Usage: fzy [OPTION]...\n" + " -l, --lines=LINES Specify how many lines of results to show (default 10)\n" + " -p, --prompt=PROMPT Input prompt (default '> ')\n" + " -q, --query=QUERY Use QUERY as the initial search string\n" + " -e, --show-matches=QUERY Output the sorted matches of QUERY\n" + " -t, --tty=TTY Specify file to use as TTY device (default /dev/tty)\n" + " -s, --show-scores Show the scores of each match\n" + " -h, --help Display this help and exit\n" + " -v, --version Output version information and exit\n"; + +static void usage(const char *argv0) { + fprintf(stderr, usage_str, argv0); +} + +static struct option longopts[] = {{"show-matches", required_argument, NULL, 'e'}, + {"query", required_argument, NULL, 'q'}, + {"lines", required_argument, NULL, 'l'}, + {"tty", required_argument, NULL, 't'}, + {"prompt", required_argument, NULL, 'p'}, + {"show-scores", no_argument, NULL, 's'}, + {"version", no_argument, NULL, 'v'}, + {"benchmark", optional_argument, NULL, 'b'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0}}; + +void options_set_defaults(options_t *options) { + /* set defaults */ + options->benchmark = 0; + options->filter = NULL; + options->init_search = NULL; + options->tty_filename = "/dev/tty"; + options->show_scores = 0; + options->num_lines = 10; + options->scrolloff = 1; + options->prompt = "> "; +} + +void options_parse(options_t *options, int argc, char *argv[]) { + options_set_defaults(options); + + char c; + while ((c = getopt_long(argc, argv, "vhse:q:l:t:p:", longopts, NULL)) != -1) { + switch (c) { + case 'v': + printf("%s " VERSION " (c) 2014 John Hawthorn\n", argv[0]); + exit(EXIT_SUCCESS); + case 's': + options->show_scores = 1; + break; + case 'q': + options->init_search = optarg; + break; + case 'e': + options->filter = optarg; + break; + case 'b': + if (optarg) { + if (sscanf(optarg, "%d", &options->benchmark) != 1) { + usage(argv[0]); + exit(EXIT_FAILURE); + } + } else { + options->benchmark = 100; + } + break; + case 't': + options->tty_filename = optarg; + break; + case 'p': + options->prompt = optarg; + break; + case 'l': { + int l; + if (!strcmp(optarg, "max")) { + l = INT_MAX; + } else if (sscanf(optarg, "%d", &l) != 1 || l < 3) { + fprintf(stderr, "Invalid format for --lines: %s\n", optarg); + fprintf(stderr, "Must be integer in range 3..\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + options->num_lines = l; + } break; + case 'h': + default: + usage(argv[0]); + exit(EXIT_SUCCESS); + } + } + if (optind != argc) { + usage(argv[0]); + exit(EXIT_FAILURE); + } +} diff --git a/src/options.h b/src/options.h new file mode 100644 index 0000000..e19e292 --- /dev/null +++ b/src/options.h @@ -0,0 +1,12 @@ +typedef struct { + int benchmark; + const char *filter; + const char *init_search; + const char *tty_filename; + int show_scores; + unsigned int num_lines; + unsigned int scrolloff; + const char *prompt; +} options_t; + +void options_parse(options_t *options, int argc, char *argv[]); |