linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/22] tty: vt: cleanup ESC sequences handling
@ 2024-02-02  6:55 Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 01/22] tty: vt: make rgb_from_256() slighly more comprehensible Jiri Slaby (SUSE)
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

This is a promised followup of "tty: vt: cleanup and documentation" [1].

The escape sequences parser is cleaned up, so that it is easier to
follow.

Most of the patches are easier to review with '-w -b' passed to git diff
(as the code is moved to separate functions with a different level of
indentation only).

[1] https://lore.kernel.org/all/20240122110401.7289-28-jirislaby@kernel.org/T/

Jiri Slaby (SUSE) (22):
  tty: vt: make rgb_from_256() slighly more comprehensible
  tty: vt: define enums for CSI+h/l codes
  tty: vt: rename set_mode() to csi_hl()
  tty: vt: split DEC CSI+h/l handling into csi_DEC_hl()
  tty: vt: remove unneeded assignment of EPecma to vc_priv
  tty: vt: move CSI+n handling along to other ECMA CSIs
  tty: vt: define an enum for CSI+] codes
  tty: vt: rename setterm_command() to csi_RSB()
  tty: vt: put cases on separate lines
  tty: vt: accept u8 in do_con_trol() and vc_setGx()
  tty: vt: extract ascii handling to handle_ascii()
  tty: vt: separate ESesc state handling into handle_esc()
  tty: vt: move CSI DEC handling to a separate function
  tty: vt: move CSI ECMA handling to a separate function
  tty: vt: name, reflow and document enum vc_ctl_state
  tty: vt: simplify ansi_control_string()
  tty: vt: handle CSI+[ inside preexisting switch-case
  tty: vt: add new helper for reseting vc parameters
  tty: vt: use switch+case in the ESnonstd case
  tty: vt: use switch+case in the ESgetpars case
  tty: vt: use ASCII enum constants in vt_console_print()
  tty: vt: decrypt magic constants in vc_is_control()

 drivers/tty/vt/vt.c | 876 ++++++++++++++++++++++++++------------------
 1 file changed, 514 insertions(+), 362 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 01/22] tty: vt: make rgb_from_256() slighly more comprehensible
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 02/22] tty: vt: define enums for CSI+h/l codes Jiri Slaby (SUSE)
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

* make the parameter unsigned, as it is expected to be unsigned,
* make the computation easier to follow -- step-by-step, and
* don't use 85 / 2 which is only a reduced form of 255 / 6 (by a factor
  3). Unlike the former, the latter can be understood.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 65cd40cac96b..7d42f148559a 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1588,7 +1588,7 @@ static void default_attr(struct vc_data *vc)
 
 struct rgb { u8 r; u8 g; u8 b; };
 
-static void rgb_from_256(int i, struct rgb *c)
+static void rgb_from_256(unsigned int i, struct rgb *c)
 {
 	if (i < 8) {            /* Standard colours. */
 		c->r = i&1 ? 0xaa : 0x00;
@@ -1599,9 +1599,12 @@ static void rgb_from_256(int i, struct rgb *c)
 		c->g = i&2 ? 0xff : 0x55;
 		c->b = i&4 ? 0xff : 0x55;
 	} else if (i < 232) {   /* 6x6x6 colour cube. */
-		c->r = (i - 16) / 36 * 85 / 2;
-		c->g = (i - 16) / 6 % 6 * 85 / 2;
-		c->b = (i - 16) % 6 * 85 / 2;
+		i -= 16;
+		c->b = i % 6 * 255 / 6;
+		i /= 6;
+		c->g = i % 6 * 255 / 6;
+		i /= 6;
+		c->r = i     * 255 / 6;
 	} else                  /* Grayscale ramp. */
 		c->r = c->g = c->b = i * 10 - 2312;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 02/22] tty: vt: define enums for CSI+h/l codes
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 01/22] tty: vt: make rgb_from_256() slighly more comprehensible Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 03/22] tty: vt: rename set_mode() to csi_hl() Jiri Slaby (SUSE)
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

Decrypt the constant values by proper enum names. This time in
set_mode().

Define two of them as DEC ('CSI ?') is about to be split away in the
next patches.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 42 ++++++++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 7d42f148559a..7b55d87248f8 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1862,6 +1862,24 @@ int mouse_reporting(void)
 	return vc_cons[fg_console].d->vc_report_mouse;
 }
 
+enum {
+	CSI_DEC_hl_CURSOR_KEYS	= 1,	/* CKM: cursor keys send ^[Ox/^[[x */
+	CSI_DEC_hl_132_COLUMNS	= 3,	/* COLM: 80/132 mode switch */
+	CSI_DEC_hl_REVERSE_VIDEO = 5,	/* SCNM */
+	CSI_DEC_hl_ORIGIN_MODE	= 6,	/* OM: origin relative/absolute */
+	CSI_DEC_hl_AUTOWRAP	= 7,	/* AWM */
+	CSI_DEC_hl_AUTOREPEAT	= 8,	/* ARM */
+	CSI_DEC_hl_MOUSE_X10	= 9,
+	CSI_DEC_hl_SHOW_CURSOR	= 25,	/* TCEM */
+	CSI_DEC_hl_MOUSE_VT200	= 1000,
+};
+
+enum {
+	CSI_hl_DISPLAY_CTRL	= 3,	/* handle ansi control chars */
+	CSI_hl_INSERT		= 4,	/* IRM: insert/replace */
+	CSI_hl_AUTO_NL		= 20,	/* LNM: Enter == CrLf/Lf */
+};
+
 /* console_lock is held */
 static void set_mode(struct vc_data *vc, int on_off)
 {
@@ -1870,20 +1888,20 @@ static void set_mode(struct vc_data *vc, int on_off)
 	for (i = 0; i <= vc->vc_npar; i++)
 		if (vc->vc_priv == EPdec) {
 			switch(vc->vc_par[i]) {	/* DEC private modes set/reset */
-			case 1:			/* Cursor keys send ^[Ox/^[[x */
+			case CSI_DEC_hl_CURSOR_KEYS:
 				if (on_off)
 					set_kbd(vc, decckm);
 				else
 					clr_kbd(vc, decckm);
 				break;
-			case 3:	/* 80/132 mode switch unimplemented */
+			case CSI_DEC_hl_132_COLUMNS:	/* unimplemented */
 #if 0
 				vc_resize(deccolm ? 132 : 80, vc->vc_rows);
 				/* this alone does not suffice; some user mode
 				   utility has to change the hardware regs */
 #endif
 				break;
-			case 5:			/* Inverted screen on/off */
+			case CSI_DEC_hl_REVERSE_VIDEO:
 				if (vc->vc_decscnm != on_off) {
 					vc->vc_decscnm = on_off;
 					invert_screen(vc, 0,
@@ -1892,38 +1910,38 @@ static void set_mode(struct vc_data *vc, int on_off)
 					update_attr(vc);
 				}
 				break;
-			case 6:			/* Origin relative/absolute */
+			case CSI_DEC_hl_ORIGIN_MODE:
 				vc->vc_decom = on_off;
 				gotoxay(vc, 0, 0);
 				break;
-			case 7:			/* Autowrap on/off */
+			case CSI_DEC_hl_AUTOWRAP:
 				vc->vc_decawm = on_off;
 				break;
-			case 8:			/* Autorepeat on/off */
+			case CSI_DEC_hl_AUTOREPEAT:
 				if (on_off)
 					set_kbd(vc, decarm);
 				else
 					clr_kbd(vc, decarm);
 				break;
-			case 9:
+			case CSI_DEC_hl_MOUSE_X10:
 				vc->vc_report_mouse = on_off ? 1 : 0;
 				break;
-			case 25:		/* Cursor on/off */
+			case CSI_DEC_hl_SHOW_CURSOR:
 				vc->vc_deccm = on_off;
 				break;
-			case 1000:
+			case CSI_DEC_hl_MOUSE_VT200:
 				vc->vc_report_mouse = on_off ? 2 : 0;
 				break;
 			}
 		} else {
 			switch(vc->vc_par[i]) {	/* ANSI modes set/reset */
-			case 3:			/* Monitor (display ctrls) */
+			case CSI_hl_DISPLAY_CTRL:
 				vc->vc_disp_ctrl = on_off;
 				break;
-			case 4:			/* Insert Mode on/off */
+			case CSI_hl_INSERT:
 				vc->vc_decim = on_off;
 				break;
-			case 20:		/* Lf, Enter == CrLf/Lf */
+			case CSI_hl_AUTO_NL:
 				if (on_off)
 					set_kbd(vc, lnm);
 				else
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 03/22] tty: vt: rename set_mode() to csi_hl()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 01/22] tty: vt: make rgb_from_256() slighly more comprehensible Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 02/22] tty: vt: define enums for CSI+h/l codes Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 04/22] tty: vt: split DEC CSI+h/l handling into csi_DEC_hl() Jiri Slaby (SUSE)
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

It's how the other CSI handling functions are named, so unify to that.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 7b55d87248f8..ae333f49790a 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1881,7 +1881,7 @@ enum {
 };
 
 /* console_lock is held */
-static void set_mode(struct vc_data *vc, int on_off)
+static void csi_hl(struct vc_data *vc, bool on_off)
 {
 	int i;
 
@@ -2380,11 +2380,11 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		switch(c) {
 		case 'h':
 			if (vc->vc_priv <= EPdec)
-				set_mode(vc, 1);
+				csi_hl(vc, true);
 			return;
 		case 'l':
 			if (vc->vc_priv <= EPdec)
-				set_mode(vc, 0);
+				csi_hl(vc, false);
 			return;
 		case 'c':
 			if (vc->vc_priv == EPdec) {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 04/22] tty: vt: split DEC CSI+h/l handling into csi_DEC_hl()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (2 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 03/22] tty: vt: rename set_mode() to csi_hl() Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 05/22] tty: vt: remove unneeded assignment of EPecma to vc_priv Jiri Slaby (SUSE)
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

The DEC and ECMA handling of CSI+h/l is needlessly complicated. Split
these two, so that DEC is handled when the state is EPdec ('CSI ?' was
seen) and ECMA is handled in the EPecma state (no '?').

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 144 +++++++++++++++++++++++---------------------
 1 file changed, 77 insertions(+), 67 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index ae333f49790a..d04dbafc0517 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1874,6 +1874,59 @@ enum {
 	CSI_DEC_hl_MOUSE_VT200	= 1000,
 };
 
+/* console_lock is held */
+static void csi_DEC_hl(struct vc_data *vc, bool on_off)
+{
+	unsigned int i;
+
+	for (i = 0; i <= vc->vc_npar; i++)
+		switch (vc->vc_par[i]) {
+		case CSI_DEC_hl_CURSOR_KEYS:
+			if (on_off)
+				set_kbd(vc, decckm);
+			else
+				clr_kbd(vc, decckm);
+			break;
+		case CSI_DEC_hl_132_COLUMNS:	/* unimplemented */
+#if 0
+			vc_resize(deccolm ? 132 : 80, vc->vc_rows);
+			/* this alone does not suffice; some user mode
+			   utility has to change the hardware regs */
+#endif
+			break;
+		case CSI_DEC_hl_REVERSE_VIDEO:
+			if (vc->vc_decscnm != on_off) {
+				vc->vc_decscnm = on_off;
+				invert_screen(vc, 0, vc->vc_screenbuf_size,
+					      false);
+				update_attr(vc);
+			}
+			break;
+		case CSI_DEC_hl_ORIGIN_MODE:
+			vc->vc_decom = on_off;
+			gotoxay(vc, 0, 0);
+			break;
+		case CSI_DEC_hl_AUTOWRAP:
+			vc->vc_decawm = on_off;
+			break;
+		case CSI_DEC_hl_AUTOREPEAT:
+			if (on_off)
+				set_kbd(vc, decarm);
+			else
+				clr_kbd(vc, decarm);
+			break;
+		case CSI_DEC_hl_MOUSE_X10:
+			vc->vc_report_mouse = on_off ? 1 : 0;
+			break;
+		case CSI_DEC_hl_SHOW_CURSOR:
+			vc->vc_deccm = on_off;
+			break;
+		case CSI_DEC_hl_MOUSE_VT200:
+			vc->vc_report_mouse = on_off ? 2 : 0;
+			break;
+		}
+}
+
 enum {
 	CSI_hl_DISPLAY_CTRL	= 3,	/* handle ansi control chars */
 	CSI_hl_INSERT		= 4,	/* IRM: insert/replace */
@@ -1883,71 +1936,22 @@ enum {
 /* console_lock is held */
 static void csi_hl(struct vc_data *vc, bool on_off)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i <= vc->vc_npar; i++)
-		if (vc->vc_priv == EPdec) {
-			switch(vc->vc_par[i]) {	/* DEC private modes set/reset */
-			case CSI_DEC_hl_CURSOR_KEYS:
-				if (on_off)
-					set_kbd(vc, decckm);
-				else
-					clr_kbd(vc, decckm);
-				break;
-			case CSI_DEC_hl_132_COLUMNS:	/* unimplemented */
-#if 0
-				vc_resize(deccolm ? 132 : 80, vc->vc_rows);
-				/* this alone does not suffice; some user mode
-				   utility has to change the hardware regs */
-#endif
-				break;
-			case CSI_DEC_hl_REVERSE_VIDEO:
-				if (vc->vc_decscnm != on_off) {
-					vc->vc_decscnm = on_off;
-					invert_screen(vc, 0,
-							vc->vc_screenbuf_size,
-							false);
-					update_attr(vc);
-				}
-				break;
-			case CSI_DEC_hl_ORIGIN_MODE:
-				vc->vc_decom = on_off;
-				gotoxay(vc, 0, 0);
-				break;
-			case CSI_DEC_hl_AUTOWRAP:
-				vc->vc_decawm = on_off;
-				break;
-			case CSI_DEC_hl_AUTOREPEAT:
-				if (on_off)
-					set_kbd(vc, decarm);
-				else
-					clr_kbd(vc, decarm);
-				break;
-			case CSI_DEC_hl_MOUSE_X10:
-				vc->vc_report_mouse = on_off ? 1 : 0;
-				break;
-			case CSI_DEC_hl_SHOW_CURSOR:
-				vc->vc_deccm = on_off;
-				break;
-			case CSI_DEC_hl_MOUSE_VT200:
-				vc->vc_report_mouse = on_off ? 2 : 0;
-				break;
-			}
-		} else {
-			switch(vc->vc_par[i]) {	/* ANSI modes set/reset */
-			case CSI_hl_DISPLAY_CTRL:
-				vc->vc_disp_ctrl = on_off;
-				break;
-			case CSI_hl_INSERT:
-				vc->vc_decim = on_off;
-				break;
-			case CSI_hl_AUTO_NL:
-				if (on_off)
-					set_kbd(vc, lnm);
-				else
-					clr_kbd(vc, lnm);
-				break;
-			}
+		switch (vc->vc_par[i]) {	/* ANSI modes set/reset */
+		case CSI_hl_DISPLAY_CTRL:
+			vc->vc_disp_ctrl = on_off;
+			break;
+		case CSI_hl_INSERT:
+			vc->vc_decim = on_off;
+			break;
+		case CSI_hl_AUTO_NL:
+			if (on_off)
+				set_kbd(vc, lnm);
+			else
+				clr_kbd(vc, lnm);
+			break;
 		}
 }
 
@@ -2379,12 +2383,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		vc->vc_state = ESnormal;
 		switch(c) {
 		case 'h':
-			if (vc->vc_priv <= EPdec)
-				csi_hl(vc, true);
+			if (vc->vc_priv == EPdec)
+				csi_DEC_hl(vc, true);
 			return;
 		case 'l':
-			if (vc->vc_priv <= EPdec)
-				csi_hl(vc, false);
+			if (vc->vc_priv == EPdec)
+				csi_DEC_hl(vc, false);
 			return;
 		case 'c':
 			if (vc->vc_priv == EPdec) {
@@ -2494,6 +2498,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			else if (vc->vc_par[0] == 3)
 				bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
 			return;
+		case 'h':
+			csi_hl(vc, true);
+			return;
+		case 'l':
+			csi_hl(vc, false);
+			return;
 		case 'm':
 			csi_m(vc);
 			return;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 05/22] tty: vt: remove unneeded assignment of EPecma to vc_priv
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (3 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 04/22] tty: vt: split DEC CSI+h/l handling into csi_DEC_hl() Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 06/22] tty: vt: move CSI+n handling along to other ECMA CSIs Jiri Slaby (SUSE)
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

vc_data::vc_priv is _always_ assigned before the ESgetpars case is
entered (in ESsquare). Therefore, there is no need to reset it when
leaving the ESgetpars case. Note the state is set to ESnormal few lines
above, so ESgetpars is entered only by the next CSI.

Therefore, this obfuscation can be removed.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index d04dbafc0517..69ebce0878f2 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2421,10 +2421,9 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			}
 			return;
 		}
-		if (vc->vc_priv != EPecma) {
-			vc->vc_priv = EPecma;
+		if (vc->vc_priv != EPecma)
 			return;
-		}
+
 		switch(c) {
 		case 'G': case '`':
 			if (vc->vc_par[0])
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 06/22] tty: vt: move CSI+n handling along to other ECMA CSIs
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (4 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 05/22] tty: vt: remove unneeded assignment of EPecma to vc_priv Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 07/22] tty: vt: define an enum for CSI+] codes Jiri Slaby (SUSE)
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

CSIs without [<=>?] modifiers (ECMA) are handled in the switch-case
below this DEC switch+case handler. So move this ECMA CSI+n there too as
it fits there better.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 69ebce0878f2..04d109464994 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2412,14 +2412,6 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 				return;
 			}
 			break;
-		case 'n':
-			if (vc->vc_priv == EPecma) {
-				if (vc->vc_par[0] == 5)
-					status_report(tty);
-				else if (vc->vc_par[0] == 6)
-					cursor_report(vc, tty);
-			}
-			return;
 		}
 		if (vc->vc_priv != EPecma)
 			return;
@@ -2506,6 +2498,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		case 'm':
 			csi_m(vc);
 			return;
+		case 'n':
+			if (vc->vc_par[0] == 5)
+				status_report(tty);
+			else if (vc->vc_par[0] == 6)
+				cursor_report(vc, tty);
+			return;
 		case 'q': /* DECLL - but only 3 leds */
 			/* map 0,1,2,3 to 0,1,2,4 */
 			if (vc->vc_par[0] < 4)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 07/22] tty: vt: define an enum for CSI+] codes
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (5 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 06/22] tty: vt: move CSI+n handling along to other ECMA CSIs Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 08/22] tty: vt: rename setterm_command() to csi_RSB() Jiri Slaby (SUSE)
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

Decrypt the constant values by proper enum names. This time in
setterm_command() (to be renamed to csi_RSB() in the next patches).

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 36 +++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 04d109464994..9db545f305dc 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1955,62 +1955,76 @@ static void csi_hl(struct vc_data *vc, bool on_off)
 		}
 }
 
+enum CSI_right_square_bracket {
+	CSI_RSB_COLOR_FOR_UNDERLINE		= 1,
+	CSI_RSB_COLOR_FOR_HALF_BRIGHT		= 2,
+	CSI_RSB_MAKE_CUR_COLOR_DEFAULT		= 8,
+	CSI_RSB_BLANKING_INTERVAL		= 9,
+	CSI_RSB_BELL_FREQUENCY			= 10,
+	CSI_RSB_BELL_DURATION			= 11,
+	CSI_RSB_BRING_CONSOLE_TO_FRONT		= 12,
+	CSI_RSB_UNBLANK				= 13,
+	CSI_RSB_VESA_OFF_INTERVAL		= 14,
+	CSI_RSB_BRING_PREV_CONSOLE_TO_FRONT	= 15,
+	CSI_RSB_CURSOR_BLINK_INTERVAL		= 16,
+};
+
 /* console_lock is held */
 static void setterm_command(struct vc_data *vc)
 {
 	switch (vc->vc_par[0]) {
-	case 1:	/* set color for underline mode */
+	case CSI_RSB_COLOR_FOR_UNDERLINE:
 		if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
 			vc->vc_ulcolor = color_table[vc->vc_par[1]];
 			if (vc->state.underline)
 				update_attr(vc);
 		}
 		break;
-	case 2:	/* set color for half intensity mode */
+	case CSI_RSB_COLOR_FOR_HALF_BRIGHT:
 		if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
 			vc->vc_halfcolor = color_table[vc->vc_par[1]];
 			if (vc->state.intensity == VCI_HALF_BRIGHT)
 				update_attr(vc);
 		}
 		break;
-	case 8:	/* store colors as defaults */
+	case CSI_RSB_MAKE_CUR_COLOR_DEFAULT:
 		vc->vc_def_color = vc->vc_attr;
 		if (vc->vc_hi_font_mask == 0x100)
 			vc->vc_def_color >>= 1;
 		default_attr(vc);
 		update_attr(vc);
 		break;
-	case 9:	/* set blanking interval */
+	case CSI_RSB_BLANKING_INTERVAL:
 		blankinterval = min(vc->vc_par[1], 60U) * 60;
 		poke_blanked_console();
 		break;
-	case 10: /* set bell frequency in Hz */
+	case CSI_RSB_BELL_FREQUENCY:
 		if (vc->vc_npar >= 1)
 			vc->vc_bell_pitch = vc->vc_par[1];
 		else
 			vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
 		break;
-	case 11: /* set bell duration in msec */
+	case CSI_RSB_BELL_DURATION:
 		if (vc->vc_npar >= 1)
 			vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
 				msecs_to_jiffies(vc->vc_par[1]) : 0;
 		else
 			vc->vc_bell_duration = DEFAULT_BELL_DURATION;
 		break;
-	case 12: /* bring specified console to the front */
+	case CSI_RSB_BRING_CONSOLE_TO_FRONT:
 		if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
 			set_console(vc->vc_par[1] - 1);
 		break;
-	case 13: /* unblank the screen */
+	case CSI_RSB_UNBLANK:
 		poke_blanked_console();
 		break;
-	case 14: /* set vesa powerdown interval */
+	case CSI_RSB_VESA_OFF_INTERVAL:
 		vesa_off_interval = min(vc->vc_par[1], 60U) * 60 * HZ;
 		break;
-	case 15: /* activate the previous console */
+	case CSI_RSB_BRING_PREV_CONSOLE_TO_FRONT:
 		set_console(last_console);
 		break;
-	case 16: /* set cursor blink duration in msec */
+	case CSI_RSB_CURSOR_BLINK_INTERVAL:
 		if (vc->vc_npar >= 1 && vc->vc_par[1] >= 50 &&
 				vc->vc_par[1] <= USHRT_MAX)
 			vc->vc_cur_blink_ms = vc->vc_par[1];
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 08/22] tty: vt: rename setterm_command() to csi_RSB()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (6 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 07/22] tty: vt: define an enum for CSI+] codes Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 09/22] tty: vt: put cases on separate lines Jiri Slaby (SUSE)
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

It follows naming of other similar functions. RSB stands here for Right
Square Bracket as (obviously) ']' cannot be in the function name.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 9db545f305dc..c072007807e1 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1969,8 +1969,14 @@ enum CSI_right_square_bracket {
 	CSI_RSB_CURSOR_BLINK_INTERVAL		= 16,
 };
 
-/* console_lock is held */
-static void setterm_command(struct vc_data *vc)
+/*
+ * csi_RSB - csi+] (Right Square Bracket) handler
+ *
+ * These are linux console private sequences.
+ *
+ * console_lock is held
+ */
+static void csi_RSB(struct vc_data *vc)
 {
 	switch (vc->vc_par[0]) {
 	case CSI_RSB_COLOR_FOR_UNDERLINE:
@@ -2549,8 +2555,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		case '@':
 			csi_at(vc, vc->vc_par[0]);
 			return;
-		case ']': /* setterm functions */
-			setterm_command(vc);
+		case ']':
+			csi_RSB(vc);
 			return;
 		}
 		return;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 09/22] tty: vt: put cases on separate lines
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (7 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 08/22] tty: vt: rename setterm_command() to csi_RSB() Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 10/22] tty: vt: accept u8 in do_con_trol() and vc_setGx() Jiri Slaby (SUSE)
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

Some cases of the CSI switch are stuffed on one line. Put them all to a
separate line as is dictated by the coding style (and for better
readability).

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index c072007807e1..42bc0957a654 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2437,7 +2437,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			return;
 
 		switch(c) {
-		case 'G': case '`':
+		case 'G':
+		case '`':
 			if (vc->vc_par[0])
 				vc->vc_par[0]--;
 			gotoxy(vc, vc->vc_par[0], vc->state.y);
@@ -2447,12 +2448,14 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 				vc->vc_par[0]++;
 			gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
 			return;
-		case 'B': case 'e':
+		case 'B':
+		case 'e':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
 			gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
 			return;
-		case 'C': case 'a':
+		case 'C':
+		case 'a':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
 			gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
@@ -2477,7 +2480,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 				vc->vc_par[0]--;
 			gotoxay(vc, vc->state.x ,vc->vc_par[0]);
 			return;
-		case 'H': case 'f':
+		case 'H':
+		case 'f':
 			if (vc->vc_par[0])
 				vc->vc_par[0]--;
 			if (vc->vc_par[1])
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 10/22] tty: vt: accept u8 in do_con_trol() and vc_setGx()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (8 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 09/22] tty: vt: put cases on separate lines Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 11/22] tty: vt: extract ascii handling to handle_ascii() Jiri Slaby (SUSE)
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

These functions expect u8 as the control character. Switch the type from
'int' appropriately. The caller passing the value (do_con_write()) is
fixed as well.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 42bc0957a654..451a852ed234 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2144,7 +2144,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
 	    csi_J(vc, CSI_J_VISIBLE);
 }
 
-static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
+static void vc_setGx(struct vc_data *vc, unsigned int which, u8 c)
 {
 	unsigned char *charset = &vc->state.Gx_charset[which];
 
@@ -2198,7 +2198,7 @@ enum {
 };
 
 /* console_lock is held */
-static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
+static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 {
 	/*
 	 *  Control characters can be used in the _middle_
@@ -2963,7 +2963,7 @@ static int do_con_write(struct tty_struct *tty, const u8 *buf, int count)
 	param.vc = vc;
 
 	while (!tty->flow.stopped && count) {
-		int orig = *buf;
+		u8 orig = *buf;
 		buf++;
 		n++;
 		count--;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 11/22] tty: vt: extract ascii handling to handle_ascii()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (9 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 10/22] tty: vt: accept u8 in do_con_trol() and vc_setGx() Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 12/22] tty: vt: separate ESesc state handling into handle_esc() Jiri Slaby (SUSE)
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

To make the do_con_trol() a bit more understandable, extract the ASCII
handling (the switch-case) to a separate function.

Other nested switch-cases will follow in the next patches.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 58 +++++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 451a852ed234..7cda1a958c5e 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2197,28 +2197,26 @@ enum {
 	ASCII_EXT_CSI		= 128 + ASCII_ESCAPE,
 };
 
-/* console_lock is held */
-static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
+/*
+ * Handle ascii characters in control sequences and change states accordingly.
+ * E.g. ESC sets the state of vc to ESesc.
+ *
+ * Returns: true if @c handled.
+ */
+static bool handle_ascii(struct tty_struct *tty, struct vc_data *vc, u8 c)
 {
-	/*
-	 *  Control characters can be used in the _middle_
-	 *  of an escape sequence, aside from ANSI control strings.
-	 */
-	if (ansi_control_string(vc->vc_state) && c >= ASCII_IGNORE_FIRST &&
-	    c <= ASCII_IGNORE_LAST)
-		return;
 	switch (c) {
 	case ASCII_NULL:
-		return;
+		return true;
 	case ASCII_BELL:
 		if (ansi_control_string(vc->vc_state))
 			vc->vc_state = ESnormal;
 		else if (vc->vc_bell_duration)
 			kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
-		return;
+		return true;
 	case ASCII_BACKSPACE:
 		bs(vc);
-		return;
+		return true;
 	case ASCII_HTAB:
 		vc->vc_pos -= (vc->state.x << 1);
 
@@ -2230,41 +2228,59 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 
 		vc->vc_pos += (vc->state.x << 1);
 		notify_write(vc, '\t');
-		return;
+		return true;
 	case ASCII_LINEFEED:
 	case ASCII_VTAB:
 	case ASCII_FORMFEED:
 		lf(vc);
 		if (!is_kbd(vc, lnm))
-			return;
+			return true;
 		fallthrough;
 	case ASCII_CAR_RET:
 		cr(vc);
-		return;
+		return true;
 	case ASCII_SHIFTOUT:
 		vc->state.charset = 1;
 		vc->vc_translate = set_translate(vc->state.Gx_charset[1], vc);
 		vc->vc_disp_ctrl = 1;
-		return;
+		return true;
 	case ASCII_SHIFTIN:
 		vc->state.charset = 0;
 		vc->vc_translate = set_translate(vc->state.Gx_charset[0], vc);
 		vc->vc_disp_ctrl = 0;
-		return;
+		return true;
 	case ASCII_CANCEL:
 	case ASCII_SUBSTITUTE:
 		vc->vc_state = ESnormal;
-		return;
+		return true;
 	case ASCII_ESCAPE:
 		vc->vc_state = ESesc;
-		return;
+		return true;
 	case ASCII_DEL:
 		del(vc);
-		return;
+		return true;
 	case ASCII_EXT_CSI:
 		vc->vc_state = ESsquare;
-		return;
+		return true;
 	}
+
+	return false;
+}
+
+/* console_lock is held */
+static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
+{
+	/*
+	 *  Control characters can be used in the _middle_
+	 *  of an escape sequence, aside from ANSI control strings.
+	 */
+	if (ansi_control_string(vc->vc_state) && c >= ASCII_IGNORE_FIRST &&
+	    c <= ASCII_IGNORE_LAST)
+		return;
+
+	if (handle_ascii(tty, vc, c))
+		return;
+
 	switch(vc->vc_state) {
 	case ESesc:
 		vc->vc_state = ESnormal;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 12/22] tty: vt: separate ESesc state handling into handle_esc()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (10 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 11/22] tty: vt: extract ascii handling to handle_ascii() Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:55 ` [PATCH 13/22] tty: vt: move CSI DEC handling to a separate function Jiri Slaby (SUSE)
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

Similar to the ASCII handling, the ESC handling can be easily moved away
from do_con_trol(). So create a new handle_esc() for that.

And add a comment with an example.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 134 ++++++++++++++++++++++++--------------------
 1 file changed, 72 insertions(+), 62 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 7cda1a958c5e..3dddb7128234 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2267,6 +2267,77 @@ static bool handle_ascii(struct tty_struct *tty, struct vc_data *vc, u8 c)
 	return false;
 }
 
+/*
+ * Handle a character (@c) following an ESC (when @vc is in the ESesc state).
+ * E.g. previous ESC with @c == '[' here yields the ESsquare state (that is:
+ * CSI).
+ */
+static void handle_esc(struct tty_struct *tty, struct vc_data *vc, u8 c)
+{
+	vc->vc_state = ESnormal;
+	switch (c) {
+	case '[':
+		vc->vc_state = ESsquare;
+		break;
+	case ']':
+		vc->vc_state = ESnonstd;
+		break;
+	case '_':
+		vc->vc_state = ESapc;
+		break;
+	case '^':
+		vc->vc_state = ESpm;
+		break;
+	case '%':
+		vc->vc_state = ESpercent;
+		break;
+	case 'E':
+		cr(vc);
+		lf(vc);
+		break;
+	case 'M':
+		ri(vc);
+		break;
+	case 'D':
+		lf(vc);
+		break;
+	case 'H':
+		if (vc->state.x < VC_TABSTOPS_COUNT)
+			set_bit(vc->state.x, vc->vc_tab_stop);
+		break;
+	case 'P':
+		vc->vc_state = ESdcs;
+		break;
+	case 'Z':
+		respond_ID(tty);
+		break;
+	case '7':
+		save_cur(vc);
+		break;
+	case '8':
+		restore_cur(vc);
+		break;
+	case '(':
+		vc->vc_state = ESsetG0;
+		break;
+	case ')':
+		vc->vc_state = ESsetG1;
+		break;
+	case '#':
+		vc->vc_state = EShash;
+		break;
+	case 'c':
+		reset_terminal(vc, 1);
+		break;
+	case '>':  /* Numeric keypad */
+		clr_kbd(vc, kbdapplic);
+		break;
+	case '=':  /* Appl. keypad */
+		set_kbd(vc, kbdapplic);
+		break;
+	}
+}
+
 /* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 {
@@ -2283,68 +2354,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 
 	switch(vc->vc_state) {
 	case ESesc:
-		vc->vc_state = ESnormal;
-		switch (c) {
-		case '[':
-			vc->vc_state = ESsquare;
-			return;
-		case ']':
-			vc->vc_state = ESnonstd;
-			return;
-		case '_':
-			vc->vc_state = ESapc;
-			return;
-		case '^':
-			vc->vc_state = ESpm;
-			return;
-		case '%':
-			vc->vc_state = ESpercent;
-			return;
-		case 'E':
-			cr(vc);
-			lf(vc);
-			return;
-		case 'M':
-			ri(vc);
-			return;
-		case 'D':
-			lf(vc);
-			return;
-		case 'H':
-			if (vc->state.x < VC_TABSTOPS_COUNT)
-				set_bit(vc->state.x, vc->vc_tab_stop);
-			return;
-		case 'P':
-			vc->vc_state = ESdcs;
-			return;
-		case 'Z':
-			respond_ID(tty);
-			return;
-		case '7':
-			save_cur(vc);
-			return;
-		case '8':
-			restore_cur(vc);
-			return;
-		case '(':
-			vc->vc_state = ESsetG0;
-			return;
-		case ')':
-			vc->vc_state = ESsetG1;
-			return;
-		case '#':
-			vc->vc_state = EShash;
-			return;
-		case 'c':
-			reset_terminal(vc, 1);
-			return;
-		case '>':  /* Numeric keypad */
-			clr_kbd(vc, kbdapplic);
-			return;
-		case '=':  /* Appl. keypad */
-			set_kbd(vc, kbdapplic);
-			return;
-		}
+		handle_esc(tty, vc, c);
 		return;
 	case ESnonstd:
 		if (c=='P') {   /* palette escape sequence */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 13/22] tty: vt: move CSI DEC handling to a separate function
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (11 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 12/22] tty: vt: separate ESesc state handling into handle_esc() Jiri Slaby (SUSE)
@ 2024-02-02  6:55 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 14/22] tty: vt: move CSI ECMA " Jiri Slaby (SUSE)
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

The handling of "CSI ? ..." (i.e. vc_priv == EPdec) can be easily moved
out of do_con_trol() into a separate function. This again increases
readability of do_con_trol().

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 75 ++++++++++++++++++++++++++-------------------
 1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3dddb7128234..7cdd0eb1e423 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2338,6 +2338,43 @@ static void handle_esc(struct tty_struct *tty, struct vc_data *vc, u8 c)
 	}
 }
 
+/*
+ * Handle special DEC control sequences ("ESC [ ? parameters char"). Parameters
+ * are in @vc->vc_par and the char is in @c here.
+ */
+static void csi_DEC(struct tty_struct *tty, struct vc_data *vc, u8 c)
+{
+	switch (c) {
+	case 'h':
+		csi_DEC_hl(vc, true);
+		break;
+	case 'l':
+		csi_DEC_hl(vc, false);
+		break;
+	case 'c':
+		if (vc->vc_par[0])
+			vc->vc_cursor_type = CUR_MAKE(vc->vc_par[0],
+						      vc->vc_par[1],
+						      vc->vc_par[2]);
+		else
+			vc->vc_cursor_type = cur_default;
+		break;
+	case 'm':
+		clear_selection();
+		if (vc->vc_par[0])
+			vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
+		else
+			vc->vc_complement_mask = vc->vc_s_complement_mask;
+		break;
+	case 'n':
+		if (vc->vc_par[0] == 5)
+			status_report(tty);
+		else if (vc->vc_par[0] == 6)
+			cursor_report(vc, tty);
+		break;
+	}
+}
+
 /* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 {
@@ -2427,40 +2464,16 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			return;
 		}
 		vc->vc_state = ESnormal;
-		switch(c) {
-		case 'h':
-			if (vc->vc_priv == EPdec)
-				csi_DEC_hl(vc, true);
-			return;
-		case 'l':
-			if (vc->vc_priv == EPdec)
-				csi_DEC_hl(vc, false);
+
+		switch (vc->vc_priv) {
+		case EPdec:
+			csi_DEC(tty, vc, c);
 			return;
-		case 'c':
-			if (vc->vc_priv == EPdec) {
-				if (vc->vc_par[0])
-					vc->vc_cursor_type =
-						CUR_MAKE(vc->vc_par[0],
-							 vc->vc_par[1],
-							 vc->vc_par[2]);
-				else
-					vc->vc_cursor_type = cur_default;
-				return;
-			}
+		case EPecma:
 			break;
-		case 'm':
-			if (vc->vc_priv == EPdec) {
-				clear_selection();
-				if (vc->vc_par[0])
-					vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
-				else
-					vc->vc_complement_mask = vc->vc_s_complement_mask;
-				return;
-			}
-			break;
-		}
-		if (vc->vc_priv != EPecma)
+		default:
 			return;
+		}
 
 		switch(c) {
 		case 'G':
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 14/22] tty: vt: move CSI ECMA handling to a separate function
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (12 preceding siblings ...)
  2024-02-02  6:55 ` [PATCH 13/22] tty: vt: move CSI DEC handling to a separate function Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 15/22] tty: vt: name, reflow and document enum vc_ctl_state Jiri Slaby (SUSE)
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

Similar to previous moves, move also "CSI ..." (i.e. vc_priv == EPecma)
handling to a separate function.

This is the last large move of code out of do_con_trol(). And despite it
is still 151 lines of code (down from 407!), it is now quite easy to
folllow the transitions of the state machine in there. ESnonstd and
ESpalette handling still can be moved away, but it won't improve that
much.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 269 +++++++++++++++++++++++---------------------
 1 file changed, 139 insertions(+), 130 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 7cdd0eb1e423..1c832d04c0dc 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2375,6 +2375,143 @@ static void csi_DEC(struct tty_struct *tty, struct vc_data *vc, u8 c)
 	}
 }
 
+/*
+ * Handle Control Sequence Introducer control characters. That is
+ * "ESC [ parameters char". Parameters are in @vc->vc_par and the char is in
+ * @c here.
+ */
+static void csi_ECMA(struct tty_struct *tty, struct vc_data *vc, u8 c)
+{
+	switch (c) {
+	case 'G':
+	case '`':
+		if (vc->vc_par[0])
+			vc->vc_par[0]--;
+		gotoxy(vc, vc->vc_par[0], vc->state.y);
+		break;
+	case 'A':
+		if (!vc->vc_par[0])
+			vc->vc_par[0]++;
+		gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
+		break;
+	case 'B':
+	case 'e':
+		if (!vc->vc_par[0])
+			vc->vc_par[0]++;
+		gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
+		break;
+	case 'C':
+	case 'a':
+		if (!vc->vc_par[0])
+			vc->vc_par[0]++;
+		gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
+		break;
+	case 'D':
+		if (!vc->vc_par[0])
+			vc->vc_par[0]++;
+		gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y);
+		break;
+	case 'E':
+		if (!vc->vc_par[0])
+			vc->vc_par[0]++;
+		gotoxy(vc, 0, vc->state.y + vc->vc_par[0]);
+		break;
+	case 'F':
+		if (!vc->vc_par[0])
+			vc->vc_par[0]++;
+		gotoxy(vc, 0, vc->state.y - vc->vc_par[0]);
+		break;
+	case 'd':
+		if (vc->vc_par[0])
+			vc->vc_par[0]--;
+		gotoxay(vc, vc->state.x ,vc->vc_par[0]);
+		break;
+	case 'H':
+	case 'f':
+		if (vc->vc_par[0])
+			vc->vc_par[0]--;
+		if (vc->vc_par[1])
+			vc->vc_par[1]--;
+		gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
+		break;
+	case 'J':
+		csi_J(vc, vc->vc_par[0]);
+		break;
+	case 'K':
+		csi_K(vc);
+		break;
+	case 'L':
+		csi_L(vc);
+		break;
+	case 'M':
+		csi_M(vc);
+		break;
+	case 'P':
+		csi_P(vc);
+		break;
+	case 'c':
+		if (!vc->vc_par[0])
+			respond_ID(tty);
+		break;
+	case 'g':
+		if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT)
+			set_bit(vc->state.x, vc->vc_tab_stop);
+		else if (vc->vc_par[0] == 3)
+			bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
+		break;
+	case 'h':
+		csi_hl(vc, true);
+		break;
+	case 'l':
+		csi_hl(vc, false);
+		break;
+	case 'm':
+		csi_m(vc);
+		break;
+	case 'n':
+		if (vc->vc_par[0] == 5)
+			status_report(tty);
+		else if (vc->vc_par[0] == 6)
+			cursor_report(vc, tty);
+		break;
+	case 'q': /* DECLL - but only 3 leds */
+		/* map 0,1,2,3 to 0,1,2,4 */
+		if (vc->vc_par[0] < 4)
+			vt_set_led_state(vc->vc_num,
+				    (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
+		break;
+	case 'r':
+		if (!vc->vc_par[0])
+			vc->vc_par[0]++;
+		if (!vc->vc_par[1])
+			vc->vc_par[1] = vc->vc_rows;
+		/* Minimum allowed region is 2 lines */
+		if (vc->vc_par[0] < vc->vc_par[1] &&
+		    vc->vc_par[1] <= vc->vc_rows) {
+			vc->vc_top = vc->vc_par[0] - 1;
+			vc->vc_bottom = vc->vc_par[1];
+			gotoxay(vc, 0, 0);
+		}
+		break;
+	case 's':
+		save_cur(vc);
+		break;
+	case 'u':
+		restore_cur(vc);
+		break;
+	case 'X':
+		csi_X(vc);
+		break;
+	case '@':
+		csi_at(vc, vc->vc_par[0]);
+		break;
+	case ']':
+		csi_RSB(vc);
+		break;
+	}
+
+}
+
 /* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 {
@@ -2470,139 +2607,11 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			csi_DEC(tty, vc, c);
 			return;
 		case EPecma:
-			break;
-		default:
-			return;
-		}
-
-		switch(c) {
-		case 'G':
-		case '`':
-			if (vc->vc_par[0])
-				vc->vc_par[0]--;
-			gotoxy(vc, vc->vc_par[0], vc->state.y);
-			return;
-		case 'A':
-			if (!vc->vc_par[0])
-				vc->vc_par[0]++;
-			gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
-			return;
-		case 'B':
-		case 'e':
-			if (!vc->vc_par[0])
-				vc->vc_par[0]++;
-			gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
-			return;
-		case 'C':
-		case 'a':
-			if (!vc->vc_par[0])
-				vc->vc_par[0]++;
-			gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
-			return;
-		case 'D':
-			if (!vc->vc_par[0])
-				vc->vc_par[0]++;
-			gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y);
-			return;
-		case 'E':
-			if (!vc->vc_par[0])
-				vc->vc_par[0]++;
-			gotoxy(vc, 0, vc->state.y + vc->vc_par[0]);
+			csi_ECMA(tty, vc, c);
 			return;
-		case 'F':
-			if (!vc->vc_par[0])
-				vc->vc_par[0]++;
-			gotoxy(vc, 0, vc->state.y - vc->vc_par[0]);
-			return;
-		case 'd':
-			if (vc->vc_par[0])
-				vc->vc_par[0]--;
-			gotoxay(vc, vc->state.x ,vc->vc_par[0]);
-			return;
-		case 'H':
-		case 'f':
-			if (vc->vc_par[0])
-				vc->vc_par[0]--;
-			if (vc->vc_par[1])
-				vc->vc_par[1]--;
-			gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
-			return;
-		case 'J':
-			csi_J(vc, vc->vc_par[0]);
-			return;
-		case 'K':
-			csi_K(vc);
-			return;
-		case 'L':
-			csi_L(vc);
-			return;
-		case 'M':
-			csi_M(vc);
-			return;
-		case 'P':
-			csi_P(vc);
-			return;
-		case 'c':
-			if (!vc->vc_par[0])
-				respond_ID(tty);
-			return;
-		case 'g':
-			if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT)
-				set_bit(vc->state.x, vc->vc_tab_stop);
-			else if (vc->vc_par[0] == 3)
-				bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
-			return;
-		case 'h':
-			csi_hl(vc, true);
-			return;
-		case 'l':
-			csi_hl(vc, false);
-			return;
-		case 'm':
-			csi_m(vc);
-			return;
-		case 'n':
-			if (vc->vc_par[0] == 5)
-				status_report(tty);
-			else if (vc->vc_par[0] == 6)
-				cursor_report(vc, tty);
-			return;
-		case 'q': /* DECLL - but only 3 leds */
-			/* map 0,1,2,3 to 0,1,2,4 */
-			if (vc->vc_par[0] < 4)
-				vt_set_led_state(vc->vc_num,
-					    (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
-			return;
-		case 'r':
-			if (!vc->vc_par[0])
-				vc->vc_par[0]++;
-			if (!vc->vc_par[1])
-				vc->vc_par[1] = vc->vc_rows;
-			/* Minimum allowed region is 2 lines */
-			if (vc->vc_par[0] < vc->vc_par[1] &&
-			    vc->vc_par[1] <= vc->vc_rows) {
-				vc->vc_top = vc->vc_par[0] - 1;
-				vc->vc_bottom = vc->vc_par[1];
-				gotoxay(vc, 0, 0);
-			}
-			return;
-		case 's':
-			save_cur(vc);
-			return;
-		case 'u':
-			restore_cur(vc);
-			return;
-		case 'X':
-			csi_X(vc);
-			return;
-		case '@':
-			csi_at(vc, vc->vc_par[0]);
-			return;
-		case ']':
-			csi_RSB(vc);
+		default:
 			return;
 		}
-		return;
 	case EScsiignore:
 		if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST)
 			return;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 15/22] tty: vt: name, reflow and document enum vc_ctl_state
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (13 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 14/22] tty: vt: move CSI ECMA " Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 16/22] tty: vt: simplify ansi_control_string() Jiri Slaby (SUSE)
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

The enum for states is currently compact and undocumented. Put each
definition on a separate line and document them all using kernel-doc.

Document the same on the use sites.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 72 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 55 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 1c832d04c0dc..6d08290fdfdf 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2091,9 +2091,44 @@ static void restore_cur(struct vc_data *vc)
 	vc->vc_need_wrap = 0;
 }
 
-enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
-	EShash, ESsetG0, ESsetG1, ESpercent, EScsiignore, ESnonstd,
-	ESpalette, ESosc, ESapc, ESpm, ESdcs };
+/**
+ * enum vc_ctl_state - control characters state of a vt
+ *
+ * @ESnormal:		initial state, no control characters parsed
+ * @ESesc:		ESC parsed
+ * @ESsquare:		CSI parsed -- modifiers/parameters/ctrl chars expected
+ * @ESgetpars:		CSI parsed -- parameters/ctrl chars expected
+ * @ESfunckey:		CSI [ parsed
+ * @EShash:		ESC # parsed
+ * @ESsetG0:		ESC ( parsed
+ * @ESsetG1:		ESC ) parsed
+ * @ESpercent:		ESC % parsed
+ * @EScsiignore:	CSI [0x20-0x3f] parsed
+ * @ESnonstd:		OSC parsed
+ * @ESpalette:		OSC P parsed
+ * @ESosc:		OSC [0-9] parsed
+ * @ESapc:		ESC _ parsed
+ * @ESpm:		ESC ^ parsed
+ * @ESdcs:		ESC P parsed
+ */
+enum vc_ctl_state {
+	ESnormal,
+	ESesc,
+	ESsquare,
+	ESgetpars,
+	ESfunckey,
+	EShash,
+	ESsetG0,
+	ESsetG1,
+	ESpercent,
+	EScsiignore,
+	ESnonstd,
+	ESpalette,
+	ESosc,
+	ESapc,
+	ESpm,
+	ESdcs,
+};
 
 /* console_lock is held (except via vc_init()) */
 static void reset_terminal(struct vc_data *vc, int do_clear)
@@ -2527,10 +2562,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 		return;
 
 	switch(vc->vc_state) {
-	case ESesc:
+	case ESesc:	/* ESC */
 		handle_esc(tty, vc, c);
 		return;
-	case ESnonstd:
+	case ESnonstd:	/* ESC ] aka OSC */
 		if (c=='P') {   /* palette escape sequence */
 			for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
 				vc->vc_par[vc->vc_npar] = 0;
@@ -2545,7 +2580,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 		else
 			vc->vc_state = ESnormal;
 		return;
-	case ESpalette:
+	case ESpalette:	/* ESC ] P aka OSC P */
 		if (isxdigit(c)) {
 			vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
 			if (vc->vc_npar == 7) {
@@ -2562,7 +2597,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 		} else
 			vc->vc_state = ESnormal;
 		return;
-	case ESsquare:
+	case ESsquare:	/* ESC [ aka CSI, parameters or modifiers expected */
 		for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
 			vc->vc_par[vc->vc_npar] = 0;
 		vc->vc_npar = 0;
@@ -2587,7 +2622,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 		}
 		vc->vc_priv = EPecma;
 		fallthrough;
-	case ESgetpars:
+	case ESgetpars: /* ESC [ aka CSI, parameters expected */
 		if (c == ';' && vc->vc_npar < NPAR - 1) {
 			vc->vc_npar++;
 			return;
@@ -2600,6 +2635,9 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			vc->vc_state = EScsiignore;
 			return;
 		}
+
+		/* parameters done, handle the control char @c */
+
 		vc->vc_state = ESnormal;
 
 		switch (vc->vc_priv) {
@@ -2617,7 +2655,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			return;
 		vc->vc_state = ESnormal;
 		return;
-	case ESpercent:
+	case ESpercent:	/* ESC % */
 		vc->vc_state = ESnormal;
 		switch (c) {
 		case '@':  /* defined in ISO 2022 */
@@ -2629,10 +2667,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			return;
 		}
 		return;
-	case ESfunckey:
+	case ESfunckey:	/* ESC [ [ aka CSI [ */
 		vc->vc_state = ESnormal;
 		return;
-	case EShash:
+	case EShash:	/* ESC # */
 		vc->vc_state = ESnormal;
 		if (c == '8') {
 			/* DEC screen alignment test. kludge :-) */
@@ -2644,21 +2682,21 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
 		}
 		return;
-	case ESsetG0:
+	case ESsetG0:	/* ESC ( */
 		vc_setGx(vc, 0, c);
 		vc->vc_state = ESnormal;
 		return;
-	case ESsetG1:
+	case ESsetG1:	/* ESC ) */
 		vc_setGx(vc, 1, c);
 		vc->vc_state = ESnormal;
 		return;
-	case ESapc:
+	case ESapc:	/* ESC _ */
 		return;
-	case ESosc:
+	case ESosc:	/* ESC ] [0-9] aka OSC [0-9] */
 		return;
-	case ESpm:
+	case ESpm:	/* ESC ^ */
 		return;
-	case ESdcs:
+	case ESdcs:	/* ESC P */
 		return;
 	default:
 		vc->vc_state = ESnormal;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 16/22] tty: vt: simplify ansi_control_string()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (14 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 15/22] tty: vt: name, reflow and document enum vc_ctl_state Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 17/22] tty: vt: handle CSI+[ inside preexisting switch-case Jiri Slaby (SUSE)
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

Given all the ANSI control states are sequential in the vc_ctl_state
enum, we can define first/last constants and use them in
ansi_control_string(). It makes the test simple and allows for removal
of the 'if' (which was unnecessary at all -- the 'return' should have
returned the 'if' content directly anyway).

And remove the useless comment -- it's clear from the function
prototype.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 6d08290fdfdf..e1cbe966bc84 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2107,9 +2107,11 @@ static void restore_cur(struct vc_data *vc)
  * @ESnonstd:		OSC parsed
  * @ESpalette:		OSC P parsed
  * @ESosc:		OSC [0-9] parsed
+ * @ESANSI_first:	first state for ignoring ansi control sequences
  * @ESapc:		ESC _ parsed
  * @ESpm:		ESC ^ parsed
  * @ESdcs:		ESC P parsed
+ * @ESANSI_last:	last state for ignoring ansi control sequences
  */
 enum vc_ctl_state {
 	ESnormal,
@@ -2125,9 +2127,11 @@ enum vc_ctl_state {
 	ESnonstd,
 	ESpalette,
 	ESosc,
+	ESANSI_first = ESosc,
 	ESapc,
 	ESpm,
 	ESdcs,
+	ESANSI_last = ESdcs,
 };
 
 /* console_lock is held (except via vc_init()) */
@@ -2202,12 +2206,9 @@ static void vc_setGx(struct vc_data *vc, unsigned int which, u8 c)
 		vc->vc_translate = set_translate(*charset, vc);
 }
 
-/* is this state an ANSI control string? */
-static bool ansi_control_string(unsigned int state)
+static bool ansi_control_string(enum vc_ctl_state state)
 {
-	if (state == ESosc || state == ESapc || state == ESpm || state == ESdcs)
-		return true;
-	return false;
+	return state >= ESANSI_first && state <= ESANSI_last;
 }
 
 enum {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 17/22] tty: vt: handle CSI+[ inside preexisting switch-case
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (15 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 16/22] tty: vt: simplify ansi_control_string() Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 18/22] tty: vt: add new helper for reseting vc parameters Jiri Slaby (SUSE)
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

In do_con_trol()'s ESsquare case, there is already a switch (c). It is
preceded by an 'if (c == '[')'. Despite this 'if' handles a state
transition and not a modifier, move it as one of the switch cases. This
makes all the 'c' decision making more obvious there.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index e1cbe966bc84..4d020a9967a2 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2603,11 +2603,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			vc->vc_par[vc->vc_npar] = 0;
 		vc->vc_npar = 0;
 		vc->vc_state = ESgetpars;
-		if (c == '[') { /* Function key */
-			vc->vc_state=ESfunckey;
-			return;
-		}
 		switch (c) {
+		case '[': /* Function key */
+			vc->vc_state = ESfunckey;
+			return;
 		case '?':
 			vc->vc_priv = EPdec;
 			return;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 18/22] tty: vt: add new helper for reseting vc parameters
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (16 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 17/22] tty: vt: handle CSI+[ inside preexisting switch-case Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 19/22] tty: vt: use switch+case in the ESnonstd case Jiri Slaby (SUSE)
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

The code to reset the vc parameter parsing is repeated on two locations.
Create a helper vc_reset_params() and use it on both of them.

And instead of a 'for' loop to clear the array of parameters, use
simpler memset().

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4d020a9967a2..b0f691d79bf2 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2548,6 +2548,12 @@ static void csi_ECMA(struct tty_struct *tty, struct vc_data *vc, u8 c)
 
 }
 
+static void vc_reset_params(struct vc_data *vc)
+{
+	memset(vc->vc_par, 0, sizeof(vc->vc_par));
+	vc->vc_npar = 0;
+}
+
 /* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 {
@@ -2568,9 +2574,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 		return;
 	case ESnonstd:	/* ESC ] aka OSC */
 		if (c=='P') {   /* palette escape sequence */
-			for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
-				vc->vc_par[vc->vc_npar] = 0;
-			vc->vc_npar = 0;
+			vc_reset_params(vc);
 			vc->vc_state = ESpalette;
 			return;
 		} else if (c=='R') {   /* reset palette */
@@ -2599,9 +2603,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 			vc->vc_state = ESnormal;
 		return;
 	case ESsquare:	/* ESC [ aka CSI, parameters or modifiers expected */
-		for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
-			vc->vc_par[vc->vc_npar] = 0;
-		vc->vc_npar = 0;
+		vc_reset_params(vc);
+
 		vc->vc_state = ESgetpars;
 		switch (c) {
 		case '[': /* Function key */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 19/22] tty: vt: use switch+case in the ESnonstd case
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (17 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 18/22] tty: vt: add new helper for reseting vc parameters Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 20/22] tty: vt: use switch+case in the ESgetpars case Jiri Slaby (SUSE)
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

To be uniform in the 'c' handling, use switch-case (with ranges) even in
the ESnonstd case in do_con_trol().

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b0f691d79bf2..b5fc3b896e26 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2573,17 +2573,19 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 		handle_esc(tty, vc, c);
 		return;
 	case ESnonstd:	/* ESC ] aka OSC */
-		if (c=='P') {   /* palette escape sequence */
+		switch (c) {
+		case 'P': /* palette escape sequence */
 			vc_reset_params(vc);
 			vc->vc_state = ESpalette;
 			return;
-		} else if (c=='R') {   /* reset palette */
+		case 'R': /* reset palette */
 			reset_palette(vc);
-			vc->vc_state = ESnormal;
-		} else if (c>='0' && c<='9')
+			break;
+		case '0' ... '9':
 			vc->vc_state = ESosc;
-		else
-			vc->vc_state = ESnormal;
+			return;
+		}
+		vc->vc_state = ESnormal;
 		return;
 	case ESpalette:	/* ESC ] P aka OSC P */
 		if (isxdigit(c)) {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 20/22] tty: vt: use switch+case in the ESgetpars case
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (18 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 19/22] tty: vt: use switch+case in the ESnonstd case Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 21/22] tty: vt: use ASCII enum constants in vt_console_print() Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 22/22] tty: vt: decrypt magic constants in vc_is_control() Jiri Slaby (SUSE)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

To be uniform in the 'c' handling, use switch-case (with ranges) even in
the ESgetpars case in do_con_trol().

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b5fc3b896e26..b3c61ec92df9 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2628,10 +2628,14 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
 		vc->vc_priv = EPecma;
 		fallthrough;
 	case ESgetpars: /* ESC [ aka CSI, parameters expected */
-		if (c == ';' && vc->vc_npar < NPAR - 1) {
-			vc->vc_npar++;
-			return;
-		} else if (c>='0' && c<='9') {
+		switch (c) {
+		case ';':
+			if (vc->vc_npar < NPAR - 1) {
+				vc->vc_npar++;
+				return;
+			}
+			break;
+		case '0' ... '9':
 			vc->vc_par[vc->vc_npar] *= 10;
 			vc->vc_par[vc->vc_npar] += c - '0';
 			return;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 21/22] tty: vt: use ASCII enum constants in vt_console_print()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (19 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 20/22] tty: vt: use switch+case in the ESgetpars case Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  2024-02-02  6:56 ` [PATCH 22/22] tty: vt: decrypt magic constants in vc_is_control() Jiri Slaby (SUSE)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

There are still numbers used for ASCII characters in vt_console_print().
As we have an ASCII enum now, use the constant names from the enum
instead.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b3c61ec92df9..e35f7a31a7bd 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3240,22 +3240,23 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
 	cnt = 0;
 	while (count--) {
 		c = *b++;
-		if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
+		if (c == ASCII_LINEFEED || c == ASCII_CAR_RET ||
+		    c == ASCII_BACKSPACE || vc->vc_need_wrap) {
 			if (cnt && con_is_visible(vc))
 				vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
 			cnt = 0;
-			if (c == 8) {		/* backspace */
+			if (c == ASCII_BACKSPACE) {
 				bs(vc);
 				start = (ushort *)vc->vc_pos;
 				start_x = vc->state.x;
 				continue;
 			}
-			if (c != 13)
+			if (c != ASCII_CAR_RET)
 				lf(vc);
 			cr(vc);
 			start = (ushort *)vc->vc_pos;
 			start_x = vc->state.x;
-			if (c == 10 || c == 13)
+			if (c == ASCII_LINEFEED || c == ASCII_CAR_RET)
 				continue;
 		}
 		vc_uniscr_putc(vc, c);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 22/22] tty: vt: decrypt magic constants in vc_is_control()
  2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
                   ` (20 preceding siblings ...)
  2024-02-02  6:56 ` [PATCH 21/22] tty: vt: use ASCII enum constants in vt_console_print() Jiri Slaby (SUSE)
@ 2024-02-02  6:56 ` Jiri Slaby (SUSE)
  21 siblings, 0 replies; 23+ messages in thread
From: Jiri Slaby (SUSE) @ 2024-02-02  6:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby (SUSE)

0x0d00ff81 and 0x0800f501 are bitmasks of ASCII characters. Spell them
explicitly using BIT() + ASCII constants. GENMASK() is used for the
9-bit range in CTRL_ACTION.

This also modifies the 'if' checking if the masks should be applied.
From a "random" ' ' to the actual size of the bitmasks' type.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 drivers/tty/vt/vt.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index e35f7a31a7bd..463be4e48dc8 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2893,9 +2893,13 @@ static bool vc_is_control(struct vc_data *vc, int tc, int c)
 	 * as cursor movement) and should not be displayed as a glyph unless
 	 * the disp_ctrl mode is explicitly enabled.
 	 */
-	static const u32 CTRL_ACTION = 0x0d00ff81;
+	static const u32 CTRL_ACTION = BIT(ASCII_NULL) |
+		GENMASK(ASCII_SHIFTIN, ASCII_BELL) | BIT(ASCII_CANCEL) |
+		BIT(ASCII_SUBSTITUTE) | BIT(ASCII_ESCAPE);
 	/* Cannot be overridden by disp_ctrl */
-	static const u32 CTRL_ALWAYS = 0x0800f501;
+	static const u32 CTRL_ALWAYS = BIT(ASCII_NULL) | BIT(ASCII_BACKSPACE) |
+		BIT(ASCII_LINEFEED) | BIT(ASCII_SHIFTIN) | BIT(ASCII_SHIFTOUT) |
+		BIT(ASCII_CAR_RET) | BIT(ASCII_FORMFEED) | BIT(ASCII_ESCAPE);
 
 	if (vc->vc_state != ESnormal)
 		return true;
@@ -2912,7 +2916,7 @@ static bool vc_is_control(struct vc_data *vc, int tc, int c)
 	 * useless without them; to display an arbitrary font position use the
 	 * direct-to-font zone in UTF-8 mode.
 	 */
-	if (c < ' ') {
+	if (c < BITS_PER_TYPE(CTRL_ALWAYS)) {
 		if (vc->vc_disp_ctrl)
 			return CTRL_ALWAYS & BIT(c);
 		else
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2024-02-02  6:56 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-02  6:55 [PATCH 00/22] tty: vt: cleanup ESC sequences handling Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 01/22] tty: vt: make rgb_from_256() slighly more comprehensible Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 02/22] tty: vt: define enums for CSI+h/l codes Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 03/22] tty: vt: rename set_mode() to csi_hl() Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 04/22] tty: vt: split DEC CSI+h/l handling into csi_DEC_hl() Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 05/22] tty: vt: remove unneeded assignment of EPecma to vc_priv Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 06/22] tty: vt: move CSI+n handling along to other ECMA CSIs Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 07/22] tty: vt: define an enum for CSI+] codes Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 08/22] tty: vt: rename setterm_command() to csi_RSB() Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 09/22] tty: vt: put cases on separate lines Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 10/22] tty: vt: accept u8 in do_con_trol() and vc_setGx() Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 11/22] tty: vt: extract ascii handling to handle_ascii() Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 12/22] tty: vt: separate ESesc state handling into handle_esc() Jiri Slaby (SUSE)
2024-02-02  6:55 ` [PATCH 13/22] tty: vt: move CSI DEC handling to a separate function Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 14/22] tty: vt: move CSI ECMA " Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 15/22] tty: vt: name, reflow and document enum vc_ctl_state Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 16/22] tty: vt: simplify ansi_control_string() Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 17/22] tty: vt: handle CSI+[ inside preexisting switch-case Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 18/22] tty: vt: add new helper for reseting vc parameters Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 19/22] tty: vt: use switch+case in the ESnonstd case Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 20/22] tty: vt: use switch+case in the ESgetpars case Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 21/22] tty: vt: use ASCII enum constants in vt_console_print() Jiri Slaby (SUSE)
2024-02-02  6:56 ` [PATCH 22/22] tty: vt: decrypt magic constants in vc_is_control() Jiri Slaby (SUSE)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).