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