This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository terminology.
View the commit online.
commit 191a4eb789fe342d57f74a93ee86c1f670131303
Author: Boris Faure <[email protected]>
AuthorDate: Thu Sep 17 20:00:02 2026 +0000
termptyesc: parse SGR 4 subparameters
; and : are not the same
---
src/bin/termptyesc.c | 41 +++++++++++++++++++++++++++++++++++++----
tests/sgr-underline-subparam.sh | 40 ++++++++++++++++++++++++++++++++++++++++
tests/tests.results | 1 +
3 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index 9810e327..06d2c535 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -158,12 +158,16 @@ enum esc_arg_error {
ESC_ARG_ERROR = 2
};
+/* sub_follows is set when the argument returned was terminated by ':',
+ * meaning the next argument is a subparameter of it */
static int
-_csi_arg_get(Termpty *ty, Eina_Unicode **ptr)
+_csi_arg_get_subparam(Termpty *ty, Eina_Unicode **ptr, Eina_Bool *sub_follows)
{
Eina_Unicode *b = *ptr;
int sum = 0;
+ *sub_follows = EINA_FALSE;
+
if ((b == NULL) || (*b == '\0'))
{
*ptr = NULL;
@@ -202,6 +206,7 @@ _csi_arg_get(Termpty *ty, Eina_Unicode **ptr)
if ((*b == ';') || (*b == ':'))
{
+ *sub_follows = (*b == ':');
if (b[1])
b++;
*ptr = b;
@@ -223,6 +228,14 @@ error:
return -ESC_ARG_ERROR;
}
+static int
+_csi_arg_get(Termpty *ty, Eina_Unicode **ptr)
+{
+ Eina_Bool sub_follows;
+
+ return _csi_arg_get_subparam(ty, ptr, &sub_follows);
+}
+
static void
_tab_forward(Termpty *ty, int n)
{
@@ -1134,7 +1147,8 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
DBG("color set");
while (b && b <= end)
{
- int arg = _csi_arg_get(ty, &b);
+ Eina_Bool sub_follows = EINA_FALSE;
+ int arg = _csi_arg_get_subparam(ty, &b, &sub_follows);
switch (arg)
{
case -ESC_ARG_ERROR:
@@ -1153,8 +1167,27 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
case 3: // italic
ty->termstate.att.italic = 1;
break;
- case 4: // underline
- ty->termstate.att.underline = 1;
+ case 4: // underline, possibly styled: 4:0 to 4:5
+ if (sub_follows)
+ {
+ int style = _csi_arg_get_subparam(ty, &b, &sub_follows);
+
+ if (style == -ESC_ARG_ERROR)
+ return;
+ /* only 4:0 removes the underline; terminology draws every
+ * other style the same way for now */
+ ty->termstate.att.underline = (style != 0);
+ while (sub_follows)
+ {
+ if (_csi_arg_get_subparam(ty, &b, &sub_follows)
+ == -ESC_ARG_ERROR)
+ return;
+ }
+ }
+ else
+ {
+ ty->termstate.att.underline = 1;
+ }
break;
case 5: // blink
ty->termstate.att.blink = 1;
diff --git a/tests/sgr-underline-subparam.sh b/tests/sgr-underline-subparam.sh
new file mode 100755
index 00000000..c41c5849
--- /dev/null
+++ b/tests/sgr-underline-subparam.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# clear screen
+printf '\033[2J'
+
+##
+# Every 4:x style draws an underline, like a plain 4
+##
+
+printf '\033[3;1H'
+printf '\033[4mplain\033[m '
+printf '\033[4:1msingle\033[m '
+printf '\033[4:2mdouble\033[m '
+printf '\033[4:3mcurly\033[m '
+printf '\033[4:4mdotted\033[m '
+printf '\033[4:5mdashed\033[m'
+
+##
+# 4:0 removes the underline and leaves the other attributes alone
+##
+
+printf '\033[5;1H'
+printf '\033[1;4mboth\033[4:0m bold only\033[m'
+
+##
+# A subparameter must not be taken for the next parameter
+##
+
+printf '\033[7;1H'
+printf '\033[4:3;1mbold underlined\033[m '
+printf '\033[4;3mitalic underlined\033[m'
+
+##
+# Unknown, missing and extra subparameters still just underline
+##
+
+printf '\033[9;1H'
+printf '\033[4:9munknown\033[m '
+printf '\033[4:mempty\033[m '
+printf '\033[4:3:7mextra\033[m'
diff --git a/tests/tests.results b/tests/tests.results
index b742ffdf..ec3524b3 100644
--- a/tests/tests.results
+++ b/tests/tests.results
@@ -156,3 +156,4 @@ csi-38-no-value.sh 4cf52fe27bf05e78bdf7eecdda5543f7
osc_selection.sh 1f53d8ce7ca39989e2f8f8a20c9148d0
lf_below_bottom_margin.sh 02e4df0e6de5f23e8947245d9a8e4adf
backlog_scroll_stress.sh 614fa95207570793cb0089243a059eda
+sgr-underline-subparam.sh 527b0d806a768efbae630bf276fa9f6c
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.