1 //===-- IOHandler.h ---------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_IOHandler_h_
11 #define liblldb_IOHandler_h_
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"
29 typedef std::unique_ptr<Application> ApplicationAP;
32 namespace lldb_private {
37 IOHandler (Debugger &debugger);
39 IOHandler (Debugger &debugger,
40 const lldb::StreamFileSP &input_sp,
41 const lldb::StreamFileSP &output_sp,
42 const lldb::StreamFileSP &error_sp,
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
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.
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
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
73 // Called when CTRL+C is pressed which usually causes
74 // Debugger::DispatchInputInterrupt to be called.
85 return m_active && !m_done;
115 // Prompt support isn't mandatory
120 SetPrompt (const char *prompt)
122 // Prompt support isn't mandatory
127 GetControlSequence (char ch)
129 return ConstString();
151 GetInputStreamFile();
154 GetOutputStreamFile();
157 GetErrorStreamFile();
172 SetUserData (void *user_data)
174 m_user_data = user_data;
189 //------------------------------------------------------------------
190 /// Check if the input is being supplied interactively by a user
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 //------------------------------------------------------------------
199 //------------------------------------------------------------------
200 /// Check if the input is coming from a real terminal.
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 //------------------------------------------------------------------
208 GetIsRealTerminal ();
211 Debugger &m_debugger;
212 lldb::StreamFileSP m_input_sp;
213 lldb::StreamFileSP m_output_sp;
214 lldb::StreamFileSP m_error_sp;
221 DISALLOW_COPY_AND_ASSIGN (IOHandler);
225 //------------------------------------------------------------------
226 /// A delegate class for use with IOHandler subclasses.
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
232 //------------------------------------------------------------------
233 class IOHandlerDelegate
236 enum class Completion {
242 IOHandlerDelegate (Completion completion = Completion::None) :
243 m_completion(completion),
244 m_io_handler_done (false)
254 IOHandlerActivated (IOHandler &io_handler)
259 IOHandlerComplete (IOHandler &io_handler,
260 const char *current_line,
262 const char *last_char,
263 int skip_first_n_matches,
265 StringList &matches);
267 //------------------------------------------------------------------
268 /// Called when a line or lines have been retrieved.
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 //------------------------------------------------------------------
277 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0;
279 //------------------------------------------------------------------
280 /// Called when a line in \a lines has been updated when doing
281 /// multi-line input.
284 /// Return an enumeration to indicate the status of the current
286 /// Success - The line is good and should be added to the
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
292 //------------------------------------------------------------------
294 IOHandlerLinesUpdated (IOHandler &io_handler,
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.
307 IOHandlerGetControlSequence (char ch)
309 return ConstString();
312 //------------------------------------------------------------------
313 // Intercept the IOHandler::Interrupt() calls and do something.
315 // Return true if the interrupt was handled, false if the IOHandler
316 // should continue to try handle the interrupt itself.
317 //------------------------------------------------------------------
319 IOHandlerInterrupt (IOHandler &io_handler)
324 Completion m_completion; // Support for common builtin completions
325 bool m_io_handler_done;
328 //----------------------------------------------------------------------
329 // IOHandlerDelegateMultiline
331 // A IOHandlerDelegate that handles terminating multi-line input when
332 // the last line is equal to "end_line" which is specified in the
334 //----------------------------------------------------------------------
335 class IOHandlerDelegateMultiline :
336 public IOHandlerDelegate
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 : "")
347 ~IOHandlerDelegateMultiline ()
352 IOHandlerGetControlSequence (char ch)
355 return ConstString (m_end_line + "\n");
356 return ConstString();
360 IOHandlerLinesUpdated (IOHandler &io_handler,
365 if (line_idx == UINT32_MAX)
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
371 return LineStatus::Done;
373 else if (line_idx + 1 == lines.GetSize())
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)
379 return LineStatus::Done;
382 return LineStatus::Success;
385 const std::string m_end_line;
389 class IOHandlerEditline : public IOHandler
392 IOHandlerEditline (Debugger &debugger,
393 const char *editline_name, // Used for saving history files
396 uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
397 IOHandlerDelegate &delegate);
399 IOHandlerEditline (Debugger &debugger,
400 const lldb::StreamFileSP &input_sp,
401 const lldb::StreamFileSP &output_sp,
402 const lldb::StreamFileSP &error_sp,
404 const char *editline_name, // Used for saving history files
407 uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
408 IOHandlerDelegate &delegate);
411 ~IOHandlerEditline ();
434 IOHandler::Activate();
435 m_delegate.IOHandlerActivated(*this);
439 GetControlSequence (char ch)
441 return m_delegate.IOHandlerGetControlSequence (ch);
448 SetPrompt (const char *prompt);
451 GetLine (std::string &line, bool &interrupted);
454 GetLines (StringList &lines, bool &interrupted);
457 SetBaseLineNumber (uint32_t line);
461 LineCompletedCallback (Editline *editline,
467 static int AutoCompleteCallback (const char *current_line,
469 const char *last_char,
470 int skip_first_n_matches,
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
483 class IOHandlerConfirm :
484 public IOHandlerEditline,
485 public IOHandlerDelegate
488 IOHandlerConfirm (Debugger &debugger,
490 bool default_response);
493 ~IOHandlerConfirm ();
498 return m_user_response;
502 IOHandlerComplete (IOHandler &io_handler,
503 const char *current_line,
505 const char *last_char,
506 int skip_first_n_matches,
508 StringList &matches);
511 IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
514 const bool m_default_response;
515 bool m_user_response;
518 class IOHandlerCursesGUI :
522 IOHandlerCursesGUI (Debugger &debugger);
525 ~IOHandlerCursesGUI ();
552 curses::ApplicationAP m_app_ap;
555 class IOHandlerCursesValueObjectList :
559 IOHandlerCursesValueObjectList (Debugger &debugger, ValueObjectList &valobj_list);
562 ~IOHandlerCursesValueObjectList ();
579 ValueObjectList m_valobj_list;
588 m_mutex(Mutex::eMutexTypeRecursive),
600 Mutex::Locker locker (m_mutex);
601 return m_stack.size();
605 Push (const lldb::IOHandlerSP& sp)
609 Mutex::Locker locker (m_mutex);
611 // Set m_top the non-locking IsTop() call
619 Mutex::Locker locker (m_mutex);
620 return m_stack.empty();
626 lldb::IOHandlerSP sp;
628 Mutex::Locker locker (m_mutex);
629 if (!m_stack.empty())
638 Mutex::Locker locker (m_mutex);
639 if (!m_stack.empty())
641 // Set m_top the non-locking IsTop() call
645 m_top = m_stack.top().get();
655 IsTop (const lldb::IOHandlerSP &io_handler_sp) const
657 return m_top == io_handler_sp.get();
661 GetTopIOHandlerControlSequence (char ch)
664 return m_top->GetControlSequence(ch);
665 return ConstString();
670 std::stack<lldb::IOHandlerSP> m_stack;
671 mutable Mutex m_mutex;
676 DISALLOW_COPY_AND_ASSIGN (IOHandlerStack);
679 } // namespace lldb_private
681 #endif // #ifndef liblldb_IOHandler_h_