mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
add option --handlers to functions to display function hooks
This commit is contained in:
parent
7764f27170
commit
3819437e0e
3 changed files with 116 additions and 2 deletions
|
@ -35,15 +35,18 @@ struct functions_cmd_opts_t {
|
||||||
bool copy = false;
|
bool copy = false;
|
||||||
bool report_metadata = false;
|
bool report_metadata = false;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
bool handlers = false;
|
||||||
|
wchar_t *handlers_type = NULL;
|
||||||
wchar_t *description = NULL;
|
wchar_t *description = NULL;
|
||||||
};
|
};
|
||||||
static const wchar_t *short_options = L":Dacehnqv";
|
static const wchar_t *short_options = L":HDacehnqv";
|
||||||
static const struct woption long_options[] = {
|
static const struct woption long_options[] = {
|
||||||
{L"erase", no_argument, NULL, 'e'}, {L"description", required_argument, NULL, 'd'},
|
{L"erase", no_argument, NULL, 'e'}, {L"description", required_argument, NULL, 'd'},
|
||||||
{L"names", no_argument, NULL, 'n'}, {L"all", no_argument, NULL, 'a'},
|
{L"names", no_argument, NULL, 'n'}, {L"all", no_argument, NULL, 'a'},
|
||||||
{L"help", no_argument, NULL, 'h'}, {L"query", no_argument, NULL, 'q'},
|
{L"help", no_argument, NULL, 'h'}, {L"query", no_argument, NULL, 'q'},
|
||||||
{L"copy", no_argument, NULL, 'c'}, {L"details", no_argument, NULL, 'D'},
|
{L"copy", no_argument, NULL, 'c'}, {L"details", no_argument, NULL, 'D'},
|
||||||
{L"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0}};
|
{L"verbose", no_argument, NULL, 'v'}, {L"handlers", no_argument, NULL, 'H'},
|
||||||
|
{L"handlers-type", required_argument, NULL, 't'}, {NULL, 0, NULL, 0}};
|
||||||
|
|
||||||
static int parse_cmd_opts(functions_cmd_opts_t &opts, int *optind, //!OCLINT(high ncss method)
|
static int parse_cmd_opts(functions_cmd_opts_t &opts, int *optind, //!OCLINT(high ncss method)
|
||||||
int argc, wchar_t **argv, parser_t &parser, io_streams_t &streams) {
|
int argc, wchar_t **argv, parser_t &parser, io_streams_t &streams) {
|
||||||
|
@ -88,6 +91,15 @@ static int parse_cmd_opts(functions_cmd_opts_t &opts, int *optind, //!OCLINT(hi
|
||||||
opts.copy = true;
|
opts.copy = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'H': {
|
||||||
|
opts.handlers = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 't': {
|
||||||
|
opts.handlers_type = w.woptarg;
|
||||||
|
opts.handlers = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ':': {
|
case ':': {
|
||||||
builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]);
|
builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]);
|
||||||
return STATUS_INVALID_ARGS;
|
return STATUS_INVALID_ARGS;
|
||||||
|
@ -311,6 +323,20 @@ int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||||
return report_function_metadata(funcname, opts.verbose, streams, false);
|
return report_function_metadata(funcname, opts.verbose, streams, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.handlers) {
|
||||||
|
int type = -1;
|
||||||
|
if (opts.handlers_type) {
|
||||||
|
type = wcs2event(opts.handlers_type);
|
||||||
|
if (type == -1) {
|
||||||
|
streams.err.append_format(_(L"%ls: Expected generic | variable | signal | exit | job-id for --handlers_type\n"),
|
||||||
|
cmd);
|
||||||
|
return STATUS_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event_print(streams, type);
|
||||||
|
return STATUS_CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts.list || argc == optind) {
|
if (opts.list || argc == optind) {
|
||||||
wcstring_list_t names = function_get_names(opts.show_hidden);
|
wcstring_list_t names = function_get_names(opts.show_hidden);
|
||||||
std::sort(names.begin(), names.end());
|
std::sort(names.begin(), names.end());
|
||||||
|
|
|
@ -50,6 +50,14 @@ static event_list_t s_event_handlers;
|
||||||
/// List of events that have been sent but have not yet been delivered because they are blocked.
|
/// List of events that have been sent but have not yet been delivered because they are blocked.
|
||||||
static event_list_t blocked;
|
static event_list_t blocked;
|
||||||
|
|
||||||
|
static std::map<int, wcstring> events_map = {
|
||||||
|
{EVENT_SIGNAL, L"signal"},
|
||||||
|
{EVENT_VARIABLE, L"variable"},
|
||||||
|
{EVENT_EXIT, L"exit"},
|
||||||
|
{EVENT_JOB_ID, L"job-id"},
|
||||||
|
{EVENT_GENERIC, L"generic"}
|
||||||
|
};
|
||||||
|
|
||||||
/// Variables (one per signal) set when a signal is observed. This is inspected by a signal handler.
|
/// Variables (one per signal) set when a signal is observed. This is inspected by a signal handler.
|
||||||
static volatile bool s_observed_signals[NSIG] = {};
|
static volatile bool s_observed_signals[NSIG] = {};
|
||||||
static void set_signal_observed(int sig, bool val) {
|
static void set_signal_observed(int sig, bool val) {
|
||||||
|
@ -448,6 +456,74 @@ void event_fire(const event_t *event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wcstring event2wcs(int type) {
|
||||||
|
std::map<int, wcstring>::iterator it = events_map.find(type);
|
||||||
|
|
||||||
|
if (it != events_map.end())
|
||||||
|
return it->second;
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
int wcs2event(wcstring const &event) {
|
||||||
|
for (std::map<int, wcstring>::iterator it = events_map.begin(); it != events_map.end(); ++it) {
|
||||||
|
if (it->second == event)
|
||||||
|
return it->first;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void event_print(io_streams_t &streams, int event_type) {
|
||||||
|
std::vector<shared_ptr<event_t>> tmp = s_event_handlers;
|
||||||
|
std::sort(tmp.begin(), tmp.end(),
|
||||||
|
[](const shared_ptr<event_t> &e1, const shared_ptr<event_t> &e2) {
|
||||||
|
if (e1->type == e2->type) {
|
||||||
|
switch (e1->type) {
|
||||||
|
case EVENT_SIGNAL:
|
||||||
|
return e1->param1.signal < e2->param1.signal;
|
||||||
|
case EVENT_JOB_ID:
|
||||||
|
return e1->param1.job_id < e2->param1.job_id;
|
||||||
|
case EVENT_VARIABLE:
|
||||||
|
case EVENT_ANY:
|
||||||
|
case EVENT_GENERIC:
|
||||||
|
return e1->str_param1 < e2->str_param1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return e1->type < e2->type;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int type = -1;
|
||||||
|
for (const shared_ptr<event_t> &evt : tmp) {
|
||||||
|
if (event_type == -1 || event_type == evt->type) {
|
||||||
|
if (evt->type != type) {
|
||||||
|
if (type != -1)
|
||||||
|
streams.out.append(L"\n");
|
||||||
|
type = evt->type;
|
||||||
|
streams.out.append_format(L"Event %ls\n", event2wcs(evt->type).c_str());
|
||||||
|
}
|
||||||
|
switch (evt->type) {
|
||||||
|
case EVENT_SIGNAL:
|
||||||
|
streams.out.append_format(L"%ls %ls\n", sig2wcs(evt->param1.signal),
|
||||||
|
evt->function_name.c_str());
|
||||||
|
break;
|
||||||
|
case EVENT_JOB_ID:
|
||||||
|
streams.out.append_format(L"%d %ls\n", evt->param1,
|
||||||
|
evt->function_name.c_str());
|
||||||
|
break;
|
||||||
|
case EVENT_VARIABLE:
|
||||||
|
case EVENT_GENERIC:
|
||||||
|
streams.out.append_format(L"%ls %ls\n", evt->str_param1.c_str(),
|
||||||
|
evt->function_name.c_str());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
streams.out.append_format(L"%ls\n", evt->function_name.c_str());
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void event_fire_generic(const wchar_t *name, wcstring_list_t *args) {
|
void event_fire_generic(const wchar_t *name, wcstring_list_t *args) {
|
||||||
CHECK(name, );
|
CHECK(name, );
|
||||||
|
|
||||||
|
|
12
src/event.h
12
src/event.h
|
@ -8,10 +8,12 @@
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
/// The signal number that is used to match any signal.
|
/// The signal number that is used to match any signal.
|
||||||
#define EVENT_ANY_SIGNAL -1
|
#define EVENT_ANY_SIGNAL -1
|
||||||
|
@ -125,6 +127,16 @@ void event_fire(const event_t *event);
|
||||||
/// May be called from signal handlers
|
/// May be called from signal handlers
|
||||||
void event_fire_signal(int signal);
|
void event_fire_signal(int signal);
|
||||||
|
|
||||||
|
/// Convert a string to the corresponding type
|
||||||
|
int wcs2event(wcstring const &event);
|
||||||
|
|
||||||
|
/// Convert a type to the corresponding string
|
||||||
|
wcstring event2wcs(int type);
|
||||||
|
|
||||||
|
/// Called by builtin functions
|
||||||
|
/// Dumped all events
|
||||||
|
void event_print(io_streams_t &streams, int event_type);
|
||||||
|
|
||||||
/// Returns a string describing the specified event.
|
/// Returns a string describing the specified event.
|
||||||
wcstring event_get_desc(const event_t &e);
|
wcstring event_get_desc(const event_t &e);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue