]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Core/IOHandler.h
MFV r308954:
[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 // C Includes
14 #include <string.h>
15
16 // C++ Includes
17 #include <memory>
18 #include <string>
19 #include <vector>
20
21 // Other libraries and framework includes
22 // Project includes
23 #include "lldb/lldb-public.h"
24 #include "lldb/lldb-enumerations.h"
25 #include "lldb/Core/ConstString.h"
26 #include "lldb/Core/Error.h"
27 #include "lldb/Core/Flags.h"
28 #include "lldb/Core/Stream.h"
29 #include "lldb/Core/StringList.h"
30 #include "lldb/Core/ValueObjectList.h"
31 #include "lldb/Host/Mutex.h"
32 #include "lldb/Host/Predicate.h"
33
34 namespace curses
35 {
36     class Application;
37     typedef std::unique_ptr<Application> ApplicationAP;
38 } // namespace curses
39
40 namespace lldb_private {
41
42     class IOHandler
43     {
44     public:
45         enum class Type {
46             CommandInterpreter,
47             CommandList,
48             Confirm,
49             Curses,
50             Expression,
51             REPL,
52             ProcessIO,
53             PythonInterpreter,
54             PythonCode,
55             Other
56         };
57
58         IOHandler (Debugger &debugger,
59                    IOHandler::Type type);
60
61         IOHandler (Debugger &debugger,
62                    IOHandler::Type type,
63                    const lldb::StreamFileSP &input_sp,
64                    const lldb::StreamFileSP &output_sp,
65                    const lldb::StreamFileSP &error_sp,
66                    uint32_t flags);
67
68         virtual
69         ~IOHandler ();
70
71         // Each IOHandler gets to run until it is done. It should read data
72         // from the "in" and place output into "out" and "err and return
73         // when done.
74         virtual void
75         Run () = 0;
76
77         // Called when an input reader should relinquish its control so another
78         // can be pushed onto the IO handler stack, or so the current IO
79         // handler can pop itself off the stack
80
81         virtual void
82         Cancel () = 0;
83
84         // Called when CTRL+C is pressed which usually causes
85         // Debugger::DispatchInputInterrupt to be called.
86         
87         virtual bool
88         Interrupt () = 0;
89         
90         virtual void
91         GotEOF() = 0;
92         
93         virtual bool
94         IsActive ()
95         {
96             return m_active && !m_done;
97         }
98
99         virtual void
100         SetIsDone (bool b)
101         {
102             m_done = b;
103         }
104
105         virtual bool
106         GetIsDone ()
107         {
108             return m_done;
109         }
110
111         Type
112         GetType () const
113         {
114             return m_type;
115         }
116
117         virtual void
118         Activate ()
119         {
120             m_active = true;
121         }
122         
123         virtual void
124         Deactivate ()
125         {
126             m_active = false;
127         }
128
129         virtual const char *
130         GetPrompt ()
131         {
132             // Prompt support isn't mandatory
133             return nullptr;
134         }
135         
136         virtual bool
137         SetPrompt (const char *prompt)
138         {
139             // Prompt support isn't mandatory
140             return false;
141         }
142         
143         virtual ConstString
144         GetControlSequence (char ch)
145         {
146             return ConstString();
147         }
148
149         virtual const char *
150         GetCommandPrefix ()
151         {
152             return nullptr;
153         }
154         
155         virtual const char *
156         GetHelpPrologue()
157         {
158             return nullptr;
159         }
160
161         int
162         GetInputFD();
163         
164         int
165         GetOutputFD();
166         
167         int
168         GetErrorFD();
169
170         FILE *
171         GetInputFILE();
172         
173         FILE *
174         GetOutputFILE();
175         
176         FILE *
177         GetErrorFILE();
178
179         lldb::StreamFileSP &
180         GetInputStreamFile();
181         
182         lldb::StreamFileSP &
183         GetOutputStreamFile();
184         
185         lldb::StreamFileSP &
186         GetErrorStreamFile();
187
188         Debugger &
189         GetDebugger()
190         {
191             return m_debugger;
192         }
193
194         void *
195         GetUserData ()
196         {
197             return m_user_data;
198         }
199
200         void
201         SetUserData (void *user_data)
202         {
203             m_user_data = user_data;
204         }
205
206         Flags &
207         GetFlags ()
208         {
209             return m_flags;
210         }
211
212         const Flags &
213         GetFlags () const
214         {
215             return m_flags;
216         }
217
218         //------------------------------------------------------------------
219         /// Check if the input is being supplied interactively by a user
220         ///
221         /// This will return true if the input stream is a terminal (tty or
222         /// pty) and can cause IO handlers to do different things (like
223         /// for a confirmation when deleting all breakpoints).
224         //------------------------------------------------------------------
225         bool
226         GetIsInteractive ();
227
228         //------------------------------------------------------------------
229         /// Check if the input is coming from a real terminal.
230         ///
231         /// A real terminal has a valid size with a certain number of rows
232         /// and columns. If this function returns true, then terminal escape
233         /// sequences are expected to work (cursor movement escape sequences,
234         /// clearing lines, etc).
235         //------------------------------------------------------------------
236         bool
237         GetIsRealTerminal ();
238         
239         void
240         SetPopped (bool b);
241         
242         void
243         WaitForPop ();
244
245         virtual void
246         PrintAsync (Stream *stream, const char *s, size_t len)
247         {
248             stream->Write (s, len);
249             stream->Flush();
250         }
251
252     protected:
253         Debugger &m_debugger;
254         lldb::StreamFileSP m_input_sp;
255         lldb::StreamFileSP m_output_sp;
256         lldb::StreamFileSP m_error_sp;
257         Predicate<bool> m_popped;
258         Flags m_flags;
259         Type m_type;
260         void *m_user_data;
261         bool m_done;
262         bool m_active;
263
264     private:
265         DISALLOW_COPY_AND_ASSIGN (IOHandler);
266     };
267     
268     //------------------------------------------------------------------
269     /// A delegate class for use with IOHandler subclasses.
270     ///
271     /// The IOHandler delegate is designed to be mixed into classes so
272     /// they can use an IOHandler subclass to fetch input and notify the
273     /// object that inherits from this delegate class when a token is
274     /// received.
275     //------------------------------------------------------------------
276     class IOHandlerDelegate
277     {
278     public:
279         enum class Completion {
280             None,
281             LLDBCommand,
282             Expression
283         };
284         
285         IOHandlerDelegate (Completion completion = Completion::None) :
286             m_completion(completion),
287             m_io_handler_done (false)
288         {
289         }
290         
291         virtual
292         ~IOHandlerDelegate() = default;
293         
294         virtual void
295         IOHandlerActivated (IOHandler &io_handler)
296         {
297         }
298
299         virtual void
300         IOHandlerDeactivated (IOHandler &io_handler)
301         {
302         }
303
304         virtual int
305         IOHandlerComplete (IOHandler &io_handler,
306                            const char *current_line,
307                            const char *cursor,
308                            const char *last_char,
309                            int skip_first_n_matches,
310                            int max_matches,
311                            StringList &matches);
312         
313         virtual const char *
314         IOHandlerGetFixIndentationCharacters ()
315         {
316             return nullptr;
317         }
318         
319         //------------------------------------------------------------------
320         /// Called when a new line is created or one of an identified set of
321         /// indentation characters is typed.
322         ///
323         /// This function determines how much indentation should be added
324         /// or removed to match the recommended amount for the final line.
325         ///
326         /// @param[in] io_handler
327         ///     The IOHandler that responsible for input.
328         ///
329         /// @param[in] lines
330         ///     The current input up to the line to be corrected.  Lines
331         ///     following the line containing the cursor are not included.
332         ///
333         /// @param[in] cursor_position
334         ///     The number of characters preceding the cursor on the final
335         ///     line at the time.
336         ///
337         /// @return
338         ///     Returns an integer describing the number of spaces needed
339         ///     to correct the indentation level.  Positive values indicate
340         ///     that spaces should be added, while negative values represent
341         ///     spaces that should be removed.
342         //------------------------------------------------------------------
343         virtual int
344         IOHandlerFixIndentation (IOHandler &io_handler,
345                                  const StringList &lines,
346                                  int cursor_position)
347         {
348             return 0;
349         }
350                         
351         //------------------------------------------------------------------
352         /// Called when a line or lines have been retrieved.
353         ///
354         /// This function can handle the current line and possibly call
355         /// IOHandler::SetIsDone(true) when the IO handler is done like when
356         /// "quit" is entered as a command, of when an empty line is
357         /// received. It is up to the delegate to determine when a line
358         /// should cause a IOHandler to exit.
359         //------------------------------------------------------------------
360         virtual void
361         IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0;
362
363         virtual void
364         IOHandlerInputInterrupted (IOHandler &io_handler, std::string &data)
365         {
366         }
367
368         //------------------------------------------------------------------
369         /// Called to determine whether typing enter after the last line in
370         /// \a lines should end input.  This function will not be called on
371         /// IOHandler objects that are getting single lines.
372         /// @param[in] io_handler
373         ///     The IOHandler that responsible for updating the lines.
374         ///
375         /// @param[in] lines
376         ///     The current multi-line content.  May be altered to provide
377         ///     alternative input when complete.
378         ///
379         /// @return
380         ///     Return an boolean to indicate whether input is complete,
381         ///     true indicates that no additional input is necessary, while
382         ///     false indicates that more input is required.
383         //------------------------------------------------------------------
384         virtual bool
385         IOHandlerIsInputComplete (IOHandler &io_handler,
386                                   StringList &lines)
387         {
388             // Impose no requirements for input to be considered
389             // complete.  subclasses should do something more intelligent.
390             return true;
391         }
392         
393         virtual ConstString
394         IOHandlerGetControlSequence (char ch)
395         {
396             return ConstString();
397         }
398         
399         virtual const char *
400         IOHandlerGetCommandPrefix ()
401         {
402             return nullptr;
403         }
404
405         virtual const char *
406         IOHandlerGetHelpPrologue ()
407         {
408             return nullptr;
409         }
410
411         //------------------------------------------------------------------
412         // Intercept the IOHandler::Interrupt() calls and do something.
413         //
414         // Return true if the interrupt was handled, false if the IOHandler
415         // should continue to try handle the interrupt itself.
416         //------------------------------------------------------------------
417         virtual bool
418         IOHandlerInterrupt (IOHandler &io_handler)
419         {
420             return false;
421         }
422
423     protected:
424         Completion m_completion; // Support for common builtin completions
425         bool m_io_handler_done;
426     };
427
428     //----------------------------------------------------------------------
429     // IOHandlerDelegateMultiline
430     //
431     // A IOHandlerDelegate that handles terminating multi-line input when
432     // the last line is equal to "end_line" which is specified in the
433     // constructor.
434     //----------------------------------------------------------------------
435     class IOHandlerDelegateMultiline :
436         public IOHandlerDelegate
437     {
438     public:
439         IOHandlerDelegateMultiline (const char *end_line,
440                                     Completion completion = Completion::None) :
441             IOHandlerDelegate (completion),
442             m_end_line((end_line && end_line[0]) ? end_line : "")
443         {
444         }
445         
446         ~IOHandlerDelegateMultiline() override = default;
447         
448         ConstString
449         IOHandlerGetControlSequence (char ch) override
450         {
451             if (ch == 'd')
452                 return ConstString (m_end_line + "\n");
453             return ConstString();
454         }
455
456         bool
457         IOHandlerIsInputComplete (IOHandler &io_handler,
458                                   StringList &lines) override
459         {
460             // Determine whether the end of input signal has been entered
461             const size_t num_lines = lines.GetSize();
462             if (num_lines > 0 && lines[num_lines - 1] == m_end_line)
463             {
464                 // Remove the terminal line from "lines" so it doesn't appear in
465                 // the resulting input and return true to indicate we are done
466                 // getting lines
467                 lines.PopBack();
468                 return true;
469             }
470             return false;
471         }
472
473     protected:
474         const std::string m_end_line;
475     };
476     
477     class IOHandlerEditline : public IOHandler
478     {
479     public:
480         IOHandlerEditline (Debugger &debugger,
481                            IOHandler::Type type,
482                            const char *editline_name, // Used for saving history files
483                            const char *prompt,
484                            const char *continuation_prompt,
485                            bool multi_line,
486                            bool color_prompts,
487                            uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
488                            IOHandlerDelegate &delegate);
489
490         IOHandlerEditline (Debugger &debugger,
491                            IOHandler::Type type,
492                            const lldb::StreamFileSP &input_sp,
493                            const lldb::StreamFileSP &output_sp,
494                            const lldb::StreamFileSP &error_sp,
495                            uint32_t flags,
496                            const char *editline_name, // Used for saving history files
497                            const char *prompt,
498                            const char *continuation_prompt,
499                            bool multi_line,
500                            bool color_prompts,
501                            uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
502                            IOHandlerDelegate &delegate);
503         
504         ~IOHandlerEditline() override;
505         
506         void
507         Run () override;
508         
509         void
510         Cancel () override;
511
512         bool
513         Interrupt () override;
514         
515         void
516         GotEOF() override;
517         
518         void
519         Activate () override;
520
521         void
522         Deactivate () override;
523
524         ConstString
525         GetControlSequence (char ch) override
526         {
527             return m_delegate.IOHandlerGetControlSequence (ch);
528         }
529
530         const char *
531         GetCommandPrefix () override
532         {
533             return m_delegate.IOHandlerGetCommandPrefix ();
534         }
535
536         const char *
537         GetHelpPrologue () override
538         {
539             return m_delegate.IOHandlerGetHelpPrologue ();
540         }
541
542         const char *
543         GetPrompt () override;
544         
545         bool
546         SetPrompt (const char *prompt) override;
547         
548         const char *
549         GetContinuationPrompt ();
550         
551         void
552         SetContinuationPrompt (const char *prompt);
553         
554         bool
555         GetLine (std::string &line, bool &interrupted);
556         
557         bool
558         GetLines (StringList &lines, bool &interrupted);
559         
560         void
561         SetBaseLineNumber (uint32_t line);
562         
563         bool
564         GetInterruptExits ()
565         {
566             return m_interrupt_exits;
567         }
568
569         void
570         SetInterruptExits (bool b)
571         {
572             m_interrupt_exits = b;
573         }
574         
575         const StringList *
576         GetCurrentLines () const
577         {
578             return m_current_lines_ptr;
579         }
580         
581         uint32_t
582         GetCurrentLineIndex () const;
583
584         void
585         PrintAsync (Stream *stream, const char *s, size_t len) override;
586
587     private:
588 #ifndef LLDB_DISABLE_LIBEDIT
589         static bool
590         IsInputCompleteCallback (Editline *editline,
591                                  StringList &lines,
592                                  void *baton);
593         
594         static int
595         FixIndentationCallback (Editline *editline,
596                                 const StringList &lines,
597                                 int cursor_position,
598                                 void *baton);
599         
600         static int AutoCompleteCallback (const char *current_line,
601                                          const char *cursor,
602                                          const char *last_char,
603                                          int skip_first_n_matches,
604                                          int max_matches,
605                                          StringList &matches,
606                                          void *baton);
607 #endif
608
609     protected:
610 #ifndef LLDB_DISABLE_LIBEDIT
611         std::unique_ptr<Editline> m_editline_ap;
612 #endif
613         IOHandlerDelegate &m_delegate;
614         std::string m_prompt;
615         std::string m_continuation_prompt;
616         StringList *m_current_lines_ptr;
617         uint32_t m_base_line_number; // If non-zero, then show line numbers in prompt
618         uint32_t m_curr_line_idx;
619         bool m_multi_line;
620         bool m_color_prompts;
621         bool m_interrupt_exits;
622         bool m_editing; // Set to true when fetching a line manually (not using libedit)
623     };
624     
625     // The order of base classes is important. Look at the constructor of IOHandlerConfirm
626     // to see how.
627     class IOHandlerConfirm :
628         public IOHandlerDelegate,
629         public IOHandlerEditline
630     {
631     public:
632         IOHandlerConfirm (Debugger &debugger,
633                           const char *prompt,
634                           bool default_response);
635         
636         ~IOHandlerConfirm() override;
637                 
638         bool
639         GetResponse () const
640         {
641             return m_user_response;
642         }
643         
644         int
645         IOHandlerComplete (IOHandler &io_handler,
646                            const char *current_line,
647                            const char *cursor,
648                            const char *last_char,
649                            int skip_first_n_matches,
650                            int max_matches,
651                            StringList &matches) override;
652         
653         void
654         IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override;
655
656     protected:
657         const bool m_default_response;
658         bool m_user_response;
659     };
660
661     class IOHandlerCursesGUI :
662         public IOHandler
663     {
664     public:
665         IOHandlerCursesGUI (Debugger &debugger);
666         
667         ~IOHandlerCursesGUI () override;
668         
669         void
670         Run () override;
671         
672         void
673         Cancel () override;
674
675         bool
676         Interrupt () override;
677         
678         void
679         GotEOF() override;
680         
681         void
682         Activate () override;
683         
684         void
685         Deactivate () override;
686
687     protected:
688         curses::ApplicationAP m_app_ap;
689     };
690
691     class IOHandlerCursesValueObjectList :
692         public IOHandler
693     {
694     public:
695         IOHandlerCursesValueObjectList (Debugger &debugger, ValueObjectList &valobj_list);
696         
697         ~IOHandlerCursesValueObjectList() override;
698         
699         void
700         Run () override;
701         
702         void
703         GotEOF() override;
704
705     protected:
706         ValueObjectList m_valobj_list;
707     };
708
709     class IOHandlerStack
710     {
711     public:
712         IOHandlerStack () :
713             m_stack(),
714             m_mutex(Mutex::eMutexTypeRecursive),
715             m_top (nullptr)
716         {
717         }
718         
719         ~IOHandlerStack() = default;
720         
721         size_t
722         GetSize () const
723         {
724             Mutex::Locker locker (m_mutex);
725             return m_stack.size();
726         }
727         
728         void
729         Push (const lldb::IOHandlerSP& sp)
730         {
731             if (sp)
732             {
733                 Mutex::Locker locker (m_mutex);
734                 sp->SetPopped (false);
735                 m_stack.push_back (sp);
736                 // Set m_top the non-locking IsTop() call
737                 m_top = sp.get();
738             }
739         }
740         
741         bool
742         IsEmpty () const
743         {
744             Mutex::Locker locker (m_mutex);
745             return m_stack.empty();
746         }
747         
748         lldb::IOHandlerSP
749         Top ()
750         {
751             lldb::IOHandlerSP sp;
752             {
753                 Mutex::Locker locker (m_mutex);
754                 if (!m_stack.empty())
755                     sp = m_stack.back();
756             }
757             return sp;
758         }
759         
760         void
761         Pop ()
762         {
763             Mutex::Locker locker (m_mutex);
764             if (!m_stack.empty())
765             {
766                 lldb::IOHandlerSP sp (m_stack.back());
767                 m_stack.pop_back();
768                 sp->SetPopped (true);
769             }
770             // Set m_top the non-locking IsTop() call
771
772             m_top = (m_stack.empty() ? nullptr : m_stack.back().get());
773         }
774
775         Mutex &
776         GetMutex()
777         {
778             return m_mutex;
779         }
780       
781         bool
782         IsTop (const lldb::IOHandlerSP &io_handler_sp) const
783         {
784             return m_top == io_handler_sp.get();
785         }
786
787         bool
788         CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type)
789         {
790             Mutex::Locker locker (m_mutex);
791             const size_t num_io_handlers = m_stack.size();
792             return (num_io_handlers >= 2 &&
793                     m_stack[num_io_handlers-1]->GetType() == top_type &&
794                     m_stack[num_io_handlers-2]->GetType() == second_top_type);
795         }
796
797         ConstString
798         GetTopIOHandlerControlSequence (char ch)
799         {
800             return ((m_top != nullptr) ? m_top->GetControlSequence(ch) : ConstString());
801         }
802
803         const char *
804         GetTopIOHandlerCommandPrefix()
805         {
806             return ((m_top != nullptr) ? m_top->GetCommandPrefix() : nullptr);
807         }
808         
809         const char *
810         GetTopIOHandlerHelpPrologue()
811         {
812             return ((m_top != nullptr) ? m_top->GetHelpPrologue() : nullptr);
813         }
814
815         void
816         PrintAsync (Stream *stream, const char *s, size_t len);
817
818     protected:
819         typedef std::vector<lldb::IOHandlerSP> collection;
820         collection m_stack;
821         mutable Mutex m_mutex;
822         IOHandler *m_top;
823         
824     private:
825         DISALLOW_COPY_AND_ASSIGN (IOHandlerStack);
826     };
827
828 } // namespace lldb_private
829
830 #endif // liblldb_IOHandler_h_