[vte] parser: Implement SCI parsing



commit db9ca29cfb593468bfabe8f4ac036e1521732692
Author: Christian Persch <chpe src gnome org>
Date:   Tue Mar 27 19:40:12 2018 +0200

    parser: Implement SCI parsing

 src/parser-cat.cc  |    1 +
 src/parser-cmd.hh  |    1 -
 src/parser-glue.hh |    5 +++-
 src/parser-test.cc |   51 +++++++++++++++++++++++++++++++++++++++++++-
 src/parser.cc      |   58 ++++++++++++++++++++++++++++++++++++++++++++-------
 src/parser.hh      |    2 +-
 src/vteseq.cc      |   11 ---------
 7 files changed, 105 insertions(+), 24 deletions(-)
---
diff --git a/src/parser-cat.cc b/src/parser-cat.cc
index 08d5412..41d97f3 100644
--- a/src/parser-cat.cc
+++ b/src/parser-cat.cc
@@ -45,6 +45,7 @@ seq_to_str(unsigned int type)
         case VTE_SEQ_CSI: return "CSI";
         case VTE_SEQ_DCS: return "DCS";
         case VTE_SEQ_OSC: return "OSC";
+        case VTE_SEQ_SCI: return "SCI";
         case VTE_SEQ_APC: return "APC";
         case VTE_SEQ_PM: return "PM";
         case VTE_SEQ_SOS: return "SOS";
diff --git a/src/parser-cmd.hh b/src/parser-cmd.hh
index 535ccb3..60c301b 100644
--- a/src/parser-cmd.hh
+++ b/src/parser-cmd.hh
@@ -60,7 +60,6 @@ _VTE_CMD(DECERA) /* erase-rectangular-area */
 _VTE_CMD(DECFI) /* forward-index */
 _VTE_CMD(DECFRA) /* fill-rectangular-area */
 _VTE_CMD(DECIC) /* insert-column */
-_VTE_CMD(DECID) /* return-terminal-id */
 _VTE_CMD(DECINVM) /* invoke-macro */
 _VTE_CMD(DECKBD) /* keyboard-language-selection */
 _VTE_CMD(DECKPAM) /* keypad-application-mode */
diff --git a/src/parser-glue.hh b/src/parser-glue.hh
index 27bb680..bc983f6 100644
--- a/src/parser-glue.hh
+++ b/src/parser-glue.hh
@@ -487,6 +487,7 @@ private:
                         case VTE_SEQ_APC:    m_encoder.put(s, 0x9f); break; // APC
                         case VTE_SEQ_PM:     m_encoder.put(s, 0x9e); break; // PM
                         case VTE_SEQ_SOS:    m_encoder.put(s, 0x98); break; // SOS
+                        case VTE_SEQ_SCI:    m_encoder.put(s, 0x9a); break; // SCI
                         default: return;
                         }
                 } else {
@@ -499,6 +500,7 @@ private:
                         case VTE_SEQ_APC:    s.push_back(0x5f); break; // _
                         case VTE_SEQ_PM:     s.push_back(0x5e); break; // ^
                         case VTE_SEQ_SOS:    s.push_back(0x58); break; // X
+                        case VTE_SEQ_SCI:    s.push_back(0x5a); break; // Z
                         default: return;
                         }
                 }
@@ -542,7 +544,8 @@ private:
                 case VTE_SEQ_DCS:
                         for (unsigned char n = 0; n < m_n_intermediates; n++)
                                 s.push_back(m_intermediates[n]);
-
+                        /* [[fallthrough]]; */
+                case VTE_SEQ_SCI:
                         if (m_seq.terminator != 0)
                                 s.push_back(m_seq.terminator);
                         break;
diff --git a/src/parser-test.cc b/src/parser-test.cc
index b0890b2..72e6767 100644
--- a/src/parser-test.cc
+++ b/src/parser-test.cc
@@ -51,6 +51,7 @@ seq_to_str(unsigned int type)
         case VTE_SEQ_APC: return "APC";
         case VTE_SEQ_PM: return "PM";
         case VTE_SEQ_SOS: return "SOS";
+        case VTE_SEQ_SCI: return "SCI";
         default:
                 g_assert_not_reached();
         }
@@ -247,6 +248,7 @@ vte_seq_builder::to_string(std::u32string& s,
                 case VTE_SEQ_CSI:    s.push_back(0x9B); break; // CSI
                 case VTE_SEQ_DCS:    s.push_back(0x90); break; // DCS
                 case VTE_SEQ_OSC:    s.push_back(0x9D); break; // OSC
+                case VTE_SEQ_SCI:    s.push_back(0x9A); break; // SCI
                 default: return;
                 }
         } else {
@@ -256,6 +258,7 @@ vte_seq_builder::to_string(std::u32string& s,
                 case VTE_SEQ_CSI:    s.push_back(0x5B); break; // [
                 case VTE_SEQ_DCS:    s.push_back(0x50); break; // P
                 case VTE_SEQ_OSC:    s.push_back(0x5D); break; // ]
+                case VTE_SEQ_SCI:    s.push_back(0x5A); break; // Z
                 default: return;
                 }
         }
@@ -292,7 +295,8 @@ vte_seq_builder::to_string(std::u32string& s,
         case VTE_SEQ_DCS:
                 for (unsigned int n = 0; n < m_ni; n++)
                         s.push_back(m_i[n]);
-
+                /* [[fallthrough]]; */
+        case VTE_SEQ_SCI:
                 s.push_back(m_seq.terminator);
                 break;
         default:
@@ -519,7 +523,7 @@ test_seq_control(void)
                 { 0x97, VTE_SEQ_CONTROL, VTE_CMD_EPA     },
                 { 0x98, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
                 { 0x99, VTE_SEQ_CONTROL, VTE_CMD_NONE    },
-                { 0x9a, VTE_SEQ_CONTROL, VTE_CMD_DECID   },
+                { 0x9a, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
                 { 0x9b, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
                 { 0x9c, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
                 { 0x9d, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
@@ -826,6 +830,7 @@ test_seq_esc_Fpes(void)
                 switch (f) {
                 case 'P': /* DCS */
                 case 'X': /* SOS */
+                case 'Z': /* SCI */
                 case '_': /* APC */
                 case '[': /* CSI */
                 case ']': /* OSC */
@@ -919,6 +924,47 @@ test_seq_csi(void)
 }
 
 static void
+test_seq_sci(uint32_t f,
+             bool valid)
+{
+        vte_seq_builder b{VTE_SEQ_SCI, f};
+
+        struct vte_seq* seq;
+        /* First with C0 SCI */
+        auto rv = feed_parser(b, &seq, false);
+        if (valid) {
+                g_assert_cmpint(rv, ==, VTE_SEQ_SCI);
+                b.assert_equal_full(seq);
+        } else
+                g_assert_cmpint(rv, !=, VTE_SEQ_SCI);
+
+        /* Now with C1 SCI */
+        rv = feed_parser(b, &seq, true);
+        if (valid) {
+                g_assert_cmpint(rv, ==, VTE_SEQ_SCI);
+                b.assert_equal_full(seq);
+        } else
+                g_assert_cmpint(rv, !=, VTE_SEQ_SCI);
+}
+
+static void
+test_seq_sci(void)
+{
+        /* Tests SCI sequences, that is sequences of the form SCI F
+         * with final byte 0/8..0/13 or 2/0..7/14
+         * SCI can be either the C1 control itself, or ESC Z
+         */
+        vte_parser_reset(parser);
+
+        for (uint32_t f = 0x8; f <= 0xd; ++f)
+                test_seq_sci(f, true);
+        for (uint32_t f = 0x20; f <= 0x7e; ++f)
+                test_seq_sci(f, true);
+        for (uint32_t f = 0x7f; f <= 0xff; ++f)
+                test_seq_sci(f, false);
+}
+
+static void
 test_seq_dcs(uint32_t f,
              uint32_t p,
              vte_seq_arg_t params[16],
@@ -1463,6 +1509,7 @@ main(int argc,
         g_test_add_func("/vte/parser/sequences/escape/F[pes]", test_seq_esc_Fpes);
         g_test_add_func("/vte/parser/sequences/csi", test_seq_csi);
         g_test_add_func("/vte/parser/sequences/csi/parameters", test_seq_csi_param);
+        g_test_add_func("/vte/parser/sequences/sci", test_seq_sci);
         g_test_add_func("/vte/parser/sequences/dcs", test_seq_dcs);
         g_test_add_func("/vte/parser/sequences/osc", test_seq_osc);
 
diff --git a/src/parser.cc b/src/parser.cc
index f03661b..c9fd0c4 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -117,8 +117,9 @@ static unsigned int vte_parse_host_control(const struct vte_seq *seq)
         case 0x98: /* SOS */
                 /* this is already handled by the state-machine */
                 break;
-        case 0x9a: /* DECID */
-                return VTE_CMD_DECID;
+        case 0x9a: /* SCI */
+                /* this is already handled by the state-machine */
+                break;
         case 0x9b: /* CSI */
                 /* this is already handled by the state-machine */
                 break;
@@ -278,8 +279,9 @@ static unsigned int vte_parse_host_escape(const struct vte_seq *seq,
                 case 'X': /* SOS */
                         /* this is already handled by the state-machine */
                         break;
-                case 'Z': /* DECID */
-                        return VTE_CMD_DECID;
+                case 'Z': /* SCI */
+                        /* this is already handled by the state-machine */
+                        break;
                 case '[': /* CSI */
                         /* this is already handled by the state-machine */
                         break;
@@ -902,6 +904,11 @@ static unsigned int vte_parse_host_dcs(const struct vte_seq *seq)
         return VTE_CMD_NONE;
 }
 
+static unsigned int vte_parse_host_sci(const struct vte_seq *seq)
+{
+        return VTE_CMD_NONE;
+}
+
 /*
  * State Machine
  * This parser controls the parser-state and returns any detected sequence to
@@ -928,6 +935,8 @@ enum parser_state {
         STATE_DCS_IGNORE,       /* DCS error; ignore this DCS sequence */
         STATE_OSC_STRING,       /* parsing OSC sequence */
         STATE_ST_IGNORE,        /* unimplemented seq; ignore until ST */
+        STATE_SCI,              /* single character introducer sequence was started */
+
         STATE_N,
 };
 
@@ -948,6 +957,7 @@ enum parser_action {
         ACTION_OSC_START,       /* clear and clear string data */
         ACTION_OSC_COLLECT,     /* collect OSC data */
         ACTION_OSC_DISPATCH,    /* dispatch OSC sequence */
+        ACTION_SCI_DISPATCH,    /* dispatch SCI sequence */
         ACTION_N,
 };
 
@@ -1185,6 +1195,16 @@ static int parser_dcs(struct vte_parser *parser, uint32_t raw)
         return parser->seq.type;
 }
 
+static int parser_sci(struct vte_parser *parser, uint32_t raw)
+{
+        parser->seq.type = VTE_SEQ_SCI;
+        parser->seq.terminator = raw;
+        parser->seq.charset = VTE_CHARSET_NONE;
+        parser->seq.command = vte_parse_host_sci(&parser->seq);
+
+        return parser->seq.type;
+}
+
 /* perform state transition and dispatch related actions */
 static int parser_transition(struct vte_parser *parser,
                              uint32_t raw,
@@ -1235,6 +1255,8 @@ static int parser_transition(struct vte_parser *parser,
                 return VTE_SEQ_NONE;
         case ACTION_OSC_DISPATCH:
                 return parser_osc(parser, raw);
+        case ACTION_SCI_DISPATCH:
+                return parser_sci(parser, raw);
         default:
                 WARN(1, "invalid vte-parser action");
                 return VTE_SEQ_NONE;
@@ -1272,8 +1294,8 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                         return parser_transition(parser, raw, STATE_ESC_INT,
                                                  ACTION_COLLECT);
                 case 0x30 ... 0x4f:        /* ['0' - '~'] \ */
-                case 0x51 ... 0x57:        /* { 'P', 'X', '[', ']', '^', '_' } */
-                case 0x59 ... 0x5a:
+                case 0x51 ... 0x57:        /* { 'P', 'X', 'Z' '[', ']', '^', '_' } */
+                case 0x59:
                 case 0x5c:
                 case 0x60 ... 0x7e:
                         return parser_transition(parser, raw, STATE_GROUND,
@@ -1281,6 +1303,9 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                 case 0x50:                /* 'P' */
                         return parser_transition(parser, raw, STATE_DCS_ENTRY,
                                                  ACTION_DCS_START);
+                case 0x5a:                /* 'Z' */
+                        return parser_transition(parser, raw, STATE_SCI,
+                                                 ACTION_CLEAR);
                 case 0x5b:                /* '[' */
                         return parser_transition(parser, raw, STATE_CSI_ENTRY,
                                                  ACTION_CLEAR);
@@ -1560,6 +1585,19 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
 
                 return parser_transition(parser, raw,
                                          STATE_NONE, ACTION_NONE);
+        case STATE_SCI:
+                switch (raw) {
+                case 0x08 ... 0x0d:        /* BS, HT, LF, VT, FF, CR */
+                case 0x20 ... 0x7e:        /* [' ' - '~'] */
+                        return parser_transition(parser, raw, STATE_GROUND,
+                                                 ACTION_SCI_DISPATCH);
+                case 0x7f:                 /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE,
+                                                 ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_GROUND,
+                                         ACTION_IGNORE);
         }
 
         WARN(1, "bad vte-parser state");
@@ -1590,9 +1628,9 @@ int vte_parser_feed(struct vte_parser *parser,
                 ret = parser_transition(parser, raw,
                                         STATE_GROUND, ACTION_EXECUTE);
                 break;
-        case 0x80 ... 0x8f:        /* C1 \ {DCS, SOS, CSI, ST, OSC, PM, APC} */
+        case 0x80 ... 0x8f:        /* C1 \ {DCS, SOS, SCI, CSI, ST, OSC, PM, APC} */
         case 0x91 ... 0x97:
-        case 0x99 ... 0x9a:
+        case 0x99:
                 ret = parser_transition(parser, raw,
                                         STATE_GROUND, ACTION_EXECUTE);
                 break;
@@ -1610,6 +1648,10 @@ int vte_parser_feed(struct vte_parser *parser,
                 ret = parser_transition(parser, raw,
                                         STATE_DCS_ENTRY, ACTION_DCS_START);
                 break;
+        case 0x9a:                /* SCI */
+                ret = parser_transition(parser, raw,
+                                        STATE_SCI, ACTION_CLEAR);
+                break;
         case 0x9d:                /* OSC */
                 ret = parser_transition(parser, raw,
                                         STATE_OSC_STRING, ACTION_OSC_START);
diff --git a/src/parser.hh b/src/parser.hh
index f6a11ee..fdd47fe 100644
--- a/src/parser.hh
+++ b/src/parser.hh
@@ -80,7 +80,7 @@ enum {
         VTE_SEQ_CSI,         /* control sequence function */
         VTE_SEQ_DCS,         /* device control string */
         VTE_SEQ_OSC,         /* operating system control */
-
+        VTE_SEQ_SCI,         /* single character control function */
         VTE_SEQ_APC,         /* application program command */
         VTE_SEQ_PM,          /* privacy message */
         VTE_SEQ_SOS,         /* start of string */
diff --git a/src/vteseq.cc b/src/vteseq.cc
index f94db82..e834f8a 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -2530,17 +2530,6 @@ VteTerminalPrivate::DECIC(vte::parser::Sequence const& seq)
 }
 
 void
-VteTerminalPrivate::DECID(vte::parser::Sequence const& seq)
-{
-        /*
-         * DECID - return-terminal-id
-         * This is an obsolete form of VTE_CMD_DA1.
-         */
-
-        DA1(seq);
-}
-
-void
 VteTerminalPrivate::DECINVM(vte::parser::Sequence const& seq)
 {
         /*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]