Improve handling of malformed ANSI. (#950)
This commit is contained in:
parent
f74f66e507
commit
f825fca43c
@ -852,6 +852,8 @@ public:
|
||||
*/
|
||||
Fl_Scrollbar *hscrollbar; // horizontal scrollbar
|
||||
private:
|
||||
// Special utf8 symbols
|
||||
const char *error_char_; // utf8 string shown for invalid utf8, bad ANSI, etc
|
||||
bool fontsize_defer_; // flag defers font calcs until first draw() (issue 837)
|
||||
int scrollbar_size_; // local preference for scrollbar size
|
||||
ScrollbarStyle hscrollbar_style_;
|
||||
@ -897,7 +899,6 @@ protected:
|
||||
private:
|
||||
void create_ring(int drows, int dcols, int hrows);
|
||||
void init_(int X,int Y,int W,int H,const char*L,int rows,int cols,int hist,bool fontsize_defer);
|
||||
private:
|
||||
// Tabstops
|
||||
void init_tabstops(int newsize);
|
||||
void default_tabstops(void);
|
||||
@ -999,6 +1000,7 @@ public:
|
||||
private:
|
||||
void handle_lf(void);
|
||||
void handle_cr(void);
|
||||
void handle_esc(void);
|
||||
// Printing
|
||||
void handle_ctrl(char c);
|
||||
bool is_printable(char c);
|
||||
@ -1168,11 +1170,20 @@ private:
|
||||
public:
|
||||
float redraw_rate(void) const;
|
||||
void redraw_rate(float val);
|
||||
// API: Show unknown/unprintable chars
|
||||
// API: Show unknown/invalid utf8/ANSI sequences with an error character (¿).
|
||||
bool show_unknown(void) const;
|
||||
void show_unknown(bool val);
|
||||
protected:
|
||||
static const char *unknown_char; ///< "unknown" replacement character
|
||||
|
||||
/** Sets the "error character" utf8 string shown for invalid utf8
|
||||
or bad ANSI sequences if show_unknown() is true. Default: "¿".
|
||||
\See show_unknown(bool)
|
||||
*/
|
||||
void error_char(const char* val) { error_char_ = val; }
|
||||
|
||||
/** Returns the "error character" utf8 string, which is shown for invalid utf8
|
||||
or bad ANSI sequences if show_unknown() is true. \See show_unknown(bool)
|
||||
*/
|
||||
const char* error_char(void) const { return error_char_; }
|
||||
public:
|
||||
// API: ANSI sequences
|
||||
bool ansi(void) const;
|
||||
|
@ -37,12 +37,6 @@
|
||||
#include <FL/fl_string_functions.h>
|
||||
#include "Fl_String.H"
|
||||
|
||||
/////////////////////////////////
|
||||
////// Static Class Data ////////
|
||||
/////////////////////////////////
|
||||
|
||||
const char *Fl_Terminal::unknown_char = "¿";
|
||||
|
||||
/////////////////////////////////
|
||||
////// Static Functions /////////
|
||||
/////////////////////////////////
|
||||
@ -181,6 +175,7 @@ bool Fl_Terminal::Selection::get_selection(int &srow,int &scol,
|
||||
// Always returns true.
|
||||
//
|
||||
bool Fl_Terminal::Selection::start(int row, int col, bool char_right) {
|
||||
(void) char_right; // silence warning
|
||||
srow_ = erow_ = row;
|
||||
scol_ = ecol_ = col;
|
||||
state_ = 1; // state: "started selection"
|
||||
@ -2558,6 +2553,16 @@ void Fl_Terminal::handle_lf(void) {
|
||||
else cursor_down(1, do_scroll);
|
||||
}
|
||||
|
||||
// Handle '\e' escape character.
|
||||
void Fl_Terminal::handle_esc(void) {
|
||||
if (!ansi_) // not in ansi mode?
|
||||
{ handle_unknown_char(); return; } // ..show unknown char, early exit
|
||||
if (escseq.esc_mode() == 0x1b) // already in esc mode?
|
||||
{ handle_unknown_char(); } // ..show 1st esc as unknown char, parse 2nd
|
||||
if (escseq.parse(0x1b) == EscapeSeq::fail) // parse esc
|
||||
{ handle_unknown_char(); return; } // ..error? show unknown char
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the combined output translation flags to \p val.
|
||||
|
||||
@ -2599,9 +2604,7 @@ void Fl_Terminal::handle_ctrl(char c) {
|
||||
case '\r': handle_cr(); return; // CR?
|
||||
case '\n': handle_lf(); return; // LF?
|
||||
case '\t': cursor_tab_right(); return; // TAB?
|
||||
case 0x1b: if (ansi_) escseq.parse(c); // ESC?
|
||||
else append_utf8("␛");
|
||||
return;
|
||||
case 0x1b: handle_esc(); return; // ESC?
|
||||
default: handle_unknown_char(); return; // Unknown ctrl char?
|
||||
}
|
||||
}
|
||||
@ -2731,12 +2734,16 @@ void Fl_Terminal::handle_escseq(char c) {
|
||||
// NOTE: Use xterm to test. gnome-terminal has bugs, even in 2022.
|
||||
const bool do_scroll = true;
|
||||
const bool no_scroll = false;
|
||||
//UNUSED const bool do_wrap = true;
|
||||
//UNUSED const bool no_wrap = false;
|
||||
switch (escseq.parse(c)) { // parse char, advance s..
|
||||
case EscapeSeq::fail: escseq.reset(); return; // failed? reset, done
|
||||
case EscapeSeq::success: return; // keep parsing..
|
||||
case EscapeSeq::completed: break; // parsed complete esc sequence?
|
||||
case EscapeSeq::fail: // failed?
|
||||
escseq.reset(); // ..reset to let error_char be visible
|
||||
handle_unknown_char(); // ..show error char (if enabled)
|
||||
print_char(c); // ..show char we couldn't handle
|
||||
return; // ..done.
|
||||
case EscapeSeq::success: // success?
|
||||
return; // ..keep parsing
|
||||
case EscapeSeq::completed: // parsed complete esc sequence?
|
||||
break; // ..fall through to handle operation
|
||||
}
|
||||
// Shortcut varnames for escseq parsing..
|
||||
EscapeSeq &esc = escseq;
|
||||
@ -3254,7 +3261,7 @@ void Fl_Terminal::append(const char *s, int len/*=-1*/) {
|
||||
int Fl_Terminal::handle_unknown_char(void) {
|
||||
if (!show_unknown_) return 0;
|
||||
escseq.reset(); // disable any pending esc seq to prevent eating unknown char
|
||||
print_char(unknown_char);
|
||||
print_char(error_char_);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3270,9 +3277,9 @@ int Fl_Terminal::handle_unknown_char(void) {
|
||||
*/
|
||||
int Fl_Terminal::handle_unknown_char(int drow, int dcol) {
|
||||
if (!show_unknown_) return 0;
|
||||
int len = (int)strlen(unknown_char);
|
||||
int len = (int)strlen(error_char_);
|
||||
Utf8Char *u8c = u8c_disp_row(drow) + dcol;
|
||||
u8c->text_utf8(unknown_char, len, *current_style_);
|
||||
u8c->text_utf8(error_char_, len, *current_style_);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3384,6 +3391,7 @@ Fl_Terminal::Fl_Terminal(int X,int Y,int W,int H,const char*L,int rows,int cols,
|
||||
|
||||
// Private constructor method
|
||||
void Fl_Terminal::init_(int X,int Y,int W,int H,const char*L,int rows,int cols,int hist,bool fontsize_defer) {
|
||||
error_char_ = "¿";
|
||||
scrollbar = hscrollbar = 0; // avoid problems w/update_screen_xywh()
|
||||
// currently unused params
|
||||
(void)X; (void)Y; (void)W; (void)H; (void)L;
|
||||
@ -4039,7 +4047,7 @@ void Fl_Terminal::redraw_rate(float val) {
|
||||
|
||||
/**
|
||||
Return the "show unknown" flag.
|
||||
See show_unknown(bool) for more info.
|
||||
\See show_unknown(bool), error_char(const char*).
|
||||
*/
|
||||
bool Fl_Terminal::show_unknown(void) const {
|
||||
return show_unknown_;
|
||||
@ -4048,12 +4056,12 @@ bool Fl_Terminal::show_unknown(void) const {
|
||||
/**
|
||||
Set the "show unknown" flag.
|
||||
|
||||
If true, unknown escape sequences and unprintable control characters
|
||||
will be shown with the error character "¿".
|
||||
If true, invalid utf8 and invalid ANSI sequences will be shown
|
||||
with the error character "¿".
|
||||
|
||||
If false, those sequences and characters will be ignored.
|
||||
If false, errors characters won't be shown.
|
||||
|
||||
\see handle_unknown_char()
|
||||
\see handle_unknown_char(), error_char(const char*).
|
||||
*/
|
||||
void Fl_Terminal::show_unknown(bool val) {
|
||||
show_unknown_ = val;
|
||||
|
Loading…
Reference in New Issue
Block a user