From a6d6ded9a5d686e6033e1a97c248677f54f49455 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 13 Jun 2017 22:18:56 -0700 Subject: [PATCH] split builtin contains into its own module --- Makefile.in | 2 +- src/builtin.cpp | 53 +------------------------- src/builtin_contains.cpp | 82 ++++++++++++++++++++++++++++++++++++++++ src/builtin_contains.h | 9 +++++ 4 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 src/builtin_contains.cpp create mode 100644 src/builtin_contains.h diff --git a/Makefile.in b/Makefile.in index 912e74e53..457396588 100644 --- a/Makefile.in +++ b/Makefile.in @@ -103,7 +103,7 @@ FISH_OBJS := obj/autoload.o obj/builtin.o obj/builtin_bind.o obj/builtin_block.o obj/builtin_history.o obj/builtin_status.o obj/builtin_read.o \ obj/builtin_source.o obj/builtin_random.o obj/builtin_echo.o \ obj/builtin_cd.o obj/builtin_disown.o obj/builtin_function.o \ - obj/builtin_builtin.o obj/builtin_command.o \ + obj/builtin_builtin.o obj/builtin_command.o obj/builtin_contains.o \ obj/builtin_complete.o obj/builtin_jobs.o obj/builtin_printf.o \ obj/builtin_set.o obj/builtin_set_color.o obj/builtin_string.o \ obj/builtin_test.o obj/builtin_ulimit.o obj/color.o obj/common.o \ diff --git a/src/builtin.cpp b/src/builtin.cpp index fcb45a05b..01bfbb0ff 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -36,6 +36,7 @@ #include "builtin_command.h" #include "builtin_commandline.h" #include "builtin_complete.h" +#include "builtin_contains.h" #include "builtin_disown.h" #include "builtin_echo.h" #include "builtin_emit.h" @@ -329,58 +330,6 @@ static int builtin_count(parser_t &parser, io_streams_t &streams, wchar_t **argv return argc - 1 == 0 ? STATUS_CMD_ERROR : STATUS_CMD_OK; } -/// Implementation of the builtin contains command, used to check if a specified string is part of -/// a list. -static int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **argv) { - int argc = builtin_count_args(argv); - wchar_t *needle; - bool should_output_index = false; - - static const wchar_t *short_options = L"+hi"; - static const struct woption long_options[] = { - {L"help", no_argument, NULL, 'h'}, {L"index", no_argument, NULL, 'i'}, {NULL, 0, NULL, 0}}; - - int opt; - wgetopter_t w; - while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) { - switch (opt) { - case 'h': { - builtin_print_help(parser, streams, argv[0], streams.out); - return STATUS_CMD_OK; - } - case ':': { - builtin_missing_argument(parser, streams, argv[0], argv[w.woptind - 1]); - return STATUS_INVALID_ARGS; - } - case '?': { - builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); - return STATUS_INVALID_ARGS; - } - case 'i': { - should_output_index = true; - break; - } - default: { - DIE("unexpected retval from wgetopt_long"); - break; - } - } - } - - needle = argv[w.woptind]; - if (!needle) { - streams.err.append_format(_(L"%ls: Key not specified\n"), argv[0]); - } else { - for (int i = w.woptind + 1; i < argc; i++) { - if (!wcscmp(needle, argv[i])) { - if (should_output_index) streams.out.append_format(L"%d\n", i - w.woptind); - return STATUS_CMD_OK; - } - } - } - return STATUS_CMD_ERROR; -} - /// Builtin for putting a job in the foreground. static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) { job_t *j = NULL; diff --git a/src/builtin_contains.cpp b/src/builtin_contains.cpp new file mode 100644 index 000000000..9d9b27171 --- /dev/null +++ b/src/builtin_contains.cpp @@ -0,0 +1,82 @@ +// Implementation of the contains builtin. +#include "config.h" // IWYU pragma: keep + +#include +#include + +#include "builtin.h" +#include "builtin_contains.h" +#include "common.h" +#include "fallback.h" // IWYU pragma: keep +#include "io.h" +#include "wgetopt.h" +#include "wutil.h" // IWYU pragma: keep + +struct cmd_opts { + bool print_help = false; + bool print_index = false; +}; +static const wchar_t *short_options = L"+hi"; +static const struct woption long_options[] = { + {L"help", no_argument, NULL, 'h'}, {L"index", no_argument, NULL, 'i'}, {NULL, 0, NULL, 0}}; + +static int parse_cmd_opts(struct cmd_opts *opts, int *optind, int argc, wchar_t **argv, + parser_t &parser, io_streams_t &streams) { + wchar_t *cmd = argv[0]; + int opt; + wgetopter_t w; + while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) { + switch (opt) { + case 'h': { + opts->print_help = true; + return STATUS_CMD_OK; + } + case 'i': { + opts->print_index = true; + break; + } + case '?': { + builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); + return STATUS_INVALID_ARGS; + } + default: { + DIE("unexpected retval from wgetopt_long"); + break; + } + } + } + + *optind = w.woptind; + return STATUS_CMD_OK; +} + +/// Implementation of the builtin contains command, used to check if a specified string is part of +/// a list. +int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **argv) { + const wchar_t *cmd = argv[0]; + int argc = builtin_count_args(argv); + struct cmd_opts opts; + + int optind; + int retval = parse_cmd_opts(&opts, &optind, argc, argv, parser, streams); + if (retval != STATUS_CMD_OK) return retval; + + if (opts.print_help) { + builtin_print_help(parser, streams, cmd, streams.out); + return STATUS_INVALID_ARGS; + } + + wchar_t *needle = argv[optind]; + if (!needle) { + streams.err.append_format(_(L"%ls: Key not specified\n"), cmd); + } else { + for (int i = optind + 1; i < argc; i++) { + if (!wcscmp(needle, argv[i])) { + if (opts.print_index) streams.out.append_format(L"%d\n", i - optind); + return STATUS_CMD_OK; + } + } + } + + return STATUS_CMD_ERROR; +} diff --git a/src/builtin_contains.h b/src/builtin_contains.h new file mode 100644 index 000000000..f331846f1 --- /dev/null +++ b/src/builtin_contains.h @@ -0,0 +1,9 @@ +// Prototypes for executing builtin_contains function. +#ifndef FISH_BUILTIN_CONTAINS_H +#define FISH_BUILTIN_CONTAINS_H + +class parser_t; +struct io_streams_t; + +int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **argv); +#endif