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