File: gdbmi.hpp

package info (click to toggle)
codelite 17.0.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 136,244 kB
  • sloc: cpp: 491,547; ansic: 280,393; php: 10,259; sh: 8,930; lisp: 7,664; vhdl: 6,518; python: 6,020; lex: 4,920; yacc: 3,123; perl: 2,385; javascript: 1,715; cs: 1,193; xml: 1,110; makefile: 804; cobol: 741; sql: 709; ruby: 620; f90: 566; ada: 534; asm: 464; fortran: 350; objc: 289; tcl: 258; java: 157; erlang: 61; pascal: 51; ml: 49; awk: 44; haskell: 36
file content (162 lines) | stat: -rw-r--r-- 4,107 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#ifndef GDBMI_HPP
#define GDBMI_HPP

#include "wxStringHash.h"
#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <wx/string.h>

namespace gdbmi
{
enum eToken {
    T_LIST_OPEN = 1, // [
    T_LIST_CLOSE,    // ]
    T_TUPLE_OPEN,    // {
    T_TUPLE_CLOSE,   // }
    T_POW,           // ^
    T_STAR,          // *
    T_PLUS,          // +
    T_EQUAL,         // =
    T_TARGET_OUTPUT, // @
    T_STREAM_OUTPUT, // ~
    T_LOG_OUTPUT,    // &
    T_COMMA,         // ,
    T_CSTRING,       // string
    T_WORD,          // Token
    T_DONE,          // done
    T_RUNNING,       // running
    T_CONNECTED,     // connected
    T_ERROR,         // error
    T_EXIT,          // exit
    T_STOPPED,       // stopped
    T_EOF,
};

enum eLineType {
    LT_INVALID = -1,
    LT_RESULT,                // line starting with ^ (with optional txid)
    LT_STATUS_ASYNC_OUTPUT,   // line starting with +
    LT_EXEC_ASYNC_OUTPUT,     // line starting with *
    LT_NOTIFY_ASYNC_OUTPUT,   // line starting with =
    LT_CONSOLE_STREAM_OUTPUT, // line starting with ~
    LT_TARGET_STREAM_OUTPUT,  // line starting with @
    LT_LOG_STREAM_OUTPUT,     // line starting with &
};

struct StringView {
    const wxChar* m_pdata = nullptr;
    size_t m_length = 0;

    wxString to_string() const
    {
        if(!m_pdata) {
            return wxString();
        } else {
            return wxString(m_pdata, m_length);
        }
    }

    StringView() {}
    StringView(const wxString& buffer)
        : StringView(buffer.c_str(), buffer.length())
    {
    }

    StringView(const wxChar* p, size_t len)
    {
        m_pdata = p;
        m_length = len;
    }

    const wxChar* data() const { return m_pdata; }
    size_t length() const { return m_length; }
    char operator[](size_t index) const { return m_pdata[index]; }
    bool empty() const { return m_length == 0; }
};

class Tokenizer
{
    size_t m_pos = 0;
    StringView m_buffer;

protected:
    StringView read_string(eToken* type);
    StringView read_word(eToken* type);

public:
    Tokenizer(StringView buffer);
    StringView next_token(eToken* type);
    /**
     * @brief return the remainder string from m_pos -> end
     */
    StringView remainder();
};

struct Node {
public:
    typedef std::shared_ptr<Node> ptr_t;
    typedef std::vector<ptr_t> vec_t;

private:
    ptr_t do_add_child(const wxString& name)
    {
        children.emplace_back(std::make_shared<Node>());
        auto child = children.back();
        child->name = std::move(name);
        children_map.insert({ child->name, child });
        return child;
    }

public:
    wxString name;
    wxString value; // optional
    vec_t children;
    std::unordered_map<wxString, ptr_t> children_map;

    Node() {}
    Node& find_child(const wxString& name) const;
    Node& operator[](const wxString& name) const { return find_child(name); }
    Node& operator[](size_t index) const
    {
        if(index >= children.size()) {
            thread_local Node emptyNode;
            return emptyNode;
        }
        return *(children[index].get());
    }

    ptr_t add_child()
    {
        wxString s;
        s << children.size();
        return do_add_child(s);
    }

    ptr_t add_child(const wxString& name, const wxString& value = {});
    bool exists(const wxString& name) const { return children_map.count(name) > 0; }
};

struct ParsedResult {
    eLineType line_type = LT_INVALID;
    StringView line_type_context; // depends on the line type, this will hold the context string
    StringView txid;              //  optional
    Node::ptr_t tree = std::make_shared<Node>();
    Node& operator[](const wxString& index) const { return tree->find_child(index); }
    bool exists(const wxString& name) const { return tree->exists(name); }
};

class Parser
{
private:
    void parse_properties(Tokenizer* tokenizer, Node::ptr_t parent);

public:
    void parse(const wxString& buffer, ParsedResult* result);
    void print(Node::ptr_t node, int depth = 0);
};
} // namespace gdbmi

#endif // GDBMI_HPP