1//===-- IOChannel.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 lldb_IOChannel_h_
11#define lldb_IOChannel_h_
12
13#include <string>
14#include <queue>
15
16#if defined(__FreeBSD__)
17#include <readline/readline.h>
18#else
19#include <editline/readline.h>
20#endif
21#include <histedit.h>
22#include <pthread.h>
23#include <sys/time.h>
24
25#include "Driver.h"
26
27class IOChannel : public lldb::SBBroadcaster
28{
29public:
30    enum {
31        eBroadcastBitHasUserInput     = (1 << 0),
32        eBroadcastBitUserInterrupt    = (1 << 1),
33        eBroadcastBitThreadShouldExit = (1 << 2),
34        eBroadcastBitThreadDidExit    = (1 << 3),
35        eBroadcastBitThreadDidStart   = (1 << 4),
36        eBroadcastBitsSTDOUT          = (1 << 5),
37        eBroadcastBitsSTDERR          = (1 << 6),
38        eBroadcastBitsSTDIN           = (1 << 7),
39        eAllEventBits                 = 0xffffffff
40    };
41
42    enum LibeditGetInputResult
43    {
44        eLibeditGetInputEOF = 0,
45        eLibeditGetInputValid = 1,
46        eLibeditGetInputEmpty = 2,
47        eLibeditGetInputResultError = 4,
48        eLibeditGetInputResultUnknown = 0xffffffff
49    };
50
51    IOChannel (FILE *editline_in,
52               FILE *editline_out,
53               FILE *out,
54               FILE *err,
55               Driver *driver = NULL);
56
57    virtual
58    ~IOChannel ();
59
60    bool
61    Start ();
62
63    bool
64    Stop ();
65
66    static void *
67    IOReadThread (void *);
68
69    void
70    Run ();
71
72    void
73    OutWrite (const char *buffer, size_t len, bool asynchronous);
74
75    void
76    ErrWrite (const char *buffer, size_t len, bool asynchronous);
77
78    LibeditGetInputResult
79    LibeditGetInput (std::string &);
80
81    static void
82    LibeditOutputBytesReceived (void *baton, const void *src,size_t src_len);
83
84    void
85    SetPrompt ();
86
87    void
88    RefreshPrompt ();
89
90    void
91    AddCommandToQueue (const char *command);
92
93    bool
94    GetCommandFromQueue (std::string &cmd);
95
96    int
97    CommandQueueSize () const;
98
99    void
100    ClearCommandQueue ();
101
102    bool
103    CommandQueueIsEmpty () const;
104
105    const char *
106    GetPrompt ();
107
108    bool
109    EditLineHasCharacters ();
110
111    void
112    EraseCharsBeforeCursor ();
113
114    static unsigned char
115    ElCompletionFn (EditLine *e, int ch);
116
117    void
118    ElResize();
119
120protected:
121
122    bool
123    IsGettingCommand () const;
124
125    void
126    SetGettingCommand (bool new_value);
127
128private:
129
130    pthread_mutex_t m_output_mutex;
131    struct timeval m_enter_elgets_time;
132
133    Driver *m_driver;
134    lldb::thread_t m_read_thread;
135    bool m_read_thread_should_exit;
136    FILE *m_out_file;
137    FILE *m_err_file;
138    std::queue<std::string> m_command_queue;
139    const char *m_completion_key;
140
141    EditLine *m_edit_line;
142    History *m_history;
143    HistEvent m_history_event;
144    bool m_getting_command;
145    bool m_expecting_prompt;
146	std::string m_prompt_str;  // for accumlating the prompt as it gets written out by editline
147    bool m_refresh_request_pending;
148
149    void
150    HistorySaveLoad (bool save);
151
152    unsigned char
153    HandleCompletion (EditLine *e, int ch);
154};
155
156class IOLocker
157{
158public:
159
160    IOLocker (pthread_mutex_t &mutex);
161
162    ~IOLocker ();
163
164protected:
165
166    pthread_mutex_t *m_mutex_ptr;
167
168private:
169
170    IOLocker (const IOLocker&);
171    const IOLocker& operator= (const IOLocker&);
172};
173
174#endif  // lldb_IOChannel_h_
175