[vte] parser: Define a type for CSI parameters
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] parser: Define a type for CSI parameters
- Date: Tue, 27 Mar 2018 17:41:32 +0000 (UTC)
commit bec2fff7f9431f9765f165c3a54b7d2fc19542a9
Author: Christian Persch <chpe src gnome org>
Date: Tue Mar 27 19:40:12 2018 +0200
parser: Define a type for CSI parameters
This is in preparation to parse subparameters delimited by ':'.
src/Makefile.am | 2 +
src/interpret.cc | 2 +-
src/parser-arg.hh | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/parser-glue.hh | 4 +-
src/parser-test.cc | 62 +++++++++++++++++++++++++++++++++++++++------
src/parser.cc | 33 +++++++++---------------
src/parser.hh | 4 ++-
7 files changed, 145 insertions(+), 33 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index ef8e44b..64ff262 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -57,6 +57,7 @@ libvte_@VTE_API_MAJOR_VERSION@_@VTE_API_MINOR_VERSION@_la_SOURCES = \
keymap.h \
parser.cc \
parser.hh \
+ parser-arg.hh \
parser-cmd.hh \
parser-glue.hh \
pty.cc \
@@ -306,6 +307,7 @@ test_parser_SOURCES = \
parser-test.cc \
parser.cc \
parser.hh \
+ parser-arg.hh \
parser-cmd.hh \
parser-glue.hh \
$(NULL)
diff --git a/src/interpret.cc b/src/interpret.cc
index 3c4fd64..e2d6f86 100644
--- a/src/interpret.cc
+++ b/src/interpret.cc
@@ -114,7 +114,7 @@ static void print_seq(const struct vte_seq *seq)
for (unsigned int i = 0; i < seq->n_args; i++) {
if (i > 0)
g_print(";");
- g_print("%d", seq->args[i]);
+ g_print("%d", vte_seq_arg_value(seq->args[i]));
}
}
g_print("\n");
diff --git a/src/parser-arg.hh b/src/parser-arg.hh
new file mode 100644
index 0000000..5c5d011
--- /dev/null
+++ b/src/parser-arg.hh
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2015 David Herrmann <dh herrmann gmail com>
+ * Copyright © 2018 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <assert.h>
+
+typedef int vte_seq_arg_t;
+
+#define VTE_SEQ_ARG_INIT_DEFAULT (-1)
+#define VTE_SEQ_ARG_INIT(value) (value)
+
+static inline void vte_seq_arg_push(vte_seq_arg_t* arg,
+ uint32_t c)
+{
+ auto value = *arg;
+
+ if (value < 0)
+ value = 0;
+ value = value * 10 + (c - '0');
+
+ /*
+ * VT510 tells us to clamp all values to [0, 9999], however, it
+ * also allows commands with values up to 2^15-1. We simply use
+ * 2^16 as maximum here to be compatible to all commands, but
+ * avoid overflows in any calculations.
+ */
+ if (value > 0xffff)
+ value = 0xffff;
+
+ *arg = value;
+}
+
+static inline void vte_seq_arg_finish(vte_seq_arg_t* arg)
+{
+}
+
+static inline bool vte_seq_arg_started(vte_seq_arg_t arg)
+{
+ return arg >= 0;
+}
+
+static inline bool vte_seq_arg_finished(vte_seq_arg_t arg)
+{
+ return arg >= 0;
+}
+
+static inline bool vte_seq_arg_default(vte_seq_arg_t arg)
+{
+ return arg == -1;
+}
+
+static inline int vte_seq_arg_value(vte_seq_arg_t arg)
+{
+ return arg;
+}
diff --git a/src/parser-glue.hh b/src/parser-glue.hh
index 7614d46..e730a23 100644
--- a/src/parser-glue.hh
+++ b/src/parser-glue.hh
@@ -46,7 +46,7 @@ public:
inline int operator[](int position) const
{
- return G_LIKELY(position < (int)size()) ? m_seq->args[position] : -1;
+ return G_LIKELY(position < (int)size()) ? vte_seq_arg_value(m_seq->args[position]) : -1;
}
inline bool has_number_at_unchecked(unsigned int position) const
@@ -56,7 +56,7 @@ public:
inline bool number_at_unchecked(unsigned int position, number& v) const
{
- v = m_seq->args[position];
+ v = vte_seq_arg_value(m_seq->args[position]);
return true;
}
diff --git a/src/parser-test.cc b/src/parser-test.cc
index 6cd2e65..d8da13b 100644
--- a/src/parser-test.cc
+++ b/src/parser-test.cc
@@ -115,7 +115,7 @@ print_seq(const struct vte_seq *seq)
for (unsigned int i = 0; i < seq->n_args; i++) {
if (i > 0)
g_print(";");
- g_print("%d", seq->args[i]);
+ g_print("%d", vte_seq_arg_value(seq->args[i]));
}
}
g_print("\n");
@@ -147,7 +147,7 @@ public:
m_seq.intermediates = flags;
}
- void set_params(int params[16])
+ void set_params(vte_seq_arg_t params[16])
{
memcpy(&m_seq.args, params, 16*sizeof(params[0]));
}
@@ -248,7 +248,7 @@ vte_seq_builder::assert_equal_full(struct vte_seq* seq)
g_assert_cmpuint(m_seq.args[m_seq.n_args - 1], ==, -1);
}
for (unsigned int n = 0; n < seq->n_args; n++)
- g_assert_cmpint(std::min(m_seq.args[n], 0xffff), ==, seq->args[n]);
+ g_assert_cmpint(std::min(m_seq.args[n], 0xffff), ==, vte_seq_arg_value(seq->args[n]));
}
static int
@@ -271,6 +271,37 @@ feed_parser(vte_seq_builder& b,
}
static void
+test_seq_arg(void)
+{
+ /* Basic test */
+ vte_seq_arg_t arg = VTE_SEQ_ARG_INIT_DEFAULT;
+ g_assert_false(vte_seq_arg_started(arg));
+ g_assert_false(vte_seq_arg_finished(arg));
+ g_assert_true(vte_seq_arg_default(arg));
+
+ vte_seq_arg_push(&arg, '1');
+ vte_seq_arg_push(&arg, '2');
+ vte_seq_arg_push(&arg, '3');
+ vte_seq_arg_finish(&arg);
+
+ g_assert_true(vte_seq_arg_finished(arg));
+ g_assert_cmpint(vte_seq_arg_value(arg), ==, 123);
+ g_assert_false(vte_seq_arg_default(arg));
+
+ /* Test max value */
+ arg = VTE_SEQ_ARG_INIT_DEFAULT;
+ vte_seq_arg_push(&arg, '6');
+ vte_seq_arg_push(&arg, '5');
+ vte_seq_arg_push(&arg, '5');
+ vte_seq_arg_push(&arg, '3');
+ vte_seq_arg_push(&arg, '6');
+ vte_seq_arg_finish(&arg);
+
+ g_assert_true(vte_seq_arg_finished(arg));
+ g_assert_cmpint(vte_seq_arg_value(arg), ==, 65535);
+}
+
+static void
test_seq_control(void)
{
static struct {
@@ -446,7 +477,7 @@ test_seq_esc_Fpes(void)
static void
test_seq_csi(uint32_t f,
uint32_t p,
- int params[16],
+ vte_seq_arg_t params[16],
uint32_t i[4],
unsigned int ni)
{
@@ -477,7 +508,7 @@ test_seq_csi(uint32_t f,
static void
test_seq_csi(uint32_t p,
- int params[16])
+ vte_seq_arg_t params[16])
{
uint32_t i[4];
for (uint32_t f = 0x30; f < 0x7f; f++) {
@@ -492,7 +523,7 @@ test_seq_csi(uint32_t p,
}
static void
-test_seq_csi(int params[16])
+test_seq_csi(vte_seq_arg_t params[16])
{
test_seq_csi(0, params);
for (uint32_t p = 0x3c; p <= 0x3f; p++)
@@ -510,10 +541,24 @@ test_seq_csi(void)
* There could be any number of extra params bytes, but we only test up to 1.
* CSI can be either the C1 control itself, or ESC [
*/
- int params1[16]{ -1, 0, 1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 65534, 65535, 65536, -1, -1 };
+ vte_seq_arg_t params1[16]{ VTE_SEQ_ARG_INIT(-1), VTE_SEQ_ARG_INIT(0),
+ VTE_SEQ_ARG_INIT(1), VTE_SEQ_ARG_INIT(9),
+ VTE_SEQ_ARG_INIT(10), VTE_SEQ_ARG_INIT(99),
+ VTE_SEQ_ARG_INIT(100), VTE_SEQ_ARG_INIT(999),
+ VTE_SEQ_ARG_INIT(1000), VTE_SEQ_ARG_INIT(9999),
+ VTE_SEQ_ARG_INIT(10000), VTE_SEQ_ARG_INIT(65534),
+ VTE_SEQ_ARG_INIT(65535), VTE_SEQ_ARG_INIT(65536),
+ VTE_SEQ_ARG_INIT(-1), VTE_SEQ_ARG_INIT(-1) };
test_seq_csi(params1);
- int params2[16]{ 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1 };
+ vte_seq_arg_t params2[16]{ VTE_SEQ_ARG_INIT(1), VTE_SEQ_ARG_INIT(-1),
+ VTE_SEQ_ARG_INIT(-1), VTE_SEQ_ARG_INIT(-1),
+ VTE_SEQ_ARG_INIT(1), VTE_SEQ_ARG_INIT(-1),
+ VTE_SEQ_ARG_INIT(1), VTE_SEQ_ARG_INIT(1),
+ VTE_SEQ_ARG_INIT(1), VTE_SEQ_ARG_INIT(-1),
+ VTE_SEQ_ARG_INIT(-1), VTE_SEQ_ARG_INIT(-1),
+ VTE_SEQ_ARG_INIT(-1), VTE_SEQ_ARG_INIT(1),
+ VTE_SEQ_ARG_INIT(1), VTE_SEQ_ARG_INIT(1) };
test_seq_csi(params2);
}
@@ -526,6 +571,7 @@ main(int argc,
if (vte_parser_new(&parser) < 0)
return 1;
+ g_test_add_func("/vte/parser/sequences/arg", test_seq_arg);
g_test_add_func("/vte/parser/sequences/control", test_seq_control);
g_test_add_func("/vte/parser/sequences/escape/invalid", test_seq_esc_invalid);
g_test_add_func("/vte/parser/sequences/escape/nF", test_seq_esc_nF);
diff --git a/src/parser.cc b/src/parser.cc
index b727219..9dd9b23 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1,5 +1,6 @@
/*
* Copyright © 2015 David Herrmann <dh herrmann gmail com>
+ * Copyright © 2017, 2018 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -788,7 +789,7 @@ static unsigned int vte_parse_host_csi(const struct vte_seq *seq)
} else if (flags == VTE_SEQ_FLAG_WHAT) {
/* DECRQUPSS */
return VTE_CMD_DECRQUPSS;
- } else if (seq->args[0] == 1 && flags == VTE_SEQ_FLAG_CASH) {
+ } else if (vte_seq_arg_value(seq->args[0]) == 1 && flags == VTE_SEQ_FLAG_CASH) {
/* DECRQTSR */
return VTE_CMD_DECRQTSR;
} else if (flags == VTE_SEQ_FLAG_MULT) {
@@ -814,7 +815,7 @@ static unsigned int vte_parse_host_csi(const struct vte_seq *seq)
return VTE_CMD_DECRPKT;
break;
case 'W':
- if (seq->args[0] == 5 && flags == VTE_SEQ_FLAG_WHAT) {
+ if (vte_seq_arg_value(seq->args[0]) == 5 && flags == VTE_SEQ_FLAG_WHAT) {
/* DECST8C */
return VTE_CMD_DECST8C;
}
@@ -1007,7 +1008,7 @@ static inline void parser_clear(struct vte_parser *parser)
parser->seq.charset = VTE_CHARSET_NONE;
parser->seq.n_args = 0;
for (i = 0; i < VTE_PARSER_ARG_MAX; ++i)
- parser->seq.args[i] = -1;
+ parser->seq.args[i] = VTE_SEQ_ARG_INIT_DEFAULT;
parser->seq.n_st = 0;
parser->seq.st[0] = 0;
@@ -1064,8 +1065,10 @@ static void parser_collect(struct vte_parser *parser, uint32_t raw)
static void parser_param(struct vte_parser *parser, uint32_t raw)
{
if (raw == ';') {
- if (parser->seq.n_args < VTE_PARSER_ARG_MAX)
+ if (parser->seq.n_args < VTE_PARSER_ARG_MAX) {
+ vte_seq_arg_finish(&parser->seq.args[parser->seq.n_args]);
++parser->seq.n_args;
+ }
return;
}
@@ -1074,21 +1077,7 @@ static void parser_param(struct vte_parser *parser, uint32_t raw)
return;
if (raw >= '0' && raw <= '9') {
- auto value = parser->seq.args[parser->seq.n_args];
- if (value < 0)
- value = 0;
- value = value * 10 + raw - '0';
-
- /*
- * VT510 tells us to clamp all values to [0, 9999], however, it
- * also allows commands with values up to 2^15-1. We simply use
- * 2^16 as maximum here to be compatible to all commands, but
- * avoid overflows in any calculations.
- */
- if (value > 0xffff)
- value = 0xffff;
-
- parser->seq.args[parser->seq.n_args] = value;
+ vte_seq_arg_push(&parser->seq.args[parser->seq.n_args], raw);
}
}
@@ -1099,7 +1088,7 @@ static int parser_esc(struct vte_parser *parser, uint32_t raw)
parser->seq.terminator = raw;
parser->seq.charset = VTE_CHARSET_NONE;
parser->seq.command = vte_parse_host_escape(&parser->seq,
- &parser->seq.charset);
+ &parser->seq.charset);
return parser->seq.type;
}
@@ -1111,8 +1100,10 @@ static int parser_csi(struct vte_parser *parser, uint32_t raw)
if (parser->seq.n_args < VTE_PARSER_ARG_MAX) {
if (parser->seq.n_args > 0 ||
- parser->seq.args[parser->seq.n_args] >= 0)
+ vte_seq_arg_started(parser->seq.args[parser->seq.n_args])) {
+ vte_seq_arg_finish(&parser->seq.args[parser->seq.n_args]);
++parser->seq.n_args;
+ }
}
parser->seq.type = VTE_SEQ_CSI;
diff --git a/src/parser.hh b/src/parser.hh
index ed357ba..8718a18 100644
--- a/src/parser.hh
+++ b/src/parser.hh
@@ -20,6 +20,8 @@
#include <cstdint>
#include <cstdio>
+#include "parser-arg.hh"
+
struct vte_parser;
struct vte_seq;
struct vte_utf8;
@@ -181,7 +183,7 @@ struct vte_seq {
unsigned int intermediates;
unsigned int charset;
unsigned int n_args;
- int args[VTE_PARSER_ARG_MAX];
+ vte_seq_arg_t args[VTE_PARSER_ARG_MAX];
unsigned int n_st;
char *st;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]