]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Core/IOHandler.h
MFV r276568:
[FreeBSD/FreeBSD.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 bool
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 confirmation 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 columns. If this function returns true, then terminal escape
204         /// sequences are expected to work (cursor movement escape sequences,
205         /// clearing 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 function 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         IOHandlerGetControlSequence (char ch)
308         {
309             return ConstString();
310         }
311         
312         //------------------------------------------------------------------
313         // Intercept the IOHandler::Interrupt() calls and do something.
314         //
315         // Return true if the interrupt was handled, false if the IOHandler
316         // should continue to try handle the interrupt itself.
317         //------------------------------------------------------------------
318         virtual bool
319         IOHandlerInterrupt (IOHandler &io_handler)
320         {
321             return false;
322         }
323     protected:
324         Completion m_completion; // Support for common builtin completions
325         bool m_io_handler_done;
326     };
327
328     //----------------------------------------------------------------------
329     // IOHandlerDelegateMultiline
330     //
331     // A IOHandlerDelegate that handles terminating multi-line input when
332     // the last line is equal to "end_line" which is specified in the
333     // constructor.
334     //----------------------------------------------------------------------
335     class IOHandlerDelegateMultiline :
336         public IOHandlerDelegate
337     {
338     public:
339         IOHandlerDelegateMultiline (const char *end_line,
340                                     Completion completion = Completion::None) :
341             IOHandlerDelegate (completion),
342             m_end_line((end_line && end_line[0]) ? end_line : "")
343         {
344         }
345         
346         virtual
347         ~IOHandlerDelegateMultiline ()
348         {
349         }
350         
351         virtual ConstString
352         IOHandlerGetControlSequence (char ch)
353         {
354             if (ch == 'd')
355                 return ConstString (m_end_line + "\n");
356             return ConstString();
357         }
358
359         virtual LineStatus
360         IOHandlerLinesUpdated (IOHandler &io_handler,
361                                StringList &lines,
362                                uint32_t line_idx,
363                                Error &error)
364         {
365             if (line_idx == UINT32_MAX)
366             {
367                 // Remove the last empty line from "lines" so it doesn't appear
368                 // in our final expression and return true to indicate we are done
369                 // getting lines
370                 lines.PopBack();
371                 return LineStatus::Done;
372             }
373             else if (line_idx + 1 == lines.GetSize())
374             {
375                 // The last line was edited, if this line is empty, then we are done
376                 // getting our multiple lines.
377                 if (lines[line_idx] == m_end_line)
378                 {
379                     return LineStatus::Done;
380                 }
381             }
382             return LineStatus::Success;
383         }
384     protected:
385         const std::string m_end_line;
386     };
387     
388     
389     class IOHandlerEditline : public IOHandler
390     {
391     public:
392         IOHandlerEditline (Debugger &debugger,
393                            const char *editline_name, // Used for saving history files
394                            const char *prompt,
395                            bool multi_line,
396                            uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
397                            IOHandlerDelegate &delegate);
398
399         IOHandlerEditline (Debugger &debugger,
400                            const lldb::StreamFileSP &input_sp,
401                            const lldb::StreamFileSP &output_sp,
402                            const lldb::StreamFileSP &error_sp,
403                            uint32_t flags,
404                            const char *editline_name, // Used for saving history files
405                            const char *prompt,
406                            bool multi_line,
407                            uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
408                            IOHandlerDelegate &delegate);
409         
410         virtual
411         ~IOHandlerEditline ();
412         
413         virtual void
414         Run ();
415         
416         virtual void
417         Hide ();
418
419         virtual void
420         Refresh ();
421
422         virtual void
423         Cancel ();
424
425         virtual bool
426         Interrupt ();
427         
428         virtual void
429         GotEOF();
430         
431         virtual void
432         Activate ()
433         {
434             IOHandler::Activate();
435             m_delegate.IOHandlerActivated(*this);
436         }
437
438         virtual ConstString
439         GetControlSequence (char ch)
440         {
441             return m_delegate.IOHandlerGetControlSequence (ch);
442         }
443
444         virtual const char *
445         GetPrompt ();
446         
447         virtual bool
448         SetPrompt (const char *prompt);
449
450         bool
451         GetLine (std::string &line, bool &interrupted);
452         
453         bool
454         GetLines (StringList &lines, bool &interrupted);
455         
456         void
457         SetBaseLineNumber (uint32_t line);
458         
459     private:
460         static LineStatus
461         LineCompletedCallback (Editline *editline,
462                                StringList &lines,
463                                uint32_t line_idx,
464                                Error &error,
465                                void *baton);
466
467         static int AutoCompleteCallback (const char *current_line,
468                                          const char *cursor,
469                                          const char *last_char,
470                                          int skip_first_n_matches,
471                                          int max_matches,
472                                          StringList &matches,
473                                          void *baton);
474
475     protected:
476         std::unique_ptr<Editline> m_editline_ap;
477         IOHandlerDelegate &m_delegate;
478         std::string m_prompt;
479         uint32_t m_base_line_number; // If non-zero, then show line numbers in prompt
480         bool m_multi_line;        
481     };
482     
483     class IOHandlerConfirm :
484         public IOHandlerEditline,
485         public IOHandlerDelegate
486     {
487     public:
488         IOHandlerConfirm (Debugger &debugger,
489                           const char *prompt,
490                           bool default_response);
491         
492         virtual
493         ~IOHandlerConfirm ();
494                 
495         bool
496         GetResponse () const
497         {
498             return m_user_response;
499         }
500         
501         virtual int
502         IOHandlerComplete (IOHandler &io_handler,
503                            const char *current_line,
504                            const char *cursor,
505                            const char *last_char,
506                            int skip_first_n_matches,
507                            int max_matches,
508                            StringList &matches);
509         
510         virtual void
511         IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
512
513     protected:
514         const bool m_default_response;
515         bool m_user_response;
516     };
517
518     class IOHandlerCursesGUI :
519         public IOHandler
520     {
521     public:
522         IOHandlerCursesGUI (Debugger &debugger);
523         
524         virtual
525         ~IOHandlerCursesGUI ();
526         
527         virtual void
528         Run ();
529         
530         virtual void
531         Hide ();
532         
533         virtual void
534         Refresh ();
535
536         virtual void
537         Cancel ();
538
539         virtual bool
540         Interrupt ();
541         
542         virtual void
543         GotEOF();
544         
545         virtual void
546         Activate ();
547         
548         virtual void
549         Deactivate ();
550
551     protected:
552         curses::ApplicationAP m_app_ap;
553     };
554
555     class IOHandlerCursesValueObjectList :
556         public IOHandler
557     {
558     public:
559         IOHandlerCursesValueObjectList (Debugger &debugger, ValueObjectList &valobj_list);
560         
561         virtual
562         ~IOHandlerCursesValueObjectList ();
563         
564         virtual void
565         Run ();
566         
567         virtual void
568         Hide ();
569         
570         virtual void
571         Refresh ();
572         
573         virtual bool
574         HandleInterrupt ();
575         
576         virtual void
577         GotEOF();
578     protected:
579         ValueObjectList m_valobj_list;
580     };
581
582     class IOHandlerStack
583     {
584     public:
585         
586         IOHandlerStack () :
587             m_stack(),
588             m_mutex(Mutex::eMutexTypeRecursive),
589             m_top (NULL)
590         {
591         }
592         
593         ~IOHandlerStack ()
594         {
595         }
596         
597         size_t
598         GetSize () const
599         {
600             Mutex::Locker locker (m_mutex);
601             return m_stack.size();
602         }
603         
604         void
605         Push (const lldb::IOHandlerSP& sp)
606         {
607             if (sp)
608             {
609                 Mutex::Locker locker (m_mutex);
610                 m_stack.push (sp);
611                 // Set m_top the non-locking IsTop() call
612                 m_top = sp.get();
613             }
614         }
615         
616         bool
617         IsEmpty () const
618         {
619             Mutex::Locker locker (m_mutex);
620             return m_stack.empty();
621         }
622         
623         lldb::IOHandlerSP
624         Top ()
625         {
626             lldb::IOHandlerSP sp;
627             {
628                 Mutex::Locker locker (m_mutex);
629                 if (!m_stack.empty())
630                     sp = m_stack.top();
631             }
632             return sp;
633         }
634         
635         void
636         Pop ()
637         {
638             Mutex::Locker locker (m_mutex);
639             if (!m_stack.empty())
640                 m_stack.pop();
641             // Set m_top the non-locking IsTop() call
642             if (m_stack.empty())
643                 m_top = NULL;
644             else
645                 m_top = m_stack.top().get();
646         }
647
648         Mutex &
649         GetMutex()
650         {
651             return m_mutex;
652         }
653       
654         bool
655         IsTop (const lldb::IOHandlerSP &io_handler_sp) const
656         {
657             return m_top == io_handler_sp.get();
658         }
659
660         ConstString
661         GetTopIOHandlerControlSequence (char ch)
662         {
663             if (m_top)
664                 return m_top->GetControlSequence(ch);
665             return ConstString();
666         }
667
668     protected:
669         
670         std::stack<lldb::IOHandlerSP> m_stack;
671         mutable Mutex m_mutex;
672         IOHandler *m_top;
673         
674     private:
675         
676         DISALLOW_COPY_AND_ASSIGN (IOHandlerStack);
677     };
678
679 } // namespace lldb_private
680
681 #endif // #ifndef liblldb_IOHandler_h_