]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/include/lldb/Core/IOHandler.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / include / lldb / Core / IOHandler.h
1 //===-- IOHandler.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_IOHandler_h_
11 #define liblldb_IOHandler_h_
12
13 #include <string.h>
14
15 #include <stack>
16
17 #include "lldb/lldb-public.h"
18 #include "lldb/lldb-enumerations.h"
19 #include "lldb/Core/ConstString.h"
20 #include "lldb/Core/Error.h"
21 #include "lldb/Core/Flags.h"
22 #include "lldb/Core/StringList.h"
23 #include "lldb/Core/ValueObjectList.h"
24 #include "lldb/Host/Mutex.h"
25
26 namespace curses
27 {
28     class Application;
29     typedef std::unique_ptr<Application> ApplicationAP;
30 }
31
32 namespace lldb_private {
33
34     class IOHandler
35     {
36     public:
37         IOHandler (Debugger &debugger);
38
39         IOHandler (Debugger &debugger,
40                    const lldb::StreamFileSP &input_sp,
41                    const lldb::StreamFileSP &output_sp,
42                    const lldb::StreamFileSP &error_sp,
43                    uint32_t flags);
44
45         virtual
46         ~IOHandler ();
47
48         // Each IOHandler gets to run until it is done. It should read data
49         // from the "in" and place output into "out" and "err and return
50         // when done.
51         virtual void
52         Run () = 0;
53
54         // Hide any characters that have been displayed so far so async
55         // output can be displayed. Refresh() will be called after the
56         // output has been displayed.
57         virtual void
58         Hide () = 0;
59         
60         // Called when the async output has been received in order to update
61         // the input reader (refresh the prompt and redisplay any current
62         // line(s) that are being edited
63         virtual void
64         Refresh () = 0;
65
66         // Called when an input reader should relinquish its control so another
67         // can be pushed onto the IO handler stack, or so the current IO
68         // handler can pop itself off the stack
69
70         virtual void
71         Cancel () = 0;
72
73         // Called when CTRL+C is pressed which usually causes
74         // Debugger::DispatchInputInterrupt to be called.
75         
76         virtual void
77         Interrupt () = 0;
78         
79         virtual void
80         GotEOF() = 0;
81         
82         virtual bool
83         IsActive ()
84         {
85             return m_active && !m_done;
86         }
87
88         virtual void
89         SetIsDone (bool b)
90         {
91             m_done = b;
92         }
93
94         virtual bool
95         GetIsDone ()
96         {
97             return m_done;
98         }
99
100         virtual void
101         Activate ()
102         {
103             m_active = true;
104         }
105         
106         virtual void
107         Deactivate ()
108         {
109             m_active = false;
110         }
111
112         virtual const char *
113         GetPrompt ()
114         {
115             // Prompt support isn't mandatory
116             return NULL;
117         }
118         
119         virtual bool
120         SetPrompt (const char *prompt)
121         {
122             // Prompt support isn't mandatory
123             return false;
124         }
125         
126         virtual ConstString
127         GetControlSequence (char ch)
128         {
129             return ConstString();
130         }
131         
132         int
133         GetInputFD();
134         
135         int
136         GetOutputFD();
137         
138         int
139         GetErrorFD();
140
141         FILE *
142         GetInputFILE();
143         
144         FILE *
145         GetOutputFILE();
146         
147         FILE *
148         GetErrorFILE();
149
150         lldb::StreamFileSP &
151         GetInputStreamFile();
152         
153         lldb::StreamFileSP &
154         GetOutputStreamFile();
155         
156         lldb::StreamFileSP &
157         GetErrorStreamFile();
158
159         Debugger &
160         GetDebugger()
161         {
162             return m_debugger;
163         }
164
165         void *
166         GetUserData ()
167         {
168             return m_user_data;
169         }
170
171         void
172         SetUserData (void *user_data)
173         {
174             m_user_data = user_data;
175         }
176
177         Flags &
178         GetFlags ()
179         {
180             return m_flags;
181         }
182
183         const Flags &
184         GetFlags () const
185         {
186             return m_flags;
187         }
188
189         //------------------------------------------------------------------
190         /// Check if the input is being supplied interactively by a user
191         ///
192         /// This will return true if the input stream is a terminal (tty or
193         /// pty) and can cause IO handlers to do different things (like
194         /// for a comfirmation when deleting all breakpoints).
195         //------------------------------------------------------------------
196         bool
197         GetIsInteractive ();
198
199         //------------------------------------------------------------------
200         /// Check if the input is coming from a real terminal.
201         ///
202         /// A real terminal has a valid size with a certain number of rows
203         /// and colums. If this function returns true, then terminal escape
204         /// sequences are expected to work (cursor movement escape sequences,
205         /// clearning lines, etc).
206         //------------------------------------------------------------------
207         bool
208         GetIsRealTerminal ();
209
210     protected:
211         Debugger &m_debugger;
212         lldb::StreamFileSP m_input_sp;
213         lldb::StreamFileSP m_output_sp;
214         lldb::StreamFileSP m_error_sp;
215         Flags m_flags;
216         void *m_user_data;
217         bool m_done;
218         bool m_active;
219
220     private:
221         DISALLOW_COPY_AND_ASSIGN (IOHandler);
222     };
223
224     
225     //------------------------------------------------------------------
226     /// A delegate class for use with IOHandler subclasses.
227     ///
228     /// The IOHandler delegate is designed to be mixed into classes so
229     /// they can use an IOHandler subclass to fetch input and notify the
230     /// object that inherits from this delegate class when a token is
231     /// received.
232     //------------------------------------------------------------------
233     class IOHandlerDelegate
234     {
235     public:
236         enum class Completion {
237             None,
238             LLDBCommand,
239             Expression
240         };
241         
242         IOHandlerDelegate (Completion completion = Completion::None) :
243             m_completion(completion),
244             m_io_handler_done (false)
245         {
246         }
247         
248         virtual
249         ~IOHandlerDelegate()
250         {
251         }
252         
253         virtual void
254         IOHandlerActivated (IOHandler &io_handler)
255         {
256         }
257         
258         virtual int
259         IOHandlerComplete (IOHandler &io_handler,
260                            const char *current_line,
261                            const char *cursor,
262                            const char *last_char,
263                            int skip_first_n_matches,
264                            int max_matches,
265                            StringList &matches);
266         
267         //------------------------------------------------------------------
268         /// Called when a line or lines have been retrieved.
269         ///
270         /// This funtion can handle the current line and possibly call
271         /// IOHandler::SetIsDone(true) when the IO handler is done like when
272         /// "quit" is entered as a command, of when an empty line is
273         /// received. It is up to the delegate to determine when a line
274         /// should cause a IOHandler to exit.
275         //------------------------------------------------------------------
276         virtual void
277         IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0;
278         
279         //------------------------------------------------------------------
280         /// Called when a line in \a lines has been updated when doing
281         /// multi-line input.
282         ///
283         /// @return
284         ///     Return an enumeration to indicate the status of the current
285         ///     line:
286         ///         Success - The line is good and should be added to the
287         ///                   multiple lines
288         ///         Error - There is an error with the current line and it
289         ///                 need to be re-edited before it is acceptable
290         ///         Done - The lines collection is complete and ready to be
291         ///                returned.
292         //------------------------------------------------------------------
293         virtual LineStatus
294         IOHandlerLinesUpdated (IOHandler &io_handler,
295                                StringList &lines,
296                                uint32_t line_idx,
297                                Error &error)
298         {
299             return LineStatus::Done; // Stop getting lines on the first line that is updated
300             // subclasses should do something more intelligent here.
301             // This function will not be called on IOHandler objects
302             // that are getting single lines.
303         }
304         
305         
306         virtual ConstString
307         GetControlSequence (char ch)
308         {
309             return ConstString();
310         }
311         
312     protected:
313         Completion m_completion; // Support for common builtin completions
314         bool m_io_handler_done;
315     };
316
317     //----------------------------------------------------------------------
318     // IOHandlerDelegateMultiline
319     //
320     // A IOHandlerDelegate that handles terminating multi-line input when
321     // the last line is equal to "end_line" which is specified in the
322     // constructor.
323     //----------------------------------------------------------------------
324     class IOHandlerDelegateMultiline :
325         public IOHandlerDelegate
326     {
327     public:
328         IOHandlerDelegateMultiline (const char *end_line,
329                                     Completion completion = Completion::None) :
330             IOHandlerDelegate (completion),
331             m_end_line((end_line && end_line[0]) ? end_line : "")
332         {
333         }
334         
335         virtual
336         ~IOHandlerDelegateMultiline ()
337         {
338         }
339         
340         virtual ConstString
341         GetControlSequence (char ch)
342         {
343             if (ch == 'd')
344                 return ConstString (m_end_line + "\n");
345             return ConstString();
346         }
347
348         virtual LineStatus
349         IOHandlerLinesUpdated (IOHandler &io_handler,
350                                StringList &lines,
351                                uint32_t line_idx,
352                                Error &error)
353         {
354             if (line_idx == UINT32_MAX)
355             {
356                 // Remove the last empty line from "lines" so it doesn't appear
357                 // in our final expression and return true to indicate we are done
358                 // getting lines
359                 lines.PopBack();
360                 return LineStatus::Done;
361             }
362             else if (line_idx + 1 == lines.GetSize())
363             {
364                 // The last line was edited, if this line is empty, then we are done
365                 // getting our multiple lines.
366                 if (lines[line_idx] == m_end_line)
367                     return LineStatus::Done;
368             }
369             return LineStatus::Success;
370         }
371     protected:
372         const std::string m_end_line;
373     };
374     
375     
376     class IOHandlerEditline : public IOHandler
377     {
378     public:
379         IOHandlerEditline (Debugger &debugger,
380                            const char *editline_name, // Used for saving history files
381                            const char *prompt,
382                            bool multi_line,
383                            IOHandlerDelegate &delegate);
384
385         IOHandlerEditline (Debugger &debugger,
386                            const lldb::StreamFileSP &input_sp,
387                            const lldb::StreamFileSP &output_sp,
388                            const lldb::StreamFileSP &error_sp,
389                            uint32_t flags,
390                            const char *editline_name, // Used for saving history files
391                            const char *prompt,
392                            bool multi_line,
393                            IOHandlerDelegate &delegate);
394         
395         virtual
396         ~IOHandlerEditline ();
397         
398         virtual void
399         Run ();
400         
401         virtual void
402         Hide ();
403
404         virtual void
405         Refresh ();
406
407         virtual void
408         Cancel ();
409
410         virtual void
411         Interrupt ();
412         
413         virtual void
414         GotEOF();
415         
416         virtual void
417         Activate ()
418         {
419             IOHandler::Activate();
420             m_delegate.IOHandlerActivated(*this);
421         }
422
423         virtual ConstString
424         GetControlSequence (char ch)
425         {
426             return m_delegate.GetControlSequence (ch);
427         }
428
429         virtual const char *
430         GetPrompt ();
431         
432         virtual bool
433         SetPrompt (const char *prompt);
434
435         bool
436         GetLine (std::string &line);
437         
438         bool
439         GetLines (StringList &lines);
440
441     private:
442         static LineStatus
443         LineCompletedCallback (Editline *editline,
444                                StringList &lines,
445                                uint32_t line_idx,
446                                Error &error,
447                                void *baton);
448
449         static int AutoCompleteCallback (const char *current_line,
450                                          const char *cursor,
451                                          const char *last_char,
452                                          int skip_first_n_matches,
453                                          int max_matches,
454                                          StringList &matches,
455                                          void *baton);
456
457     protected:
458         std::unique_ptr<Editline> m_editline_ap;
459         IOHandlerDelegate &m_delegate;
460         std::string m_prompt;
461         bool m_multi_line;        
462     };
463     
464     class IOHandlerConfirm :
465         public IOHandlerEditline,
466         public IOHandlerDelegate
467     {
468     public:
469         IOHandlerConfirm (Debugger &debugger,
470                           const char *prompt,
471                           bool default_response);
472         
473         virtual
474         ~IOHandlerConfirm ();
475                 
476         bool
477         GetResponse () const
478         {
479             return m_user_response;
480         }
481         
482         virtual int
483         IOHandlerComplete (IOHandler &io_handler,
484                            const char *current_line,
485                            const char *cursor,
486                            const char *last_char,
487                            int skip_first_n_matches,
488                            int max_matches,
489                            StringList &matches);
490         
491         virtual void
492         IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
493
494     protected:
495         const bool m_default_response;
496         bool m_user_response;
497     };
498
499     class IOHandlerCursesGUI :
500         public IOHandler
501     {
502     public:
503         IOHandlerCursesGUI (Debugger &debugger);
504         
505         virtual
506         ~IOHandlerCursesGUI ();
507         
508         virtual void
509         Run ();
510         
511         virtual void
512         Hide ();
513         
514         virtual void
515         Refresh ();
516
517         virtual void
518         Cancel ();
519
520         virtual void
521         Interrupt ();
522         
523         virtual void
524         GotEOF();
525         
526         virtual void
527         Activate ();
528         
529         virtual void
530         Deactivate ();
531
532     protected:
533         curses::ApplicationAP m_app_ap;
534     };
535
536     class IOHandlerCursesValueObjectList :
537         public IOHandler
538     {
539     public:
540         IOHandlerCursesValueObjectList (Debugger &debugger, ValueObjectList &valobj_list);
541         
542         virtual
543         ~IOHandlerCursesValueObjectList ();
544         
545         virtual void
546         Run ();
547         
548         virtual void
549         Hide ();
550         
551         virtual void
552         Refresh ();
553         
554         virtual void
555         Interrupt ();
556         
557         virtual void
558         GotEOF();
559     protected:
560         ValueObjectList m_valobj_list;
561     };
562
563     class IOHandlerStack
564     {
565     public:
566         
567         IOHandlerStack () :
568             m_stack(),
569             m_mutex(Mutex::eMutexTypeRecursive),
570             m_top (NULL)
571         {
572         }
573         
574         ~IOHandlerStack ()
575         {
576         }
577         
578         size_t
579         GetSize () const
580         {
581             Mutex::Locker locker (m_mutex);
582             return m_stack.size();
583         }
584         
585         void
586         Push (const lldb::IOHandlerSP& sp)
587         {
588             if (sp)
589             {
590                 Mutex::Locker locker (m_mutex);
591                 m_stack.push (sp);
592                 // Set m_top the non-locking IsTop() call
593                 m_top = sp.get();
594             }
595         }
596         
597         bool
598         IsEmpty () const
599         {
600             Mutex::Locker locker (m_mutex);
601             return m_stack.empty();
602         }
603         
604         lldb::IOHandlerSP
605         Top ()
606         {
607             lldb::IOHandlerSP sp;
608             {
609                 Mutex::Locker locker (m_mutex);
610                 if (!m_stack.empty())
611                     sp = m_stack.top();
612             }
613             return sp;
614         }
615         
616         void
617         Pop ()
618         {
619             Mutex::Locker locker (m_mutex);
620             if (!m_stack.empty())
621                 m_stack.pop();
622             // Set m_top the non-locking IsTop() call
623             if (m_stack.empty())
624                 m_top = NULL;
625             else
626                 m_top = m_stack.top().get();
627         }
628
629         Mutex &
630         GetMutex()
631         {
632             return m_mutex;
633         }
634       
635         bool
636         IsTop (const lldb::IOHandlerSP &io_handler_sp) const
637         {
638             return m_top == io_handler_sp.get();
639         }
640
641         ConstString
642         GetTopIOHandlerControlSequence (char ch)
643         {
644             if (m_top)
645                 return m_top->GetControlSequence(ch);
646             return ConstString();
647         }
648
649     protected:
650         
651         std::stack<lldb::IOHandlerSP> m_stack;
652         mutable Mutex m_mutex;
653         IOHandler *m_top;
654         
655     private:
656         
657         DISALLOW_COPY_AND_ASSIGN (IOHandlerStack);
658     };
659
660 } // namespace lldb_private
661
662 #endif // #ifndef liblldb_IOHandler_h_