[vte] parser: glue: Add wrapper class for struct vte_parser



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

    parser: glue: Add wrapper class for struct vte_parser

 src/parser-cat.cc  |   12 +++----
 src/parser-glue.hh |   45 ++++++++++++++++++++++++
 src/parser-test.cc |   17 +++++----
 src/parser.cc      |   95 ++++++++++++++--------------------------------------
 src/parser.hh      |   10 ++++--
 src/vte.cc         |   15 ++------
 src/vteinternal.hh |    3 +-
 7 files changed, 95 insertions(+), 102 deletions(-)
---
diff --git a/src/parser-cat.cc b/src/parser-cat.cc
index 21462aa..1e7f5b7 100644
--- a/src/parser-cat.cc
+++ b/src/parser-cat.cc
@@ -308,9 +308,8 @@ process_file(int fd,
              bool plain,
              bool quiet)
 {
-        struct vte_parser *parser;
-        if (vte_parser_new(&parser) != 0)
-                return;
+        struct vte_parser parser;
+        vte_parser_init(&parser);
 
         auto subst = _vte_iso2022_state_new(charset);
 
@@ -344,10 +343,9 @@ process_file(int fd,
                 auto wbuf = &g_array_index(unichars, gunichar, 0);
                 gsize wcount = unichars->len;
 
-                struct vte_seq *seq;
+                struct vte_seq *seq = &parser.seq;
                 for (gsize i = 0; i < wcount; i++) {
-                        auto ret = vte_parser_feed(parser,
-                                                   &seq,
+                        auto ret = vte_parser_feed(&parser,
                                                    wbuf[i]);
                         if (G_UNLIKELY(ret < 0)) {
                                 g_printerr("Parser error!\n");
@@ -376,7 +374,7 @@ process_file(int fd,
         g_string_free(outbuf, TRUE);
         g_array_free(unichars, TRUE);
         g_free(buf);
-        vte_parser_free(parser);
+        vte_parser_deinit(&parser);
         _vte_iso2022_state_free(subst);
 }
 
diff --git a/src/parser-glue.hh b/src/parser-glue.hh
index 17e530b..39caf8e 100644
--- a/src/parser-glue.hh
+++ b/src/parser-glue.hh
@@ -27,9 +27,54 @@ namespace vte {
 
 namespace parser {
 
+class Sequence;
+
+class Parser {
+public:
+        friend class Sequence;
+
+        Parser() noexcept
+        {
+                vte_parser_init(&m_parser);
+        }
+        Parser(Parser const&) = delete;
+        Parser(Parser&&) = delete;
+
+        ~Parser() noexcept
+        {
+                vte_parser_deinit(&m_parser);
+        }
+
+        Parser& operator=(Parser const&) = delete;
+        Parser& operator=(Parser&&) = delete;
+
+        inline int feed(uint32_t raw) noexcept
+        {
+                return vte_parser_feed(&m_parser, raw);
+        }
+
+        inline void reset() noexcept
+        {
+                vte_parser_reset(&m_parser);
+        }
+
+protected:
+        struct vte_parser m_parser;
+};
+
 class Sequence {
 public:
 
+        Sequence() = default;
+        Sequence(Sequence const&) = delete;
+        Sequence(Sequence&&) = delete;
+        ~Sequence() = default;
+
+        Sequence(Parser& parser)
+        {
+                m_seq = &parser.m_parser.seq;
+        }
+
         typedef int number;
 
         char* ucs4_to_utf8(gunichar const* str,
diff --git a/src/parser-test.cc b/src/parser-test.cc
index 2c20295..ca1995e 100644
--- a/src/parser-test.cc
+++ b/src/parser-test.cc
@@ -370,9 +370,10 @@ static int
 feed_parser(std::u32string const& s,
             struct vte_seq** seq)
 {
+        *seq = &parser->seq;
         int rv = VTE_SEQ_NONE;
         for (auto it : s) {
-                rv = vte_parser_feed(parser, seq, (uint32_t)(char32_t)it);
+                rv = vte_parser_feed(parser, (uint32_t)(char32_t)it);
                 if (rv < 0)
                         break;
         }
@@ -528,8 +529,8 @@ test_seq_control(void)
 
         for (unsigned int i = 0; i < G_N_ELEMENTS(controls); i++) {
                 vte_parser_reset(parser);
-                struct vte_seq* seq;
-                auto rv = vte_parser_feed(parser, &seq, controls[i].c);
+                struct vte_seq* seq = &parser->seq;
+                auto rv = vte_parser_feed(parser, controls[i].c);
                 g_assert_cmpuint(controls[i].type, ==, rv);
                 g_assert_cmpuint(controls[i].cmd, ==, seq->command);
         }
@@ -545,7 +546,7 @@ test_seq_esc_invalid(void)
                 vte_parser_reset(parser);
 
                 vte_seq_builder b{VTE_SEQ_ESCAPE, f};
-                struct vte_seq* seq;
+                struct vte_seq* seq = &parser->seq;
                 auto rv = feed_parser(b, &seq);
                 g_assert_cmpint(rv, !=, VTE_SEQ_ESCAPE);
         }
@@ -1576,9 +1577,6 @@ main(int argc,
 {
         g_test_init(&argc, &argv, nullptr);
 
-        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/string", test_seq_string);
         g_test_add_func("/vte/parser/sequences/glue/arg", test_seq_glue_arg);
@@ -1605,8 +1603,11 @@ main(int argc,
         g_test_add_func("/vte/parser/sequences/dcs/known", test_seq_dcs_known);
         g_test_add_func("/vte/parser/sequences/osc", test_seq_osc);
 
+        struct vte_parser _parser;
+        parser = &_parser;
+        vte_parser_init(parser);
         auto rv = g_test_run();
+        vte_parser_deinit(parser);
 
-        parser = vte_parser_free(parser);
         return rv;
 }
diff --git a/src/parser.cc b/src/parser.cc
index 7aa786c..2205ebc 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -30,8 +30,6 @@
 #include "parser-charset-tables.hh"
 
 #define WARN(num,str) do { } while (0)
-#define kzalloc(n,v) calloc((n),1)
-#define kfree(ptr) free(ptr)
 
 /*
  * Terminal Parser
@@ -42,11 +40,6 @@
  * detected sequences.
  */
 
-struct vte_parser {
-        struct vte_seq seq;
-        unsigned int state;
-};
-
 /*
  * Command Parser
  * The ctl-seq parser "vte_parser" only detects whole sequences, it does not
@@ -527,39 +520,22 @@ enum parser_state {
 };
 
 /**
- * vte_parser_new() - Allocate parser object
- * @out:        output variable for new parser object
- *
- * Return: 0 on success, negative error code on failure.
+ * vte_parser_init() - Initialise parser object
+ * @parser: the struct vte_parser
  */
-int vte_parser_new(struct vte_parser **out)
+void vte_parser_init(struct vte_parser *parser)
 {
-        struct vte_parser *parser;
-
-        parser = (struct vte_parser*)kzalloc(sizeof(*parser), GFP_KERNEL);
-        if (!parser)
-                return -ENOMEM;
-
+        memset(parser, 0, sizeof(*parser));
         vte_seq_string_init(&parser->seq.arg_str);
-
-        *out = parser;
-        return 0;
 }
 
 /**
- * vte_parser_free() - Free parser object
- * @parser:        parser object to free, or NULL
- *
- * Return: NULL is returned.
+ * vte_parser_deinit() - Deinitialises parser object
+ * @parser: parser object to deinitialise
  */
-struct vte_parser *vte_parser_free(struct vte_parser *parser)
+void vte_parser_deinit(struct vte_parser *parser)
 {
-        if (!parser)
-                return NULL;
-
         vte_seq_string_free(&parser->seq.arg_str);
-        kfree(parser);
-        return NULL;
 }
 
 static inline int parser_clear(struct vte_parser *parser, uint32_t raw)
@@ -1278,11 +1254,8 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
 }
 
 int vte_parser_feed(struct vte_parser *parser,
-                    /* const */ struct vte_seq **seq_out,
                     uint32_t raw)
 {
-        int ret;
-
         /*
          * Notes:
          *  * DEC treats GR codes as GL. We don't do that as we require UTF-8
@@ -1294,59 +1267,41 @@ int vte_parser_feed(struct vte_parser *parser,
 
         switch (raw) {
         case 0x18:                /* CAN */
-                ret = parser_transition(parser, raw,
-                                        STATE_GROUND, ACTION_IGNORE);
-                break;
+                return parser_transition(parser, raw,
+                                         STATE_GROUND, ACTION_IGNORE);
         case 0x1a:                /* SUB */
-                ret = parser_transition(parser, raw,
-                                        STATE_GROUND, ACTION_EXECUTE);
-                break;
+                return parser_transition(parser, raw,
+                                         STATE_GROUND, ACTION_EXECUTE);
         case 0x7f:                 /* DEL */
-                ret = parser_nop(parser, raw);
-                break;
+                return parser_nop(parser, raw);
         case 0x80 ... 0x8f:        /* C1 \ {DCS, SOS, SCI, CSI, ST, OSC, PM, APC} */
         case 0x91 ... 0x97:
         case 0x99:
-                ret = parser_transition(parser, raw,
-                                        STATE_GROUND, ACTION_EXECUTE);
-                break;
+                return parser_transition(parser, raw,
+                                         STATE_GROUND, ACTION_EXECUTE);
         case 0x98:                /* SOS */
         case 0x9e:                /* PM */
         case 0x9f:                /* APC */
-                ret = parser_transition_no_action(parser, raw, STATE_ST_IGNORE);
+                return parser_transition_no_action(parser, raw, STATE_ST_IGNORE);
                 // FIXMEchpe shouldn't this use ACTION_CLEAR?
-                break;
         case 0x90:                /* DCS */
-                ret = parser_transition(parser, raw,
-                                        STATE_DCS_ENTRY, ACTION_DCS_START);
-                break;
+                return parser_transition(parser, raw,
+                                         STATE_DCS_ENTRY, ACTION_DCS_START);
         case 0x9a:                /* SCI */
-                ret = parser_transition(parser, raw,
-                                        STATE_SCI, ACTION_CLEAR);
-                break;
+                return parser_transition(parser, raw,
+                                         STATE_SCI, ACTION_CLEAR);
         case 0x9d:                /* OSC */
-                ret = parser_transition(parser, raw,
-                                        STATE_OSC_STRING, ACTION_OSC_START);
-                break;
+                return parser_transition(parser, raw,
+                                         STATE_OSC_STRING, ACTION_OSC_START);
         case 0x9b:                /* CSI */
-                ret = parser_transition(parser, raw,
-                                        STATE_CSI_ENTRY, ACTION_CLEAR);
-                break;
+                return parser_transition(parser, raw,
+                                         STATE_CSI_ENTRY, ACTION_CLEAR);
         default:
-                ret = parser_feed_to_state(parser, raw);
-                break;
+                return parser_feed_to_state(parser, raw);
         }
-
-        if (G_UNLIKELY(ret < 0))
-                *seq_out = NULL;
-        else
-                *seq_out = &parser->seq;
-
-        return ret;
 }
 
 void vte_parser_reset(struct vte_parser *parser)
 {
-        /* const */ struct vte_seq *seq;
-        vte_parser_feed(parser, &seq, 0x18 /* CAN */);
+        vte_parser_feed(parser, 0x18 /* CAN */);
 }
diff --git a/src/parser.hh b/src/parser.hh
index 687fcd6..94b5af4 100644
--- a/src/parser.hh
+++ b/src/parser.hh
@@ -176,9 +176,13 @@ struct vte_seq {
         vte_seq_string_t arg_str;
 };
 
-int vte_parser_new(struct vte_parser **out);
-struct vte_parser *vte_parser_free(struct vte_parser *parser);
+struct vte_parser {
+        struct vte_seq seq;
+        unsigned int state;
+};
+
+void vte_parser_init(struct vte_parser *parser);
+void vte_parser_deinit(struct vte_parser *parser);
 int vte_parser_feed(struct vte_parser *parser,
-                    /* const */ struct vte_seq **seq_out,
                     uint32_t raw);
 void vte_parser_reset(struct vte_parser *parser);
diff --git a/src/vte.cc b/src/vte.cc
index 8e0f89a..9195183 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -3552,7 +3552,7 @@ skip_chunk:
        bbox_bottomright.x = bbox_bottomright.y = -G_MAXINT;
        bbox_topleft.x = bbox_topleft.y = G_MAXINT;
 
-        vte::parser::Sequence seq{};
+        vte::parser::Sequence seq(m_parser);
 
         m_line_wrapped = false;
 
@@ -3560,7 +3560,7 @@ skip_chunk:
         auto const* wend = wbuf + wcount;
         for ( ; wp < wend; ++wp) {
 
-                auto rv = vte_parser_feed(m_parser, seq.seq_ptr(), *wp);
+                auto rv = m_parser.feed(*wp);
                 if (G_UNLIKELY(rv < 0)) {
                         char c_buf[7];
                         g_snprintf(c_buf, sizeof(c_buf), "%lc", *wp);
@@ -8062,11 +8062,6 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
        g_assert_cmpstr(m_encoding, ==, "UTF-8");
         m_last_graphic_character = 0;
 
-        /* Set up the emulation. */
-
-        if (vte_parser_new(&m_parser) != 0)
-                g_assert_not_reached();
-
        /* Setting the terminal type and size requires the PTY master to
         * be set up properly first. */
         m_pty = nullptr;
@@ -8563,10 +8558,6 @@ VteTerminalPrivate::~VteTerminalPrivate()
                 g_object_unref(m_pty);
        }
 
-       /* Clean up emulation structures. */
-        m_parser = vte_parser_free(m_parser);
-        g_assert_null(m_parser);
-
        remove_update_timeout(this);
 
         /* Word char exceptions */
@@ -10501,7 +10492,7 @@ VteTerminalPrivate::reset(bool clear_tabstops,
                                       m_encoding);
 
         /* Reset parser */
-        vte_parser_reset(m_parser);
+        m_parser.reset();
         m_last_graphic_character = 0;
 
         /* Reset modes */
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index f6e173a..1c44023 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -295,8 +295,7 @@ public:
 
         vte::terminal::Tabstops m_tabstops{};
 
-       /* Emulation setup data. */
-        struct vte_parser* m_parser; /* control sequence state machine */
+        vte::parser::Parser m_parser; /* control sequence state machine */
 
         vte::terminal::modes::ECMA m_modes_ecma{};
         vte::terminal::modes::Private m_modes_private{};


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