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 
22 namespace lldb_private {
23 
24 class InputReader
25 {
26 public:
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 
HandlerDataHandlerData41         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:
InitializationParametersInitializationParameters69         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&
SetEchoInitializationParameters80         SetEcho(bool e)
81         {
82             m_echo = e;
83             return *this;
84         }
85 
86         InitializationParameters&
SetSaveUserInputInitializationParameters87         SetSaveUserInput(bool s)
88         {
89             m_save_user_input = s;
90             return *this;
91         }
92 
93         InitializationParameters&
SetBatonInitializationParameters94         SetBaton(void* b)
95         {
96             m_baton = b;
97             return *this;
98         }
99 
100         InitializationParameters&
SetGranularityInitializationParameters101         SetGranularity(lldb::InputReaderGranularity g)
102         {
103             m_token_size = g;
104             return *this;
105         }
106 
107         InitializationParameters&
SetEndTokenInitializationParameters108         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&
SetPromptInitializationParameters116         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
Initialize(InitializationParameters & params)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
ActivateHandler(HandlerData &)158     ActivateHandler(HandlerData&) {}
159 
160     virtual void
DeactivateHandler(HandlerData &)161     DeactivateHandler(HandlerData&) {}
162 
163     virtual void
ReactivateHandler(HandlerData &)164     ReactivateHandler(HandlerData&) {}
165 
166     virtual void
AsynchronousOutputWrittenHandler(HandlerData &)167     AsynchronousOutputWrittenHandler(HandlerData&) {}
168 
169     virtual void
GotTokenHandler(HandlerData &)170     GotTokenHandler(HandlerData&) {}
171 
172     virtual void
InterruptHandler(HandlerData &)173     InterruptHandler(HandlerData&) {}
174 
175     virtual void
EOFHandler(HandlerData &)176     EOFHandler(HandlerData&) {}
177 
178     virtual void
DoneHandler(HandlerData &)179     DoneHandler(HandlerData&) {}
180 
181     bool
IsDone()182     IsDone () const
183     {
184         return m_done;
185     }
186 
187     void
SetIsDone(bool b)188     SetIsDone (bool b)
189     {
190         m_done = b;
191     }
192 
193     lldb::InputReaderGranularity
GetGranularity()194     GetGranularity () const
195     {
196         return m_granularity;
197     }
198 
199     bool
GetEcho()200     GetEcho () const
201     {
202         return m_echo;
203     }
204 
205     StringList&
GetUserInput()206     GetUserInput()
207     {
208         return m_user_input;
209     }
210 
211     virtual bool
GetSaveUserInput()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 &
GetDebugger()223     GetDebugger()
224     {
225         return m_debugger;
226     }
227 
228     bool
IsActive()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 
248 protected:
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 
267 private:
268     DISALLOW_COPY_AND_ASSIGN (InputReader);
269 
270 };
271 
272 } // namespace lldb_private
273 
274 #endif // #ifndef liblldb_InputReader_h_
275