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.

Reply via email to