1//===-- InputReader.h -------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_InputReader_h_
11#define liblldb_InputReader_h_
12
13#include <string.h>
14
15#include "lldb/lldb-public.h"
16#include "lldb/lldb-enumerations.h"
17#include "lldb/Core/Error.h"
18#include "lldb/Core/StringList.h"
19#include "lldb/Host/Predicate.h"
20
21
22namespace lldb_private {
23
24class InputReader
25{
26public:
27
28    typedef size_t (*Callback) (void *baton,
29                                InputReader &reader,
30                                lldb::InputReaderAction notification,
31                                const char *bytes,
32                                size_t bytes_len);
33
34    struct HandlerData
35    {
36        InputReader& reader;
37        const char *bytes;
38        size_t bytes_len;
39        void* baton;
40
41        HandlerData(InputReader& r,
42                    const char* b,
43                    size_t l,
44                    void* t) :
45        reader(r),
46        bytes(b),
47        bytes_len(l),
48        baton(t)
49        {
50        }
51
52        lldb::StreamSP
53        GetOutStream();
54
55        bool
56        GetBatchMode();
57    };
58
59    struct InitializationParameters
60    {
61    private:
62        void* m_baton;
63        lldb::InputReaderGranularity m_token_size;
64        char* m_end_token;
65        char* m_prompt;
66        bool m_echo;
67        bool m_save_user_input;
68    public:
69        InitializationParameters() :
70        m_baton(NULL),
71        m_token_size(lldb::eInputReaderGranularityLine),
72        m_echo(true),
73        m_save_user_input(false)
74        {
75            SetEndToken("DONE");
76            SetPrompt("> ");
77        }
78
79        InitializationParameters&
80        SetEcho(bool e)
81        {
82            m_echo = e;
83            return *this;
84        }
85
86        InitializationParameters&
87        SetSaveUserInput(bool s)
88        {
89            m_save_user_input = s;
90            return *this;
91        }
92
93        InitializationParameters&
94        SetBaton(void* b)
95        {
96            m_baton = b;
97            return *this;
98        }
99
100        InitializationParameters&
101        SetGranularity(lldb::InputReaderGranularity g)
102        {
103            m_token_size = g;
104            return *this;
105        }
106
107        InitializationParameters&
108        SetEndToken(const char* e)
109        {
110            m_end_token = new char[strlen(e)+1];
111            ::strcpy(m_end_token,e);
112            return *this;
113        }
114
115        InitializationParameters&
116        SetPrompt(const char* p)
117        {
118            m_prompt = new char[strlen(p)+1];
119            ::strcpy(m_prompt,p);
120            return *this;
121        }
122
123        friend class InputReaderEZ;
124
125    };
126
127    InputReader (Debugger &debugger);
128
129    virtual
130    ~InputReader ();
131
132    virtual Error
133    Initialize (Callback callback,
134                void *baton,
135                lldb::InputReaderGranularity token_size,
136                const char *end_token,
137                const char *prompt,
138                bool echo);
139
140    virtual Error Initialize(void* baton,
141                             lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
142                             const char* end_token = "DONE",
143                             const char *prompt = "> ",
144                             bool echo = true)
145    {
146        return Error("unimplemented");
147    }
148
149    virtual Error
150    Initialize(InitializationParameters& params)
151    {
152        return Error("unimplemented");
153    }
154
155    // to use these handlers instead of the Callback function, you must subclass
156    // InputReaderEZ, and redefine the handlers for the events you care about
157    virtual void
158    ActivateHandler(HandlerData&) {}
159
160    virtual void
161    DeactivateHandler(HandlerData&) {}
162
163    virtual void
164    ReactivateHandler(HandlerData&) {}
165
166    virtual void
167    AsynchronousOutputWrittenHandler(HandlerData&) {}
168
169    virtual void
170    GotTokenHandler(HandlerData&) {}
171
172    virtual void
173    InterruptHandler(HandlerData&) {}
174
175    virtual void
176    EOFHandler(HandlerData&) {}
177
178    virtual void
179    DoneHandler(HandlerData&) {}
180
181    bool
182    IsDone () const
183    {
184        return m_done;
185    }
186
187    void
188    SetIsDone (bool b)
189    {
190        m_done = b;
191    }
192
193    lldb::InputReaderGranularity
194    GetGranularity () const
195    {
196        return m_granularity;
197    }
198
199    bool
200    GetEcho () const
201    {
202        return m_echo;
203    }
204
205    StringList&
206    GetUserInput()
207    {
208        return m_user_input;
209    }
210
211    virtual bool
212    GetSaveUserInput()
213    {
214        return false;
215    }
216
217    // Subclasses _can_ override this function to get input as it comes in
218    // without any granularity
219    virtual size_t
220    HandleRawBytes (const char *bytes, size_t bytes_len);
221
222    Debugger &
223    GetDebugger()
224    {
225        return m_debugger;
226    }
227
228    bool
229    IsActive () const
230    {
231        return m_active;
232    }
233
234    const char *
235    GetPrompt () const;
236
237    void
238    RefreshPrompt();
239
240    // If you want to read from an input reader synchronously, then just initialize the
241    // reader and then call WaitOnReaderIsDone, which will return when the reader is popped.
242    void
243    WaitOnReaderIsDone ();
244
245    static const char *
246    GranularityAsCString (lldb::InputReaderGranularity granularity);
247
248protected:
249    friend class Debugger;
250
251    void
252    Notify (lldb::InputReaderAction notification);
253
254    Debugger &m_debugger;
255    Callback m_callback;
256    void *m_callback_baton;
257    std::string m_end_token;
258    std::string m_prompt;
259    lldb::InputReaderGranularity m_granularity;
260    bool m_done;
261    bool m_echo;
262    bool m_active;
263    Predicate<bool> m_reader_done;
264    StringList m_user_input;
265    bool m_save_user_input;
266
267private:
268    DISALLOW_COPY_AND_ASSIGN (InputReader);
269
270};
271
272} // namespace lldb_private
273
274#endif // #ifndef liblldb_InputReader_h_
275