From cee2b7c4a2d412480142eb5762521fd0583c8bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=B8rl=C3=BCck=20Berg?= <36937807+henrikhorluck@users.noreply.github.com> Date: Tue, 27 Jun 2023 19:59:30 +0200 Subject: [PATCH] Remove C++ code --- CMakeLists.txt | 2 +- src/builtin.cpp | 1 - src/builtins/status.cpp | 504 ---------------------------------------- src/builtins/status.h | 11 - 4 files changed, 1 insertion(+), 517 deletions(-) delete mode 100644 src/builtins/status.cpp delete mode 100644 src/builtins/status.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 35d54561c..9ce6fcfd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,7 @@ set(FISH_BUILTIN_SRCS src/builtins/function.cpp src/builtins/functions.cpp src/builtins/history.cpp src/builtins/jobs.cpp src/builtins/path.cpp src/builtins/read.cpp src/builtins/set.cpp - src/builtins/source.cpp src/builtins/status.cpp + src/builtins/source.cpp src/builtins/string.cpp src/builtins/ulimit.cpp ) diff --git a/src/builtin.cpp b/src/builtin.cpp index 194393b9d..730f26cf9 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -44,7 +44,6 @@ #include "builtins/set.h" #include "builtins/shared.rs.h" #include "builtins/source.h" -#include "builtins/status.h" #include "builtins/string.h" #include "builtins/ulimit.h" #include "complete.h" diff --git a/src/builtins/status.cpp b/src/builtins/status.cpp deleted file mode 100644 index edfbcf8b4..000000000 --- a/src/builtins/status.cpp +++ /dev/null @@ -1,504 +0,0 @@ -// Implementation of the status builtin. -#include "config.h" // IWYU pragma: keep - -#include "status.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "../builtin.h" -#include "../common.h" -#include "../enum_map.h" -#include "../fallback.h" // IWYU pragma: keep -#include "../io.h" -#include "../maybe.h" -#include "../parser.h" -#include "../proc.h" -#include "../wgetopt.h" -#include "../wutil.h" // IWYU pragma: keep -#include "future_feature_flags.h" - -enum status_cmd_t { - STATUS_CURRENT_CMD = 1, - STATUS_BASENAME, - STATUS_DIRNAME, - STATUS_FEATURES, - STATUS_FILENAME, - STATUS_FISH_PATH, - STATUS_FUNCTION, - STATUS_IS_BLOCK, - STATUS_IS_BREAKPOINT, - STATUS_IS_COMMAND_SUB, - STATUS_IS_FULL_JOB_CTRL, - STATUS_IS_INTERACTIVE, - STATUS_IS_INTERACTIVE_JOB_CTRL, - STATUS_IS_LOGIN, - STATUS_IS_NO_JOB_CTRL, - STATUS_LINE_NUMBER, - STATUS_SET_JOB_CONTROL, - STATUS_STACK_TRACE, - STATUS_TEST_FEATURE, - STATUS_CURRENT_COMMANDLINE, - STATUS_UNDEF -}; - -// Must be sorted by string, not enum or random. -const enum_map status_enum_map[] = { - {STATUS_BASENAME, L"basename"}, - {STATUS_BASENAME, L"current-basename"}, - {STATUS_CURRENT_CMD, L"current-command"}, - {STATUS_CURRENT_COMMANDLINE, L"current-commandline"}, - {STATUS_DIRNAME, L"current-dirname"}, - {STATUS_FILENAME, L"current-filename"}, - {STATUS_FUNCTION, L"current-function"}, - {STATUS_LINE_NUMBER, L"current-line-number"}, - {STATUS_DIRNAME, L"dirname"}, - {STATUS_FEATURES, L"features"}, - {STATUS_FILENAME, L"filename"}, - {STATUS_FISH_PATH, L"fish-path"}, - {STATUS_FUNCTION, L"function"}, - {STATUS_IS_BLOCK, L"is-block"}, - {STATUS_IS_BREAKPOINT, L"is-breakpoint"}, - {STATUS_IS_COMMAND_SUB, L"is-command-substitution"}, - {STATUS_IS_FULL_JOB_CTRL, L"is-full-job-control"}, - {STATUS_IS_INTERACTIVE, L"is-interactive"}, - {STATUS_IS_INTERACTIVE_JOB_CTRL, L"is-interactive-job-control"}, - {STATUS_IS_LOGIN, L"is-login"}, - {STATUS_IS_NO_JOB_CTRL, L"is-no-job-control"}, - {STATUS_SET_JOB_CONTROL, L"job-control"}, - {STATUS_LINE_NUMBER, L"line-number"}, - {STATUS_STACK_TRACE, L"print-stack-trace"}, - {STATUS_STACK_TRACE, L"stack-trace"}, - {STATUS_TEST_FEATURE, L"test-feature"}, - {STATUS_UNDEF, nullptr}}; -#define status_enum_map_len (sizeof status_enum_map / sizeof *status_enum_map) - -#define CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) \ - if (!args.empty()) { \ - const wchar_t *subcmd_str = enum_to_str(status_cmd, status_enum_map); \ - if (!subcmd_str) subcmd_str = L"default"; \ - streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 0, args.size()); \ - retval = STATUS_INVALID_ARGS; \ - break; \ - } - -/// Values that may be returned from the test-feature option to status. -enum { TEST_FEATURE_ON, TEST_FEATURE_OFF, TEST_FEATURE_NOT_RECOGNIZED }; - -static maybe_t job_control_str_to_mode(const wchar_t *mode, const wchar_t *cmd, - io_streams_t &streams) { - if (std::wcscmp(mode, L"full") == 0) { - return job_control_t::all; - } else if (std::wcscmp(mode, L"interactive") == 0) { - return job_control_t::interactive; - } else if (std::wcscmp(mode, L"none") == 0) { - return job_control_t::none; - } - streams.err.append_format(L"%ls: Invalid job control mode '%ls'\n", cmd, mode); - return none(); -} - -namespace { -struct status_cmd_opts_t { - int level{1}; - maybe_t new_job_control_mode{}; - status_cmd_t status_cmd{STATUS_UNDEF}; - bool print_help{false}; -}; -} // namespace - -/// Note: Do not add new flags that represent subcommands. We're encouraging people to switch to -/// the non-flag subcommand form. While these flags are deprecated they must be supported at -/// least until fish 3.0 and possibly longer to avoid breaking everyones config.fish and other -/// scripts. -static const wchar_t *const short_options = L":L:cbilfnhj:t"; -static const struct woption long_options[] = { - {L"help", no_argument, 'h'}, - {L"current-filename", no_argument, 'f'}, - {L"current-line-number", no_argument, 'n'}, - {L"filename", no_argument, 'f'}, - {L"fish-path", no_argument, STATUS_FISH_PATH}, - {L"is-block", no_argument, 'b'}, - {L"is-command-substitution", no_argument, 'c'}, - {L"is-full-job-control", no_argument, STATUS_IS_FULL_JOB_CTRL}, - {L"is-interactive", no_argument, 'i'}, - {L"is-interactive-job-control", no_argument, STATUS_IS_INTERACTIVE_JOB_CTRL}, - {L"is-login", no_argument, 'l'}, - {L"is-no-job-control", no_argument, STATUS_IS_NO_JOB_CTRL}, - {L"job-control", required_argument, 'j'}, - {L"level", required_argument, 'L'}, - {L"line", no_argument, 'n'}, - {L"line-number", no_argument, 'n'}, - {L"print-stack-trace", no_argument, 't'}, - {}}; - -/// Remember the status subcommand and disallow selecting more than one status subcommand. -static bool set_status_cmd(const wchar_t *cmd, status_cmd_opts_t &opts, status_cmd_t sub_cmd, - io_streams_t &streams) { - if (opts.status_cmd != STATUS_UNDEF) { - streams.err.append_format(BUILTIN_ERR_COMBO2_EXCLUSIVE, cmd, - enum_to_str(opts.status_cmd, status_enum_map), - enum_to_str(sub_cmd, status_enum_map)); - return false; - } - - opts.status_cmd = sub_cmd; - return true; -} - -/// Print the features and their values. -static void print_features(io_streams_t &streams) { - auto max_len = std::numeric_limits::min(); - for (const auto &md : feature_metadata()) - max_len = std::max(max_len, static_cast(md.name->size())); - for (const auto &md : feature_metadata()) { - int set = feature_test(md.flag); - streams.out.append_format(L"%-*ls%-3s %ls %ls\n", max_len + 1, md.name->c_str(), - set ? "on" : "off", md.groups->c_str(), md.description->c_str()); - } -} - -static int parse_cmd_opts(status_cmd_opts_t &opts, int *optind, //!OCLINT(high ncss method) - int argc, const wchar_t **argv, parser_t &parser, io_streams_t &streams) { - const wchar_t *cmd = argv[0]; - int opt; - wgetopter_t w; - while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, nullptr)) != -1) { - switch (opt) { - case STATUS_IS_FULL_JOB_CTRL: { - if (!set_status_cmd(cmd, opts, STATUS_IS_FULL_JOB_CTRL, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case STATUS_IS_INTERACTIVE_JOB_CTRL: { - if (!set_status_cmd(cmd, opts, STATUS_IS_INTERACTIVE_JOB_CTRL, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case STATUS_IS_NO_JOB_CTRL: { - if (!set_status_cmd(cmd, opts, STATUS_IS_NO_JOB_CTRL, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case STATUS_FISH_PATH: { - if (!set_status_cmd(cmd, opts, STATUS_FISH_PATH, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'L': { - opts.level = fish_wcstoi(w.woptarg); - if (opts.level < 0 || errno == ERANGE) { - streams.err.append_format(_(L"%ls: Invalid level value '%ls'\n"), argv[0], - w.woptarg); - return STATUS_INVALID_ARGS; - } else if (errno) { - streams.err.append_format(BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg); - return STATUS_INVALID_ARGS; - } - break; - } - case 'c': { - if (!set_status_cmd(cmd, opts, STATUS_IS_COMMAND_SUB, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'b': { - if (!set_status_cmd(cmd, opts, STATUS_IS_BLOCK, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'i': { - if (!set_status_cmd(cmd, opts, STATUS_IS_INTERACTIVE, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'l': { - if (!set_status_cmd(cmd, opts, STATUS_IS_LOGIN, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'f': { - if (!set_status_cmd(cmd, opts, STATUS_FILENAME, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'n': { - if (!set_status_cmd(cmd, opts, STATUS_LINE_NUMBER, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'j': { - if (!set_status_cmd(cmd, opts, STATUS_SET_JOB_CONTROL, streams)) { - return STATUS_CMD_ERROR; - } - auto job_mode = job_control_str_to_mode(w.woptarg, cmd, streams); - if (!job_mode) { - return STATUS_CMD_ERROR; - } - opts.new_job_control_mode = job_mode; - break; - } - case 't': { - if (!set_status_cmd(cmd, opts, STATUS_STACK_TRACE, streams)) { - return STATUS_CMD_ERROR; - } - break; - } - case 'h': { - opts.print_help = true; - break; - } - case ':': { - builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]); - return STATUS_INVALID_ARGS; - } - case '?': { - builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); - return STATUS_INVALID_ARGS; - } - default: { - DIE("unexpected retval from wgetopt_long"); - } - } - } - - *optind = w.woptind; - return STATUS_CMD_OK; -} - -/// The status builtin. Gives various status information on fish. -maybe_t builtin_status(parser_t &parser, io_streams_t &streams, const wchar_t **argv) { - const wchar_t *cmd = argv[0]; - int argc = builtin_count_args(argv); - status_cmd_opts_t 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); - return STATUS_CMD_OK; - } - - // If a status command hasn't already been specified via a flag check the first word. - // Note that this can be simplified after we eliminate allowing subcommands as flags. - if (optind < argc) { - status_cmd_t subcmd = str_to_enum(argv[optind], status_enum_map, status_enum_map_len); - if (subcmd != STATUS_UNDEF) { - if (!set_status_cmd(cmd, opts, subcmd, streams)) { - return STATUS_CMD_ERROR; - } - optind++; - } else { - streams.err.append_format(BUILTIN_ERR_INVALID_SUBCMD, cmd, argv[1]); - return STATUS_INVALID_ARGS; - } - } - - // Every argument that we haven't consumed already is an argument for a subcommand. - const std::vector args(argv + optind, argv + argc); - - switch (opts.status_cmd) { - case STATUS_UNDEF: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - if (get_login()) { - streams.out.append_format(_(L"This is a login shell\n")); - } else { - streams.out.append_format(_(L"This is not a login shell\n")); - } - - auto job_control_mode = get_job_control_mode(); - streams.out.append_format( - _(L"Job control: %ls\n"), - job_control_mode == job_control_t::interactive - ? _(L"Only on interactive jobs") - : (job_control_mode == job_control_t::none ? _(L"Never") : _(L"Always"))); - streams.out.append(parser.stack_trace()); - break; - } - case STATUS_SET_JOB_CONTROL: { - if (opts.new_job_control_mode) { - // Flag form was used. - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - } else { - if (args.size() != 1) { - const wchar_t *subcmd_str = enum_to_str(opts.status_cmd, status_enum_map); - streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 1, - args.size()); - return STATUS_INVALID_ARGS; - } - auto new_mode = job_control_str_to_mode(args[0].c_str(), cmd, streams); - if (!new_mode) { - return STATUS_CMD_ERROR; - } - opts.new_job_control_mode = new_mode; - } - assert(opts.new_job_control_mode && "Should have a new mode"); - set_job_control_mode(*opts.new_job_control_mode); - break; - } - case STATUS_FEATURES: { - print_features(streams); - break; - } - case STATUS_TEST_FEATURE: { - if (args.size() != 1) { - const wchar_t *subcmd_str = enum_to_str(opts.status_cmd, status_enum_map); - streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 1, args.size()); - return STATUS_INVALID_ARGS; - } - retval = TEST_FEATURE_NOT_RECOGNIZED; - for (const auto &md : feature_metadata()) { - if (*md.name == args.front()) { - retval = feature_test(md.flag) ? TEST_FEATURE_ON : TEST_FEATURE_OFF; - break; - } - } - break; - } - case STATUS_BASENAME: - case STATUS_DIRNAME: - case STATUS_FILENAME: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - auto res = parser.current_filename(); - wcstring fn = res ? *res : L""; - if (!fn.empty() && opts.status_cmd == STATUS_DIRNAME) { - fn = wdirname(fn); - } else if (!fn.empty() && opts.status_cmd == STATUS_BASENAME) { - fn = wbasename(fn); - } else if (fn.empty()) { - fn = _(L"Standard input"); - } - streams.out.append_format(L"%ls\n", fn.c_str()); - break; - } - case STATUS_FUNCTION: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - maybe_t fn = parser.get_function_name(opts.level); - streams.out.append_format(L"%ls\n", fn ? fn->c_str() : _(L"Not a function")); - break; - } - case STATUS_LINE_NUMBER: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - // TBD is how to interpret the level argument when fetching the line number. - // See issue #4161. - // streams.out.append_format(L"%d\n", parser.get_lineno(opts.level)); - streams.out.append_format(L"%d\n", parser.get_lineno()); - break; - } - case STATUS_IS_INTERACTIVE: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = is_interactive_session() ? 0 : 1; - break; - } - case STATUS_IS_COMMAND_SUB: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = parser.libdata().is_subshell ? 0 : 1; - break; - } - case STATUS_IS_BLOCK: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = parser.is_block() ? 0 : 1; - break; - } - case STATUS_IS_BREAKPOINT: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = parser.is_breakpoint() ? 0 : 1; - break; - } - case STATUS_IS_LOGIN: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = !get_login(); - break; - } - case STATUS_IS_FULL_JOB_CTRL: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = get_job_control_mode() != job_control_t::all; - break; - } - case STATUS_IS_INTERACTIVE_JOB_CTRL: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = get_job_control_mode() != job_control_t::interactive; - break; - } - case STATUS_IS_NO_JOB_CTRL: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = get_job_control_mode() != job_control_t::none; - break; - } - case STATUS_STACK_TRACE: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - streams.out.append(parser.stack_trace()); - break; - } - case STATUS_CURRENT_CMD: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - const auto &var = parser.libdata().status_vars.command; - if (!var.empty()) { - streams.out.append(var); - streams.out.push(L'\n'); - } else { - streams.out.append(program_name); - streams.out.push(L'\n'); - } - break; - } - case STATUS_CURRENT_COMMANDLINE: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - const auto &var = parser.libdata().status_vars.commandline; - streams.out.append(var); - streams.out.push(L'\n'); - break; - } - case STATUS_FISH_PATH: { - CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd); - auto path = str2wcstring(get_executable_path("fish")); - if (path.empty()) { - streams.err.append_format(L"%ls: Could not get executable path: '%s'\n", cmd, - std::strerror(errno)); - break; - } - - if (path[0] == L'/') { - // This is an absolute path, we can canonicalize it. - auto real = wrealpath(path); - if (real && waccess(*real, F_OK)) { - streams.out.append(*real); - streams.out.push(L'\n'); - } else { - // realpath did not work, just append the path - // - maybe this was obtained via $PATH? - streams.out.append(path); - streams.out.push(L'\n'); - } - } else { - // This is a relative path, it depends on where fish's parent process - // was when it started it and its idea of $PATH. - // The best we can do is to print it directly and hope it works. - streams.out.append(path); - streams.out.push(L'\n'); - } - break; - } - } - - return retval; -} diff --git a/src/builtins/status.h b/src/builtins/status.h deleted file mode 100644 index c10bb7279..000000000 --- a/src/builtins/status.h +++ /dev/null @@ -1,11 +0,0 @@ -// Prototypes for executing builtin_status function. -#ifndef FISH_BUILTIN_STATUS_H -#define FISH_BUILTIN_STATUS_H - -#include "../maybe.h" - -class parser_t; -struct io_streams_t; - -maybe_t builtin_status(parser_t &parser, io_streams_t &streams, const wchar_t **argv); -#endif