[vte] parser: Implement SCI parsing
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] parser: Implement SCI parsing
- Date: Tue, 27 Mar 2018 17:45:09 +0000 (UTC)
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]