From 5a76c7d3b1f44d4c4c93b97386144e26553cd15c Mon Sep 17 00:00:00 2001 From: Xiretza Date: Fri, 10 Feb 2023 18:19:22 +0100 Subject: [PATCH] Port emit builtin to rust --- CMakeLists.txt | 2 +- fish-rust/src/builtins/emit.rs | 52 ++++++++++++++++++++++++++++++++ fish-rust/src/builtins/mod.rs | 1 + fish-rust/src/builtins/shared.rs | 1 + fish-rust/src/ffi.rs | 3 ++ src/builtin.cpp | 6 ++-- src/builtin.h | 1 + src/builtins/emit.cpp | 40 ------------------------ src/builtins/emit.h | 11 ------- src/event.cpp | 9 ++++++ src/event.h | 4 +++ 11 files changed, 76 insertions(+), 54 deletions(-) create mode 100644 fish-rust/src/builtins/emit.rs delete mode 100644 src/builtins/emit.cpp delete mode 100644 src/builtins/emit.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a991b887..b9db60787 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,7 +103,7 @@ set(FISH_BUILTIN_SRCS src/builtins/bg.cpp src/builtins/bind.cpp src/builtins/block.cpp src/builtins/builtin.cpp src/builtins/cd.cpp src/builtins/command.cpp src/builtins/commandline.cpp src/builtins/complete.cpp src/builtins/contains.cpp - src/builtins/disown.cpp src/builtins/emit.cpp + src/builtins/disown.cpp src/builtins/eval.cpp src/builtins/exit.cpp src/builtins/fg.cpp src/builtins/function.cpp src/builtins/functions.cpp src/builtins/history.cpp src/builtins/jobs.cpp src/builtins/math.cpp src/builtins/printf.cpp src/builtins/path.cpp diff --git a/fish-rust/src/builtins/emit.rs b/fish-rust/src/builtins/emit.rs new file mode 100644 index 000000000..83bf55d8c --- /dev/null +++ b/fish-rust/src/builtins/emit.rs @@ -0,0 +1,52 @@ +use libc::c_int; +use widestring_suffix::widestrs; + +use super::shared::{ + builtin_print_help, io_streams_t, HelpOnlyCmdOpts, STATUS_CMD_OK, STATUS_INVALID_ARGS, +}; +use crate::ffi::{self, parser_t, Repin}; +use crate::wchar_ffi::{wstr, W0String, WCharToFFI}; +use crate::wutil::format::printf::sprintf; + +#[widestrs] +pub fn emit( + parser: &mut parser_t, + streams: &mut io_streams_t, + argv: &mut [&wstr], +) -> Option { + let cmd = argv[0]; + + let opts = match HelpOnlyCmdOpts::parse(argv, parser, streams) { + Ok(opts) => opts, + Err(err @ Some(_)) if err != STATUS_CMD_OK => return err, + Err(err) => panic!("Illogical exit code from parse_options(): {err:?}"), + }; + + if opts.print_help { + builtin_print_help(parser, streams, cmd); + return STATUS_CMD_OK; + } + + let Some(event_name) = argv.get(opts.optind) else { + streams.err.append(&sprintf!("%ls: expected event name\n"L, cmd)); + return STATUS_INVALID_ARGS; + }; + + let event_args: Vec = argv[opts.optind + 1..] + .iter() + .map(|s| W0String::from_ustr(s).unwrap()) + .collect(); + let event_arg_ptrs: Vec = event_args + .iter() + .map(|s| ffi::wcharz_t { str_: s.as_ptr() }) + .collect(); + + ffi::event_fire_generic( + parser.pin(), + event_name.to_ffi(), + event_arg_ptrs.as_ptr(), + c_int::try_from(event_arg_ptrs.len()).unwrap().into(), + ); + + STATUS_CMD_OK +} diff --git a/fish-rust/src/builtins/mod.rs b/fish-rust/src/builtins/mod.rs index 6fab413aa..3e05226b0 100644 --- a/fish-rust/src/builtins/mod.rs +++ b/fish-rust/src/builtins/mod.rs @@ -1,4 +1,5 @@ pub mod shared; pub mod echo; +pub mod emit; pub mod wait; diff --git a/fish-rust/src/builtins/shared.rs b/fish-rust/src/builtins/shared.rs index 2c739f941..6fb7ec1be 100644 --- a/fish-rust/src/builtins/shared.rs +++ b/fish-rust/src/builtins/shared.rs @@ -110,6 +110,7 @@ pub fn run_builtin( ) -> Option { match builtin { RustBuiltin::Echo => super::echo::echo(parser, streams, args), + RustBuiltin::Emit => super::emit::emit(parser, streams, args), RustBuiltin::Wait => wait::wait(parser, streams, args), } } diff --git a/fish-rust/src/ffi.rs b/fish-rust/src/ffi.rs index dfb334684..5f71052f7 100644 --- a/fish-rust/src/ffi.rs +++ b/fish-rust/src/ffi.rs @@ -22,6 +22,7 @@ #include "common.h" #include "builtin.h" #include "fallback.h" + #include "event.h" safety!(unsafe_ffi) @@ -63,6 +64,8 @@ generate!("wait_handle_t") generate!("wait_handle_store_t") + + generate!("event_fire_generic") } impl parser_t { diff --git a/src/builtin.cpp b/src/builtin.cpp index b4405af23..1b98fa940 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -41,7 +41,6 @@ #include "builtins/complete.h" #include "builtins/contains.h" #include "builtins/disown.h" -#include "builtins/emit.h" #include "builtins/eval.h" #include "builtins/exit.h" #include "builtins/fg.h" @@ -385,7 +384,7 @@ static constexpr builtin_data_t builtin_datas[] = { {L"disown", &builtin_disown, N_(L"Remove job from job list")}, {L"echo", &implemented_in_rust, N_(L"Print arguments")}, {L"else", &builtin_generic, N_(L"Evaluate block if condition is false")}, - {L"emit", &builtin_emit, N_(L"Emit an event")}, + {L"emit", &implemented_in_rust, N_(L"Emit an event")}, {L"end", &builtin_generic, N_(L"End a block of commands")}, {L"eval", &builtin_eval, N_(L"Evaluate a string as a statement")}, {L"exec", &builtin_generic, N_(L"Run command in current process")}, @@ -531,6 +530,9 @@ static maybe_t try_get_rust_builtin(const wcstring &cmd) { if (cmd == L"echo") { return RustBuiltin::Echo; } + if (cmd == L"emit") { + return RustBuiltin::Emit; + } if (cmd == L"wait") { return RustBuiltin::Wait; } diff --git a/src/builtin.h b/src/builtin.h index 54582475e..bce6edb47 100644 --- a/src/builtin.h +++ b/src/builtin.h @@ -110,6 +110,7 @@ int parse_help_only_cmd_opts(help_only_cmd_opts_t &opts, int *optind, int argc, /// An enum of the builtins implemented in Rust. enum RustBuiltin : int32_t { Echo, + Emit, Wait, }; #endif diff --git a/src/builtins/emit.cpp b/src/builtins/emit.cpp deleted file mode 100644 index b28adb51a..000000000 --- a/src/builtins/emit.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Implementation of the emit builtin. -#include "config.h" // IWYU pragma: keep - -#include "emit.h" - -#include - -#include "../builtin.h" -#include "../common.h" -#include "../event.h" -#include "../fallback.h" // IWYU pragma: keep -#include "../io.h" -#include "../maybe.h" -#include "../wutil.h" // IWYU pragma: keep - -/// Implementation of the builtin emit command, used to create events. -maybe_t builtin_emit(parser_t &parser, io_streams_t &streams, const wchar_t **argv) { - const wchar_t *cmd = argv[0]; - int argc = builtin_count_args(argv); - help_only_cmd_opts_t opts; - - int optind; - int retval = parse_help_only_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 (!argv[optind]) { - streams.err.append_format(L"%ls: expected event name\n", cmd); - return STATUS_INVALID_ARGS; - } - - const wchar_t *eventname = argv[optind]; - wcstring_list_t args(argv + optind + 1, argv + argc); - event_fire_generic(parser, eventname, std::move(args)); - return STATUS_CMD_OK; -} diff --git a/src/builtins/emit.h b/src/builtins/emit.h deleted file mode 100644 index b5a21c6dd..000000000 --- a/src/builtins/emit.h +++ /dev/null @@ -1,11 +0,0 @@ -// Prototypes for executing builtin_emit function. -#ifndef FISH_BUILTIN_EMIT_H -#define FISH_BUILTIN_EMIT_H - -#include "../maybe.h" - -class parser_t; -struct io_streams_t; - -maybe_t builtin_emit(parser_t &parser, io_streams_t &streams, const wchar_t **argv); -#endif diff --git a/src/event.cpp b/src/event.cpp index a0b2e8c34..5d3af0afd 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "common.h" #include "fallback.h" // IWYU pragma: keep @@ -488,6 +489,14 @@ void event_print(io_streams_t &streams, const wcstring &type_filter) { } } +void event_fire_generic(parser_t &parser, wcstring name, const wcharz_t *argv, int argc) { + wcstring_list_t args_vec{}; + for (int i = 0; i < argc; i++) { + args_vec.push_back(argv[i]); + } + event_fire_generic(parser, std::move(name), std::move(args_vec)); +} + void event_fire_generic(parser_t &parser, wcstring name, wcstring_list_t args) { event_t ev(event_type_t::generic); ev.desc.str_param1 = std::move(name); diff --git a/src/event.h b/src/event.h index bbdf7bd30..c7b2380c2 100644 --- a/src/event.h +++ b/src/event.h @@ -15,6 +15,7 @@ #include "common.h" #include "global_safety.h" +#include "wutil.h" struct io_streams_t; @@ -162,6 +163,9 @@ void event_print(io_streams_t &streams, const wcstring &type_filter); /// Returns a string describing the specified event. wcstring event_get_desc(const parser_t &parser, const event_t &e); +// FFI helper for event_fire_generic +void event_fire_generic(parser_t &parser, wcstring name, const wcharz_t *argv, int argc); + /// Fire a generic event with the specified name. void event_fire_generic(parser_t &parser, wcstring name, wcstring_list_t args = {});