From 5f0df359b88803119269b5f94e4c1e86826468e8 Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Fri, 11 Aug 2023 15:18:03 +0200 Subject: [PATCH] Remove C++ version of builtin functions And the C++ reformat_for_screen and event_filter_names as there are no more users. --- CMakeLists.txt | 2 +- src/builtin.cpp | 1 - src/builtins/functions.cpp | 398 ------------------------------------- src/builtins/functions.h | 11 - src/common.cpp | 61 ------ src/common.h | 3 - src/event.cpp | 5 - 7 files changed, 1 insertion(+), 480 deletions(-) delete mode 100644 src/builtins/functions.cpp delete mode 100644 src/builtins/functions.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3090676b6..62d04605f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,7 +103,7 @@ set(FISH_BUILTIN_SRCS src/builtins/commandline.cpp src/builtins/complete.cpp src/builtins/disown.cpp src/builtins/eval.cpp src/builtins/fg.cpp - src/builtins/functions.cpp src/builtins/history.cpp + src/builtins/history.cpp src/builtins/jobs.cpp src/builtins/read.cpp src/builtins/set.cpp src/builtins/source.cpp diff --git a/src/builtin.cpp b/src/builtin.cpp index 790b7fae3..274b1b209 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -35,7 +35,6 @@ #include "builtins/disown.h" #include "builtins/eval.h" #include "builtins/fg.h" -#include "builtins/functions.h" #include "builtins/history.h" #include "builtins/jobs.h" #include "builtins/read.h" diff --git a/src/builtins/functions.cpp b/src/builtins/functions.cpp deleted file mode 100644 index 51d660b7f..000000000 --- a/src/builtins/functions.cpp +++ /dev/null @@ -1,398 +0,0 @@ -// Implementation of the functions builtin. -#include "config.h" // IWYU pragma: keep - -#include "functions.h" - -#include - -#include -#include -#include -#include - -#include "../builtin.h" -#include "../common.h" -#include "../env.h" -#include "../event.h" -#include "../fallback.h" // IWYU pragma: keep -#include "../function.h" -#include "../highlight.h" -#include "../io.h" -#include "../maybe.h" -#include "../parser.h" -#include "../parser_keywords.h" -#include "../termsize.h" -#include "../wgetopt.h" -#include "../wutil.h" // IWYU pragma: keep - -struct functions_cmd_opts_t { - bool print_help = false; - bool erase = false; - bool list = false; - bool show_hidden = false; - bool query = false; - bool copy = false; - bool report_metadata = false; - bool no_metadata = false; - bool verbose = false; - bool handlers = false; - const wchar_t *handlers_type = nullptr; - const wchar_t *description = nullptr; -}; -static const wchar_t *const short_options = L":Ht:Dacd:ehnqv"; -static const struct woption long_options[] = {{L"erase", no_argument, 'e'}, - {L"description", required_argument, 'd'}, - {L"names", no_argument, 'n'}, - {L"all", no_argument, 'a'}, - {L"help", no_argument, 'h'}, - {L"query", no_argument, 'q'}, - {L"copy", no_argument, 'c'}, - {L"details", no_argument, 'D'}, - {L"no-details", no_argument, 1}, - {L"verbose", no_argument, 'v'}, - {L"handlers", no_argument, 'H'}, - {L"handlers-type", required_argument, 't'}, - {}}; - -static int parse_cmd_opts(functions_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 'v': { - opts.verbose = true; - break; - } - case 'e': { - opts.erase = true; - break; - } - case 'D': { - opts.report_metadata = true; - break; - } - case 1: { - opts.no_metadata = true; - break; - } - case 'd': { - opts.description = w.woptarg; - break; - } - case 'n': { - opts.list = true; - break; - } - case 'a': { - opts.show_hidden = true; - break; - } - case 'h': { - opts.print_help = true; - break; - } - case 'q': { - opts.query = true; - break; - } - case 'c': { - opts.copy = true; - break; - } - case 'H': { - opts.handlers = true; - break; - } - case 't': { - opts.handlers_type = w.woptarg; - opts.handlers = 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; -} - -static int report_function_metadata(const wcstring &funcname, bool verbose, io_streams_t &streams, - parser_t &parser, bool metadata_as_comments) { - wcstring path = L"n/a"; - const wchar_t *autoloaded = L"n/a"; - const wchar_t *shadows_scope = L"n/a"; - wcstring description = L"n/a"; - int line_number = 0; - bool is_copy = false; - wcstring copy_path = L"n/a"; - int copy_line_number = 0; - - if (auto mprops = function_get_props_autoload(funcname, parser)) { - const auto &props = *mprops; - if (auto def_file = props->definition_file()) { - path = std::move(*def_file); - autoloaded = props->is_autoload() ? L"autoloaded" : L"not-autoloaded"; - line_number = props->definition_lineno(); - } else { - path = L"stdin"; - } - - is_copy = props->is_copy(); - - auto definition_file = props->copy_definition_file(); - if (definition_file) { - copy_path = *definition_file; - copy_line_number = props->copy_definition_lineno(); - } else { - copy_path = L"stdin"; - } - - shadows_scope = props->shadow_scope() ? L"scope-shadowing" : L"no-scope-shadowing"; - description = - escape_string(*props->get_description(), ESCAPE_NO_PRINTABLES | ESCAPE_NO_QUOTED); - } - - if (metadata_as_comments) { - // "stdin" means it was defined interactively, "-" means it was defined via `source`. - // Neither is useful information. - wcstring comment; - - if (path == L"stdin") { - append_format(comment, L"# Defined interactively"); - } else if (path == L"-") { - append_format(comment, L"# Defined via `source`"); - } else { - append_format(comment, L"# Defined in %ls @ line %d", path.c_str(), line_number); - } - - if (is_copy) { - if (copy_path == L"stdin") { - append_format(comment, L", copied interactively\n"); - } else if (copy_path == L"-") { - append_format(comment, L", copied via `source`\n"); - } else { - append_format(comment, L", copied in %ls @ line %d\n", copy_path.c_str(), - copy_line_number); - } - } else { - append_format(comment, L"\n"); - } - - if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) { - std::vector colors; - highlight_shell(comment, colors, parser.context()); - streams.out.append(str2wcstring(colorize(comment, colors, parser.vars()))); - } else { - streams.out.append(comment); - } - } else { - streams.out.append_format(L"%ls\n", is_copy ? copy_path.c_str() : path.c_str()); - - if (verbose) { - streams.out.append_format(L"%ls\n", is_copy ? path.c_str() : autoloaded); - streams.out.append_format(L"%d\n", line_number); - streams.out.append_format(L"%ls\n", shadows_scope); - streams.out.append_format(L"%ls\n", description.c_str()); - } - } - - return STATUS_CMD_OK; -} - -/// \return whether a type filter is valid. -static bool type_filter_valid(const wcstring &filter) { - if (filter.empty()) return true; - for (size_t i = 0; event_filter_names[i]; i++) { - if (filter == event_filter_names[i]) return true; - } - return false; -} - -/// The functions builtin, used for listing and erasing functions. -maybe_t builtin_functions(parser_t &parser, io_streams_t &streams, const wchar_t **argv) { - const wchar_t *cmd = argv[0]; - int argc = builtin_count_args(argv); - functions_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; - } - - // Erase, desc, query, copy and list are mutually exclusive. - bool describe = opts.description != nullptr; - if (describe + opts.erase + opts.list + opts.query + opts.copy > 1) { - streams.err.append_format(BUILTIN_ERR_COMBO, cmd); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_INVALID_ARGS; - } - - if (opts.report_metadata && opts.no_metadata) { - streams.err.append_format(BUILTIN_ERR_COMBO, cmd); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_INVALID_ARGS; - } - - if (opts.erase) { - for (int i = optind; i < argc; i++) function_remove(argv[i]); - return STATUS_CMD_OK; - } - - if (opts.description) { - if (argc - optind != 1) { - streams.err.append_format(_(L"%ls: Expected exactly one function name\n"), cmd); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_INVALID_ARGS; - } - - const wchar_t *func = argv[optind]; - if (!function_exists(func, parser)) { - streams.err.append_format(_(L"%ls: Function '%ls' does not exist\n"), cmd, func); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_CMD_ERROR; - } - - function_set_desc(func, opts.description, parser); - return STATUS_CMD_OK; - } - - if (opts.report_metadata) { - if (argc - optind != 1) { - streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, argv[optind - 1], 1, - argc - optind); - return STATUS_INVALID_ARGS; - } - - const wchar_t *funcname = argv[optind]; - return report_function_metadata(funcname, opts.verbose, streams, parser, false); - } - - if (opts.handlers) { - wcstring type_filter = opts.handlers_type ? opts.handlers_type : L""; - if (!type_filter_valid(type_filter)) { - streams.err.append_format(_(L"%ls: Expected generic | variable | signal | exit | " - L"job-id for --handlers-type\n"), - cmd); - return STATUS_INVALID_ARGS; - } - event_print(streams, type_filter); - return STATUS_CMD_OK; - } - - // If we query with no argument, just return false. - if (opts.query && argc == optind) { - return STATUS_CMD_ERROR; - } - - if (opts.list || argc == optind) { - wcstring_list_ffi_t names_ffi{}; - function_get_names(opts.show_hidden, names_ffi); - std::vector names = std::move(names_ffi.vals); - std::sort(names.begin(), names.end()); - bool is_screen = !streams.out_is_redirected && isatty(STDOUT_FILENO); - if (is_screen) { - wcstring buff; - for (const auto &name : names) { - buff.append(name); - buff.append(L", "); - } - if (!names.empty()) { - // Trim trailing ", " - buff.resize(buff.size() - 2, '\0'); - } - - streams.out.append(reformat_for_screen(buff, termsize_last())); - } else { - for (auto &name : names) { - streams.out.append(name + L"\n"); - } - } - - return STATUS_CMD_OK; - } - - if (opts.copy) { - wcstring current_func; - wcstring new_func; - - if (argc - optind != 2) { - streams.err.append_format(_(L"%ls: Expected exactly two names (current function name, " - L"and new function name)\n"), - cmd); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_INVALID_ARGS; - } - current_func = argv[optind]; - new_func = argv[optind + 1]; - - if (!function_exists(current_func, parser)) { - streams.err.append_format(_(L"%ls: Function '%ls' does not exist\n"), cmd, - current_func.c_str()); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_CMD_ERROR; - } - - if (!valid_func_name(new_func) || parser_keywords_is_reserved(new_func)) { - streams.err.append_format(_(L"%ls: Illegal function name '%ls'\n"), cmd, - new_func.c_str()); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_INVALID_ARGS; - } - - // Keep things simple: don't allow existing names to be copy targets. - if (function_exists(new_func, parser)) { - streams.err.append_format( - _(L"%ls: Function '%ls' already exists. Cannot create copy '%ls'\n"), cmd, - new_func.c_str(), current_func.c_str()); - builtin_print_error_trailer(parser, streams.err, cmd); - return STATUS_CMD_ERROR; - } - - if (function_copy(current_func, new_func, parser)) return STATUS_CMD_OK; - return STATUS_CMD_ERROR; - } - - int res = STATUS_CMD_OK; - for (int i = optind; i < argc; i++) { - wcstring funcname = argv[i]; - auto func = function_get_props_autoload(argv[i], parser); - if (!func) { - res++; - } else { - if (!opts.query) { - if (i != optind) streams.out.append(L"\n"); - if (!opts.no_metadata) { - report_function_metadata(funcname, opts.verbose, streams, parser, true); - } - std::unique_ptr def_ptr = (*func)->annotated_definition(funcname); - wcstring def = std::move(*def_ptr); - - if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) { - std::vector colors; - highlight_shell(def, colors, parser.context()); - streams.out.append(str2wcstring(colorize(def, colors, parser.vars()))); - } else { - streams.out.append(def); - } - } - } - } - - return res; -} diff --git a/src/builtins/functions.h b/src/builtins/functions.h deleted file mode 100644 index 33ba623cd..000000000 --- a/src/builtins/functions.h +++ /dev/null @@ -1,11 +0,0 @@ -// Prototypes for executing builtin_functions function. -#ifndef FISH_BUILTIN_FUNCTIONS_H -#define FISH_BUILTIN_FUNCTIONS_H - -#include "../maybe.h" - -class parser_t; -struct io_streams_t; - -maybe_t builtin_functions(parser_t &parser, io_streams_t &streams, const wchar_t **argv); -#endif diff --git a/src/common.cpp b/src/common.cpp index 7f3ad518f..1a1b1913b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -657,67 +657,6 @@ void narrow_string_safe(char buff[64], const wchar_t *s) { buff[idx] = '\0'; } -wcstring reformat_for_screen(const wcstring &msg, const termsize_t &termsize) { - wcstring buff; - - int screen_width = termsize.width; - - if (screen_width) { - const wchar_t *start = msg.c_str(); - const wchar_t *pos = start; - int line_width = 0; - while (true) { - int overflow = 0; - - int tok_width = 0; - - // Tokenize on whitespace, and also calculate the width of the token. - while (*pos && (!std::wcschr(L" \n\r\t", *pos))) { - // Check is token is wider than one line. If so we mark it as an overflow and break - // the token. - if ((tok_width + fish_wcwidth(*pos)) > (screen_width - 1)) { - overflow = 1; - break; - } - - tok_width += fish_wcwidth(*pos); - pos++; - } - - // If token is zero character long, we don't do anything. - if (pos == start) { - pos = pos + 1; - } else if (overflow) { - // In case of overflow, we print a newline, except if we already are at position 0. - wcstring token = msg.substr(start - msg.c_str(), pos - start); - if (line_width != 0) buff.push_back(L'\n'); - buff.append(format_string(L"%ls-\n", token.c_str())); - line_width = 0; - } else { - // Print the token. - wcstring token = msg.substr(start - msg.c_str(), pos - start); - if ((line_width + (line_width != 0 ? 1 : 0) + tok_width) > screen_width) { - buff.push_back(L'\n'); - line_width = 0; - } - buff.append(format_string(L"%ls%ls", line_width ? L" " : L"", token.c_str())); - line_width += (line_width != 0 ? 1 : 0) + tok_width; - } - - // Break on end of string. - if (!*pos) { - break; - } - - start = pos; - } - } else { - buff.append(msg); - } - buff.push_back(L'\n'); - return buff; -} - /// Escape a string in a fashion suitable for using as a URL. Store the result in out_str. static void escape_string_url(const wcstring &in, wcstring &out) { auto result = rust_escape_string_url(in.c_str(), in.size()); diff --git a/src/common.h b/src/common.h index d0d1315d0..8db5a9115 100644 --- a/src/common.h +++ b/src/common.h @@ -517,9 +517,6 @@ std::unique_ptr unescape_string(const wchar_t *input, size_t len, std::unique_ptr unescape_string(const wcstring &input, unescape_flags_t escape_special, escape_string_style_t style = STRING_STYLE_SCRIPT); -/// Write the given paragraph of output, redoing linebreaks to fit \p termsize. -wcstring reformat_for_screen(const wcstring &msg, const termsize_t &termsize); - /// Return the number of seconds from the UNIX epoch, with subsecond precision. This function uses /// the gettimeofday function and will have the same precision as that function. using timepoint_t = double; diff --git a/src/event.cpp b/src/event.cpp index 28d0b2005..ed0736054 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -28,11 +28,6 @@ #include "wcstringutil.h" #include "wutil.h" // IWYU pragma: keep -// TODO: Remove after porting functions.cpp to rust -const wchar_t *const event_filter_names[] = {L"signal", L"variable", L"exit", - L"process-exit", L"job-exit", L"caller-exit", - L"generic", nullptr}; - void event_fire_generic(parser_t &parser, const wcstring &name, const std::vector &args) { std::vector ffi_args; for (const auto &arg : args) ffi_args.push_back(arg.c_str());