mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
restyle input_common module to match project style
Reduces lint errors from 27 to 24 (-11%). Line count from 466 to 378 (-19%). Another step in resolving issue #2902.
This commit is contained in:
parent
08c29727e0
commit
da17420cdf
2 changed files with 124 additions and 212 deletions
|
@ -1,35 +1,32 @@
|
|||
/** \file input_common.c
|
||||
|
||||
Implementation file for the low level input library
|
||||
*/
|
||||
// Implementation file for the low level input library.
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include <utility>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <memory>
|
||||
#include <cwctype>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <cwctype>
|
||||
#include <memory>
|
||||
|
||||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
#include "input_common.h"
|
||||
#include "env_universal_common.h"
|
||||
#include "env.h"
|
||||
#include "env_universal_common.h"
|
||||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "input_common.h"
|
||||
#include "iothread.h"
|
||||
#include "util.h"
|
||||
|
||||
// Time in milliseconds to wait for another byte to be available for reading
|
||||
// after \x1b is read before assuming that escape key was pressed, and not an
|
||||
|
@ -37,69 +34,49 @@ Implementation file for the low level input library
|
|||
#define WAIT_ON_ESCAPE_DEFAULT 300
|
||||
static int wait_on_escape_ms = WAIT_ON_ESCAPE_DEFAULT;
|
||||
|
||||
/** Characters that have been read and returned by the sequence matching code */
|
||||
/// Characters that have been read and returned by the sequence matching code.
|
||||
static std::deque<wint_t> lookahead_list;
|
||||
|
||||
/* Queue of pairs of (function pointer, argument) to be invoked. Expected to be mostly empty. */
|
||||
// Queue of pairs of (function pointer, argument) to be invoked. Expected to be mostly empty.
|
||||
typedef std::pair<void (*)(void *), void *> callback_info_t;
|
||||
typedef std::queue<callback_info_t, std::list<callback_info_t> > callback_queue_t;
|
||||
static callback_queue_t callback_queue;
|
||||
static void input_flush_callbacks(void);
|
||||
|
||||
static bool has_lookahead(void)
|
||||
{
|
||||
return ! lookahead_list.empty();
|
||||
}
|
||||
static bool has_lookahead(void) { return !lookahead_list.empty(); }
|
||||
|
||||
static wint_t lookahead_pop(void)
|
||||
{
|
||||
static wint_t lookahead_pop(void) {
|
||||
wint_t result = lookahead_list.front();
|
||||
lookahead_list.pop_front();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void lookahead_push_back(wint_t c)
|
||||
{
|
||||
lookahead_list.push_back(c);
|
||||
}
|
||||
static void lookahead_push_back(wint_t c) { lookahead_list.push_back(c); }
|
||||
|
||||
static void lookahead_push_front(wint_t c)
|
||||
{
|
||||
lookahead_list.push_front(c);
|
||||
}
|
||||
static void lookahead_push_front(wint_t c) { lookahead_list.push_front(c); }
|
||||
|
||||
static wint_t lookahead_front(void)
|
||||
{
|
||||
return lookahead_list.front();
|
||||
}
|
||||
static wint_t lookahead_front(void) { return lookahead_list.front(); }
|
||||
|
||||
/** Callback function for handling interrupts on reading */
|
||||
/// Callback function for handling interrupts on reading.
|
||||
static int (*interrupt_handler)();
|
||||
|
||||
void input_common_init(int (*ih)())
|
||||
{
|
||||
void input_common_init(int (*ih)()) {
|
||||
interrupt_handler = ih;
|
||||
update_wait_on_escape_ms();
|
||||
}
|
||||
|
||||
void input_common_destroy()
|
||||
{
|
||||
void input_common_destroy() {}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Internal function used by input_common_readch to read one byte from fd 0. This function should only be called by
|
||||
input_common_readch().
|
||||
*/
|
||||
static wint_t readb()
|
||||
{
|
||||
/* do_loop must be set on every path through the loop; leaving it uninitialized allows the static analyzer to assist in catching mistakes. */
|
||||
/// Internal function used by input_common_readch to read one byte from fd 0. This function should
|
||||
/// only be called by input_common_readch().
|
||||
static wint_t readb() {
|
||||
// do_loop must be set on every path through the loop; leaving it uninitialized allows the
|
||||
// static analyzer to assist in catching mistakes.
|
||||
unsigned char arr[1];
|
||||
bool do_loop;
|
||||
|
||||
do
|
||||
{
|
||||
/* Flush callbacks */
|
||||
do {
|
||||
// Flush callbacks.
|
||||
input_flush_callbacks();
|
||||
|
||||
fd_set fdset;
|
||||
|
@ -109,119 +86,94 @@ static wint_t readb()
|
|||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(0, &fdset);
|
||||
if (ioport > 0)
|
||||
{
|
||||
if (ioport > 0) {
|
||||
FD_SET(ioport, &fdset);
|
||||
fd_max = maxi(fd_max, ioport);
|
||||
}
|
||||
|
||||
/* Get our uvar notifier */
|
||||
|
||||
// Get our uvar notifier.
|
||||
universal_notifier_t ¬ifier = universal_notifier_t::default_notifier();
|
||||
|
||||
/* Get the notification fd (possibly none) */
|
||||
|
||||
// Get the notification fd (possibly none).
|
||||
int notifier_fd = notifier.notification_fd();
|
||||
if (notifier_fd > 0)
|
||||
{
|
||||
if (notifier_fd > 0) {
|
||||
FD_SET(notifier_fd, &fdset);
|
||||
fd_max = maxi(fd_max, notifier_fd);
|
||||
}
|
||||
|
||||
/* Get its suggested delay (possibly none) */
|
||||
|
||||
// Get its suggested delay (possibly none).
|
||||
struct timeval tv = {};
|
||||
const unsigned long usecs_delay = notifier.usec_delay_between_polls();
|
||||
if (usecs_delay > 0)
|
||||
{
|
||||
if (usecs_delay > 0) {
|
||||
unsigned long usecs_per_sec = 1000000;
|
||||
tv.tv_sec = (int)(usecs_delay / usecs_per_sec);
|
||||
tv.tv_usec = (int)(usecs_delay % usecs_per_sec);
|
||||
}
|
||||
|
||||
|
||||
res = select(fd_max + 1, &fdset, 0, 0, usecs_delay > 0 ? &tv : NULL);
|
||||
if (res==-1)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
if (res == -1) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
{
|
||||
if (interrupt_handler)
|
||||
{
|
||||
case EAGAIN: {
|
||||
if (interrupt_handler) {
|
||||
int res = interrupt_handler();
|
||||
if (res)
|
||||
{
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
if (has_lookahead())
|
||||
{
|
||||
if (has_lookahead()) {
|
||||
return lookahead_pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
do_loop = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/*
|
||||
The terminal has been closed. Save and exit.
|
||||
*/
|
||||
default: {
|
||||
// The terminal has been closed. Save and exit.
|
||||
return R_EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assume we loop unless we see a character in stdin */
|
||||
} else {
|
||||
// Assume we loop unless we see a character in stdin.
|
||||
do_loop = true;
|
||||
|
||||
/* Check to see if we want a universal variable barrier */
|
||||
// Check to see if we want a universal variable barrier.
|
||||
bool barrier_from_poll = notifier.poll();
|
||||
bool barrier_from_readability = false;
|
||||
if (notifier_fd > 0 && FD_ISSET(notifier_fd, &fdset))
|
||||
{
|
||||
if (notifier_fd > 0 && FD_ISSET(notifier_fd, &fdset)) {
|
||||
barrier_from_readability = notifier.notification_fd_became_readable(notifier_fd);
|
||||
}
|
||||
if (barrier_from_poll || barrier_from_readability)
|
||||
{
|
||||
if (barrier_from_poll || barrier_from_readability) {
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
if (ioport > 0 && FD_ISSET(ioport, &fdset))
|
||||
{
|
||||
if (ioport > 0 && FD_ISSET(ioport, &fdset)) {
|
||||
iothread_service_completion();
|
||||
if (has_lookahead())
|
||||
{
|
||||
if (has_lookahead()) {
|
||||
return lookahead_pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(STDIN_FILENO, &fdset))
|
||||
{
|
||||
if (read_blocked(0, arr, 1) != 1)
|
||||
{
|
||||
/* The teminal has been closed. Save and exit. */
|
||||
if (FD_ISSET(STDIN_FILENO, &fdset)) {
|
||||
if (read_blocked(0, arr, 1) != 1) {
|
||||
// The teminal has been closed. Save and exit.
|
||||
return R_EOF;
|
||||
}
|
||||
|
||||
/* We read from stdin, so don't loop */
|
||||
// We read from stdin, so don't loop.
|
||||
do_loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (do_loop);
|
||||
} while (do_loop);
|
||||
|
||||
return arr[0];
|
||||
}
|
||||
|
||||
// Update the wait_on_escape_ms value in response to the fish_escape_delay_ms
|
||||
// user variable being set.
|
||||
void update_wait_on_escape_ms()
|
||||
{
|
||||
// Update the wait_on_escape_ms value in response to the fish_escape_delay_ms user variable being
|
||||
// set.
|
||||
void update_wait_on_escape_ms() {
|
||||
env_var_t escape_time_ms = env_get_string(L"fish_escape_delay_ms");
|
||||
if (escape_time_ms.missing_or_empty())
|
||||
{
|
||||
if (escape_time_ms.missing_or_empty()) {
|
||||
wait_on_escape_ms = WAIT_ON_ESCAPE_DEFAULT;
|
||||
return;
|
||||
}
|
||||
|
@ -229,33 +181,25 @@ void update_wait_on_escape_ms()
|
|||
wchar_t *endptr;
|
||||
long tmp = wcstol(escape_time_ms.c_str(), &endptr, 10);
|
||||
|
||||
if (*endptr != '\0' || tmp < 10 || tmp >= 5000)
|
||||
{
|
||||
fwprintf(stderr, L"ignoring fish_escape_delay_ms: value '%ls' "
|
||||
"is not an integer or is < 10 or >= 5000 ms\n",
|
||||
escape_time_ms.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*endptr != '\0' || tmp < 10 || tmp >= 5000) {
|
||||
fwprintf(stderr,
|
||||
L"ignoring fish_escape_delay_ms: value '%ls' "
|
||||
"is not an integer or is < 10 or >= 5000 ms\n",
|
||||
escape_time_ms.c_str());
|
||||
} else {
|
||||
wait_on_escape_ms = (int)tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wchar_t input_common_readch(int timed)
|
||||
{
|
||||
if (! has_lookahead())
|
||||
{
|
||||
if (timed)
|
||||
{
|
||||
wchar_t input_common_readch(int timed) {
|
||||
if (!has_lookahead()) {
|
||||
if (timed) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(0, &fds);
|
||||
struct timeval tm = {wait_on_escape_ms / 1000,
|
||||
1000 * (wait_on_escape_ms % 1000)};
|
||||
struct timeval tm = {wait_on_escape_ms / 1000, 1000 * (wait_on_escape_ms % 1000)};
|
||||
int count = select(1, &fds, 0, 0, &tm);
|
||||
if (count <= 0)
|
||||
{
|
||||
if (count <= 0) {
|
||||
return WEOF;
|
||||
}
|
||||
}
|
||||
|
@ -263,80 +207,64 @@ wchar_t input_common_readch(int timed)
|
|||
wchar_t res;
|
||||
mbstate_t state = {};
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
wint_t b = readb();
|
||||
|
||||
if (MB_CUR_MAX == 1) // single-byte locale, all values are legal
|
||||
if (MB_CUR_MAX == 1) // single-byte locale, all values are legal
|
||||
{
|
||||
return (unsigned char)b;
|
||||
}
|
||||
|
||||
if ((b >= R_NULL) && (b < R_NULL + 1000))
|
||||
return b;
|
||||
if ((b >= R_NULL) && (b < R_NULL + 1000)) return b;
|
||||
|
||||
char bb = b;
|
||||
size_t sz = mbrtowc(&res, &bb, 1, &state);
|
||||
|
||||
switch (sz)
|
||||
{
|
||||
case (size_t)(-1):
|
||||
switch (sz) {
|
||||
case (size_t)(-1): {
|
||||
memset(&state, '\0', sizeof(state));
|
||||
debug(2, L"Illegal input");
|
||||
return R_NULL;
|
||||
case (size_t)(-2):
|
||||
}
|
||||
case (size_t)(-2): {
|
||||
break;
|
||||
case 0:
|
||||
}
|
||||
case 0: {
|
||||
return 0;
|
||||
default:
|
||||
return res;
|
||||
}
|
||||
default: { return res; }
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!timed)
|
||||
{
|
||||
while (has_lookahead() && lookahead_front() == WEOF)
|
||||
lookahead_pop();
|
||||
if (! has_lookahead())
|
||||
return input_common_readch(0);
|
||||
} else {
|
||||
if (!timed) {
|
||||
while (has_lookahead() && lookahead_front() == WEOF) lookahead_pop();
|
||||
if (!has_lookahead()) return input_common_readch(0);
|
||||
}
|
||||
|
||||
return lookahead_pop();
|
||||
}
|
||||
}
|
||||
|
||||
void input_common_queue_ch(wint_t ch) { lookahead_push_back(ch); }
|
||||
|
||||
void input_common_queue_ch(wint_t ch)
|
||||
{
|
||||
lookahead_push_back(ch);
|
||||
}
|
||||
void input_common_next_ch(wint_t ch) { lookahead_push_front(ch); }
|
||||
|
||||
void input_common_next_ch(wint_t ch)
|
||||
{
|
||||
lookahead_push_front(ch);
|
||||
}
|
||||
|
||||
void input_common_add_callback(void (*callback)(void *), void *arg)
|
||||
{
|
||||
void input_common_add_callback(void (*callback)(void *), void *arg) {
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
callback_queue.push(callback_info_t(callback, arg));
|
||||
}
|
||||
|
||||
static void input_flush_callbacks(void)
|
||||
{
|
||||
/* Nothing to do if nothing to do */
|
||||
if (callback_queue.empty())
|
||||
return;
|
||||
static void input_flush_callbacks(void) {
|
||||
// Nothing to do if nothing to do.
|
||||
if (callback_queue.empty()) return;
|
||||
|
||||
/* We move the queue into a local variable, so that events queued up during a callback don't get fired until next round. */
|
||||
// We move the queue into a local variable, so that events queued up during a callback don't get
|
||||
// fired until next round.
|
||||
callback_queue_t local_queue;
|
||||
std::swap(local_queue, callback_queue);
|
||||
while (! local_queue.empty())
|
||||
{
|
||||
while (!local_queue.empty()) {
|
||||
const callback_info_t &callback = local_queue.front();
|
||||
callback.first(callback.second); //cute
|
||||
callback.first(callback.second); // cute
|
||||
local_queue.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
/** \file input_common.h
|
||||
|
||||
Header file for the low level input library
|
||||
*/
|
||||
// Header file for the low level input library.
|
||||
#ifndef INPUT_COMMON_H
|
||||
#define INPUT_COMMON_H
|
||||
|
||||
|
@ -9,18 +6,17 @@ Header file for the low level input library
|
|||
|
||||
#include "common.h"
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
R_MIN = INPUT_COMMON_BASE,
|
||||
// R_NULL is sometimes returned by the input when a character was requested
|
||||
// but none could be delivered, or when an exception happened.
|
||||
// R_NULL is sometimes returned by the input when a character was requested but none could be
|
||||
// delivered, or when an exception happened.
|
||||
R_NULL = R_MIN,
|
||||
R_EOF,
|
||||
// Key codes for inputrc-style keyboard functions that are passed on
|
||||
// to the caller of input_read().
|
||||
// Key codes for inputrc-style keyboard functions that are passed on to the caller of
|
||||
// input_read().
|
||||
//
|
||||
// NOTE: If you modify this sequence of symbols you must update the
|
||||
// name_arr, code_arr and desc_arr variables in input.cpp to match!
|
||||
// NOTE: If you modify this sequence of symbols you must update the name_arr, code_arr and
|
||||
// desc_arr variables in input.cpp to match!
|
||||
R_BEGINNING_OF_LINE,
|
||||
R_END_OF_LINE,
|
||||
R_FORWARD_CHAR,
|
||||
|
@ -75,50 +71,38 @@ enum
|
|||
R_AND,
|
||||
R_CANCEL,
|
||||
R_MAX = R_CANCEL,
|
||||
// This is a special psuedo-char that is not used other than to mark the
|
||||
// end of the the special characters so we can sanity check the enum range.
|
||||
// This is a special psuedo-char that is not used other than to mark the end of the the special
|
||||
// characters so we can sanity check the enum range.
|
||||
R_SENTINAL
|
||||
};
|
||||
|
||||
/**
|
||||
Init the library
|
||||
*/
|
||||
/// Init the library.
|
||||
void input_common_init(int (*ih)());
|
||||
|
||||
/**
|
||||
Free memory used by the library
|
||||
*/
|
||||
/// Free memory used by the library.
|
||||
void input_common_destroy();
|
||||
|
||||
// Adjust the escape timeout.
|
||||
/// Adjust the escape timeout.
|
||||
void update_wait_on_escape_ms();
|
||||
|
||||
/**
|
||||
Function used by input_readch to read bytes from stdin until enough
|
||||
bytes have been read to convert them to a wchar_t. Conversion is
|
||||
done using mbrtowc. If a character has previously been read and
|
||||
then 'unread' using \c input_common_unreadch, that character is
|
||||
returned. If timed is true, readch2 will wait at most
|
||||
WAIT_ON_ESCAPE milliseconds for a character to be available for
|
||||
reading before returning with the value WEOF.
|
||||
*/
|
||||
/// Function used by input_readch to read bytes from stdin until enough bytes have been read to
|
||||
/// convert them to a wchar_t. Conversion is done using mbrtowc. If a character has previously been
|
||||
/// read and then 'unread' using \c input_common_unreadch, that character is returned. If timed is
|
||||
/// true, readch2 will wait at most WAIT_ON_ESCAPE milliseconds for a character to be available for
|
||||
/// reading before returning with the value WEOF.
|
||||
wchar_t input_common_readch(int timed);
|
||||
|
||||
/**
|
||||
Enqueue a character or a readline function to the queue of unread
|
||||
characters that input_readch will return before actually reading from fd
|
||||
0.
|
||||
*/
|
||||
/// Enqueue a character or a readline function to the queue of unread characters that input_readch
|
||||
/// will return before actually reading from fd 0.
|
||||
void input_common_queue_ch(wint_t ch);
|
||||
|
||||
/**
|
||||
Add a character or a readline function to the front of the queue of unread
|
||||
characters. This will be the first character returned by input_readch
|
||||
(unless this function is called more than once).
|
||||
*/
|
||||
/// Add a character or a readline function to the front of the queue of unread characters. This
|
||||
/// will be the first character returned by input_readch (unless this function is called more than
|
||||
/// once).
|
||||
void input_common_next_ch(wint_t ch);
|
||||
|
||||
/** Adds a callback to be invoked at the next turn of the "event loop." The callback function will be invoked and passed arg. */
|
||||
/// Adds a callback to be invoked at the next turn of the "event loop." The callback function will
|
||||
/// be invoked and passed arg.
|
||||
void input_common_add_callback(void (*callback)(void *), void *arg);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue