124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- IOChannel.h ---------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef lldb_IOChannel_h_
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define lldb_IOChannel_h_
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <string>
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <queue>
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
164b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen#if defined(__FreeBSD__)
174b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen#include <readline/readline.h>
184b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen#else
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <editline/readline.h>
204b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen#endif
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <histedit.h>
22757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice#include <pthread.h>
23757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice#include <sys/time.h>
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "Driver.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass IOChannel : public lldb::SBBroadcaster
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    enum {
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitHasUserInput     = (1 << 0),
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitUserInterrupt    = (1 << 1),
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitThreadShouldExit = (1 << 2),
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitThreadDidExit    = (1 << 3),
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitThreadDidStart   = (1 << 4),
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitsSTDOUT          = (1 << 5),
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitsSTDERR          = (1 << 6),
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eBroadcastBitsSTDIN           = (1 << 7),
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eAllEventBits                 = 0xffffffff
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
41e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata
42e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata    enum LibeditGetInputResult
43e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata    {
44e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        eLibeditGetInputEOF = 0,
45e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        eLibeditGetInputValid = 1,
46e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        eLibeditGetInputEmpty = 2,
47e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        eLibeditGetInputResultError = 4,
48e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        eLibeditGetInputResultUnknown = 0xffffffff
49e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata    };
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
514a348081030cdd2af758fddc869518357d9befd3Caroline Tice    IOChannel (FILE *editline_in,
524a348081030cdd2af758fddc869518357d9befd3Caroline Tice               FILE *editline_out,
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner               FILE *out,
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner               FILE *err,
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner               Driver *driver = NULL);
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ~IOChannel ();
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Start ();
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Stop ();
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static void *
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    IOReadThread (void *);
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Run ();
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
734a348081030cdd2af758fddc869518357d9befd3Caroline Tice    OutWrite (const char *buffer, size_t len, bool asynchronous);
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
764a348081030cdd2af758fddc869518357d9befd3Caroline Tice    ErrWrite (const char *buffer, size_t len, bool asynchronous);
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
78e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata    LibeditGetInputResult
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    LibeditGetInput (std::string &);
804a348081030cdd2af758fddc869518357d9befd3Caroline Tice
814a348081030cdd2af758fddc869518357d9befd3Caroline Tice    static void
824a348081030cdd2af758fddc869518357d9befd3Caroline Tice    LibeditOutputBytesReceived (void *baton, const void *src,size_t src_len);
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SetPrompt ();
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    RefreshPrompt ();
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    AddCommandToQueue (const char *command);
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetCommandFromQueue (std::string &cmd);
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    CommandQueueSize () const;
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ClearCommandQueue ();
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    CommandQueueIsEmpty () const;
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetPrompt ();
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
108bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham    bool
109bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham    EditLineHasCharacters ();
110bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham
1118ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen    void
1128ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen    EraseCharsBeforeCursor ();
1138ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen
11454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    static unsigned char
11554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    ElCompletionFn (EditLine *e, int ch);
1162eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham
1172eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham    void
1182eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham    ElResize();
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
120757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticeprotected:
121757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    IsGettingCommand () const;
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
125757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    void
126757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    SetGettingCommand (bool new_value);
127757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate:
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
130757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    pthread_mutex_t m_output_mutex;
131757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    struct timeval m_enter_elgets_time;
132757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Driver *m_driver;
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lldb::thread_t m_read_thread;
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool m_read_thread_should_exit;
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FILE *m_out_file;
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FILE *m_err_file;
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::queue<std::string> m_command_queue;
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *m_completion_key;
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EditLine *m_edit_line;
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    History *m_history;
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    HistEvent m_history_event;
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool m_getting_command;
1454a348081030cdd2af758fddc869518357d9befd3Caroline Tice    bool m_expecting_prompt;
1464a348081030cdd2af758fddc869518357d9befd3Caroline Tice	std::string m_prompt_str;  // for accumlating the prompt as it gets written out by editline
147388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice    bool m_refresh_request_pending;
14854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    HistorySaveLoad (bool save);
15154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
15254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    unsigned char
15354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    HandleCompletion (EditLine *e, int ch);
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
156757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticeclass IOLocker
157757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{
158757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticepublic:
159757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
160757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    IOLocker (pthread_mutex_t &mutex);
161757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
162757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    ~IOLocker ();
163757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
164757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticeprotected:
165757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
166757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    pthread_mutex_t *m_mutex_ptr;
167757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
168757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticeprivate:
169757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
170757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    IOLocker (const IOLocker&);
171757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    const IOLocker& operator= (const IOLocker&);
172757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice};
173757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif  // lldb_IOChannel_h_
175