mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-04-19 06:31:13 -03:00
restyle sanity & screen module to match project style
Reduces lint errors from 163 to 112 (-31%). Line count from 1866 to 1493 (-20%). Another step in resolving issue #2902.
This commit is contained in:
@@ -1,60 +1,41 @@
|
||||
/** \file sanity.c
|
||||
Functions for performing sanity checks on the program state
|
||||
*/
|
||||
// Functions for performing sanity checks on the program state.
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "common.h"
|
||||
#include "sanity.h"
|
||||
#include "proc.h"
|
||||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "history.h"
|
||||
#include "reader.h"
|
||||
#include "kill.h"
|
||||
#include "proc.h"
|
||||
#include "reader.h"
|
||||
#include "sanity.h"
|
||||
|
||||
/**
|
||||
Status from earlier sanity checks
|
||||
*/
|
||||
/// Status from earlier sanity checks.
|
||||
static int insane;
|
||||
|
||||
void sanity_lose()
|
||||
{
|
||||
void sanity_lose() {
|
||||
debug(0, _(L"Errors detected, shutting down. Break on sanity_lose() to debug."));
|
||||
insane = 1;
|
||||
}
|
||||
|
||||
int sanity_check()
|
||||
{
|
||||
int sanity_check() {
|
||||
if (!insane)
|
||||
if (get_is_interactive())
|
||||
history_sanity_check();
|
||||
if (!insane)
|
||||
reader_sanity_check();
|
||||
if (!insane)
|
||||
kill_sanity_check();
|
||||
if (!insane)
|
||||
proc_sanity_check();
|
||||
if (get_is_interactive()) history_sanity_check();
|
||||
if (!insane) reader_sanity_check();
|
||||
if (!insane) kill_sanity_check();
|
||||
if (!insane) proc_sanity_check();
|
||||
|
||||
return insane;
|
||||
}
|
||||
|
||||
void validate_pointer(const void *ptr, const wchar_t *err, int null_ok)
|
||||
{
|
||||
|
||||
/*
|
||||
Test if the pointer data crosses a segment boundary.
|
||||
*/
|
||||
|
||||
if ((0x00000003l & (intptr_t)ptr) != 0)
|
||||
{
|
||||
void validate_pointer(const void *ptr, const wchar_t *err, int null_ok) {
|
||||
// Test if the pointer data crosses a segment boundary.
|
||||
if ((0x00000003l & (intptr_t)ptr) != 0) {
|
||||
debug(0, _(L"The pointer '%ls' is invalid"), err);
|
||||
sanity_lose();
|
||||
}
|
||||
|
||||
if ((!null_ok) && (ptr==0))
|
||||
{
|
||||
if ((!null_ok) && (ptr == 0)) {
|
||||
debug(0, _(L"The pointer '%ls' is null"), err);
|
||||
sanity_lose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
25
src/sanity.h
25
src/sanity.h
@@ -1,27 +1,18 @@
|
||||
/** \file sanity.h
|
||||
Prototypes for functions for performing sanity checks on the program state
|
||||
*/
|
||||
|
||||
// Prototypes for functions for performing sanity checks on the program state.
|
||||
#ifndef FISH_SANITY_H
|
||||
#define FISH_SANITY_H
|
||||
|
||||
/**
|
||||
Call this function to tell the program it is not in a sane state.
|
||||
*/
|
||||
/// Call this function to tell the program it is not in a sane state.
|
||||
void sanity_lose();
|
||||
|
||||
/**
|
||||
Perform sanity checks, return 1 if program is in a sane state 0 otherwise.
|
||||
*/
|
||||
/// Perform sanity checks, return 1 if program is in a sane state 0 otherwise.
|
||||
int sanity_check();
|
||||
|
||||
/**
|
||||
Try and determine if ptr is a valid pointer. If not, loose sanity.
|
||||
|
||||
\param ptr The pointer to validate
|
||||
\param err A description of what the pointer refers to, for use in error messages
|
||||
\param null_ok Wheter the pointer is allowed to point to 0
|
||||
*/
|
||||
/// Try and determine if ptr is a valid pointer. If not, loose sanity.
|
||||
///
|
||||
/// \param ptr The pointer to validate
|
||||
/// \param err A description of what the pointer refers to, for use in error messages
|
||||
/// \param null_ok Wheter the pointer is allowed to point to 0
|
||||
void validate_pointer(const void *ptr, const wchar_t *err, int null_ok);
|
||||
|
||||
#endif
|
||||
|
||||
1299
src/screen.cpp
1299
src/screen.cpp
File diff suppressed because it is too large
Load Diff
290
src/screen.h
290
src/screen.h
@@ -1,286 +1,194 @@
|
||||
/** \file screen.h High level library for handling the terminal screen
|
||||
|
||||
The screen library allows the interactive reader to write its
|
||||
output to screen efficiently by keeping an internal representation
|
||||
of the current screen contents and trying to find a reasonably
|
||||
efficient way for transforming that to the desired screen content.
|
||||
|
||||
The current implementation is less smart than ncurses allows
|
||||
and can not for example move blocks of text around to handle text
|
||||
insertion.
|
||||
*/
|
||||
// High level library for handling the terminal screen
|
||||
//
|
||||
// The screen library allows the interactive reader to write its output to screen efficiently by
|
||||
// keeping an internal representation of the current screen contents and trying to find a reasonably
|
||||
// efficient way for transforming that to the desired screen content.
|
||||
//
|
||||
// The current implementation is less smart than ncurses allows and can not for example move blocks
|
||||
// of text around to handle text insertion.
|
||||
#ifndef FISH_SCREEN_H
|
||||
#define FISH_SCREEN_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <vector>
|
||||
#include <sys/stat.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "common.h"
|
||||
#include "highlight.h"
|
||||
#include <stdbool.h>
|
||||
#include <memory>
|
||||
|
||||
class page_rendering_t;
|
||||
|
||||
/**
|
||||
A class representing a single line of a screen.
|
||||
*/
|
||||
struct line_t
|
||||
{
|
||||
/// A class representing a single line of a screen.
|
||||
struct line_t {
|
||||
std::vector<wchar_t> text;
|
||||
std::vector<highlight_spec_t> colors;
|
||||
bool is_soft_wrapped;
|
||||
|
||||
line_t() : text(), colors(), is_soft_wrapped(false)
|
||||
{
|
||||
}
|
||||
line_t() : text(), colors(), is_soft_wrapped(false) {}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
void clear(void) {
|
||||
text.clear();
|
||||
colors.clear();
|
||||
}
|
||||
|
||||
void append(wchar_t txt, highlight_spec_t color)
|
||||
{
|
||||
void append(wchar_t txt, highlight_spec_t color) {
|
||||
text.push_back(txt);
|
||||
colors.push_back(color);
|
||||
}
|
||||
|
||||
void append(const wchar_t *txt, highlight_spec_t color)
|
||||
{
|
||||
for (size_t i=0; txt[i]; i++)
|
||||
{
|
||||
void append(const wchar_t *txt, highlight_spec_t color) {
|
||||
for (size_t i = 0; txt[i]; i++) {
|
||||
text.push_back(txt[i]);
|
||||
colors.push_back(color);
|
||||
}
|
||||
}
|
||||
|
||||
size_t size(void) const { return text.size(); }
|
||||
|
||||
wchar_t char_at(size_t idx) const { return text.at(idx); }
|
||||
|
||||
size_t size(void) const
|
||||
{
|
||||
return text.size();
|
||||
}
|
||||
highlight_spec_t color_at(size_t idx) const { return colors.at(idx); }
|
||||
|
||||
wchar_t char_at(size_t idx) const
|
||||
{
|
||||
return text.at(idx);
|
||||
}
|
||||
|
||||
highlight_spec_t color_at(size_t idx) const
|
||||
{
|
||||
return colors.at(idx);
|
||||
}
|
||||
|
||||
void append_line(const line_t &line)
|
||||
{
|
||||
void append_line(const line_t &line) {
|
||||
text.insert(text.end(), line.text.begin(), line.text.end());
|
||||
colors.insert(colors.end(), line.colors.begin(), line.colors.end());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
A class representing screen contents.
|
||||
*/
|
||||
class screen_data_t
|
||||
{
|
||||
/// A class representing screen contents.
|
||||
class screen_data_t {
|
||||
std::vector<line_t> line_datas;
|
||||
|
||||
public:
|
||||
|
||||
struct cursor_t
|
||||
{
|
||||
public:
|
||||
struct cursor_t {
|
||||
int x;
|
||||
int y;
|
||||
cursor_t() : x(0), y(0) { }
|
||||
cursor_t(int a, int b) : x(a), y(b) { }
|
||||
cursor_t() : x(0), y(0) {}
|
||||
cursor_t(int a, int b) : x(a), y(b) {}
|
||||
} cursor;
|
||||
|
||||
line_t &add_line(void)
|
||||
{
|
||||
line_t &add_line(void) {
|
||||
line_datas.resize(line_datas.size() + 1);
|
||||
return line_datas.back();
|
||||
}
|
||||
|
||||
void resize(size_t size)
|
||||
{
|
||||
line_datas.resize(size);
|
||||
}
|
||||
void resize(size_t size) { line_datas.resize(size); }
|
||||
|
||||
line_t &create_line(size_t idx)
|
||||
{
|
||||
if (idx >= line_datas.size())
|
||||
{
|
||||
line_t &create_line(size_t idx) {
|
||||
if (idx >= line_datas.size()) {
|
||||
line_datas.resize(idx + 1);
|
||||
}
|
||||
return line_datas.at(idx);
|
||||
}
|
||||
|
||||
line_t &insert_line_at_index(size_t idx)
|
||||
{
|
||||
line_t &insert_line_at_index(size_t idx) {
|
||||
assert(idx <= line_datas.size());
|
||||
return *line_datas.insert(line_datas.begin() + idx, line_t());
|
||||
}
|
||||
|
||||
line_t &line(size_t idx)
|
||||
{
|
||||
return line_datas.at(idx);
|
||||
}
|
||||
line_t &line(size_t idx) { return line_datas.at(idx); }
|
||||
|
||||
size_t line_count(void)
|
||||
{
|
||||
return line_datas.size();
|
||||
}
|
||||
size_t line_count(void) { return line_datas.size(); }
|
||||
|
||||
void append_lines(const screen_data_t &d)
|
||||
{
|
||||
void append_lines(const screen_data_t &d) {
|
||||
this->line_datas.insert(this->line_datas.end(), d.line_datas.begin(), d.line_datas.end());
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return line_datas.empty();
|
||||
}
|
||||
bool empty() const { return line_datas.empty(); }
|
||||
};
|
||||
|
||||
/**
|
||||
The class representing the current and desired screen contents.
|
||||
*/
|
||||
class screen_t
|
||||
{
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
/// The class representing the current and desired screen contents.
|
||||
class screen_t {
|
||||
public:
|
||||
/// Constructor
|
||||
screen_t();
|
||||
|
||||
/**
|
||||
The internal representation of the desired screen contents.
|
||||
*/
|
||||
/// The internal representation of the desired screen contents.
|
||||
screen_data_t desired;
|
||||
/**
|
||||
The internal representation of the actual screen contents.
|
||||
*/
|
||||
/// The internal representation of the actual screen contents.
|
||||
screen_data_t actual;
|
||||
|
||||
/**
|
||||
A string containing the prompt which was last printed to
|
||||
the screen.
|
||||
*/
|
||||
/// A string containing the prompt which was last printed to the screen.
|
||||
wcstring actual_left_prompt;
|
||||
|
||||
/** Last right prompt width */
|
||||
/// Last right prompt width.
|
||||
size_t last_right_prompt_width;
|
||||
|
||||
/**
|
||||
The actual width of the screen at the time of the last screen
|
||||
write.
|
||||
*/
|
||||
/// The actual width of the screen at the time of the last screen write.
|
||||
int actual_width;
|
||||
|
||||
/** If we support soft wrapping, we can output to this location without any cursor motion. */
|
||||
/// If we support soft wrapping, we can output to this location without any cursor motion.
|
||||
screen_data_t::cursor_t soft_wrap_location;
|
||||
|
||||
/** Whether the last-drawn autosuggestion (if any) is truncated, or hidden entirely */
|
||||
/// Whether the last-drawn autosuggestion (if any) is truncated, or hidden entirely.
|
||||
bool autosuggestion_is_truncated;
|
||||
|
||||
/**
|
||||
This flag is set to true when there is reason to suspect that
|
||||
the parts of the screen lines where the actual content is not
|
||||
filled in may be non-empty. This means that a clr_eol command
|
||||
has to be sent to the terminal at the end of each line, including
|
||||
actual_lines_before_reset.
|
||||
*/
|
||||
/// This flag is set to true when there is reason to suspect that the parts of the screen lines
|
||||
/// where the actual content is not filled in may be non-empty. This means that a clr_eol
|
||||
/// command has to be sent to the terminal at the end of each line, including
|
||||
/// actual_lines_before_reset.
|
||||
bool need_clear_lines;
|
||||
|
||||
/** Whether there may be yet more content after the lines, and we issue a clr_eos if possible. */
|
||||
/// Whether there may be yet more content after the lines, and we issue a clr_eos if possible.
|
||||
bool need_clear_screen;
|
||||
|
||||
/** If we need to clear, this is how many lines the actual screen had, before we reset it. This is used when resizing the window larger: if the cursor jumps to the line above, we need to remember to clear the subsequent lines. */
|
||||
/// If we need to clear, this is how many lines the actual screen had, before we reset it. This
|
||||
/// is used when resizing the window larger: if the cursor jumps to the line above, we need to
|
||||
/// remember to clear the subsequent lines.
|
||||
size_t actual_lines_before_reset;
|
||||
|
||||
/**
|
||||
These status buffers are used to check if any output has occurred
|
||||
other than from fish's main loop, in which case we need to redraw.
|
||||
*/
|
||||
/// These status buffers are used to check if any output has occurred other than from fish's
|
||||
/// main loop, in which case we need to redraw.
|
||||
struct stat prev_buff_1, prev_buff_2, post_buff_1, post_buff_2;
|
||||
};
|
||||
|
||||
/**
|
||||
This is the main function for the screen putput library. It is used
|
||||
to define the desired contents of the screen. The screen command
|
||||
will use it's knowlege of the current contents of the screen in
|
||||
order to render the desired output using as few terminal commands
|
||||
as possible.
|
||||
/// This is the main function for the screen putput library. It is used to define the desired
|
||||
/// contents of the screen. The screen command will use it's knowlege of the current contents of the
|
||||
/// screen in order to render the desired output using as few terminal commands as possible.
|
||||
///
|
||||
/// \param s the screen on which to write
|
||||
/// \param left_prompt the prompt to prepend to the command line
|
||||
/// \param right_prompt the right prompt, or NULL if none
|
||||
/// \param commandline the command line
|
||||
/// \param explicit_len the number of characters of the "explicit" (non-autosuggestion) portion of
|
||||
/// the command line
|
||||
/// \param colors the colors to use for the comand line
|
||||
/// \param indent the indent to use for the command line
|
||||
/// \param cursor_pos where the cursor is
|
||||
/// \param sel_start_pos where the selections starts (inclusive)
|
||||
/// \param sel_stop_pos where the selections ends (inclusive)
|
||||
/// \param pager_data any pager data, to append to the screen
|
||||
/// \param position_is_within_pager whether the position is within the pager line (first line)
|
||||
void s_write(screen_t *s, const wcstring &left_prompt, const wcstring &right_prompt,
|
||||
const wcstring &commandline, size_t explicit_len, const highlight_spec_t *colors,
|
||||
const int *indent, size_t cursor_pos, size_t sel_start_pos, size_t sel_stop_pos,
|
||||
const page_rendering_t &pager_data, bool position_is_within_pager);
|
||||
|
||||
\param s the screen on which to write
|
||||
\param left_prompt the prompt to prepend to the command line
|
||||
\param right_prompt the right prompt, or NULL if none
|
||||
\param commandline the command line
|
||||
\param explicit_len the number of characters of the "explicit" (non-autosuggestion) portion of the command line
|
||||
\param colors the colors to use for the comand line
|
||||
\param indent the indent to use for the command line
|
||||
\param cursor_pos where the cursor is
|
||||
\param sel_start_pos where the selections starts (inclusive)
|
||||
\param sel_stop_pos where the selections ends (inclusive)
|
||||
\param pager_data any pager data, to append to the screen
|
||||
\param position_is_within_pager whether the position is within the pager line (first line)
|
||||
*/
|
||||
void s_write(screen_t *s,
|
||||
const wcstring &left_prompt,
|
||||
const wcstring &right_prompt,
|
||||
const wcstring &commandline,
|
||||
size_t explicit_len,
|
||||
const highlight_spec_t *colors,
|
||||
const int *indent,
|
||||
size_t cursor_pos,
|
||||
size_t sel_start_pos,
|
||||
size_t sel_stop_pos,
|
||||
const page_rendering_t &pager_data,
|
||||
bool position_is_within_pager);
|
||||
|
||||
/**
|
||||
This function resets the screen buffers internal knowledge about
|
||||
the contents of the screen. Use this function when some other
|
||||
function than s_write has written to the screen.
|
||||
|
||||
\param s the screen to reset
|
||||
\param reset_cursor whether the line on which the cursor has changed should be assumed to have changed. If \c reset_cursor is false, the library will attempt to make sure that the screen area does not seem to move up or down on repaint.
|
||||
\param reset_prompt whether to reset the prompt as well.
|
||||
|
||||
If reset_cursor is incorrectly set to false, this may result in
|
||||
screen contents being erased. If it is incorrectly set to true, it
|
||||
may result in one or more lines of garbage on screen on the next
|
||||
repaint. If this happens during a loop, such as an interactive
|
||||
resizing, there will be one line of garbage for every repaint,
|
||||
which will quickly fill the screen.
|
||||
*/
|
||||
/// This function resets the screen buffers internal knowledge about the contents of the screen. Use
|
||||
/// this function when some other function than s_write has written to the screen.
|
||||
///
|
||||
/// \param s the screen to reset
|
||||
/// \param reset_cursor whether the line on which the cursor has changed should be assumed to have
|
||||
/// changed. If \c reset_cursor is false, the library will attempt to make sure that the screen area
|
||||
/// does not seem to move up or down on repaint.
|
||||
/// \param reset_prompt whether to reset the prompt as well.
|
||||
///
|
||||
/// If reset_cursor is incorrectly set to false, this may result in screen contents being erased. If
|
||||
/// it is incorrectly set to true, it may result in one or more lines of garbage on screen on the
|
||||
/// next repaint. If this happens during a loop, such as an interactive resizing, there will be one
|
||||
/// line of garbage for every repaint, which will quickly fill the screen.
|
||||
void s_reset(screen_t *s, bool reset_cursor, bool reset_prompt = true);
|
||||
|
||||
|
||||
enum screen_reset_mode_t
|
||||
{
|
||||
/* Do not make a new line, do not repaint the prompt. */
|
||||
enum screen_reset_mode_t {
|
||||
/// Do not make a new line, do not repaint the prompt.
|
||||
screen_reset_current_line_contents,
|
||||
|
||||
/* Do not make a new line, do repaint the prompt. */
|
||||
/// Do not make a new line, do repaint the prompt.
|
||||
screen_reset_current_line_and_prompt,
|
||||
|
||||
/* Abandon the current line, go to the next one, repaint the prompt */
|
||||
/// Abandon the current line, go to the next one, repaint the prompt.
|
||||
screen_reset_abandon_line,
|
||||
|
||||
/* Abandon the current line, go to the next one, clear the rest of the screen */
|
||||
/// Abandon the current line, go to the next one, clear the rest of the screen.
|
||||
screen_reset_abandon_line_and_clear_to_end_of_screen
|
||||
};
|
||||
|
||||
void s_reset(screen_t *s, screen_reset_mode_t mode);
|
||||
|
||||
/* Issues an immediate clr_eos, returning if it existed */
|
||||
/// Issues an immediate clr_eos, returning if it existed.
|
||||
bool screen_force_clear_to_end();
|
||||
|
||||
/* Returns the length of an escape code. Exposed for testing purposes only. */
|
||||
/// Returns the length of an escape code. Exposed for testing purposes only.
|
||||
size_t escape_code_length(const wchar_t *code);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user